* Licence details can be found in the file COPYING.
*
* \author Asger Alstrup
- * \author Alfredo Braustein
+ * \author Alfredo Braunstein
* \author Lars Gullik Bjønnes
* \author Jean-Marc Lasgouttes
* \author Angus Leeming
#include "graphics/Previews.h"
-#include "mathed/math_hullinset.h"
-
#include "support/filetools.h"
#include "support/globbing.h"
#include "support/path_defines.h"
int const last = top_y() + workarea().workHeight() - height;
LyXText * text = bv_->text();
- if (text->cursorY() < first)
+ int y = text->cursorY(bv_->cursor().cursor_.front());
+ if (y < first)
text->setCursorFromCoordinates(0, first);
- else if (text->cursorY() > last)
+ else if (y > last)
text->setCursorFromCoordinates(0, last);
owner_->updateLayoutChoice();
bv_->cursor().clearSelection();
int const half_height = workarea().workHeight() / 2;
- int new_y = std::max(0, text->cursorY() - half_height);
+ int new_y = text->cursorY(bv_->cursor().cursor_.front()) - half_height;
+ if (new_y < 0)
+ new_y = 0;
// FIXME: look at this comment again ...
// This updates top_y() but means the fitCursor() call
// to do it manually. Any operation that does a center()
// and also might have moved top_y() must make sure to call
// updateScrollbar() currently. Never mind that this is a
- // pretty obfuscated way of updating t->top_y()
+ // pretty obfuscated way of updating text->top_y()
top_y(new_y);
}
if (beg.getPar() == text->cursorPar()
&& beg.getPos() >= text->cursor().pos()) {
break;
- } else if (beg.getPar() != text->cursorPar()) {
+ }
+ if (beg.getPar() != text->cursorPar()) {
break;
}
}
if (beg != end) {
// Now find the first inset that matches code.
for (; beg != end; ++beg) {
- if (beg->lyxCode() == code) {
+ if (beg->lyxCode() == code)
return &(*beg);
- }
}
}
return 0;
}
-void BufferView::Pimpl::MenuInsertLyXFile(string const & filen)
+void BufferView::Pimpl::MenuInsertLyXFile(string const & filenm)
{
- string filename = filen;
+ string filename = filenm;
if (filename.empty()) {
// Launch a file browser
void BufferView::Pimpl::trackChanges()
{
- Buffer * buf(bv_->buffer());
+ Buffer * buf = bv_->buffer();
bool const tracking(buf->params().tracking_changes);
if (!tracking) {
buf->redostack().clear();
}
-#warning remove me
-CursorBase theTempCursor;
-
-namespace {
-
- InsetBase * insetFromCoords(BufferView * bv, int x, int y)
- {
- lyxerr << "insetFromCoords" << endl;
- InsetBase * inset = 0;
- theTempCursor.clear();
- LyXText * text = bv->text();
-#warning FIXME
-#if 0
- while (true) {
- InsetBase * const inset_hit = text->checkInsetHit(x, y);
- if (!inset_hit) {
- lyxerr << "no further inset hit" << endl;
- break;
- }
- inset = inset_hit;
- if (!inset->descendable()) {
- lyxerr << "not descendable" << endl;
- break;
- }
- int const cell = inset->getCell(x, y + bv->top_y());
- if (cell == -1)
- break;
- text = inset_hit->getText(cell);
- lyxerr << "Hit inset: " << inset << " at x: " << x
- << " text: " << text << " y: " << y << endl;
- theTempCursor.push_back(CursorSlice(inset));
- }
-#endif
- //lyxerr << "theTempCursor: " << theTempCursor << endl;
- return inset;
- }
-
-}
-
-bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd)
+bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd0)
{
- LCursor & cur = bv_->cursor();
+ //
+ // this is only called for mouse related events.
+ //
+ FuncRequest cmd = cmd0;
+ cmd.y += bv_->top_y();
+ lyxerr << "*** workAreaDispatch: request: " << cmd << std::endl;
+ LCursor cur(*bv_);
switch (cmd.action) {
+#if 0
case LFUN_MOUSE_MOTION: {
if (!available())
return false;
InsetBase * inset = cur.inset();
DispatchResult res;
if (inset) {
- cmd1.x -= inset->x();
- cmd1.y -= inset->y();
- res = inset->dispatch(cur, cmd1);
+ res = inset->dispatch(cur, cmd);
} else {
- cmd1.y += bv_->top_y();
- res = cur.innerText()->dispatch(cur, cmd1);
+ res = cur.innerText()->dispatch(cur, cmd);
}
if (bv_->fitCursor() || res.update()) {
bv_->update();
cur.updatePos();
}
-
return true;
}
+#endif
+ case LFUN_MOUSE_MOTION:
case LFUN_MOUSE_PRESS:
case LFUN_MOUSE_RELEASE:
case LFUN_MOUSE_DOUBLE:
// handle this event.
// built temporary path to inset
- InsetBase * inset = insetFromCoords(bv_, cmd.x, cmd.y);
- DispatchResult res;
+ LyXText * text = bv_->text();
+ InsetBase * const inset_hit = text->checkInsetHit(cmd.x, cmd.y);
+ if (inset_hit)
+ inset_hit->edit(cur, cmd.x, cmd.y);
+ else
+ text->setCursorFromCoordinates(cur.current(), cmd.x, cmd.y);
+ lyxerr << "created temp cursor: " << cur << endl;
- // try to dispatch to that inset
- if (inset) {
- FuncRequest cmd2 = cmd;
- lyxerr << "dispatching action " << cmd2.action
- << " to inset " << inset << endl;
- cmd2.x -= inset->x();
- cmd2.y -= inset->y();
- res = inset->dispatch(cur, cmd2);
- if (res.update()) {
- bv_->update();
- cur.updatePos();
- }
- res.update(false);
- switch (res.val()) {
- case FINISHED:
- case FINISHED_RIGHT:
- case FINISHED_UP:
- case FINISHED_DOWN:
- theTempCursor.pop_back();
- cur.cursor_ = theTempCursor;
- cur.innerText()
- ->setCursorFromCoordinates(cmd.x, top_y() + cmd.y);
- if (bv_->fitCursor())
- bv_->update();
- return true;
- default:
- lyxerr << "not dispatched by inner inset val: " << res.val() << endl;
- break;
- }
- }
+ // Dispatch to the temp cursor.
+ // An inset (or LyXText) can assign this to bv->cursor()
+ // if it wishes to do so.
+ DispatchResult res = cur.dispatch(cmd);
+
+ if (bv_->fitCursor() || res.update())
+ bv_->update();
- // otherwise set cursor to surrounding LyXText
- if (!res.dispatched()) {
- //lyxerr << "temp cursor is: " << theTempCursor << endl;
- //lyxerr << "dispatching " << cmd
- // << " to surrounding LyXText "
- // << theTempCursor.innerText() << endl;
- cur.cursor_ = theTempCursor;
- FuncRequest cmd1 = cmd;
- cmd1.y += bv_->top_y();
- res = cur.innerText()->dispatch(cur, cmd1);
- if (bv_->fitCursor() || res.update())
- bv_->update();
-
- //return DispatchResult(true, true);
- }
// see workAreaKeyPress
cursor_timeout.restart();
screen().showCursor(*bv_);
}
default:
- owner_->dispatch(cmd);
- return true;
+ lyxerr << "*** UNDISPATCHED: " << cmd;
+ //owner_->dispatch(cmd);
}
+ return true;
}
-bool BufferView::Pimpl::dispatch(FuncRequest const & ev)
+bool BufferView::Pimpl::dispatch(FuncRequest const & cmd)
{
+ lyxerr << "*** BufferView::Pimpl: request: " << cmd << std::endl;
// Make sure that the cached BufferView is correct.
lyxerr[Debug::ACTION] << "BufferView::Pimpl::Dispatch:"
- << " action[" << ev.action << ']'
- << " arg[" << ev.argument << ']'
- << " x[" << ev.x << ']'
- << " y[" << ev.y << ']'
- << " button[" << ev.button() << ']'
+ << " action[" << cmd.action << ']'
+ << " arg[" << cmd.argument << ']'
+ << " x[" << cmd.x << ']'
+ << " y[" << cmd.y << ']'
+ << " button[" << cmd.button() << ']'
<< endl;
LyXTextClass const & tclass = buffer_->params().getLyXTextClass();
LCursor & cur = bv_->cursor();
- switch (ev.action) {
+ switch (cmd.action) {
case LFUN_SCROLL_INSET:
// this is not handled here as this function is only active
break;
case LFUN_FILE_INSERT:
- MenuInsertLyXFile(ev.argument);
+ MenuInsertLyXFile(cmd.argument);
break;
case LFUN_FILE_INSERT_ASCII_PARA:
- InsertAsciiFile(bv_, ev.argument, true);
+ InsertAsciiFile(bv_, cmd.argument, true);
break;
case LFUN_FILE_INSERT_ASCII:
- InsertAsciiFile(bv_, ev.argument, false);
+ InsertAsciiFile(bv_, cmd.argument, false);
break;
case LFUN_FONT_STATE:
case LFUN_INSERT_LABEL: {
// Try and generate a valid label
- string const contents = ev.argument.empty() ?
- getPossibleLabel(*bv_) : ev.argument;
+ string const contents = cmd.argument.empty() ?
+ getPossibleLabel(*bv_) : cmd.argument;
InsetCommandParams icp("label", contents);
string data = InsetCommandMailer::params2string("label", icp);
owner_->getDialogs().show("label", data, 0);
}
case LFUN_BOOKMARK_SAVE:
- savePosition(strToUnsignedInt(ev.argument));
+ savePosition(strToUnsignedInt(cmd.argument));
break;
case LFUN_BOOKMARK_GOTO:
- restorePosition(strToUnsignedInt(ev.argument));
+ restorePosition(strToUnsignedInt(cmd.argument));
break;
case LFUN_REF_GOTO: {
- string label = ev.argument;
+ string label = cmd.argument;
if (label.empty()) {
InsetRef * inset =
static_cast<InsetRef*>(getInsetByCode(InsetBase::REF_CODE));
case LFUN_HUNG_UMLAUT:
case LFUN_CIRCLE:
case LFUN_OGONEK:
- if (ev.argument.empty()) {
+ if (cmd.argument.empty()) {
// As always...
- owner_->getLyXFunc().handleKeyFunc(ev.action);
+ owner_->getLyXFunc().handleKeyFunc(cmd.action);
} else {
- owner_->getLyXFunc().handleKeyFunc(ev.action);
+ owner_->getLyXFunc().handleKeyFunc(cmd.action);
owner_->getIntl().getTransManager()
- .TranslateAndInsert(ev.argument[0], bv_->getLyXText());
+ .TranslateAndInsert(cmd.argument[0], bv_->getLyXText());
update();
}
break;
- case LFUN_MATH_MACRO:
- case LFUN_MATH_DELIM:
- case LFUN_INSERT_MATRIX:
- case LFUN_INSERT_MATH:
- case LFUN_MATH_IMPORT_SELECTION: // Imports LaTeX from the X selection
- case LFUN_MATH_DISPLAY: // Open or create a displayed math inset
- case LFUN_MATH_MODE: // Open or create an inlined math inset
- mathDispatch(cur, ev);
- break;
-
case LFUN_INSET_INSERT: {
// Same as above.
BOOST_ASSERT(false);
- InsetBase * inset = createInset(bv_, ev);
+ InsetBase * inset = createInset(bv_, cmd);
if (!inset || !insertInset(inset))
delete inset;
break;
}
case LFUN_FLOAT_LIST:
- if (tclass.floats().typeExist(ev.argument)) {
- InsetBase * inset = new InsetFloatList(ev.argument);
+ if (tclass.floats().typeExist(cmd.argument)) {
+ InsetBase * inset = new InsetFloatList(cmd.argument);
if (!insertInset(inset, tclass.defaultLayoutName()))
delete inset;
} else {
lyxerr << "Non-existent float type: "
- << ev.argument << endl;
+ << cmd.argument << endl;
}
break;
break;
case LFUN_PARAGRAPH_APPLY:
- setParagraphParams(*bv_, ev.argument);
+ setParagraphParams(*bv_, cmd.argument);
break;
case LFUN_THESAURUS_ENTRY: {
- string arg = ev.argument;
+ string arg = cmd.argument;
if (arg.empty()) {
arg = bv_->getLyXText()->selectionAsString(*buffer_,
}
case LFUN_WORD_FIND:
- lyx::find::find(bv_, ev);
+ lyx::find::find(bv_, cmd);
break;
case LFUN_WORD_REPLACE:
- lyx::find::replace(bv_, ev);
+ lyx::find::replace(bv_, cmd);
break;
case LFUN_MARK_OFF:
cur.clearSelection();
bv_->update();
cur.resetAnchor();
- ev.message(N_("Mark off"));
+ cmd.message(N_("Mark off"));
break;
case LFUN_MARK_ON:
cur.mark() = true;
bv_->update();
cur.resetAnchor();
- ev.message(N_("Mark on"));
+ cmd.message(N_("Mark on"));
break;
case LFUN_SETMARK:
cur.clearSelection();
if (cur.mark()) {
- ev.message(N_("Mark removed"));
+ cmd.message(N_("Mark removed"));
} else {
cur.mark() = true;
- ev.message(N_("Mark set"));
+ cmd.message(N_("Mark set"));
}
cur.resetAnchor();
bv_->update();
break;
case LFUN_UNKNOWN_ACTION:
- ev.errorMessage(N_("Unknown function!"));
+ cmd.errorMessage(N_("Unknown function!"));
break;
default:
- return cur.dispatch(ev).dispatched();
- } // end of switch
+ return cur.dispatch(cmd).dispatched();
+ }
return true;
}
+
+
+2004-01-30 André Pönitz <poenitz@gmx.net>
+
+ * BufferView_pimpl.C:
+ * cursor.C:
+ * cursor.h:
+ * cursor_slice.[Ch]:
+ * lyxfunc.C:
+ * lyxtext.h:
+ * paragraph_funcs.C:
+ * paragraph_funcs.h:
+ * rowpainter.C:
+ * text.C:
+ * text2.C:
+ * text3.C: move some of the edit(x,y) handling to the insets
+ some coordinate changes.
+
2004-01-28 Lars Gullik Bjonnes <larsbj@gullik.net>
* text.C: add using statements for std::advance and std::distance
anchor_.push_back(CursorSlice());
current_ = 0;
cached_y_ = 0;
- x_target_ = -1;
+ clearTargetX();
selection_ = false;
mark_ = false;
}
DispatchResult LCursor::dispatch(FuncRequest const & cmd0)
{
- lyxerr << "\nLCursor::dispatch: " << *this << endl;
+ //lyxerr << "\nLCursor::dispatch: cmd: " << cmd0 << endl << *this << endl;
FuncRequest cmd = cmd0;
for (int i = cursor_.size() - 1; i >= 1; --i) {
lyxerr << "trying to dispatch to main text " << bv_->text() << endl;
DispatchResult res = bv_->text()->dispatch(*this, cmd);
lyxerr << " result: " << res.val() << endl;
-
- if (!res.dispatched()) {
- lyxerr << "trying to dispatch to bv " << bv_ << endl;
- bool sucess = bv_->dispatch(cmd);
- lyxerr << " result: " << sucess << endl;
- res.dispatched(sucess);
- }
-
return res;
}
void LCursor::pop(int depth)
{
- lyxerr << "LCursor::pop() to depth " << depth << endl;
+ //lyxerr << "LCursor::pop() to depth " << depth << endl;
while (int(cursor_.size()) > depth)
pop();
}
void LCursor::pop()
{
- lyxerr << "LCursor::pop() a level" << endl;
- //BOOST_ASSERT(!cursor_.empty());
+ BOOST_ASSERT(!cursor_.empty());
+ //lyxerr << "LCursor::pop() a level" << endl;
if (cursor_.size() <= 1)
lyxerr << "### TRYING TO POP FROM EMPTY CURSOR" << endl;
else {
anchor_.pop_back();
current_ = cursor_.size() - 1;
}
- lyxerr << "LCursor::pop() current now: " << current_ << endl;
+ //lyxerr << "LCursor::pop() current now: " << current_ << endl;
}
void LCursor::pushLeft(InsetBase * p)
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "Entering inset " << t << " left" << endl;
push(p);
p->idxFirst(*this);
bool LCursor::popLeft()
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "Leaving inset to the left" << endl;
if (depth() <= 1) {
if (depth() == 1)
bool LCursor::popRight()
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "Leaving inset to the right" << endl;
if (depth() <= 1) {
if (depth() == 1)
CursorSlice & LCursor::current()
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "accessing cursor slice " << current_
// << ": " << cursor_[current_] << endl;
return cursor_[current_];
int LCursor::currentMode()
{
+ BOOST_ASSERT(!cursor_.empty());
for (int i = cursor_.size() - 1; i >= 1; --i) {
int res = cursor_[i].inset()->currentMode();
if (res != MathInset::UNDECIDED_MODE)
LyXText * LCursor::innerText() const
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "LCursor::innerText() depth: " << cursor_.size() << endl;
if (cursor_.size() > 1) {
// go up until first non-0 text is hit
CursorSlice const & LCursor::innerTextSlice() const
{
+ BOOST_ASSERT(!cursor_.empty());
//lyxerr << "LCursor::innerTextSlice() depth: " << cursor_.size() << endl;
if (cursor_.size() > 1) {
// go up until first non-0 text is hit
void LCursor::updatePos()
{
+ BOOST_ASSERT(!cursor_.empty());
if (cursor_.size() > 1)
- cached_y_ = bv_->top_y() + cursor_.back().inset()->y();
+ cached_y_ = bv_->top_y() + cursor_.back().inset()->yo();
+ //cached_y_ = cursor_.back().inset()->yo();
}
-void LCursor::getDim(int & asc, int & desc) const
+void LCursor::getDim(int & asc, int & des) const
{
- LyXText * txt = innerText();
-
- if (txt) {
- Row const & row = *txt->cursorRow();
- asc = row.baseline();
- desc = row.height() - asc;
+ BOOST_ASSERT(!cursor_.empty());
+ LyXText * text = innerText();
+#warning crashes with text-in-math
+ if (0 && text) {
+ RowList::iterator const rit = text->cursorRow();
+ if (rit != text->endRow()) {
+ asc = rit->baseline();
+ des = rit->height() - asc;
+ } else {
+ asc = 10;
+ des = 10;
+ }
} else {
asc = 10;
- desc = 10;
- //innerInset()->getCursorDim(asc, desc);
+ des = 10;
+ //innerInset()->getCursorDim(asc, des);
}
}
void LCursor::getPos(int & x, int & y) const
{
+ BOOST_ASSERT(!cursor_.empty());
+ x = 0;
+ y = 0;
if (cursor_.size() <= 1) {
- x = bv_->text()->cursorX();
- y = bv_->text()->cursorY();
-// y -= bv_->top_y();
+ x = bv_->text()->cursorX(cursor_.front());
+ y = bv_->text()->cursorY(cursor_.front());
} else {
- if (inset()->asUpdatableInset()) {
- // Would be nice to clean this up to make some understandable sense...
- // Non-obvious. The reason we have to have these
- // extra checks is that the ->getCursor() calls rely
- // on the inset's own knowledge of its screen position.
- // If we scroll up or down in a big enough increment, the
- // inset->draw() is not called: this doesn't update
- // inset.top_baseline, so getCursor() returns an old value.
- // Ugly as you like.
- inset()->asUpdatableInset()->getCursorPos(cursor_.back().idx_, x, y);
- x += inset()->asUpdatableInset()->x();
- y += cached_y_;
- } else if (inset()->asMathInset()) {
- getScreenPos(x, y);
- } else {
- // this should not happen
- BOOST_ASSERT(false);
- }
+ inset()->getCursorPos(cursor_.back(), x, y);
+ // getCursorPos gives _screen_ coordinates. We need to add
+ // top_y to get document coordinates. This is hidden in cached_y_.
+ //y += cached_y_ - inset()->yo();
+ // The rest is non-obvious. The reason we have to have these
+ // extra computation is that the getCursorPos() calls rely
+ // on the inset's own knowledge of its screen position.
+ // If we scroll up or down in a big enough increment,
+ // inset->draw() is not called: this doesn't update
+ // inset.yo_, so getCursor() returns an old value.
+ // Ugly as you like.
}
+ lyxerr << "#### LCursor::getPos: x: " << x << " y: " << y << endl;
}
}
-void LCursor::x_target(int x)
+int & LCursor::x_target()
{
- x_target_ = x;
+ return x_target_;
}
}
+void LCursor::clearTargetX()
+{
+ x_target_ = -1;
+}
+
+
Paragraph & LCursor::paragraph()
{
return current_ ? current().paragraph() : *bv_->text()->getPar(par());
LCursor::pos_type LCursor::lastpos() const
{
- CursorSlice const & cur = current();
- if (cur.inset() && cur.inset()->asMathInset())
- return cell().size();
- else
- return paragraph().size();
+ InsetBase * inset = current().inset();
+ return inset && inset->asMathInset() ? cell().size() : paragraph().size();
}
bool LCursor::left()
{
autocorrect() = false;
- x_target(-1); // "no target"
+ clearTargetX();
if (inMacroMode()) {
macroModeClose();
return true;
if (pos() != 0 && openable(prevAtom())) {
posLeft();
- push(inset());
- inset()->idxFirst(*this);
+ push(nextAtom().nucleus());
+ inset()->idxLast(*this);
return true;
}
bool LCursor::right()
{
autocorrect() = false;
- x_target(-1); // "no target"
+ clearTargetX();
if (inMacroMode()) {
macroModeClose();
return true;
}
if (pos() != lastpos() && openable(nextAtom())) {
- pushLeft(inset());
+ pushLeft(nextAtom().nucleus());
+ inset()->idxFirst(*this);
return true;
}
return false;
// anchor might be deeper, should have same path then
- for (CursorBase::size_type i = 0; i < cursor.size(); ++i)
+ for (size_t i = 0; i < cursor.size(); ++i)
if (cursor[i].inset() != anchor[i].inset())
return false;
idx() = 0;
pos() = 0;
}
- x_target(-1); // "no target"
+ clearTargetX();
}
macroModeClose();
if (!inset()->idxHome(*this))
return popLeft();
- x_target(-1); // "no target"
+ clearTargetX();
return true;
}
macroModeClose();
if (!inset()->idxEnd(*this))
return popRight();
- x_target(-1); // "no target"
+ clearTargetX();
return true;
}
void LCursor::insert(string const & str)
{
- //lyxerr << "inserting '" << str << "'" << endl;
+ lyxerr << "inserting '" << str << "'" << endl;
selClearOrDel();
for (string::const_iterator it = str.begin(); it != str.end(); ++it)
plainInsert(MathAtom(new MathCharInset(*it)));
void LCursor::insert(char c)
{
- //lyxerr << "inserting '" << c << "'" << endl;
+ lyxerr << "inserting '" << c << "'" << endl;
selClearOrDel();
plainInsert(MathAtom(new MathCharInset(c)));
}
void LCursor::niceInsert(string const & t)
{
+ lyxerr << "*** LCursor::niceInsert 1: " << t << endl;
MathArray ar;
asArray(t, ar);
if (ar.size() == 1)
void LCursor::niceInsert(MathAtom const & t)
{
+ lyxerr << "*** LCursor::niceInsert 2: " << t << endl;
macroModeClose();
string safe = grabAndEraseSelection();
plainInsert(t);
// enter the new inset and move the contents of the selection if possible
if (t->isActive()) {
posLeft();
- pushLeft(inset());
+ pushLeft(nextAtom().nucleus());
paste(safe);
}
+ lyxerr << "*** LCursor::niceInsert 3: " << t << endl;
}
void LCursor::handleNest(MathAtom const & a, int c)
{
- MathAtom at = a;
- asArray(grabAndEraseSelection(), at.nucleus()->cell(c));
- insert(at);
+ MathAtom t = a;
+ asArray(grabAndEraseSelection(), t.nucleus()->cell(c));
+ insert(t);
posLeft();
- pushLeft(inset());
-}
-
-
-void LCursor::getScreenPos(int & x, int & y) const
-{
- BOOST_ASSERT(inset());
- BOOST_ASSERT(inset()->asMathInset());
- inset()->asMathInset()->getScreenPos(idx(), pos(), x, y);
+ pushLeft(t.nucleus());
}
return x_target();
int x = 0;
int y = 0;
- getScreenPos(x, y);
+ getPos(x, y);
return x;
}
// So fiddle around with it only if you know what you are doing!
int xo = 0;
int yo = 0;
- getScreenPos(xo, yo);
+ getPos(xo, yo);
// check if we had something else in mind, if not, this is the future goal
if (x_target() == -1)
- x_target(xo);
+ x_target() = xo;
else
xo = x_target();
// any improvement so far?
int xnew, ynew;
- getScreenPos(xnew, ynew);
+ getPos(xnew, ynew);
if (up ? ynew < yo : ynew > yo)
return true;
}
// avoid invalid nesting when selecting
if (!selection() || positionable(it, anchor_)) {
int xo, yo;
- it.back().getScreenPos(xo, yo);
+ CursorSlice & cur = it.back();
+ cur.inset()->getCursorPos(cur, xo, yo);
if (xlow <= xo && xo <= xhigh && ylow <= yo && yo <= yhigh) {
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
//lyxerr << "x: " << x << " y: " << y << " d: " << endl;
et.back().pos(n);
for (int i = 0; ; ++i) {
int xo, yo;
- it.back().getScreenPos(xo, yo);
+ CursorSlice & cur = it.back();
+ cur.inset()->getCursorPos(cur, xo, yo);
double d = (x - xo) * (x - xo) + (y - yo) * (y - yo);
// '<=' in order to take the last possible position
// this is important for clicking behind \sum in e.g. '\sum_i a'
bool LCursor::interpret(char c)
{
//lyxerr << "interpret 2: '" << c << "'" << endl;
- x_target(-1); // "no target"
+ clearTargetX();
if (inMacroArgMode()) {
posLeft();
plainErase();
// mouse clicks are somewhat special
// check
switch (cmd.action) {
- case LFUN_MOUSE_PRESS:
- case LFUN_MOUSE_MOTION:
- case LFUN_MOUSE_RELEASE:
- case LFUN_MOUSE_DOUBLE: {
- CursorSlice & pos = cursor_.back();
- int x = 0;
- int y = 0;
- getScreenPos(x, y);
- if (x < cmd.x && pos() != 0) {
- DispatchResult const res = prevAtom().nucleus()->dispatch(cmd);
- if (res.dispatched())
- return res;
- }
- if (x > cmd.x && pos() != lastpos()) {
- DispatchResult const res = inset()->dispatch(cmd);
- if (res.dispatched())
- return res;
- }
+ case LFUN_MOUSE_PRESS:
+ case LFUN_MOUSE_MOTION:
+ case LFUN_MOUSE_RELEASE:
+ case LFUN_MOUSE_DOUBLE: {
+ CursorSlice & pos = cursor_.back();
+ int x = 0;
+ int y = 0;
+ getPos(x, y);
+ if (x < cmd.x && pos() != 0) {
+ DispatchResult const res = prevAtom().nucleus()->dispatch(cmd);
+ if (res.dispatched())
+ return res;
}
- default:
- break;
+ if (x > cmd.x && pos() != lastpos()) {
+ DispatchResult const res = inset()->dispatch(cmd);
+ if (res.dispatched())
+ return res;
+ }
+ }
+ default:
+ break;
}
- /...
}
*/
///
bool boundary() const { return current().boundary(); }
///
+ bool & boundary() { return current().boundary(); }
+ ///
Paragraph & paragraph();
///
Paragraph const & paragraph() const;
/// move one step to the right
bool posRight();
- /// set target x position of cursor
- void x_target(int x);
+ /// write acess to target x position of cursor
+ int & x_target();
/// return target x position of cursor
int x_target() const;
+ /// clear target x position of cursor
+ void clearTargetX();
/// access to selection anchor
CursorSlice & anchor();
std::vector<CursorSlice> anchor_;
private:
- /// don't implement this
- void operator=(LCursor const &);
- /// don't implement this
- LCursor(LCursor const &);
-
///
- BufferView * const bv_;
+ BufferView * bv_;
/// current slice
int current_;
///
/// in pixels from top of screen
void setScreenPos(int x, int y);
- /// in pixels from top of screen
- void getScreenPos(int & x, int & y) const;
/// in pixels from left of screen
int targetX() const;
/// return the next enclosing grid inset and the cursor's index in it
}
+bool & CursorSlice::boundary()
+{
+ return boundary_;
+}
+
+
CursorSlice::row_type CursorSlice::row() const
{
BOOST_ASSERT(asMathInset());
}
-void CursorSlice::getScreenPos(int & x, int & y) const
-{
- BOOST_ASSERT(asMathInset());
- asMathInset()->getScreenPos(idx_, pos_, x, y);
-}
-
-
LyXText * CursorSlice::text() const
{
- return asUpdatableInset() ? asUpdatableInset()->getText(idx_) : 0;
+ inset_ ? inset_->getText(idx_) : 0;
}
std::ostream & operator<<(std::ostream & os, CursorSlice const & item)
{
os << "inset: " << item.inset_
-// << " text: " << item.text()
+ << " text: " << item.text()
<< " idx: " << item.idx_
<< " par: " << item.par_
<< " pos: " << item.pos_
/// return the grid row of the current cell
col_type col() const;
- /// FIXME
- void boundary(bool b);
- /// FIXME
- bool boundary() const;
///
/// texted specific stuff
///
+ /// see comment for the member
+ void boundary(bool b);
+ /// see comment for the member
+ bool boundary() const;
+ /// see comment for the member
+ bool & boundary();
///
LyXText * text() const;
///
///
/// returns cell corresponding to this position
MathArray & cell() const;
- /// gets screen position of the thing
- void getScreenPos(int & x, int & y) const;
///
MathInset * asMathInset() const;
int x, y, asc, desc;
bv->cursor().getPos(x, y);
+ //lyxerr << "LyXScreen::fitCursor: x: " << x << " y: " << y
+ // << " top_y: " << top_y << endl;
bv->cursor().getDim(asc, desc);
bool const big_row = h / 4 < asc + desc && asc + desc < h;
+
+2004-01-30 André Pönitz <poenitz@gmx.net>
+ * inset.[Ch]:
+ * insetbase.[Ch]:
+ * insetcharstyle.C:
+ * insetcollapsable.[Ch]:
+ * insetcommand.C:
+ * insetexternal.C:
+ * insetgraphics.[Ch]:
+ * insetinclude.C:
+ * insettabular.[Ch]:
+ * insettext.[Ch]:
+ * insetvspace.C:
+ * updatableinset.[Ch]: adjust coordinate handling to 'screen absolute'
+ coordinate
+
2004-01-28 Lars Gullik Bjonnes <larsbj@gullik.net>
* insettabular.C: add using statement for std::vector, remove
return scx;
return 0;
}
+
+
+void InsetOld::setPosCache(PainterInfo const &, int x, int y) const
+{
+ xo_ = x;
+ yo_ = y;
+}
virtual void setBackgroundColor(LColor_color);
///
LColor_color backgroundColor() const;
+ /// set x/y drawing position cache
+ void setPosCache(PainterInfo const &, int, int) const;
///
- int x() const { return xo_; }
+ int xo() const { return xo_; }
///
- int y() const { return yo_; }
+ int yo() const { return yo_; }
/// returns the actual scroll-value
virtual int scroll(bool recursive = true) const;
#include <config.h>
#include "insetbase.h"
+
+#include "BufferView.h"
+#include "LColor.h"
+#include "cursor.h"
#include "debug.h"
+#include "dimension.h"
#include "dispatchresult.h"
#include "gettext.h"
#include "lyxtext.h"
+#include "metricsinfo.h"
+
+#include "frontends/Painter.h"
+
DispatchResult InsetBase::dispatch(LCursor & cur, FuncRequest const & cmd)
}
-void InsetBase::getScreenPos(idx_type, pos_type, int & x, int & y) const
-{
- lyxerr << "InsetBase::getScreenPos() called directly!" << std::endl;
- x = y = 0;
-}
-
-
int InsetBase::plaintext(Buffer const &,
std::ostream &, OutputParams const &) const
{
}
-bool InsetBase::insetAllowed(InsetBase * inset) const
-{
- return insetAllowed(inset->lyxCode());
-}
-
-
std::string const & InsetBase::getInsetName() const
{
static std::string const name = "unknown";
void InsetBase::markErased()
{}
+
+void InsetBase::getCursorPos(CursorSlice const &, int & x, int & y) const
+{
+ lyxerr << "InsetBase::getCursorPos called directly" << std::endl;
+ x = 100;
+ y = 100;
+}
+
+
+void InsetBase::metricsMarkers(Dimension & dim, int) const
+{
+ dim.wid += 2;
+ dim.asc += 1;
+}
+
+
+void InsetBase::metricsMarkers2(Dimension & dim, int) const
+{
+ dim.wid += 2;
+ dim.asc += 1;
+ dim.des += 1;
+}
+
+
+void InsetBase::drawMarkers(PainterInfo & pi, int x, int y) const
+{
+ if (!editing(pi.base.bv))
+ return;
+ int const t = x + width() - 1;
+ int const d = y + descent();
+ pi.pain.line(x, d - 3, x, d, LColor::mathframe);
+ pi.pain.line(t, d - 3, t, d, LColor::mathframe);
+ pi.pain.line(x, d, x + 3, d, LColor::mathframe);
+ pi.pain.line(t - 3, d, t, d, LColor::mathframe);
+ setPosCache(pi, x, y);
+}
+
+
+void InsetBase::drawMarkers2(PainterInfo & pi, int x, int y) const
+{
+ if (!editing(pi.base.bv))
+ return;
+ drawMarkers(pi, x, y);
+ int const t = x + width() - 1;
+ int const a = y - ascent();
+ pi.pain.line(x, a + 3, x, a, LColor::mathframe);
+ pi.pain.line(t, a + 3, t, a, LColor::mathframe);
+ pi.pain.line(x, a, x + 3, a, LColor::mathframe);
+ pi.pain.line(t - 3, a, t, a, LColor::mathframe);
+ setPosCache(pi, x, y);
+}
+
+
+bool InsetBase::editing(BufferView * bv) const
+{
+ return bv->cursor().isInside(this);
+}
+
+
+bool InsetBase::covers(int x, int y) const
+{
+ return x >= xo()
+ && x <= xo() + width()
+ && y >= yo() - ascent()
+ && y <= yo() + descent();
+}
+
+
/////////////////////////////////////////
-bool isEditableInset(InsetBase const * i)
+bool isEditableInset(InsetBase const * inset)
{
- return i && i->editable();
+ return inset && inset->editable();
}
-bool isHighlyEditableInset(InsetBase const * i)
+bool isHighlyEditableInset(InsetBase const * inset)
{
- return i && i->editable() == InsetBase::HIGHLY_EDITABLE;
+ return inset && inset->editable() == InsetBase::HIGHLY_EDITABLE;
}
class Buffer;
class BufferView;
+class CursorSlice;
class DispatchResult;
class FuncRequest;
class LaTeXFeatures;
namespace lyx { namespace graphics { class PreviewLoader; } }
+
/// Common base class to all insets
// Do not add _any_ (non-static) data members as this would inflate
virtual void metrics(MetricsInfo & mi, Dimension & dim) const = 0;
/// draw inset and update (xo, yo)-cache
virtual void draw(PainterInfo & pi, int x, int y) const = 0;
+ ///
+ virtual bool editing(BufferView * bv) const;
+ /// draw four angular markers
+ void drawMarkers(PainterInfo & pi, int x, int y) const;
+ /// draw two angular markers
+ void drawMarkers2(PainterInfo & pi, int x, int y) const;
+ /// add space for markers
+ void metricsMarkers(Dimension & dim, int framesize = 1) const;
+ /// add space for markers
+ void metricsMarkers2(Dimension & dim, int framesize = 1) const;
/// last drawn position for 'important' insets
- virtual int x() const { return 0; }
+ virtual int xo() const { return 0; }
/// last drawn position for 'important' insets
- virtual int y() const { return 0; }
+ virtual int yo() const { return 0; }
+ /// set x/y drawing position cache if available
+ virtual void setPosCache(PainterInfo const &, int, int) const {}
+ /// do we cover screen position x/y?
+ virtual bool covers(int x, int y) const;
+ /// get the screen positions of the cursor (see note in cursor.C)
+ virtual void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
/// is this an inset that can be moved into?
virtual bool isActive() const { return nargs() > 0; }
virtual int cellYOffset(idx_type) const { return 0; }
/// can we enter this cell?
virtual bool validCell(idx_type) const { return true; }
- /// get coordinates
- virtual void getScreenPos(idx_type idx, pos_type pos, int & x, int & y) const;
/// number of embedded cells
virtual size_t nargs() const { return 0; }
/// number of rows in gridlike structures
};
/// returns true the inset can hold an inset of given type
virtual bool insetAllowed(Code) const { return false; }
- /// wrapper around the above
- bool insetAllowed(InsetBase * inset) const;
// if this inset has paragraphs should they be output all as default
// paragraphs with "Standard" layout?
virtual bool forceDefaultParagraphs(InsetBase const *) const { return false; }
void InsetCharStyle::draw(PainterInfo & pi, int x, int y) const
{
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
// FIXME: setStatus(Inlined); this is not a const operation
LyXFont tmpfont = pi.base.font;
using std::ostream;
-InsetCollapsable::InsetCollapsable(BufferParams const & bp, CollapseStatus status)
- : UpdatableInset(), inset(bp), status_(status),
- label("Label")
+InsetCollapsable::InsetCollapsable(BufferParams const & bp,
+ CollapseStatus status)
+ : inset(bp), label("Label"), status_(status)
{
inset.setOwner(this);
inset.setAutoBreakRows(true);
inset.setDrawFrame(InsetText::ALWAYS);
inset.setFrameColor(LColor::collapsableframe);
setInsetName("Collapsable");
-
setButtonLabel();
}
InsetCollapsable::InsetCollapsable(InsetCollapsable const & in)
- : UpdatableInset(in), inset(in.inset), status_(in.status_),
- labelfont_(in.labelfont_), label(in.label)
+ : UpdatableInset(in), inset(in.inset),
+ labelfont_(in.labelfont_), label(in.label), status_(in.status_)
{
inset.setOwner(this);
setButtonLabel();
}
inset.read(buf, lex);
- if (!token_found) {
- if (isOpen())
- status_ = Open;
- else
- status_ = Collapsed;
- }
+ if (!token_found)
+ status_ = isOpen() ? Open : Collapsed;
setButtonLabel();
}
void InsetCollapsable::draw(PainterInfo & pi, int x, int y) const
{
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
if (status_ == Inlined) {
inset.draw(pi, x, y);
}
-FuncRequest InsetCollapsable::adjustCommand(FuncRequest const & cmd)
-{
- FuncRequest cmd1 = cmd;
- cmd1.y += ascent() - height_collapsed();
- return cmd1;
-}
-
-
DispatchResult
InsetCollapsable::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd)
{
return DispatchResult(false, FINISHED_RIGHT);
}
lyxerr << "InsetCollapsable::lfunMouseRelease 3" << endl;
- return inset.dispatch(cur, adjustCommand(cmd));
+ return inset.dispatch(cur, cmd);
case Inlined:
return inset.dispatch(cur, cmd);
void InsetCollapsable::edit(LCursor & cur, bool left)
{
- lyxerr << "InsetCollapsable: edit left/right" << endl;
+ //lyxerr << "InsetCollapsable: edit left/right" << endl;
cur.push(this);
inset.edit(cur, left);
open();
void InsetCollapsable::edit(LCursor & cur, int x, int y)
{
cur.push(this);
- lyxerr << "InsetCollapsable: edit xy" << endl;
+ //lyxerr << "InsetCollapsable: edit xy" << endl;
if (status_ == Collapsed) {
setStatus(Open);
} else {
DispatchResult
InsetCollapsable::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{
- //lyxerr << "\nInsetCollapsable::priv_dispatch (begin): cmd: " << cmd
- // << " button y: " << button_dim.y2 << endl;
+ lyxerr << "\nInsetCollapsable::priv_dispatch (begin): cmd: " << cmd
+ << " button y: " << button_dim.y2 << endl;
switch (cmd.action) {
case LFUN_MOUSE_PRESS:
if (status_ == Inlined)
inset.dispatch(cur, cmd);
else if (status_ == Open && cmd.y > button_dim.y2)
- inset.dispatch(cur, adjustCommand(cmd));
+ inset.dispatch(cur, cmd);
return DispatchResult(true, true);
case LFUN_MOUSE_MOTION:
if (status_ == Inlined)
inset.dispatch(cur, cmd);
else if (status_ == Open && cmd.y > button_dim.y2)
- inset.dispatch(cur, adjustCommand(cmd));
+ inset.dispatch(cur, cmd);
return DispatchResult(true, true);
case LFUN_MOUSE_RELEASE:
}
default:
- return inset.dispatch(cur, adjustCommand(cmd));
+ return inset.dispatch(cur, cmd);
}
}
}
-void InsetCollapsable::getCursorPos(int cell, int & x, int & y) const
+void InsetCollapsable::getCursorPos(CursorSlice const & cur,
+ int & x, int & y) const
{
- inset.getCursorPos(cell, x, y);
- if (status_ != Inlined)
- y += - ascent() + height_collapsed() + inset.ascent();
+ inset.getCursorPos(cur, x, y);
}
///
void validate(LaTeXFeatures & features) const;
/// get the screen x,y of the cursor
- void getCursorPos(int cell, int & x, int & y) const;
+ void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
///
void setLabel(std::string const & l);
///
/// Appends \c list with all labels found within this inset.
void getLabelList(Buffer const &, std::vector<std::string> & list) const;
///
- int scroll(bool recursive=true) const;
+ int scroll(bool recursive = true) const;
///
void scroll(BufferView & bv, float sx) const;
///
protected:
///
- virtual
- DispatchResult
- priv_dispatch(LCursor & cur, FuncRequest const & cmd);
+ DispatchResult priv_dispatch(LCursor & cur, FuncRequest const & cmd);
///
void dimension_collapsed(Dimension &) const;
///
private:
///
DispatchResult lfunMouseRelease(LCursor & cur, FuncRequest const & cmd);
- ///
- FuncRequest adjustCommand(FuncRequest const &);
public:
///
mutable InsetText inset;
-private:
- ///
- mutable CollapseStatus status_;
protected:
///
LyXFont labelfont_;
mutable int topbaseline;
///
mutable std::string label;
+private:
+ ///
+ mutable CollapseStatus status_;
};
#endif
void InsetCommand::draw(PainterInfo & pi, int x, int y) const
{
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
button_.draw(pi, x, y);
}
void InsetExternal::draw(PainterInfo & pi, int x, int y) const
{
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
renderer_->draw(pi, x, y);
}
void InsetGraphics::draw(PainterInfo & pi, int x, int y) const
{
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
graphic_->draw(pi, x, y);
}
void InsetInclude::draw(PainterInfo & pi, int x, int y) const
{
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
if (!RenderPreview::activated() || !preview_->previewReady()) {
button_.draw(pi, x + button_.box().x1, y);
//lyxerr << "InsetTabular::draw: " << x << " " << y << endl;
BufferView * bv = pi.base.bv;
+ setPosCache(pi, x, y);
if (!owner())
x += scroll();
- xo_ = x;
- yo_ = y;
x += ADD_TO_TABULAR_WIDTH;
int cell = 0;
}
-extern CursorBase theTempCursor;
-
-
void InsetTabular::lfunMousePress(LCursor & cur, FuncRequest const & cmd)
{
if (hasSelection() && cmd.button() == mouse_button::button3)
lyxerr << "# InsetTabular::lfunMousePress cell: " << cell << endl;
if (cell == -1) {
tablemode = true;
- cur.cursor_ = theTempCursor;
+ //cur.cursor_ = theTempCursor;
cur.push(this);
cur.idx() = cell;
} else {
tablemode = false;
setPos(cur.bv(), cmd.x, cmd.y);
- cur.cursor_ = theTempCursor;
+ //cur.cursor_ = theTempCursor;
cur.idx() = cell;
}
cur.resetAnchor();
}
-void InsetTabular::getCursorPos(int cell, int & x, int & y) const
+void InsetTabular::getCursorPos(CursorSlice const & cur, int & x, int & y) const
{
- InsetText const & inset = tabular.getCellInset(cell);
- inset.getCursorPos(cell, x, y);
- x += inset.x() - xo_;
- y += inset.y() - yo_;
+ tabular.getCellInset(cur.idx()).getCursorPos(cur, x, y);
}
///
InsetOld::Code lyxCode() const { return InsetOld::TABULAR_CODE; }
/// get the absolute screen x,y of the cursor
- void getCursorPos(int cell, int & x, int & y) const;
+ void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
///
bool tabularFeatures(LCursor & cur, std::string const & what);
///
void InsetText::draw(PainterInfo & pi, int x, int y) const
{
// update our idea of where we are
- xo_ = x;
- yo_ = y;
-
- Painter & pain = pi.pain;
+ setPosCache(pi, x, y);
// repaint the background if needed
x += TEXT_TO_INSET_OFFSET;
if (backgroundColor() != LColor::background)
- clearInset(pain, x, y);
+ clearInset(pi.pain, x, y);
BufferView * bv = pi.base.bv;
bv->hideCursor();
text_.draw(pi, x, y);
if (drawFrame_ == ALWAYS || drawFrame_ == LOCKED)
- drawFrame(pain, xo_);
+ drawFrame(pi.pain, xo_);
}
void InsetText::edit(LCursor & cur, bool left)
{
- lyxerr << "InsetText: edit left/right" << endl;
+ //lyxerr << "InsetText: edit left/right" << endl;
old_par = -1;
setViewCache(&cur.bv());
int const par = left ? 0 : paragraphs().size() - 1;
{
lyxerr << "InsetText::edit xy" << endl;
old_par = -1;
- text_.setCursorFromCoordinates(x - text_.xo_, y + cur.bv().top_y() - text_.yo_);
- cur.clearSelection();
- finishUndo();
- sanitizeEmptyText(cur.bv());
- updateLocal(cur);
- cur.bv().updateParagraphDialog();
+ text_.edit(cur, x, y);
+ //sanitizeEmptyText(cur.bv());
+ //updateLocal(cur);
+ //cur.bv().updateParagraphDialog();
}
setViewCache(&cur.bv());
- DispatchResult result;
- result.dispatched(true);
-
bool was_empty = paragraphs().begin()->empty() && paragraphs().size() == 1;
-
- switch (cmd.action) {
- case LFUN_MOUSE_PRESS:
- cur.cursor_ = theTempCursor;
- cur.resetAnchor();
- result = text_.dispatch(cur, cmd);
- break;
-
- default:
- result = text_.dispatch(cur, cmd);
- break;
- }
+ DispatchResult result = text_.dispatch(cur, cmd);
// If the action has deleted all text in the inset, we need
// to change the language to the language of the surronding
// text.
+ // Why this cleverness? (Andre')
if (!was_empty && paragraphs().begin()->empty() &&
paragraphs().size() == 1) {
LyXFont font(LyXFont::ALL_IGNORE);
}
-void InsetText::getCursorPos(int, int & x, int & y) const
+void InsetText::getCursorPos(CursorSlice const & cur, int & x, int & y) const
{
- x = text_.cursorX() + TEXT_TO_INSET_OFFSET;
- y = text_.cursorY() - dim_.asc + TEXT_TO_INSET_OFFSET;
+ x = text_.cursorX(cur);
+ y = text_.cursorY(cur);
}
///
InsetOld::Code lyxCode() const { return InsetOld::TEXT_CODE; }
/// FIXME, document
- void getCursorPos(int cell, int & x, int & y) const;
+ void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
///
bool insetAllowed(InsetOld::Code) const;
///
{
static std::string const label = _("Vertical Space");
- xo_ = x;
- yo_ = y;
+ setPosCache(pi, x, y);
x += ADD_TO_VSPACE_WIDTH;
#include <boost/assert.hpp>
-
using lyx::support::strToDbl;
using lyx::support::strToInt;
+
// An updatable inset is highly editable by definition
InsetOld::EDITABLE UpdatableInset::editable() const
{
/// identification as text inset in a cursor slice
UpdatableInset * asUpdatableInset() { return this; }
- /// return the cursor pos, relative to the inset pos
- virtual void getCursorPos(int, int &, int &) const {}
/// return the cursor dim
virtual void getCursorDim(int &, int &) const;
// We need this method to not clobber the real method in Inset
} //namespace anon
-void LyXFunc::dispatch(FuncRequest const & func, bool verbose)
+void LyXFunc::dispatch(FuncRequest const & cmd, bool verbose)
{
- string argument = func.argument;
- kb_action action = func.action;
+ string argument = cmd.argument;
+ kb_action action = cmd.action;
- //lyxerr[Debug::ACTION] << "LyXFunc::dispatch: cmd: " << func << endl;
- lyxerr << "LyXFunc::dispatch: cmd: " << func << endl;
+ lyxerr[Debug::ACTION] << "LyXFunc::dispatch: cmd: " << cmd << endl;
+ //lyxerr << "*** LyXFunc::dispatch: cmd: " << cmd << endl;
// we have not done anything wrong yet.
errorstat = false;
selection_possible = false;
// We cannot use this function here
- if (getStatus(func).disabled()) {
+ if (getStatus(cmd).disabled()) {
lyxerr[Debug::ACTION] << "LyXFunc::dispatch: "
<< lyxaction.getActionName(action)
<< " [" << action << "] is disabled at this location"
break;
case LFUN_DIALOG_SHOW: {
- string const name = func.getArg(0);
- string data = trim(func.argument.substr(name.size()));
+ string const name = cmd.getArg(0);
+ string data = trim(cmd.argument.substr(name.size()));
if (name == "character") {
data = freefont2string();
}
case LFUN_DIALOG_SHOW_NEW_INSET: {
- string const name = func.getArg(0);
- string data = trim(func.argument.substr(name.size()));
+ string const name = cmd.getArg(0);
+ string data = trim(cmd.argument.substr(name.size()));
if (name == "bibitem" ||
name == "bibtex" ||
name == "include" ||
// Can only update a dialog connected to an existing inset
InsetBase * inset = owner->getDialogs().getOpenInset(name);
if (inset) {
- FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, func.argument);
+ FuncRequest fr(LFUN_INSET_DIALOG_UPDATE, cmd.argument);
inset->dispatch(view()->cursor(), fr);
} else if (name == "paragraph") {
dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE));
break;
default:
- view()->cursor().dispatch(FuncRequest(func));
+ view()->cursor().dispatch(cmd);
break;
}
}
view()->update();
view()->cursor().updatePos();
// if we executed a mutating lfun, mark the buffer as dirty
- if (!getStatus(func).disabled()
- && !lyxaction.funcHasFlag(func.action, LyXAction::NoBuffer)
- && !lyxaction.funcHasFlag(func.action, LyXAction::ReadOnly))
+ if (!getStatus(cmd).disabled()
+ && !lyxaction.funcHasFlag(cmd.action, LyXAction::NoBuffer)
+ && !lyxaction.funcHasFlag(cmd.action, LyXAction::ReadOnly))
view()->buffer()->markDirty();
}
- sendDispatchMessage(getMessage(), func, verbose);
+ sendDispatchMessage(getMessage(), cmd, verbose);
}
void LyXFunc::sendDispatchMessage(string const & msg,
- FuncRequest const & func, bool verbose)
+ FuncRequest const & cmd, bool verbose)
{
owner->updateMenubar();
owner->updateToolbar();
- if (func.action == LFUN_SELFINSERT || !verbose) {
+ if (cmd.action == LFUN_SELFINSERT || !verbose) {
lyxerr[Debug::ACTION] << "dispatch msg is " << msg << endl;
if (!msg.empty())
owner->message(msg);
if (!dispatch_msg.empty())
dispatch_msg += ' ';
- string comname = lyxaction.getActionName(func.action);
+ string comname = lyxaction.getActionName(cmd.action);
bool argsadded = false;
- if (!func.argument.empty()) {
- if (func.action != LFUN_UNKNOWN_ACTION) {
- comname += ' ' + func.argument;
+ if (!cmd.argument.empty()) {
+ if (cmd.action != LFUN_UNKNOWN_ACTION) {
+ comname += ' ' + cmd.argument;
argsadded = true;
}
}
- string const shortcuts = toplevel_keymap->findbinding(func);
+ string const shortcuts = toplevel_keymap->findbinding(cmd);
if (!shortcuts.empty()) {
comname += ": " + shortcuts;
- } else if (!argsadded && !func.argument.empty()) {
- comname += ' ' + func.argument;
+ } else if (!argsadded && !cmd.argument.empty()) {
+ comname += ' ' + cmd.argument;
}
if (!comname.empty()) {
// Each "owner" should have it's own message method. lyxview and
// the minibuffer would use the minibuffer, but lyxserver would
// send an ERROR signal to its client. Alejandro 970603
-// This func is bit problematic when it comes to NLS, to make the
+// This function is bit problematic when it comes to NLS, to make the
// lyx servers client be language indepenent we must not translate
// strings sent to this func.
void LyXFunc::setErrorMessage(string const & m) const
/// This class encapsulates the main text data and operations in LyX
class LyXText {
public:
- /// Constructor
+ /// constructor
LyXText(BufferView *, bool ininset);
///
void init(BufferView *);
-
/// update y coordinate cache of all paragraphs
void updateParPositions();
///
ParagraphList::iterator end);
/// rebreaks the given par
void redoParagraph(ParagraphList::iterator pit);
-
/// rebreaks the cursor par
void redoParagraph();
///
std::string getStringToIndex();
- /** insert a character, moves all the following breaks in the
- same Paragraph one to the right and make a little rebreak
- */
+ /// insert a character at cursor position
void insertChar(char c);
- ///
+ /// insert an inset at cursor position
void insertInset(InsetBase * inset);
/// a full rebreak of the whole text
/// try to handle that request
DispatchResult dispatch(LCursor & cur, FuncRequest const & cmd);
-
+ /// access to out BufferView. This should go...
BufferView * bv();
-
+ /// access to out BufferView. This should go...
BufferView * bv() const;
- friend class LyXScreen;
-
/// returns an iterator pointing to a cursor paragraph
ParagraphList::iterator getPar(CursorSlice const & cursor) const;
///
///
void setCursorFromCoordinates(CursorSlice &, int x, int y);
///
+ void edit(LCursor & cur, int x, int y);
+ ///
void cursorUp(bool selecting = false);
///
void cursorDown(bool selecting = false);
* characters to the right. No safety checks.
*/
void setSelectionRange(lyx::pos_type length);
-
/** simple replacing. The font of the first selected character
is used
*/
* the cursor and when creating a visible row */
void prepareToPrint(ParagraphList::iterator pit, Row & row) const;
- //
- // special owner functions
- ///
+ /// access to our paragraphs
ParagraphList & paragraphs() const;
-
/// return true if this is owned by an inset.
bool isInInset() const;
-
- ///
+ /// the first of our paragraphs
ParagraphList::iterator firstPar() const;
- ///
+ /// the last of our paragraphs
ParagraphList::iterator lastPar() const;
- ///
+ /// one past the last of our paragraphs
ParagraphList::iterator endPar() const;
/// return first row of text
///
int descent() const;
///
- int cursorX() const;
- ///
- int cursorY() const;
- ///
int cursorX(CursorSlice const & cursor) const;
///
int cursorY(CursorSlice const & cursor) const;
/// access to the selection anchor
CursorSlice const & anchor() const;
+ friend class LyXScreen;
+
public:
///
int height;
math_mathmlstream.h \
math_matrixinset.C \
math_matrixinset.h \
+ math_mboxinset.C \
+ math_mboxinset.h \
math_nestinset.C \
math_nestinset.h \
math_numberinset.C \
* Full author contact details are available in file CREDITS.
*/
-#if 0
#include <config.h>
#include "formula.h"
+#include "formulamacro.h"
#include "math_data.h"
-#include "math_parser.h"
#include "math_hullinset.h"
#include "math_mathmlstream.h"
-#include "textpainter.h"
+#include "math_parser.h"
#include "BufferView.h"
#include "cursor.h"
+#include "dispatchresult.h"
#include "debug.h"
+#include "funcrequest.h"
+#include "gettext.h"
+#include "LaTeXFeatures.h"
#include "LColor.h"
-#include "lyx_main.h"
-#include "outputparams.h"
-
-#include "frontends/Painter.h"
-
-#include "graphics/PreviewLoader.h"
+#include "lyxrc.h"
+#include "lyxtext.h"
+#include "textpainter.h"
-#include "insets/render_preview.h"
+#include "frontends/Alert.h"
#include "support/std_sstream.h"
-#include <boost/bind.hpp>
+using lyx::support::trim;
-using std::string;
-using std::ostream;
-using std::ostringstream;
-using std::vector;
-using std::auto_ptr;
using std::endl;
+using std::max;
+using std::string;
+using std::auto_ptr;
+using std::istringstream;
+using std::ostringstream;
+using std::pair;
-InsetFormula::InsetFormula()
- : par_(MathAtom(new MathHullInset)),
- preview_(new RenderPreview)
-{
- preview_->connect(boost::bind(&InsetFormula::statusChanged, this));
-}
+namespace {
-InsetFormula::InsetFormula(InsetFormula const & other)
- : InsetFormulaBase(other),
- par_(other.par_),
- preview_(new RenderPreview)
+bool openNewInset(LCursor & cur, InsetBase * inset)
{
- preview_->connect(boost::bind(&InsetFormula::statusChanged, this));
+ if (!cur.bv().insertInset(inset)) {
+ delete inset;
+ return false;
+ }
+ inset->edit(cur, true);
+ return true;
}
-InsetFormula::InsetFormula(string const & data)
- : par_(MathAtom(new MathHullInset)),
- preview_(new RenderPreview)
-{
- preview_->connect(boost::bind(&InsetFormula::statusChanged, this));
- if (!data.size())
- return;
- if (!mathed_parse_normal(par_, data))
- lyxerr << "cannot interpret '" << data << "' as math" << endl;
-}
+} // namespace anon
-InsetFormula::~InsetFormula()
-{}
-auto_ptr<InsetBase> InsetFormula::clone() const
+std::auto_ptr<InsetBase> InsetFormula::clone() const
{
return auto_ptr<InsetBase>(new InsetFormula(*this));
}
-void InsetFormula::write(Buffer const &, ostream & os) const
+void InsetFormula::write(Buffer const &, std::ostream & os) const
{
WriteStream wi(os, false, false);
- os << par_->fileInsetLabel() << ' ';
- par_->write(wi);
+ os << fileInsetLabel() << ' ';
+ MathHullInset::write(wi);
}
-int InsetFormula::latex(Buffer const &, ostream & os,
- OutputParams const & runparams) const
-{
- WriteStream wi(os, runparams.moving_arg, true);
- par_->write(wi);
- return wi.line();
-}
-
-
-int InsetFormula::plaintext(Buffer const &, ostream & os,
- OutputParams const &) const
+void InsetFormula::read(Buffer const &, LyXLex & lex)
{
- if (0 && display()) {
- Dimension dim;
- TextMetricsInfo mi;
- par()->metricsT(mi, dim);
- TextPainter tpain(dim.width(), dim.height());
- par()->drawT(tpain, 0, dim.ascent());
- tpain.show(os, 3);
- // reset metrics cache to "real" values
- //metrics();
- return tpain.textheight();
- } else {
- WriteStream wi(os, false, true);
- wi << ' ' << (par_->asNestInset()->cell(0)) << ' ';
- return wi.line();
- }
+ MathAtom at;
+ mathed_parse_normal(at, lex);
+ MathHullInset::operator=(*at->asHullInset());
}
-int InsetFormula::linuxdoc(Buffer const & buf, ostream & os,
- OutputParams const & runparams) const
-{
- return docbook(buf, os, runparams);
-}
+/////////////////////////////////////////////
-int InsetFormula::docbook(Buffer const & buf, ostream & os,
- OutputParams const & runparams) const
+void mathDispatchCreation(LCursor & cur, FuncRequest const & cmd,
+ bool display)
{
- MathMLStream ms(os);
- ms << MTag("equation");
- ms << MTag("alt");
- ms << "<[CDATA[";
- int res = plaintext(buf, ms.os(), runparams);
- ms << "]]>";
- ms << ETag("alt");
- ms << MTag("math");
- ms << par_;
- ms << ETag("math");
- ms << ETag("equation");
- return ms.line() + res;
-}
+ // use selection if available..
+ //string sel;
+ //if (action == LFUN_MATH_IMPORT_SELECTION)
+ // sel = "";
+ //else
+ string sel =
+ cur.bv().getLyXText()->selectionAsString(*cur.bv().buffer(), false);
-void InsetFormula::read(Buffer const &, LyXLex & lex)
-{
- mathed_parse_normal(par_, lex);
- // remove extra 'mathrm' for chemistry stuff.
- // will be re-added on write
- if (par_->asHullInset()->getType() =="chemistry") {
- lyxerr << "this is chemistry" << endl;
- if (par_->cell(0).size() == 1) {
- lyxerr << "this is size 1" << endl;
- if (par_->cell(0)[0]->asFontInset()) {
- lyxerr << "this is a font inset "
- << "replacing " << par_.nucleus()->cell(0) <<
- " with " << par_->cell(0)[0]->cell(0) << endl;
- }
+ if (sel.empty()) {
+ InsetBase * f = new MathHullInset;
+ if (openNewInset(cur, f)) {
+ cur.inset()->dispatch(cur, FuncRequest(LFUN_MATH_MUTATE, "simple"));
+ // don't do that also for LFUN_MATH_MODE unless you want end up with
+ // always changing to mathrm when opening an inlined inset
+ // -- I really hate "LyXfunc overloading"...
+ if (display)
+ f->dispatch(cur, FuncRequest(LFUN_MATH_DISPLAY));
+ f->dispatch(cur, FuncRequest(LFUN_INSERT_MATH, cmd.argument));
}
- }
- //metrics();
-}
-
-
-void InsetFormula::draw(PainterInfo & pi, int x, int y) const
-{
- xo_ = x;
- yo_ = y;
-
- // The previews are drawn only when we're not editing the inset.
- bool const use_preview = !pi.base.bv->cursor().isInside(this)
- && RenderPreview::activated()
- && preview_->previewReady();
-
- int const w = dim_.wid;
- int const d = dim_.des;
- int const a = dim_.asc;
- int const h = a + d;
-
- if (use_preview) {
- // one pixel gap in front
- preview_->draw(pi, x + 1, y);
} else {
- PainterInfo p(pi.base.bv);
- p.base.style = LM_ST_TEXT;
- p.base.font = pi.base.font;
- p.base.font.setColor(LColor::math);
- if (lcolor.getX11Name(LColor::mathbg)
- != lcolor.getX11Name(LColor::background))
- p.pain.fillRectangle(x, y - a, w, h, LColor::mathbg);
-
- if (!pi.base.bv->cursor().isInside(this)) {
- pi.base.bv->cursor().drawSelection(pi);
- //p.pain.rectangle(x, y - a, w, h, LColor::mathframe);
- }
-
- par_->draw(p, x, y);
+ // create a macro if we see "\\newcommand" somewhere, and an ordinary
+ // formula otherwise
+ InsetBase * f;
+ if (sel.find("\\newcommand") == string::npos &&
+ sel.find("\\def") == string::npos)
+ f = new MathHullInset(sel);
+ else
+ f = new InsetFormulaMacro(sel);
+ cur.bv().getLyXText()->cutSelection(true, false);
+ openNewInset(cur, f);
}
+ cmd.message(N_("Math editor mode"));
}
-void InsetFormula::getLabelList(Buffer const & buffer,
- vector<string> & res) const
-{
- par()->getLabelList(buffer, res);
-}
-
-
-InsetOld::Code InsetFormula::lyxCode() const
-{
- return InsetOld::MATH_CODE;
-}
-
-
-void InsetFormula::validate(LaTeXFeatures & features) const
+void mathDispatch(LCursor & cur, FuncRequest const & cmd)
{
- par_->validate(features);
-}
-
-
-bool InsetFormula::insetAllowed(InsetOld::Code code) const
-{
- return
- code == InsetOld::LABEL_CODE
- || code == InsetOld::REF_CODE
- || code == InsetOld::ERT_CODE;
-}
+ if (!cur.bv().available())
+ return;
+ switch (cmd.action) {
+
+ case LFUN_MATH_DISPLAY:
+ mathDispatchCreation(cur, cmd, true);
+ break;
+
+ case LFUN_MATH_MODE:
+ mathDispatchCreation(cur, cmd, false);
+ break;
+
+ case LFUN_MATH_IMPORT_SELECTION:
+ mathDispatchCreation(cur, cmd, false);
+ break;
+
+/*
+ case LFUN_MATH_MACRO:
+ if (cmd.argument.empty())
+ cmd.errorMessage(N_("Missing argument"));
+ else {
+ string s = cmd.argument;
+ string const s1 = token(s, ' ', 1);
+ int const nargs = s1.empty() ? 0 : atoi(s1);
+ string const s2 = token(s, ' ', 2);
+ string const type = s2.empty() ? "newcommand" : s2;
+ openNewInset(cur, new InsetFormulaMacro(token(s, ' ', 0), nargs, s2));
+ }
+ break;
+
+ case LFUN_INSERT_MATH:
+ case LFUN_INSERT_MATRIX:
+ case LFUN_MATH_DELIM: {
+ MathHullInset * f = new MathHullInset;
+ if (openNewInset(cur, f)) {
+ cur.inset()->dispatch(cur, FuncRequest(LFUN_MATH_MUTATE, "simple"));
+ cur.inset()->dispatch(cur, cmd);
+ }
+ break;
+ }
+*/
-void InsetFormula::metrics(MetricsInfo & m, Dimension & dim) const
-{
- bool const use_preview = !m.base.bv->cursor().isInside(this)
- && RenderPreview::activated()
- && preview_->previewReady();
-
- if (use_preview) {
- preview_->metrics(m, dim);
- // insert a one pixel gap in front of the formula
- dim.wid += 1;
- if (display())
- dim.des += 12;
- } else {
- MetricsInfo mi = m;
- mi.base.style = LM_ST_TEXT;
- mi.base.font.setColor(LColor::math);
- par()->metrics(mi, dim);
- dim.asc += 1;
- dim.des += 1;
+ default:
+ break;
}
-
- dim_ = dim;
-}
-
-
-void InsetFormula::mutate(string const & type)
-{
- par_.nucleus()->mutate(type);
-}
-
-
-//
-// preview stuff
-//
-
-void InsetFormula::statusChanged() const
-{
- LyX::cref().updateInset(this);
-}
-
-
-namespace {
-
-string const latex_string(InsetFormula const & inset, Buffer const &)
-{
- ostringstream os;
- WriteStream wi(os, false, false);
- inset.par()->write(wi);
- return os.str();
-}
-
-} // namespace anon
-
-
-void InsetFormula::addPreview(lyx::graphics::PreviewLoader & ploader) const
-{
- string const snippet = latex_string(*this, ploader.buffer());
- preview_->addPreview(snippet, ploader);
-}
-
-
-void InsetFormula::generatePreview(Buffer const & buffer) const
-{
- string const snippet = latex_string(*this, buffer);
- preview_->addPreview(snippet, buffer);
- preview_->startLoading(buffer);
}
-#endif
* Full author contact details are available in file CREDITS.
*/
-#if 0
#ifndef INSET_FORMULA_H
#define INSET_FORMULA_H
-#include "formulabase.h"
-#include "math_atom.h"
-
-#include <boost/scoped_ptr.hpp>
-
-class RenderPreview;
+#include "math_hullinset.h"
/// The main LyX math inset
-class InsetFormula : public InsetFormulaBase {
+class InsetFormula : public MathHullInset {
public:
///
- InsetFormula();
- ///
- explicit InsetFormula(std::string const & data);
- ///
- InsetFormula(InsetFormula const &);
- ///
- ~InsetFormula();
- ///
- void metrics(MetricsInfo & mi, Dimension & dim) const;
- ///
- void draw(PainterInfo & pi, int x, int y) const;
-
- ///
- void write(Buffer const &, std::ostream &) const;
- ///
- void read(Buffer const &, LyXLex & lex);
- ///
- int latex(Buffer const &, std::ostream &,
- OutputParams const &) const;
- ///
- int plaintext(Buffer const &, std::ostream &,
- OutputParams const &) const;
- ///
- int linuxdoc(Buffer const &, std::ostream &,
- OutputParams const &) const;
+ std::auto_ptr<InsetBase> clone() const;
///
- int docbook(Buffer const &, std::ostream &,
- OutputParams const &) const;
-
- ///
- virtual std::auto_ptr<InsetBase> clone() const;
- ///
- void validate(LaTeXFeatures & features) const;
- ///
- InsetOld::Code lyxCode() const;
- ///
- bool insetAllowed(InsetOld::Code code) const;
- /// Appends \c list with all labels found within this inset.
- void getLabelList(Buffer const &,
- std::vector<std::string> & list) const;
- ///
- MathAtom const & par() const { return par_; }
- ///
- MathAtom & par() { return par_; }
+ void write(Buffer const & buf, std::ostream & os) const;
///
- void generatePreview(Buffer const &) const;
- ///
- void addPreview(lyx::graphics::PreviewLoader &) const;
- ///
- void mutate(std::string const & type);
-
-private:
- /// Slot receiving a signal that the preview is ready to display.
- void statusChanged() const;
- /// available in AMS only?
- bool ams() const;
+ void read(Buffer const & buf, LyXLex & lex);
+};
- /// contents
- MathAtom par_;
+// We don't really want to mess around with mathed stuff outside mathed.
+// So do it here.
+void mathDispatch(LCursor & cur, FuncRequest const & cmd);
- /// The pointer never changes although *preview_'s contents may.
- boost::scoped_ptr<RenderPreview> const preview_;
-};
-#endif
#endif
+++ /dev/null
-/**
- * \file formulabase.C
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author Alejandro Aguilar Sierra
- * \author André Pönitz
- *
- * Full author contact details are available in file CREDITS.
- */
-
-#include <config.h>
-
-#include "cursor.h"
-#include "formulabase.h"
-#include "formula.h"
-#include "formulamacro.h"
-#include "math_support.h"
-#include "math_arrayinset.h"
-#include "math_deliminset.h"
-#include "math_cursor.h"
-#include "math_factory.h"
-#include "math_hullinset.h"
-#include "math_parser.h"
-#include "math_spaceinset.h"
-#include "ref_inset.h"
-
-#include "BufferView.h"
-#include "bufferview_funcs.h"
-#include "dispatchresult.h"
-#include "debug.h"
-#include "funcrequest.h"
-#include "gettext.h"
-#include "LColor.h"
-#include "lyxtext.h"
-#include "undo.h"
-
-#include "frontends/LyXView.h"
-#include "frontends/Dialogs.h"
-
-#include "support/std_sstream.h"
-#include "support/lstrings.h"
-#include "support/lyxlib.h"
-
-using lyx::support::atoi;
-using lyx::support::split;
-using lyx::support::token;
-
-using std::string;
-using std::abs;
-using std::endl;
-using std::max;
-using std::istringstream;
-using std::ostringstream;
-
-
-namespace {
-
-// local global
-int first_x;
-int first_y;
-
-bool openNewInset(LCursor & cur, UpdatableInset * inset)
-{
- if (!cur.bv().insertInset(inset)) {
- delete inset;
- return false;
- }
- inset->edit(cur, true);
- return true;
-}
-
-
-} // namespace anon
-
-
-
-InsetFormulaBase::InsetFormulaBase()
-{
- // This is needed as long the math parser is not re-entrant
- initMath();
- //lyxerr << "sizeof MathInset: " << sizeof(MathInset) << endl;
- //lyxerr << "sizeof MetricsInfo: " << sizeof(MetricsInfo) << endl;
- //lyxerr << "sizeof MathCharInset: " << sizeof(MathCharInset) << endl;
- //lyxerr << "sizeof LyXFont: " << sizeof(LyXFont) << endl;
-}
-
-
-// simply scrap this function if you want
-void InsetFormulaBase::mutateToText()
-{
-#if 0
- // translate to latex
- ostringstream os;
- latex(NULL, os, false, false);
- string str = os.str();
-
- // insert this text
- LyXText * lt = view_->getLyXText();
- string::const_iterator cit = str.begin();
- string::const_iterator end = str.end();
- for (; cit != end; ++cit)
- view_->owner()->getIntl()->getTransManager().TranslateAndInsert(*cit, lt);
-
- // remove ourselves
- //view_->owner()->dispatch(LFUN_ESCAPE);
-#endif
-}
-
-
-void InsetFormulaBase::handleFont
- (LCursor & cur, string const & arg, string const & font)
-{
- // this whole function is a hack and won't work for incremental font
- // changes...
- recordUndo(cur, Undo::ATOMIC);
-
- if (cur.inset()->asMathInset()->name() == font)
- mathcursor::handleFont(cur, font);
- else {
- mathcursor::handleNest(cur, createMathInset(font));
- mathcursor::insert(cur, arg);
- }
-}
-
-
-void InsetFormulaBase::handleFont2(LCursor & cur, string const & arg)
-{
- recordUndo(cur, Undo::ATOMIC);
- LyXFont font;
- bool b;
- bv_funcs::string2font(arg, font, b);
- if (font.color() != LColor::inherit) {
- MathAtom at = createMathInset("color");
- asArray(lcolor.getGUIName(font.color()), at.nucleus()->cell(0));
- mathcursor::handleNest(cur, at, 1);
- }
-}
-
-
-
-void InsetFormulaBase::validate(LaTeXFeatures &) const
-{}
-
-
-string const InsetFormulaBase::editMessage() const
-{
- return _("Math editor mode");
-}
-
-
-void InsetFormulaBase::insetUnlock(BufferView & bv)
-{
- if (inMathed()) {
- if (mathcursor::inMacroMode(bv.cursor()))
- mathcursor::macroModeClose(bv.cursor());
- releaseMathCursor(bv.cursor());
- }
- if (bv.buffer())
- generatePreview(*bv.buffer());
- bv.update();
-}
-
-
-void InsetFormulaBase::getCursorPos(BufferView & bv, int & x, int & y) const
-{
- if (inMathed()) {
- mathcursor::getScreenPos(bv.cursor(), x, y);
- x = mathcursor::targetX(bv.cursor());
- x -= xo_;
- y -= yo_;
- lyxerr << "InsetFormulaBase::getCursorPos: " << x << ' ' << y << endl;
- } else {
- x = 0;
- y = 0;
- lyxerr << "getCursorPos - should not happen";
- }
-}
-
-
-void InsetFormulaBase::getCursorDim(int & asc, int & desc) const
-{
- if (inMathed()) {
- asc = 10;
- desc = 2;
- //math_font_max_dim(font_, asc, des);
- }
-}
-
-
-DispatchResult
-InsetFormulaBase::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd)
-{
- if (!inMathed())
- return DispatchResult(false);
- cur.bv().update();
- //lyxerr << "lfunMouseRelease: buttons: " << cmd.button() << endl;
-
- if (cmd.button() == mouse_button::button3) {
- // try to dispatch to enclosed insets first
- if (!mathcursor::dispatch(cur, cmd).dispatched()) {
- // launch math panel for right mouse button
- lyxerr << "lfunMouseRelease: undispatched: " << cmd.button() << endl;
- cur.bv().owner()->getDialogs().show("mathpanel");
- }
- return DispatchResult(true, true);
- }
-
- if (cmd.button() == mouse_button::button2) {
- MathArray ar;
- asArray(cur.bv().getClipboard(), ar);
- mathcursor::selClear(cur);
- mathcursor::setScreenPos(cur, cmd.x + xo_, cmd.y + yo_);
- mathcursor::insert(cur, ar);
- cur.bv().update();
- return DispatchResult(true, true);
- }
-
- if (cmd.button() == mouse_button::button1) {
- // try to dispatch to enclosed insets first
- mathcursor::dispatch(cur, cmd);
- cur.bv().stuffClipboard(mathcursor::grabSelection(cur));
- // try to set the cursor
- //delete mathcursor;
- //mathcursor = new MathCursor(bv, this, x == 0);
- //metrics(bv);
- //mathcursor::setScreenPos(x + xo_, y + yo_);
- return DispatchResult(true, true);
- }
-
- return DispatchResult(false);
-}
-
-
-DispatchResult
-InsetFormulaBase::lfunMousePress(LCursor & cur, FuncRequest const & cmd)
-{
- //lyxerr << "lfunMousePress: buttons: " << cmd.button() << endl;
-
- if (!inMathed() || mathcursor::formula() != this) {
- lyxerr[Debug::MATHED] << "re-create cursor" << endl;
- releaseMathCursor(cur);
- mathcursor::formula_ = this;
- cur.idx() = 0;
- //metrics(bv);
- mathcursor::setScreenPos(cur, cmd.x + xo_, cmd.y + yo_);
- }
-
- if (cmd.button() == mouse_button::button3) {
- mathcursor::dispatch(cur, cmd);
- return DispatchResult(true, true);
- }
-
- if (cmd.button() == mouse_button::button1) {
- first_x = cmd.x;
- first_y = cmd.y;
- mathcursor::selClear(cur);
- mathcursor::setScreenPos(cur, cmd.x + xo_, cmd.y + yo_);
- mathcursor::dispatch(cur, cmd);
- return DispatchResult(true, true);
- }
-
- cur.bv().update();
- return DispatchResult(true, true);
-}
-
-
-DispatchResult
-InsetFormulaBase::lfunMouseMotion(LCursor & cur, FuncRequest const & cmd)
-{
- if (!inMathed())
- return DispatchResult(true, true);
-
- if (mathcursor::dispatch(cur, FuncRequest(cmd)).dispatched())
- return DispatchResult(true, true);
-
- // only select with button 1
- if (cmd.button() != mouse_button::button1)
- return DispatchResult(true, true);
-
- if (abs(cmd.x - first_x) < 2 && abs(cmd.y - first_y) < 2)
- return DispatchResult(true, true);
-
- first_x = cmd.x;
- first_y = cmd.y;
-
- if (!cur.selection())
- mathcursor::selStart(cur);
-
- mathcursor::setScreenPos(cur, cmd.x + xo_, cmd.y + yo_);
- cur.bv().update();
- return DispatchResult(true, true);
-}
-
-
-void InsetFormulaBase::edit(LCursor & cur, bool /*left*/)
-{
- lyxerr << "Called FormulaBase::edit" << endl;
- mathcursor::formula_ = this;
- cur.push(this);
- cur.idx() = 0;
- cur.pos() = 0;
-#warning FIXME
- cur.push(par().nucleus()->asHullInset());
- //cur.idx() = left ? 0 : cur.lastidx();
- cur.idx() = 0;
- cur.pos() = 0;
- cur.resetAnchor();
-}
-
-
-void InsetFormulaBase::edit(LCursor & cur, int x, int y)
-{
- lyxerr << "Called FormulaBase::EDIT with '" << x << ' ' << y << "'" << endl;
- releaseMathCursor(cur);
- //metrics(bv);
- cur.push(this);
- cur.idx() = 0;
- cur.pos() = 0;
- mathcursor::setScreenPos(cur, x + xo_, y + yo_);
- cur.push(par().nucleus()->asHullInset());
- //cur.idx() = left ? 0 : cur.lastidx();
- cur.idx() = 0;
- cur.pos() = 0;
- // if that is removed, we won't get the magenta box when entering an
- // inset for the first time
- cur.bv().update();
-}
-
-
-DispatchResult
-InsetFormulaBase::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
-{
- return par().nucleus()->dispatch(cur, cmd);
-
- //lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action
- // << " arg: '" << cmd.argument
- // << "' x: '" << cmd.x
- // << " y: '" << cmd.y
- // << "' button: " << cmd.button() << endl;
-
-#if 0
- // delete empty mathbox (LFUN_BACKSPACE and LFUN_DELETE)
- bool remove_inset = false;
-
- switch (cmd.action) {
- case LFUN_MOUSE_PRESS:
- //lyxerr << "Mouse single press" << endl;
- return lfunMousePress(cur, cmd);
- case LFUN_MOUSE_MOTION:
- //lyxerr << "Mouse motion" << endl;
- return lfunMouseMotion(cur, cmd);
- case LFUN_MOUSE_RELEASE:
- //lyxerr << "Mouse single release" << endl;
- return lfunMouseRelease(cur, cmd);
- case LFUN_MOUSE_DOUBLE:
- //lyxerr << "Mouse double" << endl;
- return dispatch(cur, FuncRequest(LFUN_WORDSEL));
- default:
- break;
- }
-
- DispatchResult result(true);
- string argument = cmd.argument;
- bool sel = false;
- bool was_macro = mathcursor::inMacroMode(cur);
-
- mathcursor::normalize(cur);
- mathcursor::touch();
-
- switch (cmd.action) {
-
- case LFUN_MATH_MUTATE:
- case LFUN_MATH_DISPLAY:
- case LFUN_MATH_NUMBER:
- case LFUN_MATH_NONUMBER:
- case LFUN_CELL_SPLIT:
- case LFUN_BREAKLINE:
- case LFUN_DELETE_LINE_FORWARD:
- case LFUN_INSERT_LABEL:
- case LFUN_MATH_EXTERN:
- case LFUN_TABULAR_FEATURE:
- case LFUN_PASTESELECTION:
- case LFUN_MATH_LIMITS:
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::dispatch(cur, cmd);
- break;
-
- case LFUN_WORDSEL:
- mathcursor::home(cur, false);
- mathcursor::end(cur, true);
- break;
-
- case LFUN_UP_PARAGRAPHSEL:
- case LFUN_UP_PARAGRAPH:
- case LFUN_DOWN_PARAGRAPHSEL:
- case LFUN_DOWN_PARAGRAPH:
- result = DispatchResult(true, FINISHED);
- break;
-
- case LFUN_HOMESEL:
- case LFUN_WORDLEFTSEL:
- sel = true; // fall through
- case LFUN_HOME:
- case LFUN_WORDLEFT:
- result = mathcursor::home(cur, sel)
- ? DispatchResult(true, true) : DispatchResult(true, FINISHED);
- break;
-
- case LFUN_ENDSEL:
- case LFUN_WORDRIGHTSEL:
- sel = true; // fall through
- case LFUN_END:
- case LFUN_WORDRIGHT:
- result = mathcursor::end(cur, sel)
- ? DispatchResult(true, true) : DispatchResult(false, FINISHED_RIGHT);
- break;
-
- case LFUN_PRIORSEL:
- case LFUN_PRIOR:
- case LFUN_BEGINNINGBUFSEL:
- case LFUN_BEGINNINGBUF:
- result = DispatchResult(true, FINISHED);
- break;
-
- case LFUN_NEXTSEL:
- case LFUN_NEXT:
- case LFUN_ENDBUFSEL:
- case LFUN_ENDBUF:
- result = DispatchResult(false, FINISHED_RIGHT);
- break;
-
- case LFUN_CELL_FORWARD:
- mathcursor::idxNext(cur);
- break;
-
- case LFUN_CELL_BACKWARD:
- mathcursor::idxPrev(cur);
- break;
-
- case LFUN_DELETE_WORD_BACKWARD:
- case LFUN_BACKSPACE:
- recordUndo(cur, Undo::ATOMIC);
- if (!mathcursor::backspace(cur)) {
- result = DispatchResult(true, FINISHED);
- remove_inset = true;
- }
- break;
-
- case LFUN_DELETE_WORD_FORWARD:
- case LFUN_DELETE:
- recordUndo(cur, Undo::ATOMIC);
- if (!mathcursor::erase(cur)) {
- result = DispatchResult(true, FINISHED);
- remove_inset = true;
- }
- break;
-
- // case LFUN_GETXY:
- // sprintf(dispatch_buffer, "%d %d",);
- // DispatchResult= dispatch_buffer;
- // break;
- case LFUN_SETXY: {
- lyxerr << "LFUN_SETXY broken!" << endl;
- int x = 0;
- int y = 0;
- istringstream is(cmd.argument.c_str());
- is >> x >> y;
- mathcursor::setScreenPos(cur, x, y);
- break;
- }
-
- case LFUN_PASTE: {
- size_t n = 0;
- istringstream is(cmd.argument.c_str());
- is >> n;
- if (was_macro)
- mathcursor::macroModeClose(cur);
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::selPaste(cur, n);
- break;
- }
-
- case LFUN_CUT:
- recordUndo(cur, Undo::DELETE);
- mathcursor::selCut(cur);
- break;
-
- case LFUN_COPY:
- mathcursor::selCopy(cur);
- break;
-
-
- // Special casing for superscript in case of LyX handling
- // dead-keys:
- case LFUN_CIRCUMFLEX:
- if (cmd.argument.empty()) {
- // do superscript if LyX handles
- // deadkeys
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::script(cur, true);
- }
- break;
-
- case LFUN_UMLAUT:
- case LFUN_ACUTE:
- case LFUN_GRAVE:
- case LFUN_BREVE:
- case LFUN_DOT:
- case LFUN_MACRON:
- case LFUN_CARON:
- case LFUN_TILDE:
- case LFUN_CEDILLA:
- case LFUN_CIRCLE:
- case LFUN_UNDERDOT:
- case LFUN_TIE:
- case LFUN_OGONEK:
- case LFUN_HUNG_UMLAUT:
- break;
-
- // Math fonts
- case LFUN_FREEFONT_APPLY:
- case LFUN_FREEFONT_UPDATE:
- handleFont2(cur, cmd.argument);
- break;
-
- case LFUN_BOLD: handleFont(cur, cmd.argument, "mathbf"); break;
- case LFUN_SANS: handleFont(cur, cmd.argument, "mathsf"); break;
- case LFUN_EMPH: handleFont(cur, cmd.argument, "mathcal"); break;
- case LFUN_ROMAN: handleFont(cur, cmd.argument, "mathrm"); break;
- case LFUN_CODE: handleFont(cur, cmd.argument, "texttt"); break;
- case LFUN_FRAK: handleFont(cur, cmd.argument, "mathfrak"); break;
- case LFUN_ITAL: handleFont(cur, cmd.argument, "mathit"); break;
- case LFUN_NOUN: handleFont(cur, cmd.argument, "mathbb"); break;
- //case LFUN_FREEFONT_APPLY: handleFont(cur, cmd.argument, "textrm"); break;
- case LFUN_DEFAULT: handleFont(cur, cmd.argument, "textnormal"); break;
-
- case LFUN_MATH_MODE:
- if (mathcursor::currentMode(cur) == MathInset::TEXT_MODE)
- mathcursor::niceInsert(cur, MathAtom(new MathHullInset("simple")));
- else
- handleFont(cur, cmd.argument, "textrm");
- //cur.owner()->message(_("math text mode toggled"));
- break;
-
- case LFUN_MATH_SIZE:
-#if 0
- if (!arg.empty()) {
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::setSize(arg);
- }
-#endif
- break;
-
- case LFUN_INSERT_MATRIX: {
- recordUndo(cur, Undo::ATOMIC);
- unsigned int m = 1;
- unsigned int n = 1;
- string v_align;
- string h_align;
- istringstream is(argument);
- is >> m >> n >> v_align >> h_align;
- m = max(1u, m);
- n = max(1u, n);
- v_align += 'c';
- mathcursor::niceInsert(cur,
- MathAtom(new MathArrayInset("array", m, n, v_align[0], h_align)));
- break;
- }
-
- case LFUN_MATH_DELIM: {
- //lyxerr << "formulabase::LFUN_MATH_DELIM, arg: '" << arg << "'" << endl;
- string ls;
- string rs = split(cmd.argument, ls, ' ');
- // Reasonable default values
- if (ls.empty())
- ls = '(';
- if (rs.empty())
- rs = ')';
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::handleNest(cur, MathAtom(new MathDelimInset(ls, rs)));
- break;
- }
-
- case LFUN_SPACE_INSERT:
- case LFUN_MATH_SPACE:
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::insert(cur, MathAtom(new MathSpaceInset(",")));
- break;
-
- case LFUN_UNDO:
- cur.bv().owner()->message(_("Invalid action in math mode!"));
- break;
-
-
- case LFUN_EXEC_COMMAND:
- result = DispatchResult(false);
- break;
-
- case LFUN_INSET_ERT:
- // interpret this as if a backslash was typed
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::interpret(cur, '\\');
- break;
-
- case LFUN_BREAKPARAGRAPH:
- case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
- case LFUN_BREAKPARAGRAPH_SKIP:
- argument = "\n";
- // fall through
-
-// FIXME: We probably should swap parts of "math-insert" and "self-insert"
-// handling such that "self-insert" works on "arbitrary stuff" too, and
-// math-insert only handles special math things like "matrix".
- case LFUN_INSERT_MATH:
- recordUndo(cur, Undo::ATOMIC);
- mathcursor::niceInsert(cur, argument);
- break;
-
- case -1:
- case LFUN_SELFINSERT:
- if (!argument.empty()) {
- recordUndo(cur, Undo::ATOMIC);
- if (argument.size() == 1)
- result = mathcursor::interpret(cur, argument[0])
- ? DispatchResult(true, true) : DispatchResult(false, FINISHED_RIGHT);
- else
- mathcursor::insert(cur, argument);
- }
- break;
-
- case LFUN_ESCAPE:
- if (cur.selection())
- mathcursor::selClear(cur);
- else
- result = DispatchResult(false);
- break;
-
- case LFUN_INSET_TOGGLE:
- mathcursor::insetToggle(cur);
- break;
-
- case LFUN_DIALOG_SHOW:
- result = DispatchResult(false);
- break;
-
- case LFUN_DIALOG_SHOW_NEW_INSET: {
- string const & name = argument;
- string data;
- if (name == "ref") {
- RefInset tmp(name);
- data = tmp.createDialogStr(name);
- }
-
- if (data.empty())
- result = DispatchResult(false);
- else
- cur.bv().owner()->getDialogs().show(name, data, 0);
- break;
- }
-
- case LFUN_INSET_APPLY: {
- string const name = cmd.getArg(0);
- InsetBase * base = cur.bv().owner()->getDialogs().getOpenInset(name);
-
- if (base) {
- FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument);
- result = base->dispatch(cur, fr);
- } else {
- MathArray ar;
- if (createMathInset_fromDialogStr(cmd.argument, ar)) {
- mathcursor::insert(cur, ar);
- result = DispatchResult(true, true);
- } else {
- result = DispatchResult(false);
- }
- }
- break;
- }
-
- case LFUN_WORD_REPLACE:
- case LFUN_WORD_FIND: {
- result =
- searchForward(&cur.bv(), cmd.getArg(0), false, false)
- ? DispatchResult(true, true) : DispatchResult(false);
- break;
- }
-
- default:
- result = DispatchResult(false);
- }
-
- if (result == DispatchResult(true, true))
- cur.bv().update();
-
- mathcursor::normalize(cur);
- mathcursor::touch();
-
- BOOST_ASSERT(inMathed());
-
- if (result.dispatched()) {
- revealCodes(cur);
- cur.bv().stuffClipboard(mathcursor::grabSelection(cur));
- } else {
- releaseMathCursor(cur);
- if (remove_inset)
- cur.bv().owner()->dispatch(FuncRequest(LFUN_DELETE));
- }
-
- return result; // original version
-#endif
-}
-
-
-void InsetFormulaBase::revealCodes(LCursor & cur) const
-{
- if (!inMathed())
- return;
- ostringstream os;
- cur.info(os);
- cur.bv().owner()->message(os.str());
-/*
- // write something to the minibuffer
- // translate to latex
- mathcursor::markInsert(bv);
- ostringstream os;
- write(NULL, os);
- string str = os.str();
- mathcursor::markErase(bv);
- string::size_type pos = 0;
- string res;
- for (string::iterator it = str.begin(); it != str.end(); ++it) {
- if (*it == '\n')
- res += ' ';
- else if (*it == '\0') {
- res += " -X- ";
- pos = it - str.begin();
- }
- else
- res += *it;
- }
- if (pos > 30)
- res = res.substr(pos - 30);
- if (res.size() > 60)
- res = res.substr(0, 60);
- bv.owner()->message(res);
-*/
-}
-
-
-InsetOld::Code InsetFormulaBase::lyxCode() const
-{
- return InsetOld::MATH_CODE;
-}
-
-
-int InsetFormulaBase::ylow() const
-{
- return yo_ - dim_.asc;
-}
-
-
-int InsetFormulaBase::yhigh() const
-{
- return yo_ + dim_.des;
-}
-
-
-int InsetFormulaBase::xlow() const
-{
- return xo_;
-}
-
-
-int InsetFormulaBase::xhigh() const
-{
- return xo_ + dim_.wid;
-}
-
-
-/////////////////////////////////////////////////////////////////////
-
-
-bool InsetFormulaBase::searchForward(BufferView * bv, string const & str,
- bool, bool)
-{
- return false;
-#ifdef WITH_WARNINGS
-#warning pretty ugly
-#endif
- static InsetFormulaBase * lastformula = 0;
- static CursorBase current = CursorBase(ibegin(par().nucleus()));
- static MathArray ar;
- static string laststr;
-
- if (lastformula != this || laststr != str) {
- //lyxerr << "reset lastformula to " << this << endl;
- lastformula = this;
- laststr = str;
- current = ibegin(par().nucleus());
- ar.clear();
- mathed_parse_cell(ar, str);
- } else {
- increment(current);
- }
- //lyxerr << "searching '" << str << "' in " << this << ar << endl;
-
- for (CursorBase it = current; it != iend(par().nucleus()); increment(it)) {
- CursorSlice & top = it.back();
- MathArray const & a = top.asMathInset()->cell(top.idx_);
- if (a.matchpart(ar, top.pos_)) {
- mathcursor::formula_ = this;
- mathcursor::setSelection(bv->cursor(), it, ar.size());
- current = it;
- top.pos_ += ar.size();
- bv->update();
- return true;
- }
- }
-
- //lyxerr << "not found!" << endl;
- lastformula = 0;
- return false;
-}
-
-
-bool InsetFormulaBase::searchBackward(BufferView * bv, string const & what,
- bool a, bool b)
-{
- lyxerr[Debug::MATHED] << "searching backward not implemented in mathed" << endl;
- return searchForward(bv, what, a, b);
-}
-
-
-bool InsetFormulaBase::display() const
-{
- return par()->asHullInset() && par()->asHullInset()->display();
-}
-
-
-string InsetFormulaBase::selectionAsString(BufferView & bv) const
-{
- return inMathed() ? mathcursor::grabSelection(bv.cursor()) : string();
-}
-
-/////////////////////////////////////////////////////////////////////
-
-
-void mathDispatchCreation(LCursor & cur, FuncRequest const & cmd,
- bool display)
-{
- // use selection if available..
- //string sel;
- //if (action == LFUN_MATH_IMPORT_SELECTION)
- // sel = "";
- //else
-
- string sel =
- cur.bv().getLyXText()->selectionAsString(*cur.bv().buffer(), false);
-
- if (sel.empty()) {
- InsetFormula * f = new InsetFormula;
- if (openNewInset(cur, f)) {
- cur.inset()->dispatch(cur, FuncRequest(LFUN_MATH_MUTATE, "simple"));
- // don't do that also for LFUN_MATH_MODE unless you want end up with
- // always changing to mathrm when opening an inlined inset
- // -- I really hate "LyXfunc overloading"...
- if (display)
- f->dispatch(cur, FuncRequest(LFUN_MATH_DISPLAY));
- f->dispatch(cur, FuncRequest(LFUN_INSERT_MATH, cmd.argument));
- }
- } else {
- // create a macro if we see "\\newcommand" somewhere, and an ordinary
- // formula otherwise
- InsetFormulaBase * f;
- if (sel.find("\\newcommand") == string::npos &&
- sel.find("\\def") == string::npos)
- f = new InsetFormula(sel);
- else
- f = new InsetFormulaMacro(sel);
- cur.bv().getLyXText()->cutSelection(true, false);
- openNewInset(cur, f);
- }
- cmd.message(N_("Math editor mode"));
-}
-
-
-void mathDispatch(LCursor & cur, FuncRequest const & cmd)
-{
- if (!cur.bv().available())
- return;
-
- switch (cmd.action) {
-
- case LFUN_MATH_DISPLAY:
- mathDispatchCreation(cur, cmd, true);
- break;
-
- case LFUN_MATH_MODE:
- mathDispatchCreation(cur, cmd, false);
- break;
-
- case LFUN_MATH_IMPORT_SELECTION:
- mathDispatchCreation(cur, cmd, false);
- break;
-
- case LFUN_MATH_MACRO:
- if (cmd.argument.empty())
- cmd.errorMessage(N_("Missing argument"));
- else {
- string s = cmd.argument;
- string const s1 = token(s, ' ', 1);
- int const nargs = s1.empty() ? 0 : atoi(s1);
- string const s2 = token(s, ' ', 2);
- string const type = s2.empty() ? "newcommand" : s2;
- openNewInset(cur, new InsetFormulaMacro(token(s, ' ', 0), nargs, s2));
- }
- break;
-
- case LFUN_INSERT_MATH:
- case LFUN_INSERT_MATRIX:
- case LFUN_MATH_DELIM: {
- InsetFormula * f = new InsetFormula;
- if (openNewInset(cur, f)) {
- cur.inset()->dispatch(cur, FuncRequest(LFUN_MATH_MUTATE, "simple"));
- cur.inset()->dispatch(cur, cmd);
- }
- break;
- }
-
- default:
- break;
- }
-}
+++ /dev/null
-// -*- C++ -*-
-/**
- * \file formulabase.h
- * This file is part of LyX, the document processor.
- * Licence details can be found in the file COPYING.
- *
- * \author André Pönitz
- *
- * Full author contact details are available in file CREDITS.
- *
- * Common parts of the math LyX insets.
- */
-
-#ifndef INSET_FORMULABASE_H
-#define INSET_FORMULABASE_H
-
-#include "insets/updatableinset.h"
-
-class Buffer;
-class BufferView;
-class MathAtom;
-class CursorSlice;
-class LCursor;
-
-
-/// An abstract base class for all math related LyX insets
-class InsetFormulaBase : public UpdatableInset {
-public:
- ///
- InsetFormulaBase();
- /// lowest x coordinate
- virtual int xlow() const;
- /// highest x coordinate
- virtual int xhigh() const;
- /// lowest y coordinate
- virtual int ylow() const;
- /// highest y coordinate
- virtual int yhigh() const;
-
-public:
- ///
- // Don't use this for AMS validation as long as there is no
- // user-accessible way to override "false positives"
- virtual void validate(LaTeXFeatures &) const;
- ///
- virtual InsetOld::Code lyxCode() const;
- /// what appears in the minibuffer when opening
- virtual std::string const editMessage() const;
- /// get the absolute document x,y of the cursor
- virtual void getCursorPos(BufferView & bv, int & x, int & y) const;
- ///
- virtual void getCursorDim(int &, int &) const;
- ///
- virtual void insetUnlock(BufferView & bv);
-
- /// To allow transparent use of math editing functions
- //virtual void status(FuncRequest const &);
-
- ///
- virtual MathAtom const & par() const = 0;
- ///
- virtual MathAtom & par() = 0;
- ///
- ///
- virtual bool searchForward(BufferView *, std::string const &,
- bool = true, bool = false);
- ///
- virtual bool searchBackward(BufferView *, std::string const &,
- bool = true, bool = false);
- ///
- virtual bool isTextInset() const { return true; }
- ///
- virtual void mutateToText();
- ///
- virtual void revealCodes(LCursor & cur) const;
- ///
- virtual EDITABLE editable() const { return HIGHLY_EDITABLE; }
- ///
- bool display() const;
- // return the selection as std::string
- std::string selectionAsString(BufferView & bv) const;
- ///
- void edit(LCursor & cur, bool);
- ///
- void edit(LCursor & cur, int, int);
-protected:
- /// To allow transparent use of math editing functions
- DispatchResult priv_dispatch(LCursor & cur, FuncRequest const & cmd);
-private:
- /// unimplemented
- void operator=(const InsetFormulaBase &);
- /// common base for handling accents
- void handleAccent(BufferView & bv, std::string const & arg, std::string const & name);
- /// lfun handler
- DispatchResult lfunMousePress(LCursor &, FuncRequest const &);
- ///
- DispatchResult lfunMouseRelease(LCursor &, FuncRequest const &);
- ///
- DispatchResult lfunMouseMotion(LCursor &, FuncRequest const &);
-
-protected:
-
- /** Find the PreviewLoader, add a LaTeX snippet to it and
- * start the loading process.
- *
- * Most insets have no interest in this capability, so the method
- * defaults to empty.
- */
- virtual void generatePreview(Buffer const &) const {}
-
- ///
- void handleFont(LCursor &, std::string const & arg, std::string const & font);
- ///
- void handleFont2(LCursor &, std::string const & arg);
-};
-
-// We don't really mess want around with mathed stuff outside mathed.
-// So do it here.
-void mathDispatch(LCursor & cur, FuncRequest const & cmd);
-
-///
-void releaseMathCursor(LCursor & cur);
-
-#endif
#warning FIXME
#if 0
par()->draw(pi, x + font_metrics::width(prefix(), p.base.font) + 5, y);
- xo_ = x;
- yo_ = y;
#endif
+ setPosCache(pi, x, y);
}
{
ArrayChanger dummy(mi.base);
MathGridInset::metrics(mi);
- metricsMarkers2();
+ metricsMarkers2(dim_);
dim = dim_;
}
{
//FontSetChanger dummy(mi.base, "mathbf");
cell(0).metrics(mi, dim);
- metricsMarkers(1);
+ metricsMarkers(dim);
++dim.wid; // for 'double stroke'
dim_ = dim;
}
void MathBoxInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
FontSetChanger dummy(mi.base, "textnormal");
- cell(0).metrics(mi, dim_);
- metricsMarkers();
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ metricsMarkers(dim);
+ dim_ = dim;
}
dim.asc += 4;
dim.des += 4;
dim.wid += 2 * w_ + 4;
- metricsMarkers();
+ metricsMarkers(dim);
}
dim_ = dim;
}
void MathCommentInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
cell(0).metrics(mi);
- metricsMarkers();
+ metricsMarkers(dim_);
dim = dim_;
}
}
+bool MathArray::contains(int x, int y) const
+{
+ return xo_ <= x && x <= xo_ + width()
+ && yo_ - ascent() <= y && y <= yo_ + descent();
+}
+
+
void MathArray::center(int & x, int & y) const
{
x = xo_ + width() / 2;
int xm() const { return xo_ + dim_.wid / 2; }
/// access to cached y coordinate of mid point of last drawing
int ym() const { return yo_ + (dim_.des - dim_.asc) / 2; }
+ ///
+ bool contains(int x, int y) const;
/// write access to coordinate;
void setXY(int x, int y) const;
/// returns x coordinate of given position in the array
void MathDecorationInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
- cell(0).metrics(mi);
- dim_ = cell(0).dim();
+ cell(0).metrics(mi, dim);
dh_ = 6; //mathed_char_height(LM_TC_VAR, mi, 'I', ascent_, descent_);
dw_ = 6; //mathed_char_width(LM_TC_VAR, mi, 'x');
if (upper()) {
- dy_ = -dim_.asc - dh_;
- dim_.asc += dh_ + 1;
+ dy_ = -dim.asc - dh_;
+ dim.asc += dh_ + 1;
} else {
- dy_ = dim_.des + 1;
- dim_.des += dh_ + 2;
+ dy_ = dim.des + 1;
+ dim.des += dh_ + 2;
}
- metricsMarkers();
- dim = dim_;
+ metricsMarkers(dim);
+ dim_ = dim;
}
#include "math_diminset.h"
-void MathDimInset::metricsT(TextMetricsInfo const &) const
+
+int MathDimInset::ascent() const
+{
+ return dim_.asc;
+}
+
+
+int MathDimInset::descent() const
+{
+ return dim_.des;
+}
+
+
+int MathDimInset::width() const
{
-#ifndef WITH_WARNINGS
-#warning temporarily disabled
-#endif
-/*
- std::ostringstream os;
- os << MathAtom(this);
- dim_.wid = int(os.str().size());
- dim_.asc = 1;
- dim_.des = 0;
-*/
+ return dim_.wid;
}
-void MathDimInset::drawT(TextPainter &, int, int) const
+void MathDimInset::setPosCache(PainterInfo const &, int x, int y) const
{
-/*
- std::ostringstream os;
- os << MathAtom(this);
- pain.draw(x, y, STRCONV(os.str()));
-*/
+ xo_ = x;
+ yo_ = y;
}
#include "math_inset.h"
#include "dimension.h"
+class PainterInfo;
+
/// things that need the dimension cache
class MathDimInset : public MathInset {
public:
- /// not sure whether the initialization is really necessary
- MathDimInset() {}
///
Dimension dimensions() const { return dim_; }
///
- void metricsT(TextMetricsInfo const &) const;
+ int ascent() const;
+ ///
+ int descent() const;
+ ///
+ int width() const;
+
+ ///
+ int xo() const { return xo_; }
+ ///
+ int yo() const { return yo_; }
///
- void drawT(TextPainter & pain, int x, int y) const;
+ void setPosCache(PainterInfo const & pi, int x, int y) const;
protected:
///
mutable Dimension dim_;
+ ///
+ mutable int xo_;
+ ///
+ mutable int yo_;
};
#endif
void MathEnvInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
- cell(0).metrics(mi, dim_);
- metricsMarkers();
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ metricsMarkers(dim);
+ dim_ = dim;
}
void MathErtInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
FontSetChanger dummy(mi.base, "lyxert");
- MathTextInset::metrics(mi, dim_);
+ MathTextInset::metrics(mi, dim);
cache_.colinfo_[0].align_ = 'l';
- metricsMarkers();
- dim = dim_;
+ metricsMarkers(dim);
+ dim_ = dim;
}
void extractStrings(MathArray & ar)
{
//lyxerr << "\nStrings from: " << ar << endl;
- for (MathArray::size_type i = 0; i < ar.size(); ++i) {
+ for (size_t i = 0; i < ar.size(); ++i) {
if (!ar[i]->asCharInset())
continue;
string s = charSequence(ar.begin() + i, ar.end());
{
//lyxerr << "\nMatrices from: " << ar << endl;
// first pass for explicitly delimited stuff
- for (MathArray::size_type i = 0; i < ar.size(); ++i) {
+ for (size_t i = 0; i < ar.size(); ++i) {
if (!ar[i]->asDelimInset())
continue;
MathArray const & arr = ar[i]->asDelimInset()->cell(0);
}
// second pass for AMS "pmatrix" etc
- for (MathArray::size_type i = 0; i < ar.size(); ++i)
+ for (size_t i = 0; i < ar.size(); ++i)
if (ar[i]->asAMSArrayInset())
ar[i] = MathAtom(new MathMatrixInset(*(ar[i]->asGridInset())));
//lyxerr << "\nMatrices to: " << ar << endl;
{
// use indices rather than iterators for the loop because we are going
// to modify the array.
- for (MathArray::size_type i = 0; i < ar.size(); ++i) {
+ for (size_t i = 0; i < ar.size(); ++i) {
// check whether this is the begin of the sequence
if (!testOpen(ar[i]))
continue;
void splitScripts(MathArray & ar)
{
//lyxerr << "\nScripts from: " << ar << endl;
- for (MathArray::size_type i = 0; i < ar.size(); ++i) {
+ for (size_t i = 0; i < ar.size(); ++i) {
// is this script inset?
if (!ar[i]->asScriptInset())
continue;
void extractExps(MathArray & ar)
{
//lyxerr << "\nExps from: " << ar << endl;
- for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
+ for (size_t i = 0; i + 1 < ar.size(); ++i) {
// is this 'e'?
if (ar[i]->getChar() != 'e')
continue;
void extractNumbers(MathArray & ar)
{
//lyxerr << "\nNumbers from: " << ar << endl;
- for (MathArray::size_type i = 0; i < ar.size(); ++i) {
+ for (size_t i = 0; i < ar.size(); ++i) {
if (!ar[i]->asCharInset())
continue;
if (!isDigitOrSimilar(ar[i]->asCharInset()->getChar()))
return;
//lyxerr << "\nFunctions from: " << ar << endl;
- for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
+ for (size_t i = 0; i + 1 < ar.size(); ++i) {
MathArray::iterator it = ar.begin() + i;
MathArray::iterator jt = it + 1;
return;
//lyxerr << "\nIntegrals from: " << ar << endl;
- for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
+ for (size_t i = 0; i + 1 < ar.size(); ++i) {
MathArray::iterator it = ar.begin() + i;
// search 'd'
return;
//lyxerr << "\nSums from: " << ar << endl;
- for (MathArray::size_type i = 0; i + 1 < ar.size(); ++i) {
+ for (size_t i = 0; i + 1 < ar.size(); ++i) {
MathArray::iterator it = ar.begin() + i;
// is this a sum name?
void extractDiff(MathArray & ar)
{
//lyxerr << "\nDiffs from: " << ar << endl;
- for (MathArray::size_type i = 0; i < ar.size(); ++i) {
+ for (size_t i = 0; i < ar.size(); ++i) {
MathArray::iterator it = ar.begin() + i;
// is this a "differential fraction"?
return;
//lyxerr << "\nLimits from: " << ar << endl;
- for (MathArray::size_type i = 0; i + 2 < ar.size(); ++i) {
+ for (size_t i = 0; i + 2 < ar.size(); ++i) {
MathArray::iterator it = ar.begin() + i;
// is this a limit function?
{
if (key_->name == "fbox") {
FontSetChanger dummy(mi.base, "textnormal");
- cell(0).metrics(mi, dim_);
+ cell(0).metrics(mi, dim);
} else {
- cell(0).metrics(mi, dim_);
+ cell(0).metrics(mi, dim);
}
- metricsMarkers(5); // 5 pixels margin
- dim = dim_;
+ metricsMarkers(dim, 5); // 5 pixels margin
+ dim_ = dim;
}
void MathFontInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
FontSetChanger dummy(mi.base, key_->name.c_str());
- cell(0).metrics(mi, dim_);
- metricsMarkers(1);
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ metricsMarkers(dim);
+ dim_ = dim;
}
}
-void MathFontInset::metricsT(TextMetricsInfo const & mi, Dimension & /*dim*/) const
+void MathFontInset::metricsT(TextMetricsInfo const & mi, Dimension &) const
{
cell(0).metricsT(mi, dim_);
}
void MathFontOldInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
FontSetChanger dummy(mi.base, key_->name.c_str());
- cell(0).metrics(mi, dim_);
- metricsMarkers(1);
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ metricsMarkers(dim);
+ dim_ = dim;
}
void MathFracInset::draw(PainterInfo & pi, int x, int y) const
{
+ setPosCache(pi, x, y);
int m = x + dim_.wid / 2;
FracChanger dummy(pi.base);
cell(0).draw(pi, m - cell(0).width() / 2, y - cell(0).descent() - 2 - 5);
FontSetChanger dummy(mi.base, "textnormal");
w_ = mathed_char_width(mi.base.font, '[');
MathNestInset::metrics(mi);
- dim_ = cell(0).dim();
- dim_ += cell(1).dim();
- dim_ += cell(2).dim();
- metricsMarkers();
- dim = dim_;
+ dim = cell(0).dim();
+ dim += cell(1).dim();
+ dim += cell(2).dim();
+ metricsMarkers(dim);
+ dim_ = dim;
}
DispatchResult
MathGridInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{
+ lyxerr << "*** MathGridInset: request: " << cmd << endl;
switch (cmd.action) {
case LFUN_MOUSE_RELEASE:
/// Ensures that the dialog is closed.
~MathGridInset();
///
- virtual std::auto_ptr<InsetBase> clone() const;
+ std::auto_ptr<InsetBase> clone() const;
///
void metrics(MetricsInfo & mi) const;
///
#include "LaTeXFeatures.h"
#include "LColor.h"
#include "lyxrc.h"
+#include "outputparams.h"
#include "textpainter.h"
#include "frontends/Alert.h"
#include "support/std_sstream.h"
-
using lyx::support::trim;
using std::endl;
using std::max;
using std::string;
+using std::ostream;
using std::auto_ptr;
using std::istringstream;
using std::ostream;
} // end anon namespace
+
MathHullInset::MathHullInset()
: MathGridInset(1, 1), type_("none"), nonum_(1), label_(1)
{
StyleChanger dummy2(mi.base, display() ? LM_ST_DISPLAY : LM_ST_TEXT);
// let the cells adjust themselves
- MathGridInset::metrics(mi);
+ MathGridInset::metrics(mi, dim);
if (display()) {
- dim_.asc += 12;
- dim_.des += 12;
+ dim.asc += 12;
+ dim.des += 12;
}
if (numberedType()) {
l = max(l, mathed_string_width(mi.base.font, nicelabel(row)));
if (l)
- dim_.wid += 30 + l;
+ dim.wid += 30 + l;
}
// make it at least as high as the current font
int asc = 0;
int des = 0;
math_font_max_dim(mi.base.font, asc, des);
- dim_.asc = max(dim_.asc, asc);
- dim_.des = max(dim_.des, des);
+ dim.asc = max(dim.asc, asc);
+ dim.des = max(dim.des, des);
// for markers
- metricsMarkers2();
- dim = dim_;
+ metricsMarkers2(dim);
+ dim_ = dim;
}
DispatchResult
MathHullInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{
+ lyxerr << "*** MathHullInset: request: " << cmd << endl;
switch (cmd.action) {
case LFUN_BREAKLINE:
#include "formulamacro.h"
#include "math_arrayinset.h"
-#include "math_data.h"
#include "math_deliminset.h"
#include "math_factory.h"
-#include "math_hullinset.h"
#include "math_parser.h"
#include "math_spaceinset.h"
-#include "math_support.h"
#include "ref_inset.h"
-#include "BufferView.h"
#include "bufferview_funcs.h"
-#include "cursor.h"
-#include "dispatchresult.h"
-#include "debug.h"
-#include "funcrequest.h"
-#include "gettext.h"
-#include "LColor.h"
#include "lyxtext.h"
#include "undo.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
-using lyx::support::atoi;
-using lyx::support::split;
-using lyx::support::token;
-
-using std::abs;
-using std::endl;
-using std::max;
-using std::istringstream;
-using std::ostringstream;
namespace {
int first_x;
int first_y;
-bool openNewInset(LCursor & cur, InsetBase * inset)
-{
- if (!cur.bv().insertInset(inset)) {
- delete inset;
- return false;
- }
- inset->edit(cur, true);
- return true;
-}
-
-
} // namespace anon
}
-void MathHullInset::getCursorPos(BufferView & bv, int & x, int & y) const
-{
- if (bv.cursor().inMathed()) {
- bv.cursor().getScreenPos(x, y);
- x = bv.cursor().targetX();
- x -= xo_;
- y -= yo_;
- lyxerr << "MathHullInset::getCursorPos: " << x << ' ' << y << endl;
- } else {
- x = 0;
- y = 0;
- lyxerr << "getCursorPos - should not happen";
- }
-}
-
-
void MathHullInset::getCursorDim(int & asc, int & desc) const
{
asc = 10;
MathArray ar;
asArray(cur.bv().getClipboard(), ar);
cur.selClear();
- cur.setScreenPos(cmd.x + xo_, cmd.y + yo_);
+ cur.setScreenPos(cmd.x, cmd.y);
cur.insert(ar);
cur.bv().update();
return DispatchResult(true, true);
// try to dispatch to enclosed insets first
cur.dispatch(cmd);
cur.bv().stuffClipboard(cur.grabSelection());
- // try to set the cursor
- //delete mathcursor;
- //mathcursor = new MathCursor(bv, this, x == 0);
- //metrics(bv);
- //cur.setScreenPos(x + xo_, y + yo_);
return DispatchResult(true, true);
}
}
+/*
void MathHullInset::edit(LCursor & cur, int x, int y)
{
- lyxerr << "Called FormulaBase::EDIT with '" << x << ' ' << y << "'" << endl;
- //metrics(bv);
+ lyxerr << "Called MathHullInset::edit with '" << x << ' ' << y << "'" << endl;
cur.push(this);
//cur.idx() = left ? 0 : cur.lastidx();
cur.idx() = 0;
- cur.idx() = 0;
+ cur.pos() = 0;
cur.setScreenPos(x + xo_, y + yo_);
// if that is removed, we won't get the magenta box when entering an
// inset for the first time
cur.bv().update();
}
-
-
+*/
void MathHullInset::revealCodes(LCursor & cur) const
#warning pretty ugly
#endif
static MathHullInset * lastformula = 0;
- static CursorBase current = CursorBase(ibegin(par().nucleus()));
+ static CursorBase current = CursorBase(ibegin(nucleus()));
static MathArray ar;
static string laststr;
//lyxerr << "reset lastformula to " << this << endl;
lastformula = this;
laststr = str;
- current = ibegin(par().nucleus());
+ current = ibegin(nucleus());
ar.clear();
mathed_parse_cell(ar, str);
} else {
}
//lyxerr << "searching '" << str << "' in " << this << ar << endl;
- for (CursorBase it = current; it != iend(par().nucleus()); increment(it)) {
+ for (CursorBase it = current; it != iend(nucleus()); increment(it)) {
CursorSlice & top = it.back();
MathArray const & a = top.asMathInset()->cell(top.idx_);
if (a.matchpart(ar, top.pos_)) {
bool MathHullInset::searchBackward(BufferView * bv, string const & what,
bool a, bool b)
{
- lyxerr[Debug::MATHED] << "searching backward not implemented in mathed" << endl;
+ lyxerr[Debug::MATHED]
+ << "searching backward not implemented in mathed" << endl;
return searchForward(bv, what, a, b);
}
+void MathHullInset::write(Buffer const &, std::ostream & os) const
+{
+ WriteStream wi(os, false, false);
+ os << fileInsetLabel() << ' ';
+ write(wi);
+}
+
+
+void MathHullInset::read(Buffer const &, LyXLex & lex)
+{
+ MathAtom at;
+ mathed_parse_normal(at, lex);
+ operator=(*at->asHullInset());
+}
+
+
+int MathHullInset::latex(Buffer const &, ostream & os,
+ OutputParams const & runparams) const
+{
+ WriteStream wi(os, runparams.moving_arg, true);
+ write(wi);
+ return wi.line();
+}
+
+
+int MathHullInset::plaintext(Buffer const &, ostream & os,
+ OutputParams const &) const
+{
+ if (0 && display()) {
+ Dimension dim;
+ TextMetricsInfo mi;
+ metricsT(mi, dim);
+ TextPainter tpain(dim.width(), dim.height());
+ drawT(tpain, 0, dim.ascent());
+ tpain.show(os, 3);
+ // reset metrics cache to "real" values
+ //metrics();
+ return tpain.textheight();
+ } else {
+ WriteStream wi(os, false, true);
+ wi << ' ' << cell(0) << ' ';
+ return wi.line();
+ }
+}
+
+
+int MathHullInset::linuxdoc(Buffer const & buf, ostream & os,
+ OutputParams const & runparams) const
+{
+ return docbook(buf, os, runparams);
+}
+
+
+int MathHullInset::docbook(Buffer const & buf, ostream & os,
+ OutputParams const & runparams) const
+{
+ MathMLStream ms(os);
+ ms << MTag("equation");
+ ms << MTag("alt");
+ ms << "<[CDATA[";
+ int res = plaintext(buf, ms.os(), runparams);
+ ms << "]]>";
+ ms << ETag("alt");
+ ms << MTag("math");
+ MathGridInset::mathmlize(ms);
+ ms << ETag("math");
+ ms << ETag("equation");
+ return ms.line() + res;
+}
+
+
+
+/////////////////////////////////////////////
+
+namespace {
+
+bool openNewInset(LCursor & cur, InsetBase * inset)
+{
+ if (!cur.bv().insertInset(inset)) {
+ delete inset;
+ return false;
+ }
+ inset->edit(cur, true);
+ return true;
+}
+
+
void mathDispatchCreation(LCursor & cur, FuncRequest const & cmd,
bool display)
{
cmd.message(N_("Math editor mode"));
}
+} // namespace anon
+
void mathDispatch(LCursor & cur, FuncRequest const & cmd)
{
#include "math_gridinset.h"
-class LaTeXFeatures;
-
/// This provides an interface between "LyX insets" and "LyX math insets"
class MathHullInset : public MathGridInset {
public:
///
explicit MathHullInset(std::string const & type);
///
- virtual std::auto_ptr<InsetBase> clone() const;
+ std::auto_ptr<InsetBase> clone() const;
///
mode_type currentMode() const;
///
///
void infoize(std::ostream & os) const;
+ ///
+ void write(Buffer const &, std::ostream & os) const;
+ ///
+ void read(Buffer const &, LyXLex & lex);
+ ///
+ int latex(Buffer const &, std::ostream &,
+ OutputParams const &) const;
+ ///
+ int plaintext(Buffer const &, std::ostream &,
+ OutputParams const &) const;
+ ///
+ int linuxdoc(Buffer const &, std::ostream &,
+ OutputParams const &) const;
+ ///
+ int docbook(Buffer const &, std::ostream &,
+ OutputParams const &) const;
+
+ ///
+ //bool insetAllowed(Code code) const;
+ ///
+ //void addPreview(lyx::graphics::PreviewLoader &) const;
+
+
protected:
///
DispatchResult priv_dispatch(LCursor & cur, FuncRequest const & cmd);
/// what appears in the minibuffer when opening
virtual std::string const editMessage() const;
- /// get the absolute document x,y of the cursor
- virtual void getCursorPos(BufferView & bv, int & x, int & y) const;
///
virtual void getCursorDim(int &, int &) const;
///
///
bool display() const;
///
- void edit(LCursor & cur, bool);
- ///
- void edit(LCursor & cur, int, int);
+ void edit(LCursor & cur, bool left);
///
- Code MathHullInset::lyxCode() const;
+ Code lyxCode() const;
private:
/// common base for handling accents
DispatchResult lfunMouseRelease(LCursor &, FuncRequest const &);
///
DispatchResult lfunMouseMotion(LCursor &, FuncRequest const &);
- ///
- int x() const { return xo_; }
- ///
- int y() const { return yo_; }
- ///
- int yo_;
- ///
- int xo_;
protected:
void handleFont2(LCursor &, std::string const & arg);
};
-// We don't really mess want around with mathed stuff outside mathed.
+// We don't really want to mess around with mathed stuff outside mathed.
// So do it here.
void mathDispatch(LCursor & cur, FuncRequest const & cmd);
#endif
void MathLefteqnInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
- cell(0).metrics(mi);
- dim_.asc = cell(0).ascent() + 2;
- dim_.des = cell(0).descent() + 2;
- dim_.wid = 4;
- metricsMarkers();
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ dim.asc += 2;
+ dim.des += 2;
+ dim.wid = 4;
+ metricsMarkers(dim);
+ dim_ = dim;
}
if (defining()) {
- mathed_string_dim(font_, name(), dim_);
+ mathed_string_dim(font_, name(), dim);
} else if (editing(mi.base.bv)) {
expand();
- expanded_.metrics(mi_, dim_);
- metricsMarkers();
+ expanded_.metrics(mi_, dim);
+ metricsMarkers(dim);
- dim_.wid += mathed_string_width(font_, name()) + 10;
+ dim.wid += mathed_string_width(font_, name()) + 10;
int ww = mathed_string_width(font_, "#1: ");
for (idx_type i = 0; i < nargs(); ++i) {
MathArray const & c = cell(i);
c.metrics(mi_);
- dim_.wid = max(dim_.wid, c.width() + ww);
- dim_.des += max(c.ascent(), dim_.asc) + 5;
- dim_.des += max(c.descent(), dim_.des) + 5;
+ dim.wid = max(dim.wid, c.width() + ww);
+ dim.des += max(c.ascent(), dim.asc) + 5;
+ dim.des += max(c.descent(), dim.des) + 5;
}
} else {
expand();
expanded_.substitute(*this);
- expanded_.metrics(mi_, dim_);
+ expanded_.metrics(mi_, dim);
}
- dim = dim_;
+ dim_ = dim;
}
FontSetChanger dummy(mi.base, "textnormal");
w_ = mathed_char_width(mi.base.font, '[');
MathNestInset::metrics(mi);
- dim_ = cell(0).dim();
- dim_ += cell(1).dim();
- dim_ += cell(2).dim();
- dim_.wid += 4 * w_ + 4;
- metricsMarkers();
- dim = dim_;
+ dim = cell(0).dim();
+ dim += cell(1).dim();
+ dim += cell(2).dim();
+ dim.wid += 4 * w_ + 4;
+ metricsMarkers(dim);
+ dim_ = dim;
}
--- /dev/null
+/**
+ * \file math_mboxinset.C
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author André Pönitz
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#include <config.h>
+
+#include "math_mboxinset.h"
+#include "math_data.h"
+#include "math_mathmlstream.h"
+
+#include "BufferView.h"
+#include "buffer.h"
+#include "bufferparams.h"
+#include "debug.h"
+#include "metricsinfo.h"
+#include "paragraph.h"
+
+using std::auto_ptr;
+using std::endl;
+
+
+MathMBoxInset::MathMBoxInset(BufferView & bv)
+ : text_(&bv, true), bv_(&bv)
+{
+ text_.paragraphs().push_back(Paragraph());
+ text_.paragraphs().back().
+ layout(bv.buffer()->params().getLyXTextClass().defaultLayout());
+ text_.redoParagraph(text_.paragraphs().begin());
+}
+
+
+auto_ptr<InsetBase> MathMBoxInset::clone() const
+{
+ return auto_ptr<InsetBase>(new MathMBoxInset(*this));
+}
+
+
+void MathMBoxInset::metrics(MetricsInfo & mi, Dimension & dim) const
+{
+ text_.metrics(mi, dim);
+ metricsMarkers2(dim);
+ dim_ = dim;
+}
+
+
+void MathMBoxInset::draw(PainterInfo & pi, int x, int y) const
+{
+ text_.draw(pi, x + 1, y);
+ drawMarkers(pi, x, y);
+}
+
+
+void MathMBoxInset::write(WriteStream & os) const
+{
+ os << "\\mbox{\n";
+ text_.write(*bv_->buffer(), os.os());
+ os << "}";
+}
+
+
+DispatchResult MathMBoxInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
+{
+ return text_.dispatch(cur, cmd);
+}
+
+
+LyXText * MathMBoxInset::getText(int) const
+{
+ return &text_;
+}
+
+
+void MathMBoxInset::getCursorPos(CursorSlice const & cur, int & x, int & y) const
+{
+ x = text_.cursorX(cur);
+ //y = text_.cursorY(cur);
+ y = 100;
+}
--- /dev/null
+// -*- C++ -*-
+/**
+ * \file math_mboxinset.h
+ * This file is part of LyX, the document processor.
+ * Licence details can be found in the file COPYING.
+ *
+ * \author André Pönitz
+ *
+ * Full author contact details are available in file CREDITS.
+ */
+
+#ifndef MATH_MBOXINSET_H
+#define MATH_MBOXINSET_H
+
+#include "math_diminset.h"
+#include "lyxtext.h"
+
+class BufferView;
+
+
+// not yet a substitute for the real text inset...
+
+class MathMBoxInset : public MathDimInset {
+public:
+ ///
+ MathMBoxInset(BufferView & bv);
+ ///
+ std::auto_ptr<InsetBase> clone() const;
+ /// this stores metrics information in cache_
+ void metrics(MetricsInfo & mi, Dimension & dim) const;
+ /// draw according to cached metrics
+ void draw(PainterInfo &, int x, int y) const;
+ ///
+ DispatchResult priv_dispatch(LCursor & cur, FuncRequest const & cmd);
+
+ ///
+ void write(WriteStream & os) const;
+
+ ///
+ LyXText * getText(int) const;
+ ///
+ void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
+protected:
+ ///
+ mutable LyXText text_;
+ ///
+ BufferView * const bv_;
+};
+
+#endif
#include "math_nestinset.h"
+#include "math_arrayinset.h"
+#include "math_data.h"
+#include "math_deliminset.h"
+#include "math_factory.h"
+#include "math_hullinset.h"
+#include "math_mathmlstream.h"
+#include "math_parser.h"
+#include "math_spaceinset.h"
+#include "math_support.h"
+#include "math_mboxinset.h"
+
#include "BufferView.h"
-#include "LColor.h"
+#include "bufferview_funcs.h"
#include "cursor.h"
#include "debug.h"
#include "dispatchresult.h"
#include "funcrequest.h"
-#include "math_data.h"
-#include "math_mathmlstream.h"
-#include "math_parser.h"
+#include "gettext.h"
+#include "LColor.h"
#include "undo.h"
+#include "support/std_sstream.h"
+#include "support/lstrings.h"
+
+#include "frontends/Dialogs.h"
+#include "frontends/LyXView.h"
#include "frontends/Painter.h"
+using std::endl;
+using std::string;
+using std::istringstream;
+
+
MathNestInset::MathNestInset(idx_type nargs)
: cells_(nargs), lock_(false)
{}
}
-void MathNestInset::getScreenPos(idx_type idx, pos_type pos, int & x, int & y) const
+void MathNestInset::getCursorPos(CursorSlice const & cur,
+ int & x, int & y) const
{
- MathArray const & ar = cell(idx);
- x = ar.xo() + ar.pos2x(pos);
+ MathArray const & ar = cur.cell();
+ x = ar.xo() + ar.pos2x(cur.pos());
y = ar.yo();
// move cursor visually into empty cells ("blue rectangles");
- if (cell(idx).empty())
+ if (cur.cell().empty())
x += 2;
}
}
-bool MathNestInset::editing(BufferView * bv) const
-{
- return bv->cursor().isInside(this);
-}
-
-
bool MathNestInset::lock() const
{
return lock_;
}
+void MathNestInset::handleFont
+ (LCursor & cur, string const & arg, string const & font)
+{
+ // this whole function is a hack and won't work for incremental font
+ // changes...
+ recordUndo(cur, Undo::ATOMIC);
+
+ if (cur.inset()->asMathInset()->name() == font)
+ cur.handleFont(font);
+ else {
+ cur.handleNest(createMathInset(font));
+ cur.insert(arg);
+ }
+}
+
+
+void MathNestInset::handleFont2(LCursor & cur, string const & arg)
+{
+ recordUndo(cur, Undo::ATOMIC);
+ LyXFont font;
+ bool b;
+ bv_funcs::string2font(arg, font, b);
+ if (font.color() != LColor::inherit) {
+ MathAtom at = createMathInset("color");
+ asArray(lcolor.getGUIName(font.color()), at.nucleus()->cell(0));
+ cur.handleNest(at, 1);
+ }
+}
+
+
DispatchResult
MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd)
{
+ lyxerr << "*** MathNestInset: request: " << cmd << std::endl;
//lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action
// << " arg: '" << cmd.argument
// << "' x: '" << cmd.x
switch (cmd.action) {
+ case LFUN_PASTE:
+ if (!cmd.argument.empty()) {
+ MathArray ar;
+ mathed_parse_cell(ar, cmd.argument);
+ cur.cell().insert(cur.pos(), ar);
+ cur.pos() += ar.size();
+ }
+ return DispatchResult(true, true);
+/*
case LFUN_PASTE: {
- MathArray ar;
- mathed_parse_cell(ar, cmd.argument);
- cur.cell().insert(cur.pos(), ar);
- cur.pos() += ar.size();
+ size_t n = 0;
+ istringstream is(cmd.argument.c_str());
+ is >> n;
+ if (was_macro)
+ cur.macroModeClose();
+ recordUndo(cur, Undo::ATOMIC);
+ cur.selPaste(n);
return DispatchResult(true, true);
}
+*/
case LFUN_PASTESELECTION:
return dispatch(cur, FuncRequest(LFUN_PASTE, cur.bv().getClipboard()));
#if 0
//
-// this needs to bee incorporated
+// this needs to be incorporated
//
//lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action
// << " arg: '" << cmd.argument
}
DispatchResult result(true);
- string argument = cmd.argument;
bool was_macro = cur.inMacroMode();
cur.normalize();
switch (cmd.action) {
- case LFUN_MATH_MUTATE:
- case LFUN_MATH_DISPLAY:
- case LFUN_MATH_NUMBER:
- case LFUN_MATH_NONUMBER:
- case LFUN_CELL_SPLIT:
- case LFUN_BREAKLINE:
- case LFUN_DELETE_LINE_FORWARD:
- case LFUN_INSERT_LABEL:
- case LFUN_MATH_EXTERN:
- case LFUN_TABULAR_FEATURE:
- case LFUN_PASTESELECTION:
case LFUN_MATH_LIMITS:
recordUndo(cur, Undo::ATOMIC);
cur.dispatch(cmd);
break;
+#endif
// case LFUN_GETXY:
// sprintf(dispatch_buffer, "%d %d",);
istringstream is(cmd.argument.c_str());
is >> x >> y;
cur.setScreenPos(x, y);
- break;
- }
-
- case LFUN_PASTE: {
- size_t n = 0;
- istringstream is(cmd.argument.c_str());
- is >> n;
- if (was_macro)
- cur.macroModeClose();
- recordUndo(cur, Undo::ATOMIC);
- cur.selPaste(n);
- break;
+ return DispatchResult(true, true);
}
case LFUN_CUT:
recordUndo(cur, Undo::DELETE);
cur.selCut();
- break;
+ return DispatchResult(true, true);
case LFUN_COPY:
cur.selCopy();
- break;
+ return DispatchResult(true, true);
// Special casing for superscript in case of LyX handling
recordUndo(cur, Undo::ATOMIC);
cur.script(true);
}
- break;
+ return DispatchResult(true, true);
case LFUN_UMLAUT:
case LFUN_ACUTE:
case LFUN_TIE:
case LFUN_OGONEK:
case LFUN_HUNG_UMLAUT:
- break;
+ return DispatchResult(true, true);
// Math fonts
case LFUN_FREEFONT_APPLY:
case LFUN_FREEFONT_UPDATE:
handleFont2(cur, cmd.argument);
- break;
+ return DispatchResult(true, true);
- case LFUN_BOLD: handleFont(cur, cmd.argument, "mathbf"); break;
- case LFUN_SANS: handleFont(cur, cmd.argument, "mathsf"); break;
- case LFUN_EMPH: handleFont(cur, cmd.argument, "mathcal"); break;
- case LFUN_ROMAN: handleFont(cur, cmd.argument, "mathrm"); break;
- case LFUN_CODE: handleFont(cur, cmd.argument, "texttt"); break;
- case LFUN_FRAK: handleFont(cur, cmd.argument, "mathfrak"); break;
- case LFUN_ITAL: handleFont(cur, cmd.argument, "mathit"); break;
- case LFUN_NOUN: handleFont(cur, cmd.argument, "mathbb"); break;
- //case LFUN_FREEFONT_APPLY: handleFont(cur, cmd.argument, "textrm"); break;
- case LFUN_DEFAULT: handleFont(cur, cmd.argument, "textnormal"); break;
+ case LFUN_BOLD:
+ handleFont(cur, cmd.argument, "mathbf");
+ return DispatchResult(true, true);
+ case LFUN_SANS:
+ handleFont(cur, cmd.argument, "mathsf");
+ return DispatchResult(true, true);
+ case LFUN_EMPH:
+ handleFont(cur, cmd.argument, "mathcal");
+ return DispatchResult(true, true);
+ case LFUN_ROMAN:
+ handleFont(cur, cmd.argument, "mathrm");
+ return DispatchResult(true, true);
+ case LFUN_CODE:
+ handleFont(cur, cmd.argument, "texttt");
+ return DispatchResult(true, true);
+ case LFUN_FRAK:
+ handleFont(cur, cmd.argument, "mathfrak");
+ return DispatchResult(true, true);
+ case LFUN_ITAL:
+ handleFont(cur, cmd.argument, "mathit");
+ return DispatchResult(true, true);
+ case LFUN_NOUN:
+ handleFont(cur, cmd.argument, "mathbb");
+ return DispatchResult(true, true);
+ //case LFUN_FREEFONT_APPLY:
+ handleFont(cur, cmd.argument, "textrm");
+ return DispatchResult(true, true);
+ case LFUN_DEFAULT:
+ handleFont(cur, cmd.argument, "textnormal");
+ return DispatchResult(true, true);
case LFUN_MATH_MODE:
+#if 1
+ cur.macroModeClose();
+ cur.selClearOrDel();
+ cur.plainInsert(MathAtom(new MathMBoxInset(cur.bv())));
+ cur.posLeft();
+ cur.pushLeft(cur.nextAtom().nucleus());
+#else
if (cur.currentMode() == InsetBase::TEXT_MODE)
cur.niceInsert(MathAtom(new MathHullInset("simple")));
else
handleFont(cur, cmd.argument, "textrm");
//cur.owner()->message(_("math text mode toggled"));
- break;
+#endif
+ return DispatchResult(true, true);
case LFUN_MATH_SIZE:
#if 0
cur.setSize(arg);
}
#endif
- break;
+ return DispatchResult(true, true);
case LFUN_INSERT_MATRIX: {
recordUndo(cur, Undo::ATOMIC);
unsigned int n = 1;
string v_align;
string h_align;
- istringstream is(argument);
+ istringstream is(cmd.argument);
is >> m >> n >> v_align >> h_align;
- m = max(1u, m);
- n = max(1u, n);
+ if (m < 1)
+ m = 1;
+ if (n < 1)
+ n = 1;
v_align += 'c';
cur.niceInsert(
MathAtom(new MathArrayInset("array", m, n, v_align[0], h_align)));
- break;
+ return DispatchResult(true, true);
}
case LFUN_MATH_DELIM: {
//lyxerr << "formulabase::LFUN_MATH_DELIM, arg: '" << arg << "'" << endl;
string ls;
- string rs = split(cmd.argument, ls, ' ');
+ string rs = lyx::support::split(cmd.argument, ls, ' ');
// Reasonable default values
if (ls.empty())
ls = '(';
rs = ')';
recordUndo(cur, Undo::ATOMIC);
cur.handleNest(MathAtom(new MathDelimInset(ls, rs)));
- break;
+ return DispatchResult(true, true);
}
case LFUN_SPACE_INSERT:
case LFUN_MATH_SPACE:
recordUndo(cur, Undo::ATOMIC);
cur.insert(MathAtom(new MathSpaceInset(",")));
- break;
+ return DispatchResult(true, true);
case LFUN_UNDO:
- cur.bv().owner()->message(_("Invalid action in math mode!"));
- break;
-
-
- case LFUN_EXEC_COMMAND:
- result = DispatchResult(false);
- break;
+#warning look here
+ //cur.bv().owner()->message(_("Invalid action in math mode!"));
+ return DispatchResult(true, true);
case LFUN_INSET_ERT:
// interpret this as if a backslash was typed
recordUndo(cur, Undo::ATOMIC);
cur.interpret('\\');
- break;
+ return DispatchResult(true, true);
+#if 0
case LFUN_BREAKPARAGRAPH:
case LFUN_BREAKPARAGRAPHKEEPLAYOUT:
case LFUN_BREAKPARAGRAPH_SKIP:
- argument = "\n";
- // fall through
+ cmd.argument = "\n";
+ recordUndo(cur, Undo::ATOMIC);
+ cur.niceInsert(argument);
+ return DispatchResult(true, true);
+#endif
// FIXME: We probably should swap parts of "math-insert" and "self-insert"
// handling such that "self-insert" works on "arbitrary stuff" too, and
// math-insert only handles special math things like "matrix".
case LFUN_INSERT_MATH:
recordUndo(cur, Undo::ATOMIC);
- cur.niceInsert(argument);
- break;
-
- case LFUN_INSET_TOGGLE:
- cur.lockToggle();
- break;
+ cur.niceInsert(cmd.argument);
+ return DispatchResult(true, true);
case LFUN_DIALOG_SHOW:
- result = DispatchResult(false);
- break;
+ return DispatchResult(false);
case LFUN_DIALOG_SHOW_NEW_INSET: {
- string const & name = argument;
+ string const & name = cmd.argument;
string data;
+#if 0
if (name == "ref") {
RefInset tmp(name);
data = tmp.createDialogStr(name);
}
-
+#endif
if (data.empty())
- result = DispatchResult(false);
- else
- cur.bv().owner()->getDialogs().show(name, data, 0);
- break;
+ return DispatchResult(false);
+ cur.bv().owner()->getDialogs().show(name, data, 0);
+ return DispatchResult(true, true);
}
case LFUN_INSET_APPLY: {
if (base) {
FuncRequest fr(LFUN_INSET_MODIFY, cmd.argument);
- result = base->dispatch(cur, fr);
- } else {
- MathArray ar;
- if (createMathInset_fromDialogStr(cmd.argument, ar)) {
- cur.insert(ar);
- result = DispatchResult(true, true);
- } else {
- result = DispatchResult(false);
- }
+ return base->dispatch(cur, fr);
}
- break;
+ MathArray ar;
+ if (createMathInset_fromDialogStr(cmd.argument, ar)) {
+ cur.insert(ar);
+ return DispatchResult(true, true);
+ }
+ return DispatchResult(false);
}
+#warning look here
+#if 0
+
case LFUN_WORD_REPLACE:
- case LFUN_WORD_FIND: {
- result =
+ case LFUN_WORD_FIND:
+ return
searchForward(&cur.bv(), cmd.getArg(0), false, false)
? DispatchResult(true, true) : DispatchResult(false);
- break;
- }
case LFUN_INSERT_MATH:
case LFUN_INSERT_MATRIX:
cur.inset()->dispatch(cur, FuncRequest(LFUN_MATH_MUTATE, "simple"));
cur.inset()->dispatch(cur, cmd);
}
- break;
- }
-
- default:
- result = DispatchResult(false);
+ return DispatchResult(true, true);
}
- if (result == DispatchResult(true, true))
- cur.bv().update();
-
cur.normalize();
cur.touch();
#endif
default:
- return MathInset::priv_dispatch(cur, cmd);
+ return MathDimInset::priv_dispatch(cur, cmd);
}
}
-void MathNestInset::metricsMarkers(int) const
-{
- dim_.wid += 2;
- dim_.asc += 1;
-}
-
-
-void MathNestInset::metricsMarkers2(int) const
-{
- dim_.wid += 2;
- dim_.asc += 1;
- dim_.des += 1;
-}
-
-
-void MathNestInset::drawMarkers(PainterInfo & pi, int x, int y) const
+void MathNestInset::edit(LCursor & cur, int x, int y)
{
- if (!editing(pi.base.bv))
- return;
- int t = x + dim_.width() - 1;
- int d = y + dim_.descent();
- pi.pain.line(x, d - 3, x, d, LColor::mathframe);
- pi.pain.line(t, d - 3, t, d, LColor::mathframe);
- pi.pain.line(x, d, x + 3, d, LColor::mathframe);
- pi.pain.line(t - 3, d, t, d, LColor::mathframe);
-}
-
-
-void MathNestInset::drawMarkers2(PainterInfo & pi, int x, int y) const
-{
- if (!editing(pi.base.bv))
- return;
- drawMarkers(pi, x, y);
- int t = x + dim_.width() - 1;
- int a = y - dim_.ascent();
- pi.pain.line(x, a + 3, x, a, LColor::mathframe);
- pi.pain.line(t, a + 3, t, a, LColor::mathframe);
- pi.pain.line(x, a, x + 3, a, LColor::mathframe);
- pi.pain.line(t - 3, a, t, a, LColor::mathframe);
+ lyxerr << "Called MathHullInset::edit with '" << x << ' ' << y << "'" << endl;
+ cur.push(this);
+ int idx_min = 0;
+ int dist_min = 1000000;
+ for (idx_type i = 0; i < nargs(); ++i) {
+ int d = cell(i).dist(x, y);
+ if (d < dist_min) {
+ dist_min = d;
+ idx_min = i;
+ }
+ }
+ MathArray & ar = cell(idx_min);
+ cur.push(this);
+ cur.idx() = idx_min;
+ cur.pos() = ar.x2pos(x - ar.xo());
+ lyxerr << "found cell : " << idx_min << " pos: " << cur.pos() << endl;
+ if (dist_min == 0) {
+ // hit inside cell
+ for (pos_type i = 0, n = ar.size(); i < n; ++i)
+ if (ar[i]->covers(x, y))
+ ar[i].nucleus()->edit(cur, x, y);
+ }
}
/// identifies NestInsets
MathNestInset const * asNestInset() const { return this; }
/// get cursor position
- void getScreenPos(idx_type idx, pos_type pos, int & x, int & y) const;
+ void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
+ ///
+ void edit(LCursor & cur, int, int);
/// order of movement through the cells when pressing the left key
bool idxLeft(LCursor &) const;
void normalize(NormalStream & os) const;
protected:
///
- virtual
- DispatchResult
- priv_dispatch(LCursor & cur, FuncRequest const & cmd);
+ DispatchResult priv_dispatch(LCursor & cur, FuncRequest const & cmd);
+ ///
+ void handleFont(LCursor & cur,
+ std::string const & arg, std::string const & font);
+ ///
+ void handleFont2(LCursor & cur, std::string const & arg);
/// we store the cells in a vector
typedef std::vector<MathArray> cells_type;
cells_type cells_;
/// if the inset is locked, it can't be entered with the cursor
bool lock_;
-
- ///
- bool editing(BufferView * bv) const;
- /// draw four angular markers
- void drawMarkers(PainterInfo & pi, int x, int y) const;
- /// draw two angular markers
- void drawMarkers2(PainterInfo & pi, int x, int y) const;
-
- /// add space for markers
- void metricsMarkers(int frame = 1) const;
- /// add space for markers
- void metricsMarkers2(int frame = 1) const;
};
#endif
{
FontSetChanger dummy1(mi.base, "textnormal");
WidthChanger dummy2(mi.base, lyx_width_);
- MathTextInset::metrics(mi, dim_);
- metricsMarkers();
- dim = dim_;
+ MathTextInset::metrics(mi, dim);
+ metricsMarkers(dim);
+ dim_ = dim;
}
void MathRootInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
MathNestInset::metrics(mi);
- dim_.asc = max(cell(0).ascent() + 5, cell(1).ascent()) + 2;
- dim_.des = max(cell(1).descent() + 5, cell(0).descent()) + 2;
- dim_.wid = cell(0).width() + cell(1).width() + 10;
- metricsMarkers(1);
- dim = dim_;
+ dim.asc = max(cell(0).ascent() + 5, cell(1).ascent()) + 2;
+ dim.des = max(cell(1).descent() + 5, cell(0).descent()) + 2;
+ dim.wid = cell(0).width() + cell(1).width() + 10;
+ metricsMarkers(dim);
+ dim_ = dim;
}
ScriptChanger dummy(mi.base);
cell(0).metrics(mi);
cell(1).metrics(mi);
- dim_.wid = 0;
+ dim.wid = 0;
if (hasLimits()) {
- dim_.wid = nwid();
+ dim.wid = nwid();
if (hasUp())
- dim_.wid = max(dim_.wid, up().width());
+ dim.wid = max(dim.wid, up().width());
if (hasDown())
- dim_.wid = max(dim_.wid, down().width());
+ dim.wid = max(dim.wid, down().width());
} else {
if (hasUp())
- dim_.wid = max(dim_.wid, up().width());
+ dim.wid = max(dim.wid, up().width());
if (hasDown())
- dim_.wid = max(dim_.wid, down().width());
- dim_.wid += nwid();
+ dim.wid = max(dim.wid, down().width());
+ dim.wid += nwid();
}
- dim_.asc = dy1() + (hasUp() ? up().ascent() : 0);
- dim_.des = dy0() + (hasDown() ? down().descent() : 0);
- metricsMarkers();
- dim = dim_;
+ dim.asc = dy1() + (hasUp() ? up().ascent() : 0);
+ dim.des = dy0() + (hasDown() ? down().descent() : 0);
+ metricsMarkers(dim);
+ dim_ = dim;
}
void MathSizeInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
StyleChanger dummy(mi.base, style_);
- cell(0).metrics(mi, dim_);
- metricsMarkers();
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ metricsMarkers(dim);
+ dim_ = dim;
}
void MathSqrtInset::metrics(MetricsInfo & mi, Dimension & dim) const
{
- cell(0).metrics(mi, dim_);
- dim_.asc += 4;
- dim_.des += 2;
- dim_.wid += 12;
- metricsMarkers(1);
- dim = dim_;
+ cell(0).metrics(mi, dim);
+ dim.asc += 4;
+ dim.des += 2;
+ dim.wid += 12;
+ metricsMarkers(dim);
+ dim_ = dim;
}
cell(1).metrics(mi);
FracChanger dummy(mi.base);
cell(0).metrics(mi);
- dim_.wid = max(cell(0).width(), cell(1).width()) + 4;
- dim_.asc = cell(1).ascent() + cell(0).height() + 4;
- dim_.des = cell(1).descent();
- metricsMarkers();
- dim = dim_;
+ dim.wid = max(cell(0).width(), cell(1).width()) + 4;
+ dim.asc = cell(1).ascent() + cell(0).height() + 4;
+ dim.des = cell(1).descent();
+ metricsMarkers(dim);
+ dim_ = dim;
}
{
if (mi.base.style == LM_ST_DISPLAY) {
StyleChanger dummy(mi.base, LM_ST_TEXT);
- MathGridInset::metrics(mi);
+ MathGridInset::metrics(mi, dim);
} else {
- MathGridInset::metrics(mi);
+ MathGridInset::metrics(mi, dim);
}
- metricsMarkers();
- dim = dim_;
+ metricsMarkers(dim);
+ dim_ = dim;
}
#include "math_textinset.h"
#include "math_data.h"
-#include "metricsinfo.h"
+
+#include "cursor_slice.h"
#include "debug.h"
+#include "metricsinfo.h"
using std::auto_ptr;
using std::endl;
}
-void MathTextInset::getScreenPos(idx_type /*idx*/, pos_type pos, int & x, int & y) const
+void MathTextInset::getCursorPos(CursorSlice const & cur, int & x, int & y) const
{
- idx_type const i = pos2row(pos);
- pos_type const p = pos - cache_.cellinfo_[i].begin_;
- cache_.getScreenPos(i, p, x, y);
- y = cache_.cell(i).yo();
+ CursorSlice c = cur;
+ c.idx() = pos2row(cur.pos());
+ c.pos() -= cache_.cellinfo_[c.idx()].begin_;
+ cache_.getCursorPos(c, x, y);
+ y = cache_.cell(c.idx()).yo();
}
///
virtual std::auto_ptr<InsetBase> clone() const;
/// get cursor position
- void getScreenPos(idx_type idx, pos_type pos, int & x, int & y) const;
+ void getCursorPos(CursorSlice const & cur, int & x, int & y) const;
/// this stores metrics information in cache_
void metrics(MetricsInfo & mi, Dimension & dim) const;
/// draw according to cached metrics
}
+/// return the range of pars [beg, end[ owning the range of y [ystart, yend]
void getParsInRange(ParagraphList & pl,
- int ystart, int yend,
- ParagraphList::iterator & beg,
- ParagraphList::iterator & end)
+ int ystart, int yend,
+ ParagraphList::iterator & beg,
+ ParagraphList::iterator & end)
{
ParagraphList::iterator const endpar = pl.end();
ParagraphList::iterator const begpar = pl.begin();
for (end = beg ; end != endpar && end->y <= yend; ++end)
;
}
+
#include <string>
-
class Buffer;
class BufferParams;
class LyXFont;
class LyXLex;
class InsetBase;
+
///
void breakParagraph(BufferParams const & bparams,
ParagraphList & paragraphs,
/// return the range of pars [beg, end[ owning the range of y [ystart, yend]
void getParsInRange(ParagraphList & pl,
- int ystart, int yend,
- ParagraphList::iterator & beg,
- ParagraphList::iterator & end);
-
-
+ int ystart, int yend,
+ ParagraphList::iterator & beg,
+ ParagraphList::iterator & end);
#endif // PARAGRAPH_FUNCS_H
extern int NEST_MARGIN;
extern int CHANGEBAR_MARGIN;
+
namespace {
/**
hfill_(row_.fill_hfill()),
label_hfill_(row_.fill_label_hfill())
{
+ //lyxerr << "RowPainter: x: " << x_ << " xo: " << xo << " yo: " << yo
+ // << " pit->y: " << pit_->y
+ // << " row: " << (pit_->size() ? pit_->getChar(row_.pos()) : 'X') << endl;
x_ += xo_;
// background has already been cleared.
int w;
if (sel_on_one_row) {
if (startx < endx) {
- x = int(xo_) + startx;
+ x = startx;
w = endx - startx;
} else {
- x = int(xo_) + endx;
+ x = endx;
w = startx - endx;
}
pain_.fillRectangle(x, yo_, w, h, LColor::selection);
} else if (sel_starts_here) {
- int const x = is_rtl ? int(xo_) : int(xo_ + startx);
+ int const x = is_rtl ? 0 : startx;
int const w = is_rtl ? startx : (width_ - startx);
pain_.fillRectangle(x, yo_, w, h, LColor::selection);
} else if (sel_ends_here) {
- int const x = is_rtl ? int(xo_ + endx) : int(xo_);
+ int const x = is_rtl ? endx : 0;
int const w = is_rtl ? (width_ - endx) : endx;
pain_.fillRectangle(x, yo_, w, h, LColor::selection);
} else if (row_y > starty && row_y < endy) {
int paintText(BufferView const & bv)
{
ParagraphList::iterator pit;
- bv.text()->getRowNearY(bv.top_y(), pit);
+ bv.text()->updateParPositions();
+ bv.text()->getRowNearY(0, pit);
+ lyxerr << "top_y: " << bv.top_y() << " y: " << pit->y << endl;
return paintPars(bv, *bv.text(), pit, 0, 0, pit->y);
}
ParagraphList::iterator LyXText::cursorPar() const
{
+ //lyxerr << "### cursorPar: cursor: " << bv()->cursor() << endl;
+ //lyxerr << "xxx cursorPar: cursor: " << cursor() << endl;
return getPar(cursor().par());
}
ParagraphList::iterator LyXText::getPar(int par) const
{
+ //lyxerr << "getPar: " << par << " from " << paragraphs().size() << endl;
BOOST_ASSERT(par >= 0);
BOOST_ASSERT(par < int(paragraphs().size()));
ParagraphList::iterator pit = paragraphs().begin();
RowList::iterator
LyXText::getRowNearY(int y, ParagraphList::iterator & pit) const
{
- //lyxerr << "getRowNearY: y " << y << endl;
#if 1
ParagraphList::iterator const
pend = boost::prior(paragraphs().end());
}
-int LyXText::cursorX() const
-{
- return cursorX(cursor());
-}
-
-
-int LyXText::cursorY() const
-{
- return cursorY(cursor());
-}
-
-
int LyXText::cursorX(CursorSlice const & cur) const
{
ParagraphList::iterator pit = getPar(cur);
if (pit->rows.empty())
- return 0;
+ return xo_;
Row const & row = *pit->getRow(cur.pos());
pos_type pos = cur.pos();
pos_type cursor_vpos = 0;
} else
x += singleWidth(pit, pos);
}
- return int(x);
+ return xo_ + int(x);
}
{
Paragraph & par = *getPar(cur);
Row & row = *par.getRow(cur.pos());
- return par.y + row.y_offset() + row.baseline();
+ return yo_ + par.y + row.y_offset() + row.baseline();
+}
+
+
+namespace {
+
+int findText(LyXText const * text)
+{
+ CursorBase & cur = text->bv()->cursor().cursor_;
+ //lyxerr << "findText: text: " << text << " cursor: "
+ // << text->bv()->cursor() << endl;
+ for (int i = cur.size() - 1; i > 0; --i)
+ if (cur[i].text() == text)
+ return i;
+ if (text->bv()->text() == text)
+ return 0;
+ lyxerr << "Trying to access text not touched by cursor" << endl;
+ BOOST_ASSERT(false);
+ return 0; // shut up compiler
+}
+
}
CursorSlice & LyXText::cursor()
{
- return bv()->cursor().cursor_.back();
+ //lyxerr << "# accessing slice " << findText(this) << endl;
+ return bv()->cursor().cursor_[findText(this)];
}
CursorSlice const & LyXText::cursor() const
{
- return bv()->cursor().cursor_.back();
+ return bv()->cursor().cursor_[findText(this)];
}
CursorSlice & LyXText::anchor()
{
- return bv()->cursor().anchor_.back();
+ return bv()->cursor().anchor_[findText(this)];
}
CursorSlice const & LyXText::anchor() const
{
- return bv()->cursor().anchor_.back();
+ return bv()->cursor().anchor_[findText(this)];
}
// return past-the-last paragraph influenced by a layout change on pit
-ParagraphList::iterator
-LyXText::undoSpan(ParagraphList::iterator pit)
+ParagraphList::iterator LyXText::undoSpan(ParagraphList::iterator pit)
{
ParagraphList::iterator end = paragraphs().end();
ParagraphList::iterator nextpit = boost::next(pit);
pos_type pos, bool setfont, bool boundary)
{
setCursor(cursor(), par, pos, boundary);
- bv()->cursor().x_target(cursorX() + xo_);
+ bv()->cursor().x_target() = cursorX(cursor());
if (setfont)
setCurrentFont();
}
pos_type LyXText::getColumnNearX(ParagraphList::iterator pit,
Row const & row, int & x, bool & boundary) const
{
+ x -= xo_;
double tmpx = row.x();
double fill_separator = row.fill_separator();
double fill_hfill = row.fill_hfill();
// check for empty row
if (vc == end) {
- x = int(tmpx);
+ x = int(tmpx) + xo_;
return 0;
}
c = end - 1;
}
- c -= row.pos();
- x = int(tmpx);
- return c;
+ x = int(tmpx) + xo_;
+ return c - row.pos();
}
ParagraphList::iterator pit;
Row const & row = *getRowNearY(y, pit);
bool bound = false;
- pos_type const column = getColumnNearX(pit, row, x, bound);
- cur.par(parOffset(pit));
- cur.pos(row.pos() + column);
- cur.boundary(bound);
+ pos_type const pos = row.pos() + getColumnNearX(pit, row, x, bound);
+ cur.par() = parOffset(pit);
+ cur.pos() = pos;
+ cur.boundary() = bound;
+}
+
+
+// x,y are absolute screen coordinates
+void LyXText::edit(LCursor & cur, int x, int y)
+{
+ int xx = x; // is modified by getColumnNearX
+ ParagraphList::iterator pit;
+ Row const & row = *getRowNearY(y, pit);
+ bool bound = false;
+ pos_type const pos = row.pos() + getColumnNearX(pit, row, xx, bound);
+ cur.par() = parOffset(pit);
+ cur.pos() = pos;
+ cur.boundary() = bound;
+
+ // try to descend into nested insets
+ InsetBase * inset = checkInsetHit(x, y);
+ if (inset) {
+ // This should be just before or just behind the cursor position
+ // set above.
+ BOOST_ASSERT((pos != 0 && inset == pit->getInset(pos - 1))
+ || inset == pit->getInset(pos));
+ // Make sure the cursor points to the position before this inset.
+ if (inset == pit->getInset(pos - 1))
+ --cur.pos();
+ inset->edit(cur, x, y);
+ }
}
{
LCursor & cur = bv()->cursor();
Row const & row = *cursorRow();
- int x = cur.x_target() - xo_;
- int y = cursorY() - row.baseline() - 1;
+ int x = cur.x_target();
+ int y = cursorY(cur.current()) - row.baseline() - 1;
setCursorFromCoordinates(x, y);
if (!selecting) {
- int y_abs = y + yo_ - bv()->top_y();
- InsetBase * inset_hit = checkInsetHit(cur.x_target(), y_abs);
+ InsetBase * inset_hit = checkInsetHit(cur.x_target(), y);
if (inset_hit && isHighlyEditableInset(inset_hit))
- inset_hit->edit(cur, cur.x_target(), y_abs);
+ inset_hit->edit(cur, cur.x_target(), y);
}
}
{
LCursor & cur = bv()->cursor();
Row const & row = *cursorRow();
- int x = cur.x_target() - xo_;
- int y = cursorY() - row.baseline() + row.height() + 1;
+ int x = cur.x_target();
+ int y = cursorY(cur.current()) - row.baseline() + row.height() + 1;
setCursorFromCoordinates(x, y);
if (!selecting) {
- int y_abs = y + yo_ - bv()->top_y();
- InsetBase * inset_hit = checkInsetHit(cur.x_target(), y_abs);
+ InsetBase * inset_hit = checkInsetHit(cur.x_target(), y);
if (inset_hit && isHighlyEditableInset(inset_hit))
- inset_hit->edit(cur, cur.x_target(), y_abs);
+ inset_hit->edit(cur, cur.x_target(), y);
}
}
ParagraphList::iterator end;
getParsInRange(paragraphs(),
- bv()->top_y() - yo_,
- bv()->top_y() - yo_ + bv()->workHeight(),
+ bv()->top_y(),
+ bv()->top_y() + bv()->workHeight(),
pit, end);
lyxerr << "checkInsetHit: x: " << x << " y: " << y << endl;
InsetList::iterator iend = pit->insetlist.end();
for ( ; iit != iend; ++iit) {
InsetBase * inset = iit->inset;
- //lyxerr << "examining inset " << inset
- // << " xy: " << inset->x() << "/" << inset->y()
- // << " x: " << inset->x() << "..." << inset->x() + inset->width()
- // << " y: " << inset->y() - inset->ascent() << "..."
- // << inset->y() + inset->descent()
- // << endl;
- if (x >= inset->x()
- && x <= inset->x() + inset->width()
- && y >= inset->y() - inset->ascent()
- && y <= inset->y() + inset->descent())
- {
+#if 1
+ lyxerr << "examining inset " << inset
+ //<< " xo/yo: " << inset->xo() << "/" << inset->yo()
+ << " xo: " << inset->xo() << "..." << inset->xo() + inset->width()
+ << " yo: " << inset->yo() - inset->ascent() << "..."
+ << inset->yo() + inset->descent() << endl;
+#endif
+ if (inset->covers(x, y - bv()->top_y())) {
lyxerr << "Hit inset: " << inset << endl;
return inset;
}
void LyXText::cursorPrevious()
{
LCursor & cur = bv()->cursor();
- RowList::iterator crit = cursorRow();
+ pos_type cpos = cur.pos();
lyx::paroffset_type cpar = cur.par();
- int x = bv()->cursor().x_target() - xo_;
- int y = bv()->top_y() - yo_;
+ int x = bv()->cursor().x_target();
+ int y = bv()->top_y();
setCursorFromCoordinates(x, y);
- if (cpar == cur.par() && crit == cursorRow()) {
+ if (cpar == cur.par() && cpos == cur.pos()) {
// we have a row which is taller than the workarea. The
// simplest solution is to move to the previous row instead.
cursorUp(true);
void LyXText::cursorNext()
{
- RowList::iterator crit = cursorRow();
- ParagraphList::iterator cpar = cursorPar();
+ LCursor & cur = bv()->cursor();
+ pos_type cpos = cur.pos();
+ lyx::paroffset_type cpar = cur.par();
- int x = bv()->cursor().x_target() - xo_;
- int y = bv()->top_y() + bv()->workHeight() - yo_;
+ int x = cur.x_target();
+ int y = bv()->top_y() + bv()->workHeight();
setCursorFromCoordinates(x, y);
- if (cpar == cursorPar() && crit == cursorRow()) {
+ if (cpar == cur.par() && cpos == cur.pos()) {
// we have a row which is taller than the workarea. The
// simplest solution is to move to the next row instead.
cursorDown(true);
namespace {
-void specialChar(LyXText * lt, BufferView * bv, InsetSpecialChar::Kind kind)
+void specialChar(LyXText * text, BufferView * bv, InsetSpecialChar::Kind kind)
{
bv->update();
InsetSpecialChar * new_inset = new InsetSpecialChar(kind);
- replaceSelection(lt);
+ replaceSelection(text);
if (!bv->insertInset(new_inset))
delete new_inset;
else
DispatchResult LyXText::dispatch(LCursor & cur, FuncRequest const & cmd)
{
- //lyxerr[Debug::ACTION] << "LyXText::dispatch: cmd: " << cmd << endl;
+ lyxerr[Debug::ACTION] << "LyXText::dispatch: cmd: " << cmd << endl;
+ //lyxerr << "*** LyXText::dispatch: cmd: " << cmd << endl;
BufferView * bv = &cur.bv();
break;
case LFUN_GETXY:
- cmd.message(tostr(cursorX()) + ' ' + tostr(cursorY()));
+ cmd.message(tostr(cursorX(cur.current())) + ' '
+ + tostr(cursorY(cur.current())));
break;
case LFUN_SETXY: {
break;
case LFUN_MOUSE_MOTION: {
+#if 0
// Only use motion with button 1
//if (ev.button() != mouse_button::button1)
// return false;
+ // don't set anchor_
+ bv->cursor().cursor_ = cur.cursor_;
if (!bv->buffer())
break;
cursorUp(true);
}
cur.setSelection();
+#endif
break;
}
break;
}
- setCursorFromCoordinates(cmd.x, cmd.y);
+ setCursorFromCoordinates(cur.current(), cmd.x, cmd.y);
cur.resetAnchor();
finishUndo();
- cur.x_target(cursorX() + xo_);
+ cur.x_target() = cursorX(cur.current());
+
+ // set cursor and anchor to this position
+ bv->cursor() = cur;
if (bv->fitCursor())
selection_possible = false;