X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathNest.cpp;h=a03aaefb168a38304e91042f1d076bc59d1a13bd;hb=9296344b9a26191a2092d175a51e357ecc35145d;hp=93d344dcb1b32c7fc526caba092c71659bfc8a33;hpb=2de30c62f8d671a8c8d4d52a6a7310e2c5ca84de;p=lyx.git diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 93d344dcb1..a03aaefb16 100644 --- a/src/mathed/InsetMathNest.cpp +++ b/src/mathed/InsetMathNest.cpp @@ -32,8 +32,8 @@ #include "MathCompletionList.h" #include "MathData.h" #include "MathFactory.h" -#include "MathMacro.h" -#include "MathMacroArgument.h" +#include "InsetMathMacro.h" +#include "InsetMathMacroArgument.h" #include "MathParser.h" #include "MathStream.h" #include "MathSupport.h" @@ -171,17 +171,19 @@ void InsetMathNest::cursorPos(BufferView const & bv, // << " asc: " << ascent() << " des: " << descent() // << " ar.asc: " << ar.ascent() << " ar.des: " << ar.descent() << endl; // move cursor visually into empty cells ("blue rectangles"); - if (ar.empty()) - x += 2; + if (ar.empty()) { + Dimension const dim = coord_cache.getArrays().dim(&ar); + x += dim.wid / 3; + } } -void InsetMathNest::metrics(MetricsInfo const & mi) const +void InsetMathNest::cellsMetrics(MetricsInfo const & mi) const { MetricsInfo m = mi; - for (idx_type i = 0, n = nargs(); i != n; ++i) { + for (auto const & cell : cells_) { Dimension dim; - cell(i).metrics(m, dim); + cell.metrics(m, dim); } } @@ -275,54 +277,6 @@ void InsetMathNest::draw(PainterInfo &, int, int) const } -void InsetMathNest::drawSelection(PainterInfo & pi, int x, int y) const -{ - BufferView & bv = *pi.base.bv; - // this should use the x/y values given, not the cached values - Cursor & cur = bv.cursor(); - if (!cur.selection()) - return; - if (&cur.inset() != this) - return; - - // FIXME: hack to get position cache warm - bool const original_drawing_state = pi.pain.isDrawingEnabled(); - pi.pain.setDrawingEnabled(false); - draw(pi, x, y); - pi.pain.setDrawingEnabled(original_drawing_state); - - CursorSlice s1 = cur.selBegin(); - CursorSlice s2 = cur.selEnd(); - - //lyxerr << "InsetMathNest::drawing selection: " - // << " s1: " << s1 << " s2: " << s2 << endl; - if (s1.idx() == s2.idx()) { - MathData const & c = cell(s1.idx()); - Geometry const & g = bv.coordCache().getArrays().geometry(&c); - int x1 = g.pos.x_ + c.pos2x(pi.base.bv, s1.pos()); - int y1 = g.pos.y_ - g.dim.ascent(); - int x2 = g.pos.x_ + c.pos2x(pi.base.bv, s2.pos()); - int y2 = g.pos.y_ + g.dim.descent(); - pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, Color_selection); - //lyxerr << "InsetMathNest::drawing selection 3: " - // << " x1: " << x1 << " x2: " << x2 - // << " y1: " << y1 << " y2: " << y2 << endl; - } else { - for (idx_type i = 0; i < nargs(); ++i) { - if (idxBetween(i, s1.idx(), s2.idx())) { - MathData const & c = cell(i); - Geometry const & g = bv.coordCache().getArrays().geometry(&c); - int x1 = g.pos.x_; - int y1 = g.pos.y_ - g.dim.ascent(); - int x2 = g.pos.x_ + g.dim.width(); - int y2 = g.pos.y_ + g.dim.descent(); - pi.pain.fillRectangle(x1, y1, x2 - x1, y2 - y1, Color_selection); - } - } - } -} - - void InsetMathNest::validate(LaTeXFeatures & features) const { for (idx_type i = 0; i < nargs(); ++i) @@ -642,21 +596,42 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) cur.bv().cursor() = cur; break; + case LFUN_WORD_RIGHT: + case LFUN_WORD_LEFT: + case LFUN_WORD_BACKWARD: + case LFUN_WORD_FORWARD: case LFUN_CHAR_RIGHT: case LFUN_CHAR_LEFT: case LFUN_CHAR_BACKWARD: case LFUN_CHAR_FORWARD: cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); // fall through + case LFUN_WORD_RIGHT_SELECT: + case LFUN_WORD_LEFT_SELECT: + case LFUN_WORD_BACKWARD_SELECT: + case LFUN_WORD_FORWARD_SELECT: case LFUN_CHAR_RIGHT_SELECT: case LFUN_CHAR_LEFT_SELECT: case LFUN_CHAR_BACKWARD_SELECT: case LFUN_CHAR_FORWARD_SELECT: { // are we in a selection? - bool select = (act == LFUN_CHAR_RIGHT_SELECT + bool select = (act == LFUN_WORD_RIGHT_SELECT + || act == LFUN_WORD_LEFT_SELECT + || act == LFUN_WORD_BACKWARD_SELECT + || act == LFUN_WORD_FORWARD_SELECT + || act == LFUN_CHAR_RIGHT_SELECT || act == LFUN_CHAR_LEFT_SELECT || act == LFUN_CHAR_BACKWARD_SELECT || act == LFUN_CHAR_FORWARD_SELECT); + // select words + bool word = (act == LFUN_WORD_RIGHT_SELECT + || act == LFUN_WORD_LEFT_SELECT + || act == LFUN_WORD_BACKWARD_SELECT + || act == LFUN_WORD_FORWARD_SELECT + || act == LFUN_WORD_RIGHT + || act == LFUN_WORD_LEFT + || act == LFUN_WORD_BACKWARD + || act == LFUN_WORD_FORWARD); // are we moving forward or backwards? // If the command was RIGHT or LEFT, then whether we're moving forward // or backwards depends on the cursor movement mode (logical or visual): @@ -669,18 +644,24 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) FuncCode finish_lfun; if (act == LFUN_CHAR_FORWARD - || act == LFUN_CHAR_FORWARD_SELECT) { + || act == LFUN_CHAR_FORWARD_SELECT + || act == LFUN_WORD_FORWARD + || act == LFUN_WORD_FORWARD_SELECT) { forward = true; finish_lfun = LFUN_FINISHED_FORWARD; } else if (act == LFUN_CHAR_BACKWARD - || act == LFUN_CHAR_BACKWARD_SELECT) { + || act == LFUN_CHAR_BACKWARD_SELECT + || act == LFUN_WORD_BACKWARD + || act == LFUN_WORD_BACKWARD_SELECT) { forward = false; finish_lfun = LFUN_FINISHED_BACKWARD; } else { bool right = (act == LFUN_CHAR_RIGHT_SELECT - || act == LFUN_CHAR_RIGHT); + || act == LFUN_CHAR_RIGHT + || act == LFUN_WORD_RIGHT_SELECT + || act == LFUN_WORD_RIGHT); if (lyxrc.visual_cursor || !cur.reverseDirectionNeeded()) forward = right; else @@ -696,7 +677,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) cur.clearTargetX(); cur.macroModeClose(); // try moving forward or backwards as necessary... - if (!(forward ? cursorMathForward(cur) : cursorMathBackward(cur))) { + if (!(forward ? cur.mathForward(word) : cur.mathBackward(word))) { // ... and if movement failed, then finish forward or backwards // as necessary cmd = FuncRequest(finish_lfun); @@ -707,10 +688,14 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_DOWN: case LFUN_UP: + case LFUN_PARAGRAPH_UP: + case LFUN_PARAGRAPH_DOWN: cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); // fall through case LFUN_DOWN_SELECT: - case LFUN_UP_SELECT: { + case LFUN_UP_SELECT: + case LFUN_PARAGRAPH_UP_SELECT: + case LFUN_PARAGRAPH_DOWN_SELECT: { // close active macro if (cur.inMacroMode()) { cur.macroModeClose(); @@ -718,8 +703,10 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) } // stop/start the selection - bool select = act == LFUN_DOWN_SELECT || - act == LFUN_UP_SELECT; + bool select = act == LFUN_DOWN_SELECT + || act == LFUN_UP_SELECT + || act == LFUN_PARAGRAPH_DOWN_SELECT + || act == LFUN_PARAGRAPH_UP_SELECT; cur.selHandle(select); // handle autocorrect: @@ -729,7 +716,8 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) } // go up/down - bool up = act == LFUN_UP || act == LFUN_UP_SELECT; + bool up = act == LFUN_UP || act == LFUN_UP_SELECT + || act == LFUN_PARAGRAPH_UP || act == LFUN_PARAGRAPH_UP_SELECT; bool successful = cur.upDownInMath(up); if (successful) break; @@ -747,38 +735,24 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_MOUSE_DOUBLE: case LFUN_WORD_SELECT: cur.pos() = 0; - cur.resetAnchor(); - cur.selection(true); + cur.bv().mouseSetCursor(cur); cur.pos() = cur.lastpos(); - cur.bv().cursor() = cur; + cur.bv().mouseSetCursor(cur, true); break; case LFUN_MOUSE_TRIPLE: cur.idx() = 0; cur.pos() = 0; - cur.resetAnchor(); - cur.selection(true); + cur.bv().mouseSetCursor(cur); cur.idx() = cur.lastidx(); cur.pos() = cur.lastpos(); - cur.bv().cursor() = cur; - break; - - case LFUN_PARAGRAPH_UP: - case LFUN_PARAGRAPH_DOWN: - cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); - // fall through - case LFUN_PARAGRAPH_UP_SELECT: - case LFUN_PARAGRAPH_DOWN_SELECT: + cur.bv().mouseSetCursor(cur, true); break; case LFUN_LINE_BEGIN: - case LFUN_WORD_BACKWARD: - case LFUN_WORD_LEFT: cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); // fall through case LFUN_LINE_BEGIN_SELECT: - case LFUN_WORD_BACKWARD_SELECT: - case LFUN_WORD_LEFT_SELECT: cur.selHandle(act == LFUN_WORD_BACKWARD_SELECT || act == LFUN_WORD_LEFT_SELECT || act == LFUN_LINE_BEGIN_SELECT); @@ -797,13 +771,9 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) } break; - case LFUN_WORD_FORWARD: - case LFUN_WORD_RIGHT: case LFUN_LINE_END: cur.screenUpdateFlags(Update::Decoration | Update::FitCursor); // fall through - case LFUN_WORD_FORWARD_SELECT: - case LFUN_WORD_RIGHT_SELECT: case LFUN_LINE_END_SELECT: cur.selHandle(act == LFUN_WORD_FORWARD_SELECT || act == LFUN_WORD_RIGHT_SELECT || @@ -842,9 +812,9 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) else if (!cur.inMacroMode()) cur.recordUndoSelection(); // if the inset can not be removed from within, delete it - if (!cur.backspace()) { - FuncRequest cmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD); - cur.innerText()->dispatch(cur, cmd); + if (!cur.backspace(cmd.getArg(0) == "force")) { + FuncRequest newcmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD, "force"); + cur.innerText()->dispatch(cur, newcmd); } break; @@ -856,9 +826,9 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) else cur.recordUndoSelection(); // if the inset can not be removed from within, delete it - if (!cur.erase()) { - FuncRequest cmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD); - cur.innerText()->dispatch(cur, cmd); + if (!cur.erase(cmd.getArg(0) == "force")) { + FuncRequest newcmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD, "force"); + cur.innerText()->dispatch(cur, newcmd); } break; @@ -866,8 +836,12 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) if (cur.selection()) cur.clearSelection(); else { - cmd = FuncRequest(LFUN_FINISHED_FORWARD); - cur.undispatched(); + if (cur.inMacroMode()) + cur.macroModeClose(true); + else { + cmd = FuncRequest(LFUN_FINISHED_FORWARD); + cur.undispatched(); + } } break; @@ -926,7 +900,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) int y = 0; istringstream is(to_utf8(cmd.argument())); is >> x >> y; - cur.setScreenPos(x, y); + cur.setTargetX(x); break; } @@ -1236,7 +1210,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) bool fold = act == LFUN_MATH_MACRO_FOLD; bool found = findMacroToFoldUnfold(it, fold); if (found) { - MathMacro * macro = it.nextInset()->asInsetMath()->asMacro(); + InsetMathMacro * macro = it.nextInset()->asInsetMath()->asMacro(); cur.recordUndoInset(); if (fold) macro->fold(cur); @@ -1332,7 +1306,7 @@ bool InsetMathNest::findMacroToFoldUnfold(Cursor & it, bool fold) const { // go backward through the current cell Inset * inset = it.nextInset(); while (inset && inset->asInsetMath()) { - MathMacro * macro = inset->asInsetMath()->asMacro(); + InsetMathMacro * macro = inset->asInsetMath()->asMacro(); if (macro) { // found the an macro to open/close? if (macro->folded() != fold) @@ -1523,7 +1497,7 @@ void InsetMathNest::edit(Cursor & cur, bool front, EntryDirection entry_from) Inset * InsetMathNest::editXY(Cursor & cur, int x, int y) { - int idx_min = 0; + int idx_min = -1; int dist_min = 1000000; for (idx_type i = 0, n = nargs(); i != n; ++i) { int const d = cell(i).dist(cur.bv(), x, y); @@ -1532,6 +1506,9 @@ Inset * InsetMathNest::editXY(Cursor & cur, int x, int y) idx_min = i; } } + if (idx_min == -1) + return this; + MathData & ar = cell(idx_min); cur.push(*this); cur.idx() = idx_min; @@ -1561,6 +1538,10 @@ void InsetMathNest::lfunMousePress(Cursor & cur, FuncRequest & cmd) return; } } + + // set cursor after the inset if x is nearer to that position (bug 9748) + cur.moveToClosestEdge(cmd.x(), true); + bool do_selection = cmd.button() == mouse_button::button1 && cmd.modifier() == ShiftModifier; bv.mouseSetCursor(cur, do_selection); @@ -1605,6 +1586,9 @@ void InsetMathNest::lfunMouseMotion(Cursor & cur, FuncRequest & cmd) return; } + // set cursor after the inset if x is nearer to that position (bug 9748) + cur.moveToClosestEdge(cmd.x()); + CursorSlice old = bvcur.top(); // We continue with our existing selection or start a new one, so don't @@ -1657,7 +1641,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c) cur.backspace(); int n = c - '0'; if (n >= 1 && n <= 9) - cur.insert(new MathMacroArgument(n)); + cur.insert(new InsetMathMacroArgument(n)); return true; } @@ -2051,8 +2035,7 @@ bool InsetMathNest::insertCompletion(Cursor & cur, docstring const & s, #if 0 // FIXME: this creates duplicates in the completion popup // which looks ugly. Moreover the changes the list lengths - // which seems to - confuse the popup as well. + // which seems to confuse the popup as well. MathCompletionList::addToFavorites(inset->name()); #endif lyx::dispatch(FuncRequest(LFUN_SELF_INSERT, " ")); @@ -2083,43 +2066,6 @@ void InsetMathNest::completionPosAndDim(Cursor const & cur, int & x, int & y, } -bool InsetMathNest::cursorMathForward(Cursor & cur) -{ - if (cur.pos() != cur.lastpos() && cur.openable(cur.nextAtom())) { - cur.pushBackward(*cur.nextAtom().nucleus()); - cur.inset().idxFirst(cur); - return true; - } - if (cur.posForward() || idxForward(cur)) - return true; - // try to pop forwards --- but don't pop out of math! leave that to - // the FINISH lfuns - int s = cur.depth() - 2; - if (s >= 0 && cur[s].inset().asInsetMath()) - return cur.popForward(); - return false; -} - - -bool InsetMathNest::cursorMathBackward(Cursor & cur) -{ - if (cur.pos() != 0 && cur.openable(cur.prevAtom())) { - cur.posBackward(); - cur.push(*cur.nextAtom().nucleus()); - cur.inset().idxLast(cur); - return true; - } - if (cur.posBackward() || idxBackward(cur)) - return true; - // try to pop backwards --- but don't pop out of math! leave that to - // the FINISH lfuns - int s = cur.depth() - 2; - if (s >= 0 && cur[s].inset().asInsetMath()) - return cur.popBackward(); - return false; -} - - //////////////////////////////////////////////////////////////////// MathCompletionList::MathCompletionList(Cursor const & cur)