From 99aacdad5ce32c5905149d800405ff48ffb3a3d6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Andr=C3=A9=20P=C3=B6nitz?= Date: Fri, 30 Jan 2004 11:41:12 +0000 Subject: [PATCH] more IU git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8376 a592a061-630c-0410-9148-cb99ea01b6c8 --- src/BufferView_pimpl.C | 232 +++----- src/ChangeLog | 18 + src/cursor.C | 211 +++---- src/cursor.h | 17 +- src/cursor_slice.C | 17 +- src/cursor_slice.h | 12 +- src/frontends/screen.C | 2 + src/insets/ChangeLog | 16 + src/insets/inset.C | 7 + src/insets/inset.h | 6 +- src/insets/insetbase.C | 98 +++- src/insets/insetbase.h | 26 +- src/insets/insetcharstyle.C | 3 +- src/insets/insetcollapsable.C | 53 +- src/insets/insetcollapsable.h | 16 +- src/insets/insetcommand.C | 3 +- src/insets/insetexternal.C | 3 +- src/insets/insetgraphics.C | 3 +- src/insets/insetinclude.C | 3 +- src/insets/insettabular.C | 17 +- src/insets/insettabular.h | 2 +- src/insets/insettext.C | 44 +- src/insets/insettext.h | 2 +- src/insets/insetvspace.C | 3 +- src/insets/updatableinset.C | 2 +- src/insets/updatableinset.h | 2 - src/lyxfunc.C | 52 +- src/lyxtext.h | 37 +- src/mathed/Makefile.am | 2 + src/mathed/formula.C | 340 ++++------- src/mathed/formula.h | 77 +-- src/mathed/formulabase.C | 934 ------------------------------ src/mathed/formulabase.h | 124 ---- src/mathed/formulamacro.C | 3 +- src/mathed/math_arrayinset.C | 2 +- src/mathed/math_boldsymbolinset.C | 2 +- src/mathed/math_boxinset.C | 6 +- src/mathed/math_colorinset.C | 2 +- src/mathed/math_commentinset.C | 2 +- src/mathed/math_data.C | 7 + src/mathed/math_data.h | 2 + src/mathed/math_decorationinset.C | 15 +- src/mathed/math_diminset.C | 35 +- src/mathed/math_diminset.h | 21 +- src/mathed/math_envinset.C | 6 +- src/mathed/math_ertinset.C | 6 +- src/mathed/math_extern.C | 24 +- src/mathed/math_fboxinset.C | 8 +- src/mathed/math_fontinset.C | 8 +- src/mathed/math_fontoldinset.C | 6 +- src/mathed/math_fracinset.C | 1 + src/mathed/math_frameboxinset.C | 10 +- src/mathed/math_gridinset.C | 1 + src/mathed/math_gridinset.h | 2 +- src/mathed/math_hullinset.C | 181 +++--- src/mathed/math_hullinset.h | 45 +- src/mathed/math_lefteqninset.C | 12 +- src/mathed/math_macro.C | 18 +- src/mathed/math_makeboxinset.C | 12 +- src/mathed/math_mboxinset.C | 84 +++ src/mathed/math_mboxinset.h | 50 ++ src/mathed/math_nestinset.C | 342 ++++++----- src/mathed/math_nestinset.h | 25 +- src/mathed/math_parboxinset.C | 6 +- src/mathed/math_rootinset.C | 10 +- src/mathed/math_scriptinset.C | 22 +- src/mathed/math_sizeinset.C | 6 +- src/mathed/math_sqrtinset.C | 12 +- src/mathed/math_stackrelinset.C | 10 +- src/mathed/math_substackinset.C | 8 +- src/mathed/math_textinset.C | 15 +- src/mathed/math_textinset.h | 2 +- src/paragraph_funcs.C | 8 +- src/paragraph_funcs.h | 10 +- src/rowpainter.C | 16 +- src/text.C | 51 +- src/text2.C | 66 ++- src/text3.C | 63 +- 78 files changed, 1332 insertions(+), 2295 deletions(-) delete mode 100644 src/mathed/formulabase.C delete mode 100644 src/mathed/formulabase.h create mode 100644 src/mathed/math_mboxinset.C create mode 100644 src/mathed/math_mboxinset.h diff --git a/src/BufferView_pimpl.C b/src/BufferView_pimpl.C index 73c3f7d7ab..27adc9dcfb 100644 --- a/src/BufferView_pimpl.C +++ b/src/BufferView_pimpl.C @@ -4,7 +4,7 @@ * 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 @@ -59,8 +59,6 @@ #include "graphics/Previews.h" -#include "mathed/math_hullinset.h" - #include "support/filetools.h" #include "support/globbing.h" #include "support/path_defines.h" @@ -483,9 +481,10 @@ void BufferView::Pimpl::scrollDocView(int value) 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(); @@ -727,7 +726,9 @@ void BufferView::Pimpl::center() 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 @@ -737,7 +738,7 @@ void BufferView::Pimpl::center() // 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); } @@ -778,7 +779,8 @@ InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code) if (beg.getPar() == text->cursorPar() && beg.getPos() >= text->cursor().pos()) { break; - } else if (beg.getPar() != text->cursorPar()) { + } + if (beg.getPar() != text->cursorPar()) { break; } } @@ -787,9 +789,8 @@ InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code) 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; @@ -797,9 +798,9 @@ InsetBase * BufferView::Pimpl::getInsetByCode(InsetBase::Code code) } -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 @@ -853,7 +854,7 @@ void BufferView::Pimpl::MenuInsertLyXFile(string const & filen) void BufferView::Pimpl::trackChanges() { - Buffer * buf(bv_->buffer()); + Buffer * buf = bv_->buffer(); bool const tracking(buf->params().tracking_changes); if (!tracking) { @@ -883,50 +884,18 @@ void BufferView::Pimpl::trackChanges() 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; @@ -934,22 +903,20 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd) 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: @@ -970,55 +937,22 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd) // 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_); @@ -1037,27 +971,29 @@ bool BufferView::Pimpl::workAreaDispatch(FuncRequest const & cmd) } 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 @@ -1066,15 +1002,15 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) 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: @@ -1083,8 +1019,8 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) 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); @@ -1092,15 +1028,15 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) } 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(getInsetByCode(InsetBase::REF_CODE)); @@ -1134,44 +1070,34 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) 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; @@ -1188,11 +1114,11 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) 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_, @@ -1250,18 +1176,18 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) } 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: @@ -1269,28 +1195,28 @@ bool BufferView::Pimpl::dispatch(FuncRequest const & ev) 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; } diff --git a/src/ChangeLog b/src/ChangeLog index eb669090a6..f28aee93de 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,21 @@ + + +2004-01-30 André Pönitz + + * 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 * text.C: add using statements for std::advance and std::distance diff --git a/src/cursor.C b/src/cursor.C index 7f96e6e329..7c43f3092f 100644 --- a/src/cursor.C +++ b/src/cursor.C @@ -67,7 +67,7 @@ void LCursor::reset() anchor_.push_back(CursorSlice()); current_ = 0; cached_y_ = 0; - x_target_ = -1; + clearTargetX(); selection_ = false; mark_ = false; } @@ -75,7 +75,7 @@ void LCursor::reset() 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) { @@ -113,14 +113,6 @@ DispatchResult LCursor::dispatch(FuncRequest const & cmd0) 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; } @@ -137,7 +129,7 @@ void LCursor::push(InsetBase * inset) 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(); } @@ -145,8 +137,8 @@ void LCursor::pop(int depth) 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 { @@ -154,12 +146,13 @@ void LCursor::pop() 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); @@ -168,6 +161,7 @@ void LCursor::pushLeft(InsetBase * p) bool LCursor::popLeft() { + BOOST_ASSERT(!cursor_.empty()); //lyxerr << "Leaving inset to the left" << endl; if (depth() <= 1) { if (depth() == 1) @@ -182,6 +176,7 @@ bool LCursor::popLeft() bool LCursor::popRight() { + BOOST_ASSERT(!cursor_.empty()); //lyxerr << "Leaving inset to the right" << endl; if (depth() <= 1) { if (depth() == 1) @@ -197,6 +192,7 @@ bool LCursor::popRight() CursorSlice & LCursor::current() { + BOOST_ASSERT(!cursor_.empty()); //lyxerr << "accessing cursor slice " << current_ // << ": " << cursor_[current_] << endl; return cursor_[current_]; @@ -213,6 +209,7 @@ CursorSlice const & LCursor::current() const 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) @@ -224,6 +221,7 @@ int LCursor::currentMode() 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 @@ -238,6 +236,7 @@ LyXText * LCursor::innerText() const 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 @@ -252,53 +251,57 @@ CursorSlice const & LCursor::innerTextSlice() const 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; } @@ -453,9 +456,9 @@ void LCursor::clearSelection() } -void LCursor::x_target(int x) +int & LCursor::x_target() { - x_target_ = x; + return x_target_; } @@ -465,6 +468,12 @@ int LCursor::x_target() const } +void LCursor::clearTargetX() +{ + x_target_ = -1; +} + + Paragraph & LCursor::paragraph() { return current_ ? current().paragraph() : *bv_->text()->getPar(par()); @@ -479,11 +488,8 @@ Paragraph const & LCursor::paragraph() const 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(); } @@ -851,7 +857,7 @@ bool LCursor::inNucleus() bool LCursor::left() { autocorrect() = false; - x_target(-1); // "no target" + clearTargetX(); if (inMacroMode()) { macroModeClose(); return true; @@ -859,8 +865,8 @@ bool LCursor::left() if (pos() != 0 && openable(prevAtom())) { posLeft(); - push(inset()); - inset()->idxFirst(*this); + push(nextAtom().nucleus()); + inset()->idxLast(*this); return true; } @@ -871,14 +877,15 @@ bool LCursor::left() 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; } @@ -893,7 +900,7 @@ bool positionable(CursorBase const & cursor, CursorBase const & anchor) 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; @@ -911,7 +918,7 @@ void LCursor::setScreenPos(int x, int y) idx() = 0; pos() = 0; } - x_target(-1); // "no target" + clearTargetX(); } @@ -922,7 +929,7 @@ bool LCursor::home() macroModeClose(); if (!inset()->idxHome(*this)) return popLeft(); - x_target(-1); // "no target" + clearTargetX(); return true; } @@ -933,7 +940,7 @@ bool LCursor::end() macroModeClose(); if (!inset()->idxEnd(*this)) return popRight(); - x_target(-1); // "no target" + clearTargetX(); return true; } @@ -973,7 +980,7 @@ void LCursor::insert2(string const & str) 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))); @@ -982,7 +989,7 @@ void LCursor::insert(string const & str) void LCursor::insert(char c) { - //lyxerr << "inserting '" << c << "'" << endl; + lyxerr << "inserting '" << c << "'" << endl; selClearOrDel(); plainInsert(MathAtom(new MathCharInset(c))); } @@ -998,6 +1005,7 @@ void LCursor::insert(MathAtom const & t) void LCursor::niceInsert(string const & t) { + lyxerr << "*** LCursor::niceInsert 1: " << t << endl; MathArray ar; asArray(t, ar); if (ar.size() == 1) @@ -1009,15 +1017,17 @@ void LCursor::niceInsert(string const & t) 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; } @@ -1175,19 +1185,11 @@ void LCursor::drawSelection(PainterInfo & pi) 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()); } @@ -1197,7 +1199,7 @@ int LCursor::targetX() const return x_target(); int x = 0; int y = 0; - getScreenPos(x, y); + getPos(x, y); return x; } @@ -1332,11 +1334,11 @@ bool LCursor::goUpDown(bool up) // 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(); @@ -1407,7 +1409,7 @@ bool LCursor::goUpDown(bool up) // any improvement so far? int xnew, ynew; - getScreenPos(xnew, ynew); + getPos(xnew, ynew); if (up ? ynew < yo : ynew > yo) return true; } @@ -1425,7 +1427,8 @@ bool LCursor::bruteFind(int x, int y, int xlow, int xhigh, int ylow, int yhigh) // 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; @@ -1460,7 +1463,8 @@ void LCursor::bruteFind2(int x, int y) 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' @@ -1544,7 +1548,7 @@ bool LCursor::script(bool up) bool LCursor::interpret(char c) { //lyxerr << "interpret 2: '" << c << "'" << endl; - x_target(-1); // "no target" + clearTargetX(); if (inMacroArgMode()) { posLeft(); plainErase(); @@ -1718,29 +1722,28 @@ DispatchResult dispatch(LCursor & cur, FuncRequest const & cmd) // 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; } - /... } */ diff --git a/src/cursor.h b/src/cursor.h index 59519bbb86..f7a119fd15 100644 --- a/src/cursor.h +++ b/src/cursor.h @@ -195,6 +195,8 @@ public: /// bool boundary() const { return current().boundary(); } /// + bool & boundary() { return current().boundary(); } + /// Paragraph & paragraph(); /// Paragraph const & paragraph() const; @@ -219,10 +221,12 @@ public: /// 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(); @@ -251,13 +255,8 @@ public: std::vector 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_; /// @@ -331,8 +330,6 @@ public: /// 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 diff --git a/src/cursor_slice.C b/src/cursor_slice.C index 464f1517fb..5ae0015a9c 100644 --- a/src/cursor_slice.C +++ b/src/cursor_slice.C @@ -131,6 +131,12 @@ bool CursorSlice::boundary() const } +bool & CursorSlice::boundary() +{ + return boundary_; +} + + CursorSlice::row_type CursorSlice::row() const { BOOST_ASSERT(asMathInset()); @@ -164,16 +170,9 @@ MathArray & CursorSlice::cell() const } -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; } @@ -235,7 +234,7 @@ bool operator>(CursorSlice const & p, CursorSlice const & q) 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_ diff --git a/src/cursor_slice.h b/src/cursor_slice.h index 045ac748bd..a06a374222 100644 --- a/src/cursor_slice.h +++ b/src/cursor_slice.h @@ -91,13 +91,15 @@ public: /// 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; /// @@ -112,8 +114,6 @@ public: /// /// 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; diff --git a/src/frontends/screen.C b/src/frontends/screen.C index 68da7ca38d..525b3912e1 100644 --- a/src/frontends/screen.C +++ b/src/frontends/screen.C @@ -212,6 +212,8 @@ bool LyXScreen::fitCursor(BufferView * bv) 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; diff --git a/src/insets/ChangeLog b/src/insets/ChangeLog index c8b39dfca5..57c34f57a2 100644 --- a/src/insets/ChangeLog +++ b/src/insets/ChangeLog @@ -1,3 +1,19 @@ + +2004-01-30 André Pönitz + * 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 * insettabular.C: add using statement for std::vector, remove diff --git a/src/insets/inset.C b/src/insets/inset.C index 353712f59a..b61eafd076 100644 --- a/src/insets/inset.C +++ b/src/insets/inset.C @@ -85,3 +85,10 @@ int InsetOld::scroll(bool recursive) const return scx; return 0; } + + +void InsetOld::setPosCache(PainterInfo const &, int x, int y) const +{ + xo_ = x; + yo_ = y; +} diff --git a/src/insets/inset.h b/src/insets/inset.h index 3d75481725..4d26e71603 100644 --- a/src/insets/inset.h +++ b/src/insets/inset.h @@ -54,10 +54,12 @@ public: 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; diff --git a/src/insets/insetbase.C b/src/insets/insetbase.C index 9e52e8639e..1bd6b65e37 100644 --- a/src/insets/insetbase.C +++ b/src/insets/insetbase.C @@ -11,10 +11,19 @@ #include #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) @@ -70,13 +79,6 @@ bool InsetBase::idxUpDown2(LCursor &, bool) const } -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 { @@ -122,12 +124,6 @@ std::string const InsetBase::editMessage() const } -bool InsetBase::insetAllowed(InsetBase * inset) const -{ - return insetAllowed(inset->lyxCode()); -} - - std::string const & InsetBase::getInsetName() const { static std::string const name = "unknown"; @@ -161,17 +157,85 @@ int InsetBase::getCell(int x, int y) const 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; } diff --git a/src/insets/insetbase.h b/src/insets/insetbase.h index 0e0219bec8..23d390db45 100644 --- a/src/insets/insetbase.h +++ b/src/insets/insetbase.h @@ -18,6 +18,7 @@ class Buffer; class BufferView; +class CursorSlice; class DispatchResult; class FuncRequest; class LaTeXFeatures; @@ -34,6 +35,7 @@ class UpdatableInset; namespace lyx { namespace graphics { class PreviewLoader; } } + /// Common base class to all insets // Do not add _any_ (non-static) data members as this would inflate @@ -77,10 +79,26 @@ public: 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; } @@ -128,8 +146,6 @@ public: 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 @@ -283,8 +299,6 @@ public: }; /// 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; } diff --git a/src/insets/insetcharstyle.C b/src/insets/insetcharstyle.C index 5ad33db650..db6a945005 100644 --- a/src/insets/insetcharstyle.C +++ b/src/insets/insetcharstyle.C @@ -105,8 +105,7 @@ void InsetCharStyle::metrics(MetricsInfo & mi, Dimension & dim) const 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; diff --git a/src/insets/insetcollapsable.C b/src/insets/insetcollapsable.C index bec1a74371..272cacfd74 100644 --- a/src/insets/insetcollapsable.C +++ b/src/insets/insetcollapsable.C @@ -39,23 +39,22 @@ using std::min; 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(); @@ -116,12 +115,8 @@ void InsetCollapsable::read(Buffer const & buf, LyXLex & lex) } inset.read(buf, lex); - if (!token_found) { - if (isOpen()) - status_ = Open; - else - status_ = Collapsed; - } + if (!token_found) + status_ = isOpen() ? Open : Collapsed; setButtonLabel(); } @@ -168,8 +163,7 @@ void InsetCollapsable::draw_collapsed(PainterInfo & pi, int x, int y) const 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); @@ -205,14 +199,6 @@ bool InsetCollapsable::descendable() const } -FuncRequest InsetCollapsable::adjustCommand(FuncRequest const & cmd) -{ - FuncRequest cmd1 = cmd; - cmd1.y += ascent() - height_collapsed(); - return cmd1; -} - - DispatchResult InsetCollapsable::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd) { @@ -236,7 +222,7 @@ 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); @@ -303,7 +289,7 @@ string const InsetCollapsable::getNewLabel(string const & l) const 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(); @@ -313,7 +299,7 @@ void InsetCollapsable::edit(LCursor & cur, bool left) 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 { @@ -329,21 +315,21 @@ void InsetCollapsable::edit(LCursor & cur, int x, int y) 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: @@ -361,7 +347,7 @@ InsetCollapsable::priv_dispatch(LCursor & cur, FuncRequest const & cmd) } default: - return inset.dispatch(cur, adjustCommand(cmd)); + return inset.dispatch(cur, cmd); } } @@ -372,11 +358,10 @@ void InsetCollapsable::validate(LaTeXFeatures & features) const } -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); } diff --git a/src/insets/insetcollapsable.h b/src/insets/insetcollapsable.h index dd2147ce5a..0f4cd27e40 100644 --- a/src/insets/insetcollapsable.h +++ b/src/insets/insetcollapsable.h @@ -79,7 +79,7 @@ public: /// 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); /// @@ -89,7 +89,7 @@ public: /// Appends \c list with all labels found within this inset. void getLabelList(Buffer const &, std::vector & list) const; /// - int scroll(bool recursive=true) const; + int scroll(bool recursive = true) const; /// void scroll(BufferView & bv, float sx) const; /// @@ -121,9 +121,7 @@ public: protected: /// - virtual - DispatchResult - priv_dispatch(LCursor & cur, FuncRequest const & cmd); + DispatchResult priv_dispatch(LCursor & cur, FuncRequest const & cmd); /// void dimension_collapsed(Dimension &) const; /// @@ -142,15 +140,10 @@ protected: private: /// DispatchResult lfunMouseRelease(LCursor & cur, FuncRequest const & cmd); - /// - FuncRequest adjustCommand(FuncRequest const &); public: /// mutable InsetText inset; -private: - /// - mutable CollapseStatus status_; protected: /// LyXFont labelfont_; @@ -162,6 +155,9 @@ protected: mutable int topbaseline; /// mutable std::string label; +private: + /// + mutable CollapseStatus status_; }; #endif diff --git a/src/insets/insetcommand.C b/src/insets/insetcommand.C index 5e3699be85..c932a2ac9f 100644 --- a/src/insets/insetcommand.C +++ b/src/insets/insetcommand.C @@ -57,8 +57,7 @@ void InsetCommand::metrics(MetricsInfo & mi, Dimension & dim) const void InsetCommand::draw(PainterInfo & pi, int x, int y) const { - xo_ = x; - yo_ = y; + setPosCache(pi, x, y); button_.draw(pi, x, y); } diff --git a/src/insets/insetexternal.C b/src/insets/insetexternal.C index 3c43adb9ba..7bc4d67980 100644 --- a/src/insets/insetexternal.C +++ b/src/insets/insetexternal.C @@ -492,8 +492,7 @@ void InsetExternal::metrics(MetricsInfo & mi, Dimension & dim) const void InsetExternal::draw(PainterInfo & pi, int x, int y) const { - xo_ = x; - yo_ = y; + setPosCache(pi, x, y); renderer_->draw(pi, x, y); } diff --git a/src/insets/insetgraphics.C b/src/insets/insetgraphics.C index 0675472731..245596e17c 100644 --- a/src/insets/insetgraphics.C +++ b/src/insets/insetgraphics.C @@ -235,8 +235,7 @@ void InsetGraphics::metrics(MetricsInfo & mi, Dimension & dim) const void InsetGraphics::draw(PainterInfo & pi, int x, int y) const { - xo_ = x; - yo_ = y; + setPosCache(pi, x, y); graphic_->draw(pi, x, y); } diff --git a/src/insets/insetinclude.C b/src/insets/insetinclude.C index 93585fb1b9..52aaf38c8d 100644 --- a/src/insets/insetinclude.C +++ b/src/insets/insetinclude.C @@ -548,8 +548,7 @@ void InsetInclude::metrics(MetricsInfo & mi, Dimension & dim) const 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); diff --git a/src/insets/insettabular.C b/src/insets/insettabular.C index 83b8483d49..81e20817ab 100644 --- a/src/insets/insettabular.C +++ b/src/insets/insettabular.C @@ -249,12 +249,11 @@ void InsetTabular::draw(PainterInfo & pi, int x, int y) const //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; @@ -383,9 +382,6 @@ void InsetTabular::updateLocal(LCursor & cur) const } -extern CursorBase theTempCursor; - - void InsetTabular::lfunMousePress(LCursor & cur, FuncRequest const & cmd) { if (hasSelection() && cmd.button() == mouse_button::button3) @@ -397,13 +393,13 @@ void InsetTabular::lfunMousePress(LCursor & cur, FuncRequest const & cmd) 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(); @@ -971,12 +967,9 @@ void InsetTabular::calculate_dimensions_of_cells(MetricsInfo & mi) const } -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); } diff --git a/src/insets/insettabular.h b/src/insets/insettabular.h index b4658d087e..e5f6176f54 100644 --- a/src/insets/insettabular.h +++ b/src/insets/insettabular.h @@ -110,7 +110,7 @@ public: /// 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); /// diff --git a/src/insets/insettext.C b/src/insets/insettext.C index d243604755..f06f56b0e0 100644 --- a/src/insets/insettext.C +++ b/src/insets/insettext.C @@ -192,15 +192,12 @@ void InsetText::metrics(MetricsInfo & mi, Dimension & dim) const 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(); @@ -212,7 +209,7 @@ void InsetText::draw(PainterInfo & pi, int x, int y) const text_.draw(pi, x, y); if (drawFrame_ == ALWAYS || drawFrame_ == LOCKED) - drawFrame(pain, xo_); + drawFrame(pi.pain, xo_); } @@ -285,7 +282,7 @@ extern CursorBase theTempCursor; 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; @@ -303,12 +300,10 @@ void InsetText::edit(LCursor & cur, int x, int y) { 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(); } @@ -319,26 +314,13 @@ DispatchResult InsetText::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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); @@ -397,10 +379,10 @@ void InsetText::validate(LaTeXFeatures & features) const } -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); } diff --git a/src/insets/insettext.h b/src/insets/insettext.h index fafb5d355b..09c9b3d0c0 100644 --- a/src/insets/insettext.h +++ b/src/insets/insettext.h @@ -88,7 +88,7 @@ public: /// 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; /// diff --git a/src/insets/insetvspace.C b/src/insets/insetvspace.C index 6cac2c883f..59d7efdc77 100644 --- a/src/insets/insetvspace.C +++ b/src/insets/insetvspace.C @@ -129,8 +129,7 @@ void InsetVSpace::draw(PainterInfo & pi, int x, int y) const { static std::string const label = _("Vertical Space"); - xo_ = x; - yo_ = y; + setPosCache(pi, x, y); x += ADD_TO_VSPACE_WIDTH; diff --git a/src/insets/updatableinset.C b/src/insets/updatableinset.C index 0e0713c301..4666658635 100644 --- a/src/insets/updatableinset.C +++ b/src/insets/updatableinset.C @@ -26,11 +26,11 @@ #include - using lyx::support::strToDbl; using lyx::support::strToInt; + // An updatable inset is highly editable by definition InsetOld::EDITABLE UpdatableInset::editable() const { diff --git a/src/insets/updatableinset.h b/src/insets/updatableinset.h index 5723fad720..275d00c711 100644 --- a/src/insets/updatableinset.h +++ b/src/insets/updatableinset.h @@ -28,8 +28,6 @@ public: /// 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 diff --git a/src/lyxfunc.C b/src/lyxfunc.C index 2c503cfdba..d079a8970b 100644 --- a/src/lyxfunc.C +++ b/src/lyxfunc.C @@ -824,13 +824,13 @@ bool ensureBufferClean(BufferView * bv) } //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; @@ -846,7 +846,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) 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" @@ -1187,8 +1187,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) 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(); @@ -1233,8 +1233,8 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) } 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" || @@ -1297,7 +1297,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) // 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)); @@ -1440,7 +1440,7 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) break; default: - view()->cursor().dispatch(FuncRequest(func)); + view()->cursor().dispatch(cmd); break; } } @@ -1452,23 +1452,23 @@ void LyXFunc::dispatch(FuncRequest const & func, bool verbose) 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); @@ -1479,23 +1479,23 @@ void LyXFunc::sendDispatchMessage(string const & 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()) { @@ -1740,7 +1740,7 @@ void LyXFunc::closeBuffer() // 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 diff --git a/src/lyxtext.h b/src/lyxtext.h index 880f9002c2..61a8cbbdc4 100644 --- a/src/lyxtext.h +++ b/src/lyxtext.h @@ -48,12 +48,11 @@ class VSpace; /// 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(); /// @@ -102,7 +101,6 @@ public: ParagraphList::iterator end); /// rebreaks the given par void redoParagraph(ParagraphList::iterator pit); - /// rebreaks the cursor par void redoParagraph(); @@ -112,11 +110,9 @@ public: /// 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 @@ -128,13 +124,11 @@ public: /// 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; /// @@ -199,6 +193,8 @@ public: /// 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); @@ -271,7 +267,6 @@ public: * characters to the right. No safety checks. */ void setSelectionRange(lyx::pos_type length); - /** simple replacing. The font of the first selected character is used */ @@ -323,19 +318,15 @@ public: * 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 @@ -392,10 +383,6 @@ public: /// int descent() const; /// - int cursorX() const; - /// - int cursorY() const; - /// int cursorX(CursorSlice const & cursor) const; /// int cursorY(CursorSlice const & cursor) const; @@ -409,6 +396,8 @@ public: /// access to the selection anchor CursorSlice const & anchor() const; + friend class LyXScreen; + public: /// int height; diff --git a/src/mathed/Makefile.am b/src/mathed/Makefile.am index f7a2abadbd..9e2dec5669 100644 --- a/src/mathed/Makefile.am +++ b/src/mathed/Makefile.am @@ -100,6 +100,8 @@ libmathed_la_SOURCES = \ math_mathmlstream.h \ math_matrixinset.C \ math_matrixinset.h \ + math_mboxinset.C \ + math_mboxinset.h \ math_nestinset.C \ math_nestinset.h \ math_numberinset.C \ diff --git a/src/mathed/formula.C b/src/mathed/formula.C index 9544b1fb70..06aa68e22c 100644 --- a/src/mathed/formula.C +++ b/src/mathed/formula.C @@ -9,293 +9,171 @@ * Full author contact details are available in file CREDITS. */ -#if 0 #include #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 +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 InsetFormula::clone() const +std::auto_ptr InsetFormula::clone() const { return auto_ptr(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 & 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 diff --git a/src/mathed/formula.h b/src/mathed/formula.h index 1d3f654f8e..2c79e230a3 100644 --- a/src/mathed/formula.h +++ b/src/mathed/formula.h @@ -10,84 +10,25 @@ * 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 - -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 clone() const; /// - int docbook(Buffer const &, std::ostream &, - OutputParams const &) const; - - /// - virtual std::auto_ptr 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 & 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 const preview_; -}; -#endif #endif diff --git a/src/mathed/formulabase.C b/src/mathed/formulabase.C deleted file mode 100644 index f2a31f32e1..0000000000 --- a/src/mathed/formulabase.C +++ /dev/null @@ -1,934 +0,0 @@ -/** - * \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 - -#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; - } -} diff --git a/src/mathed/formulabase.h b/src/mathed/formulabase.h deleted file mode 100644 index d9854faa68..0000000000 --- a/src/mathed/formulabase.h +++ /dev/null @@ -1,124 +0,0 @@ -// -*- 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 diff --git a/src/mathed/formulamacro.C b/src/mathed/formulamacro.C index ec4a5addc4..9c373ddaeb 100644 --- a/src/mathed/formulamacro.C +++ b/src/mathed/formulamacro.C @@ -180,7 +180,6 @@ void InsetFormulaMacro::draw(PainterInfo & p, int x, int y) const #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); } diff --git a/src/mathed/math_arrayinset.C b/src/mathed/math_arrayinset.C index c32473e30e..5794ee7913 100644 --- a/src/mathed/math_arrayinset.C +++ b/src/mathed/math_arrayinset.C @@ -79,7 +79,7 @@ void MathArrayInset::metrics(MetricsInfo & mi, Dimension & dim) const { ArrayChanger dummy(mi.base); MathGridInset::metrics(mi); - metricsMarkers2(); + metricsMarkers2(dim_); dim = dim_; } diff --git a/src/mathed/math_boldsymbolinset.C b/src/mathed/math_boldsymbolinset.C index d60189ae2b..c17b3ff791 100644 --- a/src/mathed/math_boldsymbolinset.C +++ b/src/mathed/math_boldsymbolinset.C @@ -34,7 +34,7 @@ void MathBoldsymbolInset::metrics(MetricsInfo & mi, Dimension & dim) const { //FontSetChanger dummy(mi.base, "mathbf"); cell(0).metrics(mi, dim); - metricsMarkers(1); + metricsMarkers(dim); ++dim.wid; // for 'double stroke' dim_ = dim; } diff --git a/src/mathed/math_boxinset.C b/src/mathed/math_boxinset.C index ca053c422e..10e070c8b7 100644 --- a/src/mathed/math_boxinset.C +++ b/src/mathed/math_boxinset.C @@ -48,9 +48,9 @@ void MathBoxInset::normalize(NormalStream & os) const 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; } diff --git a/src/mathed/math_colorinset.C b/src/mathed/math_colorinset.C index 16a9acc1a8..fcc1fc1f15 100644 --- a/src/mathed/math_colorinset.C +++ b/src/mathed/math_colorinset.C @@ -45,7 +45,7 @@ void MathColorInset::metrics(MetricsInfo & mi, Dimension & dim) const dim.asc += 4; dim.des += 4; dim.wid += 2 * w_ + 4; - metricsMarkers(); + metricsMarkers(dim); } dim_ = dim; } diff --git a/src/mathed/math_commentinset.C b/src/mathed/math_commentinset.C index 793a806b06..232710c83c 100644 --- a/src/mathed/math_commentinset.C +++ b/src/mathed/math_commentinset.C @@ -41,7 +41,7 @@ auto_ptr MathCommentInset::clone() const void MathCommentInset::metrics(MetricsInfo & mi, Dimension & dim) const { cell(0).metrics(mi); - metricsMarkers(); + metricsMarkers(dim_); dim = dim_; } diff --git a/src/mathed/math_data.C b/src/mathed/math_data.C index 89d607f263..0270d5d87c 100644 --- a/src/mathed/math_data.C +++ b/src/mathed/math_data.C @@ -370,6 +370,13 @@ void MathArray::boundingBox(int & x1, int & x2, int & y1, int & y2) } +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; diff --git a/src/mathed/math_data.h b/src/mathed/math_data.h index 05caf55d00..87ed99c495 100644 --- a/src/mathed/math_data.h +++ b/src/mathed/math_data.h @@ -120,6 +120,8 @@ public: 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 diff --git a/src/mathed/math_decorationinset.C b/src/mathed/math_decorationinset.C index d823419983..e2dfb63bce 100644 --- a/src/mathed/math_decorationinset.C +++ b/src/mathed/math_decorationinset.C @@ -87,22 +87,21 @@ bool MathDecorationInset::wide() const 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; } diff --git a/src/mathed/math_diminset.C b/src/mathed/math_diminset.C index f1253db192..ff779ad580 100644 --- a/src/mathed/math_diminset.C +++ b/src/mathed/math_diminset.C @@ -13,26 +13,27 @@ #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; } diff --git a/src/mathed/math_diminset.h b/src/mathed/math_diminset.h index 75c7cad1cc..2131e5d740 100644 --- a/src/mathed/math_diminset.h +++ b/src/mathed/math_diminset.h @@ -15,21 +15,34 @@ #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 diff --git a/src/mathed/math_envinset.C b/src/mathed/math_envinset.C index 2f10a1c5df..d0a282f1e7 100644 --- a/src/mathed/math_envinset.C +++ b/src/mathed/math_envinset.C @@ -34,9 +34,9 @@ auto_ptr MathEnvInset::clone() const 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; } diff --git a/src/mathed/math_ertinset.C b/src/mathed/math_ertinset.C index d5e5cacbb9..79a8e76c52 100644 --- a/src/mathed/math_ertinset.C +++ b/src/mathed/math_ertinset.C @@ -26,10 +26,10 @@ auto_ptr MathErtInset::clone() const 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; } diff --git a/src/mathed/math_extern.C b/src/mathed/math_extern.C index 78dcf35092..99e381d78a 100644 --- a/src/mathed/math_extern.C +++ b/src/mathed/math_extern.C @@ -148,7 +148,7 @@ string charSequence 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()); @@ -163,7 +163,7 @@ void extractMatrices(MathArray & ar) { //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); @@ -175,7 +175,7 @@ void extractMatrices(MathArray & ar) } // 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; @@ -251,7 +251,7 @@ void replaceNested( { // 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; @@ -278,7 +278,7 @@ void replaceNested( 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; @@ -310,7 +310,7 @@ void splitScripts(MathArray & ar) 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; @@ -373,7 +373,7 @@ string digitSequence 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())) @@ -435,7 +435,7 @@ void extractFunctions(MathArray & ar) 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; @@ -526,7 +526,7 @@ void extractIntegrals(MathArray & ar) 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' @@ -598,7 +598,7 @@ void extractSums(MathArray & ar) 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? @@ -670,7 +670,7 @@ bool testDiffFrac(MathAtom const & at) 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"? @@ -760,7 +760,7 @@ void extractLims(MathArray & ar) 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? diff --git a/src/mathed/math_fboxinset.C b/src/mathed/math_fboxinset.C index cef9c1d6ed..7411545fb4 100644 --- a/src/mathed/math_fboxinset.C +++ b/src/mathed/math_fboxinset.C @@ -44,12 +44,12 @@ void MathFboxInset::metrics(MetricsInfo & mi, Dimension & dim) const { 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; } diff --git a/src/mathed/math_fontinset.C b/src/mathed/math_fontinset.C index 2ffacba941..b4ad80771c 100644 --- a/src/mathed/math_fontinset.C +++ b/src/mathed/math_fontinset.C @@ -45,9 +45,9 @@ MathInset::mode_type MathFontInset::currentMode() const 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; } @@ -59,7 +59,7 @@ void MathFontInset::draw(PainterInfo & pi, int x, int y) const } -void MathFontInset::metricsT(TextMetricsInfo const & mi, Dimension & /*dim*/) const +void MathFontInset::metricsT(TextMetricsInfo const & mi, Dimension &) const { cell(0).metricsT(mi, dim_); } diff --git a/src/mathed/math_fontoldinset.C b/src/mathed/math_fontoldinset.C index 66b38c73e3..6b2a27174b 100644 --- a/src/mathed/math_fontoldinset.C +++ b/src/mathed/math_fontoldinset.C @@ -36,9 +36,9 @@ auto_ptr MathFontOldInset::clone() const 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; } diff --git a/src/mathed/math_fracinset.C b/src/mathed/math_fracinset.C index b592e654d2..a326c41994 100644 --- a/src/mathed/math_fracinset.C +++ b/src/mathed/math_fracinset.C @@ -61,6 +61,7 @@ void MathFracInset::metrics(MetricsInfo & mi, Dimension & dim) const 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); diff --git a/src/mathed/math_frameboxinset.C b/src/mathed/math_frameboxinset.C index d1cf3afb17..ebeccae203 100644 --- a/src/mathed/math_frameboxinset.C +++ b/src/mathed/math_frameboxinset.C @@ -36,11 +36,11 @@ void MathFrameboxInset::metrics(MetricsInfo & mi, Dimension & dim) const 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; } diff --git a/src/mathed/math_gridinset.C b/src/mathed/math_gridinset.C index 2dbfd74a28..20cd11011c 100644 --- a/src/mathed/math_gridinset.C +++ b/src/mathed/math_gridinset.C @@ -1046,6 +1046,7 @@ void MathGridInset::splitCell(LCursor & cur) DispatchResult MathGridInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) { + lyxerr << "*** MathGridInset: request: " << cmd << endl; switch (cmd.action) { case LFUN_MOUSE_RELEASE: diff --git a/src/mathed/math_gridinset.h b/src/mathed/math_gridinset.h index 5fc1e51364..cc81bc7e67 100644 --- a/src/mathed/math_gridinset.h +++ b/src/mathed/math_gridinset.h @@ -94,7 +94,7 @@ public: /// Ensures that the dialog is closed. ~MathGridInset(); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; /// void metrics(MetricsInfo & mi) const; /// diff --git a/src/mathed/math_hullinset.C b/src/mathed/math_hullinset.C index 64c960fb39..10cd59951b 100644 --- a/src/mathed/math_hullinset.C +++ b/src/mathed/math_hullinset.C @@ -27,19 +27,20 @@ #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; @@ -112,6 +113,7 @@ namespace { } // end anon namespace + MathHullInset::MathHullInset() : MathGridInset(1, 1), type_("none"), nonum_(1), label_(1) { @@ -199,11 +201,11 @@ void MathHullInset::metrics(MetricsInfo & mi, Dimension & dim) const 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()) { @@ -213,19 +215,19 @@ void MathHullInset::metrics(MetricsInfo & mi, Dimension & dim) const 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; } @@ -787,6 +789,7 @@ void MathHullInset::doExtern(LCursor & cur, FuncRequest const & func) DispatchResult MathHullInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) { + lyxerr << "*** MathHullInset: request: " << cmd << endl; switch (cmd.action) { case LFUN_BREAKLINE: @@ -887,23 +890,13 @@ string MathHullInset::fileInsetLabel() const #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" @@ -914,15 +907,6 @@ string MathHullInset::fileInsetLabel() const #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 { @@ -931,17 +915,6 @@ 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 @@ -1041,22 +1014,6 @@ void MathHullInset::insetUnlock(BufferView & bv) } -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; @@ -1087,7 +1044,7 @@ MathHullInset::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd) 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); @@ -1097,11 +1054,6 @@ MathHullInset::lfunMouseRelease(LCursor & cur, FuncRequest const & cmd) // 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); } @@ -1179,21 +1131,20 @@ void MathHullInset::edit(LCursor & cur, bool left) } +/* 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 @@ -1256,7 +1207,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str, #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; @@ -1264,7 +1215,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str, //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 { @@ -1272,7 +1223,7 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str, } //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_)) { @@ -1294,11 +1245,99 @@ bool MathHullInset::searchForward(BufferView * bv, string const & str, 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) { @@ -1337,6 +1376,8 @@ void mathDispatchCreation(LCursor & cur, FuncRequest const & cmd, cmd.message(N_("Math editor mode")); } +} // namespace anon + void mathDispatch(LCursor & cur, FuncRequest const & cmd) { diff --git a/src/mathed/math_hullinset.h b/src/mathed/math_hullinset.h index a951d77da2..e88b6576e3 100644 --- a/src/mathed/math_hullinset.h +++ b/src/mathed/math_hullinset.h @@ -15,8 +15,6 @@ #include "math_gridinset.h" -class LaTeXFeatures; - /// This provides an interface between "LyX insets" and "LyX math insets" class MathHullInset : public MathGridInset { public: @@ -25,7 +23,7 @@ public: /// explicit MathHullInset(std::string const & type); /// - virtual std::auto_ptr clone() const; + std::auto_ptr clone() const; /// mode_type currentMode() const; /// @@ -94,6 +92,29 @@ public: /// 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); @@ -145,8 +166,6 @@ public: /// 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; /// @@ -172,11 +191,9 @@ public: /// 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 @@ -189,14 +206,6 @@ private: 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: @@ -214,7 +223,7 @@ 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 diff --git a/src/mathed/math_lefteqninset.C b/src/mathed/math_lefteqninset.C index b26b700fb1..fd2c691a3f 100644 --- a/src/mathed/math_lefteqninset.C +++ b/src/mathed/math_lefteqninset.C @@ -32,12 +32,12 @@ auto_ptr MathLefteqnInset::clone() const 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; } diff --git a/src/mathed/math_macro.C b/src/mathed/math_macro.C index 9058cb1fa5..eba161e677 100644 --- a/src/mathed/math_macro.C +++ b/src/mathed/math_macro.C @@ -73,35 +73,35 @@ void MathMacro::metrics(MetricsInfo & mi, Dimension & dim) const 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; } diff --git a/src/mathed/math_makeboxinset.C b/src/mathed/math_makeboxinset.C index cf3325b329..7154dfff7a 100644 --- a/src/mathed/math_makeboxinset.C +++ b/src/mathed/math_makeboxinset.C @@ -36,12 +36,12 @@ void MathMakeboxInset::metrics(MetricsInfo & mi, Dimension & dim) const 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; } diff --git a/src/mathed/math_mboxinset.C b/src/mathed/math_mboxinset.C new file mode 100644 index 0000000000..2e5fdbb328 --- /dev/null +++ b/src/mathed/math_mboxinset.C @@ -0,0 +1,84 @@ +/** + * \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 + +#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 MathMBoxInset::clone() const +{ + return auto_ptr(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; +} diff --git a/src/mathed/math_mboxinset.h b/src/mathed/math_mboxinset.h new file mode 100644 index 0000000000..8758b000f4 --- /dev/null +++ b/src/mathed/math_mboxinset.h @@ -0,0 +1,50 @@ +// -*- 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 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 diff --git a/src/mathed/math_nestinset.C b/src/mathed/math_nestinset.C index f2f485a81c..344d91933b 100644 --- a/src/mathed/math_nestinset.C +++ b/src/mathed/math_nestinset.C @@ -12,20 +12,40 @@ #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) {} @@ -49,13 +69,14 @@ MathArray const & MathNestInset::cell(idx_type i) const } -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; } @@ -216,12 +237,6 @@ bool MathNestInset::contains(MathArray const & ar) const } -bool MathNestInset::editing(BufferView * bv) const -{ - return bv->cursor().isInside(this); -} - - bool MathNestInset::lock() const { return lock_; @@ -278,9 +293,40 @@ void MathNestInset::notifyCursorLeaves(idx_type idx) } +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 @@ -289,13 +335,26 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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())); @@ -419,7 +478,7 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) #if 0 // -// this needs to bee incorporated +// this needs to be incorporated // //lyxerr << "InsetFormulaBase::localDispatch: act: " << cmd.action // << " arg: '" << cmd.argument @@ -448,7 +507,6 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) } DispatchResult result(true); - string argument = cmd.argument; bool was_macro = cur.inMacroMode(); cur.normalize(); @@ -456,21 +514,11 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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",); @@ -483,28 +531,17 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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 @@ -516,7 +553,7 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) recordUndo(cur, Undo::ATOMIC); cur.script(true); } - break; + return DispatchResult(true, true); case LFUN_UMLAUT: case LFUN_ACUTE: @@ -532,32 +569,60 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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 @@ -566,7 +631,7 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) cur.setSize(arg); } #endif - break; + return DispatchResult(true, true); case LFUN_INSERT_MATRIX: { recordUndo(cur, Undo::ATOMIC); @@ -574,20 +639,22 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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 = '('; @@ -595,65 +662,60 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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: { @@ -662,26 +724,24 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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: @@ -691,16 +751,9 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) 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(); @@ -719,48 +772,33 @@ MathNestInset::priv_dispatch(LCursor & cur, FuncRequest const & cmd) #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); + } } diff --git a/src/mathed/math_nestinset.h b/src/mathed/math_nestinset.h index 27de5a1c92..853a33aa54 100644 --- a/src/mathed/math_nestinset.h +++ b/src/mathed/math_nestinset.h @@ -40,7 +40,9 @@ public: /// 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; @@ -97,9 +99,12 @@ public: 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 cells_type; @@ -107,18 +112,6 @@ protected: 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 diff --git a/src/mathed/math_parboxinset.C b/src/mathed/math_parboxinset.C index a2c9ccd624..176d34988f 100644 --- a/src/mathed/math_parboxinset.C +++ b/src/mathed/math_parboxinset.C @@ -53,9 +53,9 @@ void MathParboxInset::metrics(MetricsInfo & mi, Dimension & dim) const { 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; } diff --git a/src/mathed/math_rootinset.C b/src/mathed/math_rootinset.C index 310d6e9fa5..85025a1add 100644 --- a/src/mathed/math_rootinset.C +++ b/src/mathed/math_rootinset.C @@ -38,11 +38,11 @@ auto_ptr MathRootInset::clone() const 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; } diff --git a/src/mathed/math_scriptinset.C b/src/mathed/math_scriptinset.C index 26151a7c1f..52f9796298 100644 --- a/src/mathed/math_scriptinset.C +++ b/src/mathed/math_scriptinset.C @@ -204,24 +204,24 @@ void MathScriptInset::metrics(MetricsInfo & mi, Dimension & dim) const 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; } diff --git a/src/mathed/math_sizeinset.C b/src/mathed/math_sizeinset.C index 04ee8dadee..b6e3a81769 100644 --- a/src/mathed/math_sizeinset.C +++ b/src/mathed/math_sizeinset.C @@ -38,9 +38,9 @@ auto_ptr MathSizeInset::clone() const 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; } diff --git a/src/mathed/math_sqrtinset.C b/src/mathed/math_sqrtinset.C index 00ecc675f0..61da212107 100644 --- a/src/mathed/math_sqrtinset.C +++ b/src/mathed/math_sqrtinset.C @@ -33,12 +33,12 @@ auto_ptr MathSqrtInset::clone() const 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; } diff --git a/src/mathed/math_stackrelinset.C b/src/mathed/math_stackrelinset.C index 90b9c5f0ba..4254f1869d 100644 --- a/src/mathed/math_stackrelinset.C +++ b/src/mathed/math_stackrelinset.C @@ -34,11 +34,11 @@ void MathStackrelInset::metrics(MetricsInfo & mi, Dimension & dim) const 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; } diff --git a/src/mathed/math_substackinset.C b/src/mathed/math_substackinset.C index 4767f3402e..ce15a19a48 100644 --- a/src/mathed/math_substackinset.C +++ b/src/mathed/math_substackinset.C @@ -33,12 +33,12 @@ void MathSubstackInset::metrics(MetricsInfo & mi, Dimension & dim) const { 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; } diff --git a/src/mathed/math_textinset.C b/src/mathed/math_textinset.C index 0c8772d7c3..d60928a79b 100644 --- a/src/mathed/math_textinset.C +++ b/src/mathed/math_textinset.C @@ -12,8 +12,10 @@ #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; @@ -40,12 +42,13 @@ MathInset::idx_type MathTextInset::pos2row(pos_type pos) const } -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(); } diff --git a/src/mathed/math_textinset.h b/src/mathed/math_textinset.h index 8f81c83216..44ebf919f6 100644 --- a/src/mathed/math_textinset.h +++ b/src/mathed/math_textinset.h @@ -24,7 +24,7 @@ public: /// virtual std::auto_ptr 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 diff --git a/src/paragraph_funcs.C b/src/paragraph_funcs.C index 487ee37eb5..07c9703dc1 100644 --- a/src/paragraph_funcs.C +++ b/src/paragraph_funcs.C @@ -605,10 +605,11 @@ Paragraph const & ownerPar(Buffer const & buf, InsetBase const * inset) } +/// 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(); @@ -622,3 +623,4 @@ void getParsInRange(ParagraphList & pl, for (end = beg ; end != endpar && end->y <= yend; ++end) ; } + diff --git a/src/paragraph_funcs.h b/src/paragraph_funcs.h index 0b1284962c..5b22c42117 100644 --- a/src/paragraph_funcs.h +++ b/src/paragraph_funcs.h @@ -17,13 +17,13 @@ #include - class Buffer; class BufferParams; class LyXFont; class LyXLex; class InsetBase; + /// void breakParagraph(BufferParams const & bparams, ParagraphList & paragraphs, @@ -77,10 +77,8 @@ Paragraph const & ownerPar(Buffer const & buf, InsetBase const * inset); /// 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 diff --git a/src/rowpainter.C b/src/rowpainter.C index d90558a4e8..7772d889f2 100644 --- a/src/rowpainter.C +++ b/src/rowpainter.C @@ -47,6 +47,7 @@ using std::string; extern int NEST_MARGIN; extern int CHANGEBAR_MARGIN; + namespace { /** @@ -125,6 +126,9 @@ RowPainter::RowPainter(BufferView const & bv, LyXText const & text, 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. @@ -411,19 +415,19 @@ void RowPainter::paintSelection() 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) { @@ -882,7 +886,9 @@ int paintPars(BufferView const & bv, LyXText const & text, 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); } diff --git a/src/text.C b/src/text.C index a5f41923b8..db52a26cc5 100644 --- a/src/text.C +++ b/src/text.C @@ -1385,6 +1385,8 @@ void LyXText::backspace() ParagraphList::iterator LyXText::cursorPar() const { + //lyxerr << "### cursorPar: cursor: " << bv()->cursor() << endl; + //lyxerr << "xxx cursorPar: cursor: " << cursor() << endl; return getPar(cursor().par()); } @@ -1403,6 +1405,7 @@ ParagraphList::iterator LyXText::getPar(CursorSlice const & cur) const 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(); @@ -1414,7 +1417,6 @@ ParagraphList::iterator LyXText::getPar(int par) const 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()); @@ -1862,23 +1864,11 @@ int LyXText::descent() const } -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; @@ -1931,7 +1921,7 @@ int LyXText::cursorX(CursorSlice const & cur) const } else x += singleWidth(pit, pos); } - return int(x); + return xo_ + int(x); } @@ -1939,29 +1929,50 @@ int LyXText::cursorY(CursorSlice const & cur) const { 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)]; } diff --git a/src/text2.C b/src/text2.C index 5aeeb6fbc1..3aa14065e6 100644 --- a/src/text2.C +++ b/src/text2.C @@ -269,8 +269,7 @@ void LyXText::makeFontEntriesLayoutSpecific(BufferParams const & params, // 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); @@ -1199,7 +1198,7 @@ void LyXText::setCursorIntern(paroffset_type par, 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(); } @@ -1250,6 +1249,7 @@ void LyXText::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(); @@ -1271,7 +1271,7 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, // check for empty row if (vc == end) { - x = int(tmpx); + x = int(tmpx) + xo_; return 0; } @@ -1343,9 +1343,8 @@ pos_type LyXText::getColumnNearX(ParagraphList::iterator pit, c = end - 1; } - c -= row.pos(); - x = int(tmpx); - return c; + x = int(tmpx) + xo_; + return c - row.pos(); } @@ -1364,10 +1363,37 @@ void LyXText::setCursorFromCoordinates(CursorSlice & cur, int x, int y) 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); + } } @@ -1502,15 +1528,14 @@ void LyXText::cursorUp(bool selecting) { 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); } } @@ -1519,15 +1544,14 @@ void LyXText::cursorDown(bool selecting) { 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); } } diff --git a/src/text3.C b/src/text3.C index eadbe33e90..c9461f4648 100644 --- a/src/text3.C +++ b/src/text3.C @@ -252,8 +252,8 @@ InsetBase * LyXText::checkInsetHit(int x, int 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; @@ -262,17 +262,14 @@ InsetBase * LyXText::checkInsetHit(int x, int y) 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; } @@ -357,14 +354,14 @@ void LyXText::gotoInset(InsetOld_code code, bool same_content) 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); @@ -377,14 +374,15 @@ void LyXText::cursorPrevious() 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); @@ -397,11 +395,11 @@ void LyXText::cursorNext() 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 @@ -450,7 +448,8 @@ bool LyXText::rtl() const 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(); @@ -977,7 +976,8 @@ DispatchResult LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) break; case LFUN_GETXY: - cmd.message(tostr(cursorX()) + ' ' + tostr(cursorY())); + cmd.message(tostr(cursorX(cur.current())) + ' ' + + tostr(cursorY(cur.current()))); break; case LFUN_SETXY: { @@ -1158,9 +1158,12 @@ DispatchResult LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) 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; @@ -1185,6 +1188,7 @@ DispatchResult LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) cursorUp(true); } cur.setSelection(); +#endif break; } @@ -1227,10 +1231,13 @@ DispatchResult LyXText::dispatch(LCursor & cur, FuncRequest const & cmd) 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; -- 2.39.2