X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Fmathed%2FInsetMathNest.cpp;h=4b19c3ce090f516fe348c5deffc197619a8df45a;hb=ba3ff646db52efc8faaa735107c5580eae82b29d;hp=3460cdca35a7be3b65c7b66664d1820497da6064;hpb=239b9919ffe28338d789e6dc9122228f77ab77a7;p=lyx.git diff --git a/src/mathed/InsetMathNest.cpp b/src/mathed/InsetMathNest.cpp index 3460cdca35..4b19c3ce09 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,8 +171,10 @@ 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; + } } @@ -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) @@ -606,7 +560,7 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) case LFUN_CUT: cur.recordUndo(); - cutSelection(cur, true, true); + cutSelection(cur, true); cur.message(_("Cut")); // Prevent stale position >= size crash // Probably not necessary anymore, see eraseSelection (gb 2005-10-09) @@ -781,20 +735,18 @@ 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; + cur.bv().mouseSetCursor(cur, true); break; case LFUN_LINE_BEGIN: @@ -860,8 +812,8 @@ 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); + if (!cur.backspace(cmd.getArg(0) == "force")) { + FuncRequest cmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD, "force"); cur.innerText()->dispatch(cur, cmd); } break; @@ -874,8 +826,8 @@ 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); + if (!cur.erase(cmd.getArg(0) == "force")) { + FuncRequest cmd = FuncRequest(LFUN_CHAR_DELETE_FORWARD, "force"); cur.innerText()->dispatch(cur, cmd); } break; @@ -884,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; @@ -898,40 +854,41 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) break; case LFUN_SELF_INSERT: - if (cmd.argument().size() != 1) { - cur.recordUndoSelection(); - docstring const arg = cmd.argument(); - if (!interpretString(cur, arg)) - cur.insert(arg); + // special case first for big delimiters + if (cmd.argument().size() != 1 && interpretString(cur, cmd.argument())) break; - } - // Don't record undo steps if we are in macro mode and thus - // cmd.argument is the next character of the macro name. - // Otherwise we'll get an invalid cursor if we undo after - // the macro was finished and the macro is a known command, - // e.g. sqrt. Cursor::macroModeClose replaces in this case - // the InsetMathUnknown with name "frac" by an empty - // InsetMathFrac -> a pos value > 0 is invalid. - // A side effect is that an undo before the macro is finished - // undoes the complete macro, not only the last character. - // At the time we hit '\' we are not in macro mode, still. - if (!cur.inMacroMode()) - cur.recordUndoSelection(); - // spacial handling of space. If we insert an inset - // via macro mode, we want to put the cursor inside it - // if relevant. Think typing "\frac". - if (cmd.argument()[0] == ' ' - && cur.inMacroMode() && cur.macroName() != "\\" - && cur.macroModeClose() && cur.pos() > 0) { - MathAtom const atom = cur.prevAtom(); - if (atom->asNestInset() && atom->isActive()) { - cur.posBackward(); - cur.pushBackward(*cur.nextInset()); + for (char_type c : cmd.argument()) { + // Don't record undo steps if we are in macro mode and thus + // cmd.argument is the next character of the macro name. + // Otherwise we'll get an invalid cursor if we undo after + // the macro was finished and the macro is a known command, + // e.g. sqrt. Cursor::macroModeClose replaces in this case + // the InsetMathUnknown with name "frac" by an empty + // InsetMathFrac -> a pos value > 0 is invalid. + // A side effect is that an undo before the macro is finished + // undoes the complete macro, not only the last character. + // At the time we hit '\' we are not in macro mode, still. + if (!cur.inMacroMode()) + cur.recordUndoSelection(); + + // special handling of space. If we insert an inset + // via macro mode, we want to put the cursor inside it + // if relevant. Think typing "\frac". + if (c == ' ' + && cur.inMacroMode() && cur.macroName() != "\\" + && cur.macroModeClose() && cur.pos() > 0) { + MathAtom const atom = cur.prevAtom(); + if (atom->asNestInset() && atom->isActive()) { + cur.posBackward(); + cur.pushBackward(*cur.nextInset()); + } + } else if (!interpretChar(cur, c)) { + cmd = FuncRequest(LFUN_FINISHED_FORWARD); + cur.undispatched(); + // FIXME: can we avoid skipping the end of the string? + break; } - } else if (!interpretChar(cur, cmd.argument()[0])) { - cmd = FuncRequest(LFUN_FINISHED_FORWARD); - cur.undispatched(); } break; @@ -1254,7 +1211,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); @@ -1290,22 +1247,6 @@ void InsetMathNest::doDispatch(Cursor & cur, FuncRequest & cmd) break; } - case LFUN_UNICODE_INSERT: { - if (cmd.argument().empty()) - break; - docstring hexstring = cmd.argument(); - if (isHex(hexstring)) { - char_type c = hexToInt(hexstring); - if (c >= 32 && c < 0x10ffff) { - docstring s = docstring(1, c); - FuncCode code = currentMode() == MATH_MODE ? - LFUN_MATH_INSERT : LFUN_SELF_INSERT; - lyx::dispatch(FuncRequest(code, s)); - } - } - break; - } - case LFUN_DIALOG_SHOW_NEW_INSET: { docstring const & name = cmd.argument(); string data; @@ -1350,7 +1291,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) @@ -1541,7 +1482,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); @@ -1550,6 +1491,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; @@ -1579,6 +1523,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); @@ -1623,6 +1571,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 @@ -1675,7 +1626,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; } @@ -1940,6 +1891,7 @@ bool InsetMathNest::interpretString(Cursor & cur, docstring const & str) prev = prev.substr(1); latexkeys const * l = in_word_set(prev); if (l && l->inset == "big") { + cur.recordUndoSelection(); cur.cell()[cur.pos() - 1] = MathAtom(new InsetMathBig(prev, str)); return true;