]> git.lyx.org Git - features.git/commitdiff
When inserting math inset, put cursor selection in the correct cell
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Wed, 4 Apr 2018 16:24:14 +0000 (18:24 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Thu, 5 Apr 2018 09:22:02 +0000 (11:22 +0200)
The original use case for this bug is entering an overset inset when
there is a selection. The expected result was to have the selection
pasted in main text, but the result was to have it in the cell.

Insets already have idxFirst() that is able to set cursor to the
"entry" cell of an inset. This patch introduces firstIdx(), which is
the index of this cell and uses it in idxFirst() (idem for
lastIdx/idxLast).

As a consequence, several instances of idxFirst/idxLast can be removed.

Now for the real fix: the two places where the cell in which selection
is inserted seem to be:
* Cursor::macroModeClose
* Cursor::handleNest

These two methods are changed to insert material in the entry cell
instead of cell 0.

idxFirst/Last methods are added to InsetMathRoot and InsetMathStackrel
so that the natural entry point is the nucleus of those insets.

Finallly, a typo is fixed in InsetMathNest::edit() where enter_front
computation was incorrect.

18 files changed:
src/Cursor.cpp
src/Cursor.h
src/mathed/InsetMathGrid.cpp
src/mathed/InsetMathGrid.h
src/mathed/InsetMathHull.cpp
src/mathed/InsetMathHull.h
src/mathed/InsetMathNest.cpp
src/mathed/InsetMathNest.h
src/mathed/InsetMathOverset.cpp
src/mathed/InsetMathOverset.h
src/mathed/InsetMathRoot.h
src/mathed/InsetMathScript.cpp
src/mathed/InsetMathScript.h
src/mathed/InsetMathSideset.cpp
src/mathed/InsetMathSideset.h
src/mathed/InsetMathStackrel.h
src/mathed/InsetMathUnderset.cpp
src/mathed/InsetMathUnderset.h

index eb8c50110f80a318e6ac4bc74cdd80254439f128..f3fccfa98e4803afff5f247413a70d92f2ecc3ac 100644 (file)
@@ -1646,6 +1646,12 @@ void Cursor::handleNest(MathAtom const & a, int c)
 }
 
 
+void Cursor::handleNest(MathAtom const & a)
+{
+       handleNest(a, a.nucleus()->asNestInset()->firstIdx());
+}
+
+
 int Cursor::targetX() const
 {
        if (x_target() != -1)
@@ -1703,6 +1709,7 @@ bool Cursor::macroModeClose(bool cancel)
        // try to put argument into macro, if we just inserted a macro
        bool macroArg = false;
        InsetMathMacro * atomAsMacro = atom.nucleus()->asMacro();
+       InsetMathNest * atomAsNest = atom.nucleus()->asNestInset();
        if (atomAsMacro) {
                // macros here are still unfolded (in init mode in fact). So
                // we have to resolve the macro here manually and check its arity
@@ -1717,8 +1724,8 @@ bool Cursor::macroModeClose(bool cancel)
        }
 
        // insert remembered selection into first argument of a non-macro
-       else if (atom.nucleus()->nargs() > 0)
-               atom.nucleus()->cell(0).append(selection);
+       else if (atomAsNest && atomAsNest->nargs() > 0)
+               atomAsNest->cell(atomAsNest->firstIdx()).append(selection);
 
        MathWordList const & words = mathedWordList();
        MathWordList::const_iterator it = words.find(name);
index 5ca98cbda5ec8e331e5c54665a75750312d84ab2..08309fa0c8c8446b87cd8f9fae5777849a403237 100644 (file)
@@ -514,9 +514,12 @@ public:
        docstring macroName();
 
 
+       /// replace selected stuff with at, placing the former
+       // selection in entry cell of atom
+       void handleNest(MathAtom const & at);
        /// replace selected stuff with at, placing the former
        // selection in given cell of atom
-       void handleNest(MathAtom const & at, int cell = 0);
+       void handleNest(MathAtom const & at, int cell);
 
        /// make sure cursor position is valid
        /// FIXME: It does a subset of fixIfBroken. Maybe merge them?
index 90fe7fc09a6fa2b912f57f5d8e072b345c54b447..6c237f6cdf582d8783bea3f2891d13fb7beaf1e5 100644 (file)
@@ -1007,47 +1007,47 @@ bool InsetMathGrid::idxForward(Cursor & cur) const
 }
 
 
-bool InsetMathGrid::idxFirst(Cursor & cur) const
+idx_type InsetMathGrid::firstIdx() const
 {
+       size_type idx = 0;
        switch (v_align_) {
                case 't':
-                       cur.idx() = 0;
+                       //idx = 0;
                        break;
                case 'b':
-                       cur.idx() = (nrows() - 1) * ncols();
+                       idx = (nrows() - 1) * ncols();
                        break;
                default:
-                       cur.idx() = ((nrows() - 1) / 2) * ncols();
+                       idx = ((nrows() - 1) / 2) * ncols();
        }
        // If we are in a multicolumn cell, move to the "real" cell
-       while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) {
-               LASSERT(cur.idx() > 0, return false);
-               --cur.idx();
+       while (cellinfo_[idx].multi_ == CELL_PART_OF_MULTICOLUMN) {
+               LASSERT(idx > 0, return 0);
+               --idx;
        }
-       cur.pos() = 0;
-       return true;
+       return idx;
 }
 
 
-bool InsetMathGrid::idxLast(Cursor & cur) const
+idx_type InsetMathGrid::lastIdx() const
 {
+       size_type idx = 0;
        switch (v_align_) {
                case 't':
-                       cur.idx() = ncols() - 1;
+                       idx = ncols() - 1;
                        break;
                case 'b':
-                       cur.idx() = nargs() - 1;
+                       idx = nargs() - 1;
                        break;
                default:
-                       cur.idx() = ((nrows() - 1) / 2 + 1) * ncols() - 1;
+                       idx = ((nrows() - 1) / 2 + 1) * ncols() - 1;
        }
        // If we are in a multicolumn cell, move to the "real" cell
-       while (cellinfo_[cur.idx()].multi_ == CELL_PART_OF_MULTICOLUMN) {
-               LASSERT(cur.idx() > 0, return false);
-               --cur.idx();
+       while (cellinfo_[idx].multi_ == CELL_PART_OF_MULTICOLUMN) {
+               LASSERT(idx > 0, return false);
+               --idx;
        }
-       cur.pos() = cur.lastpos();
-       return true;
+       return idx;
 }
 
 
index 9cd22eae510c06521adeba49fa54d1738b9a08e5..af3f4c14031492b87016a40195fb3a8b7065e771 100644 (file)
@@ -162,10 +162,10 @@ public:
        bool idxBackward(Cursor &) const;
        ///
        bool idxForward(Cursor &) const;
-       ///
-       bool idxFirst(Cursor &) const;
-       ///
-       bool idxLast(Cursor &) const;
+       //
+       idx_type firstIdx() const;
+       //
+       idx_type lastIdx() const;
        ///
        bool idxDelete(idx_type & idx);
        /// pulls cell after pressing erase
index 8f40d2cff1fbb7e31cbb64d814b3fc5252e08226..08d92871ca942e8acfbb4d12031356d32e425d1d 100644 (file)
@@ -419,22 +419,6 @@ InsetMath::mode_type InsetMathHull::currentMode() const
 }
 
 
-bool InsetMathHull::idxFirst(Cursor & cur) const
-{
-       cur.idx() = 0;
-       cur.pos() = 0;
-       return true;
-}
-
-
-bool InsetMathHull::idxLast(Cursor & cur) const
-{
-       cur.idx() = nargs() - 1;
-       cur.pos() = cur.lastpos();
-       return true;
-}
-
-
 // FIXME: InsetMathGrid should be changed to let the real column alignment be
 // given by a virtual method like displayColAlign, because the values produced
 // by defaultColAlign can be invalidated by lfuns such as add-column. For the
@@ -2253,17 +2237,14 @@ void InsetMathHull::handleFont2(Cursor & cur, docstring const & arg)
        font.fromString(to_utf8(arg), b);
        if (font.fontInfo().color() != Color_inherit) {
                MathAtom at = MathAtom(new InsetMathColor(buffer_, true, font.fontInfo().color()));
-               cur.handleNest(at, 0);
+               cur.handleNest(at);
        }
 }
 
 
 void InsetMathHull::edit(Cursor & cur, bool front, EntryDirection entry_from)
 {
-       cur.push(*this);
-       bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_LEFT ||
-               (entry_from == Inset::ENTRY_DIRECTION_IGNORE && front));
-       enter_front ? idxFirst(cur) : idxLast(cur);
+       InsetMathNest::edit(cur, front, entry_from);
        // The inset formula dimension is not necessarily the same as the
        // one of the instant preview image, so we have to indicate to the
        // BufferView that a metrics update is needed.
index 89c05043634c5d83373b421fa352cffaf2a2bab9..73de59f0a2367fb9d06f479720e7f26622277f1d 100644 (file)
@@ -120,10 +120,6 @@ public:
        char defaultColAlign(col_type col);
        ///
        char displayColAlign(idx_type idx) const;
-       ///
-       bool idxFirst(Cursor &) const;
-       ///
-       bool idxLast(Cursor &) const;
 
        ///
        void write(WriteStream & os) const;
index 2ce31a45e7061aad927da980ea922f36c50ca5e9..ec464134be53cb9728c184a8ee743d6407be3a72 100644 (file)
@@ -235,7 +235,7 @@ bool InsetMathNest::idxFirst(Cursor & cur) const
        LASSERT(&cur.inset() == this, return false);
        if (nargs() == 0)
                return false;
-       cur.idx() = 0;
+       cur.idx() = firstIdx();
        cur.pos() = 0;
        return true;
 }
@@ -246,7 +246,7 @@ bool InsetMathNest::idxLast(Cursor & cur) const
        LASSERT(&cur.inset() == this, return false);
        if (nargs() == 0)
                return false;
-       cur.idx() = cur.lastidx();
+       cur.idx() = lastIdx();
        cur.pos() = cur.lastpos();
        return true;
 }
@@ -1491,10 +1491,9 @@ bool InsetMathNest::getStatus(Cursor & cur, FuncRequest const & cmd,
 void InsetMathNest::edit(Cursor & cur, bool front, EntryDirection entry_from)
 {
        cur.push(*this);
-       bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_RIGHT ||
+       bool enter_front = (entry_from == Inset::ENTRY_DIRECTION_LEFT ||
                (entry_from == Inset::ENTRY_DIRECTION_IGNORE && front));
-       cur.idx() = enter_front ? 0 : cur.lastidx();
-       cur.pos() = enter_front ? 0 : cur.lastpos();
+       enter_front ? idxFirst(cur) : idxLast(cur);
        cur.resetAnchor();
        //lyxerr << "InsetMathNest::edit, cur:\n" << cur << endl;
 }
@@ -1734,7 +1733,7 @@ bool InsetMathNest::interpretChar(Cursor & cur, char_type const c)
                        MathAtom const atom = cur.prevAtom();
                        if (atom->asNestInset() && atom->isActive()) {
                                cur.posBackward();
-                               cur.pushBackward(*cur.nextInset());
+                               cur.nextInset()->edit(cur, true);
                        }
                }
                if (c == '{')
index 3d4977d63c44e38a9d42c4dbf954bd8953760259..57e7ab340f560d18829a5a015b24fb89fde5fd6e 100644 (file)
@@ -62,6 +62,11 @@ public:
        /// move to previous cell
        bool idxPrev(Cursor &) const;
 
+       // The index of the cell entered while moving forward
+       virtual idx_type firstIdx() const { return 0; }
+       // The index of the cell entered while moving backward
+       virtual idx_type lastIdx() const { return nargs() - 1; }
+
        /// target pos when we enter the inset while moving forward
        bool idxFirst(Cursor &) const;
        /// target pos when we enter the inset while moving backwards
index cea8840926ae6ef7ccae44dedf55d2668920ebc5..1295685d782567dafc609e767650ca963a0a2ed2 100644 (file)
@@ -57,22 +57,6 @@ void InsetMathOverset::draw(PainterInfo & pi, int x, int y) const
 }
 
 
-bool InsetMathOverset::idxFirst(Cursor & cur) const
-{
-       cur.idx() = 1;
-       cur.pos() = 0;
-       return true;
-}
-
-
-bool InsetMathOverset::idxLast(Cursor & cur) const
-{
-       cur.idx() = 1;
-       cur.pos() = cur.lastpos();
-       return true;
-}
-
-
 void InsetMathOverset::write(WriteStream & os) const
 {
        MathEnsurer ensurer(os);
index ac055e1dc92701fa749b9a9cea86114494eb54f1..1202bbcfd42c1d81796477cc5c4e79629c6893f1 100644 (file)
@@ -28,9 +28,9 @@ public:
        ///
        void draw(PainterInfo & pi, int x, int y) const;
        ///
-       bool idxFirst(Cursor &) const;
+       idx_type firstIdx() const { return 1; }
        ///
-       bool idxLast(Cursor &) const;
+       idx_type lastIdx() const { return 1; }
        ///
        void write(WriteStream & os) const;
        ///
index 923e9a5f61f9b4b3d709e8e26fa6b789ab8c41a4..cb5c34ff2029d6890dc76dfd06721e15d54990d6 100644 (file)
@@ -30,6 +30,10 @@ public:
        void metrics(MetricsInfo & mi, Dimension & dim) const;
        ///
        void draw(PainterInfo & pi, int x, int y) const;
+       ///
+       idx_type firstIdx() const { return 1; }
+       ///
+       idx_type lastIdx() const { return 1; }
 
        ///
        void write(WriteStream & os) const;
index 57f3b87f88299414f9b4649f75d7c0d46107153f..8c6416a8c658bd89c08456cc287c3fb80f72409e 100644 (file)
@@ -72,22 +72,6 @@ InsetMathScript * InsetMathScript::asScriptInset()
 }
 
 
-bool InsetMathScript::idxFirst(Cursor & cur) const
-{
-       cur.idx() = 0;
-       cur.pos() = 0;
-       return true;
-}
-
-
-bool InsetMathScript::idxLast(Cursor & cur) const
-{
-       cur.idx() = 0;
-       cur.pos() = nuc().size();
-       return true;
-}
-
-
 MathData const & InsetMathScript::down() const
 {
        if (nargs() == 3)
index 0b96d03ce2e03bdc9307229d93136b35c5c0c934..c1589b1586f0ff32411327175644b0b5647e8f65 100644 (file)
@@ -49,10 +49,8 @@ public:
        bool idxForward(Cursor & cur) const;
        /// move cursor up or down
        bool idxUpDown(Cursor & cur, bool up) const;
-       /// Target pos when we enter the inset while moving forward
-       bool idxFirst(Cursor & cur) const;
-       /// Target pos when we enter the inset while moving backwards
-       bool idxLast(Cursor & cur) const;
+       /// The index of the cell entered while moving backward
+       size_type lastIdx() const { return 0; }
 
        /// write LaTeX and Lyx code
        void write(WriteStream & os) const;
index cdc5637282e0d817d49530defbdb5bb87b0e7dbb..ccbab52a80ef30ad14d2bd19222c2a5be6db0c75 100644 (file)
@@ -62,22 +62,6 @@ Inset * InsetMathSideset::clone() const
 }
 
 
-bool InsetMathSideset::idxFirst(Cursor & cur) const
-{
-       cur.idx() = 0;
-       cur.pos() = 0;
-       return true;
-}
-
-
-bool InsetMathSideset::idxLast(Cursor & cur) const
-{
-       cur.idx() = 0;
-       cur.pos() = nuc().size();
-       return true;
-}
-
-
 int InsetMathSideset::dybt(BufferView const & bv, int asc, int des, bool top) const
 {
        bool isCharBox = nuc().empty() ? false : isAlphaSymbol(nuc().back());
index b88548bdb5be4d52da9094a56630d027329b7f5a..b99e6308d9cd490b1c27578efae0b19d77e44fa6 100644 (file)
@@ -46,10 +46,8 @@ public:
        bool idxForward(Cursor & cur) const;
        /// move cursor up or down
        bool idxUpDown(Cursor & cur, bool up) const;
-       /// Target pos when we enter the inset while moving forward
-       bool idxFirst(Cursor & cur) const;
-       /// Target pos when we enter the inset while moving backwards
-       bool idxLast(Cursor & cur) const;
+       /// The index of the cell entered while moving backward
+       size_type lastIdx() const { return 0; }
 
        /// write LaTeX and Lyx code
        void write(WriteStream & os) const;
index d6ac81518231201cc2608ea2c681b63d82e1f0d0..2dc7a4975c5043230ace25d3a0a5ef8dcd1cb9d9 100644 (file)
@@ -30,6 +30,10 @@ public:
        ///
        void draw(PainterInfo & pi, int x, int y) const;
        ///
+       idx_type firstIdx() const { return 1; }
+       ///
+       idx_type lastIdx() const { return 1; }
+       ///
        void write(WriteStream & os) const;
        ///
        void normalize(NormalStream &) const;
index b8c5d14625dd81f097ac06196867f49c66b6efe7..4df7f59a5bbaa2db73ba7eee1bfd42bac64f8f73 100644 (file)
@@ -58,22 +58,6 @@ void InsetMathUnderset::draw(PainterInfo & pi, int x, int y) const
 }
 
 
-bool InsetMathUnderset::idxFirst(Cursor & cur) const
-{
-       cur.idx() = 1;
-       cur.pos() = 0;
-       return true;
-}
-
-
-bool InsetMathUnderset::idxLast(Cursor & cur) const
-{
-       cur.idx() = 1;
-       cur.pos() = cur.lastpos();
-       return true;
-}
-
-
 bool InsetMathUnderset::idxUpDown(Cursor & cur, bool up) const
 {
        idx_type target = up; // up ? 1 : 0, since upper cell has idx 1
index 239a576aebb06d6d4b909a4553dbe4119621e8b9..ff671adccba7c77a44a0cd4b87010d022fb07301 100644 (file)
@@ -28,9 +28,9 @@ public:
        ///
        void draw(PainterInfo & pi, int x, int y) const;
        ///
-       bool idxFirst(Cursor & cur) const;
+       idx_type firstIdx() const { return 1; }
        ///
-       bool idxLast(Cursor & cur) const;
+       idx_type lastIdx() const { return 1; }
        ///
        bool idxUpDown(Cursor & cur, bool up) const;
        ///