]> git.lyx.org Git - lyx.git/blobdiff - src/Cursor.cpp
de.po
[lyx.git] / src / Cursor.cpp
index 3f5bff854cfabe9c5506ca6637658748f8168539..56a9dd872245c62f66f345c3679406f52f61f502 100644 (file)
@@ -121,19 +121,19 @@ DocIterator bruteFind(Cursor const & c, int x, int y)
 
 CursorData::CursorData()
        : DocIterator(), anchor_(), selection_(false), mark_(false),
-         word_selection_(false), current_font(inherit_font), autocorrect_(false)
+         word_selection_(false), autocorrect_(false), current_font(inherit_font)
 {}
 
 
 CursorData::CursorData(Buffer * buffer)
        : DocIterator(buffer), anchor_(), selection_(false), mark_(false),
-         word_selection_(false), current_font(inherit_font), autocorrect_(false)
+         word_selection_(false), autocorrect_(false), current_font(inherit_font)
 {}
 
 
 CursorData::CursorData(DocIterator const & dit)
        : DocIterator(dit), anchor_(), selection_(false), mark_(false),
-         word_selection_(false), current_font(inherit_font), autocorrect_(false)
+         word_selection_(false), autocorrect_(false), current_font(inherit_font)
 {}
 
 
@@ -457,34 +457,32 @@ void CursorData::checkNewWordPosition()
 {
        if (!lyxrc.spellcheck_continuously || new_word_.empty())
                return ;
-       if (!inTexted())
-               clearNewWordPosition();
-       else {
-               // forget the position of the current new word if
-               // 1) the paragraph changes or
-               // 2) the count of nested insets changes or
-               // 3) the cursor pos is out of paragraph bound
-               if (pit() != new_word_.pit() ||
-                       depth() != new_word_.depth() ||
-                       new_word_.pos() > new_word_.lastpos()) {
-                       clearNewWordPosition();
-               } else if (new_word_.fixIfBroken())
-                       // 4) or the remembered position was "broken"
+       // forget the position of the current new word if
+       // 1) or the remembered position was "broken"
+       // 2) or the count of nested insets changed
+       // 3) the top-level inset is not the same anymore
+       // 4) the cell index changed
+       // 5) or the paragraph changed
+       // 6) or the cursor pos is out of paragraph bound
+       if (new_word_.fixIfBroken()
+           || depth() != new_word_.depth()
+           || &inset() != &new_word_.inset()
+           || pit() != new_word_.pit()
+           || idx() != new_word_.idx()
+           || new_word_.pos() > new_word_.lastpos())
                        clearNewWordPosition();
-               else {
-                       FontSpan nw = locateWord(WHOLE_WORD);
-                       if (!nw.empty()) {
-                               FontSpan ow = new_word_.locateWord(WHOLE_WORD);
-                               if (nw.intersect(ow).empty())
-                                       clearNewWordPosition();
-                               else
-                                       LYXERR(Debug::DEBUG, "new word: "
-                                                  << " par: " << pit()
-                                                  << " pos: " << nw.first << ".." << nw.last);
-                       } else {
+       else {
+               FontSpan nw = locateWord(WHOLE_WORD);
+               if (!nw.empty()) {
+                       FontSpan ow = new_word_.locateWord(WHOLE_WORD);
+                       if (nw.intersect(ow).empty())
                                clearNewWordPosition();
-                       }
-               }
+                       else
+                               LYXERR(Debug::DEBUG, "new word: "
+                                          << " par: " << pit()
+                                          << " pos: " << nw.first << ".." << nw.last);
+               } else
+                       clearNewWordPosition();
        }
 }
 
@@ -498,6 +496,56 @@ void CursorData::clearSelection()
 }
 
 
+int CursorData::countInsetsInSelection(InsetCode const & inset_code)
+{
+       if (!selection_)
+               return 0;
+
+       DocIterator from, to;
+       from = selectionBegin();
+       to = selectionEnd();
+
+       int count = 0;
+
+       if (!from.nextInset())      //move to closest inset
+               from.forwardInset();
+
+       while (!from.empty() && from < to) {
+               Inset * inset = from.nextInset();
+               if (!inset)
+                       break;
+               if (inset->lyxCode() == inset_code)
+                       count ++;
+               from.forwardInset();
+       }
+       return count;
+}
+
+
+bool CursorData::insetInSelection(InsetCode const & inset_code)
+{
+       if (!selection_)
+               return false;
+
+       DocIterator from, to;
+       from = selectionBegin();
+       to = selectionEnd();
+
+       if (!from.nextInset())      //move to closest inset
+               from.forwardInset();
+
+       while (!from.empty() && from < to) {
+               Inset * inset = from.nextInset();
+               if (!inset)
+                       break;
+               if (inset->lyxCode() == inset_code)
+                       return true;
+               from.forwardInset();
+       }
+       return false;
+}
+
+
 bool CursorData::fixIfBroken()
 {
        bool const broken_cursor = DocIterator::fixIfBroken();
@@ -515,6 +563,7 @@ bool CursorData::fixIfBroken()
 void CursorData::sanitize()
 {
        DocIterator::sanitize();
+       new_word_.sanitize();
        if (selection())
                anchor_.sanitize();
        else
@@ -522,38 +571,18 @@ void CursorData::sanitize()
 }
 
 
-bool CursorData::isInside(Inset const * p) const
-{
-       for (size_t i = 0; i != depth(); ++i)
-               if (&operator[](i).inset() == p)
-                       return true;
-       return false;
-}
-
-
-void CursorData::leaveInset(Inset const & inset)
-{
-       for (size_t i = 0; i != depth(); ++i) {
-               if (&operator[](i).inset() == &inset) {
-                       resize(i);
-                       return;
-               }
-       }
-}
-
-
-bool CursorData::textUndo()
+bool CursorData::undoAction()
 {
-       if (!buffer()->undo().textUndo(*this))
+       if (!buffer()->undo().undoAction(*this))
                return false;
        sanitize();
        return true;
 }
 
 
-bool CursorData::textRedo()
+bool CursorData::redoAction()
 {
-       if (!buffer()->undo().textRedo(*this))
+       if (!buffer()->undo().redoAction(*this))
                return false;
        sanitize();
        return true;
@@ -872,6 +901,31 @@ void Cursor::pushBackward(Inset & p)
 }
 
 
+void Cursor::editInsertedInset()
+{
+       LASSERT(!empty(), return);
+       if (pos() == 0)
+               return;
+
+       InsetMath &p = prevMath();
+       if (!p.isActive())
+               return;
+
+       posBackward();
+       push(p);
+       p.idxFirst(*this);
+       // this could be a while() loop, but only one cell is not empty in
+       // cases we are interested in. The cell is not empty because we
+       // have inserted the selection in there.
+       if (!cell().empty()) {
+               // if it is not empty, move to the next one.
+               if (!inset().idxNext(*this))
+                       // If there is no next one, exit the inset.
+                       popForward();
+       }
+}
+
+
 bool Cursor::popBackward()
 {
        LASSERT(!empty(), return false);
@@ -1388,9 +1442,9 @@ bool Cursor::openable(MathAtom const & t) const
                return true;
 
        // we can't move into anything new during selection
-       if (depth() >= anchor_.depth())
+       if (depth() >= realAnchor().depth())
                return false;
-       if (t.nucleus() != &anchor_[depth()].inset())
+       if (t.nucleus() != &realAnchor()[depth()].inset())
                return false;
 
        return true;
@@ -1492,14 +1546,11 @@ void Cursor::niceInsert(MathAtom const & t)
        plainInsert(t);
        // If possible, enter the new inset and move the contents of the selection
        if (t->isActive()) {
-               posBackward();
-               // be careful here: don't use 'pushBackward(t)' as this we need to
-               // push the clone, not the original
-               pushBackward(*nextInset());
-               // We may not use niceInsert here (recursion)
+               idx_type const idx = prevMath().asNestInset()->firstIdx();
                MathData ar(buffer());
                asArray(safe, ar);
-               insert(ar);
+               prevMath().cell(idx).insert(0, ar);
+               editInsertedInset();
        } else if (t->asMacro() && !safe.empty()) {
                MathData ar(buffer());
                asArray(safe, ar);
@@ -1636,14 +1687,14 @@ bool Cursor::down()
 }
 
 
-void Cursor::handleNest(MathAtom const & a, int c)
+void Cursor::handleNest(MathAtom const & a)
 {
-       //lyxerr << "Cursor::handleNest: " << c << endl;
+       idx_type const idx = a.nucleus()->asNestInset()->firstIdx();
+       //lyxerr << "Cursor::handleNest: " << idx << endl;
        MathAtom t = a;
-       asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(c));
+       asArray(cap::grabAndEraseSelection(*this), t.nucleus()->cell(idx));
        insert(t);
-       posBackward();
-       pushBackward(*nextInset());
+       editInsertedInset();
 }
 
 
@@ -1673,7 +1724,7 @@ void Cursor::setTargetX()
 }
 
 
-bool Cursor::macroModeClose()
+bool Cursor::macroModeClose(bool cancel)
 {
        if (!inMacroMode())
                return false;
@@ -1685,14 +1736,15 @@ bool Cursor::macroModeClose()
        --pos();
        cell().erase(pos());
 
-       // do nothing if the macro name is empty
-       if (s == "\\")
-               return false;
-
        // trigger updates of macros, at least, if no full
        // updates take place anyway
        screenUpdateFlags(Update::Force);
 
+       // do nothing if the macro name is empty
+       if (s == "\\" || cancel) {
+               return false;
+       }
+
        docstring const name = s.substr(1);
        InsetMathNest * const in = inset().asInsetMath()->asNestInset();
        if (in && in->interpretString(*this, s))
@@ -1704,6 +1756,7 @@ bool Cursor::macroModeClose()
        // 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
@@ -1718,8 +1771,8 @@ bool Cursor::macroModeClose()
        }
 
        // 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);
@@ -2105,15 +2158,15 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
 
        // with and without selection are handled differently
        if (!selection()) {
-               int yo = bv().getPos(*this).y_;
+               int yo1 = bv().getPos(*this).y_;
                Cursor old = *this;
                // To next/previous row
                // FIXME: the y position is often guessed wrongly across styles and
                // insets, which leads to weird behaviour.
                if (up)
-                       tm.editXY(*this, xo, yo - textRow().ascent() - 1);
+                       tm.editXY(*this, xo, yo1 - textRow().ascent() - 1);
                else
-                       tm.editXY(*this, xo, yo + textRow().descent() + 1);
+                       tm.editXY(*this, xo, yo1 + textRow().descent() + 1);
                x_target_ = old.x_target_;
                clearSelection();
 
@@ -2141,10 +2194,10 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                                --next_row;
                        } else if (pit() > 0) {
                                --pit();
-                               TextMetrics & tm = bv_->textMetrics(text());
-                               if (!tm.contains(pit()))
-                                       tm.newParMetricsUp();
-                               ParagraphMetrics const & pmcur = tm.parMetrics(pit());
+                               TextMetrics & tm2 = bv_->textMetrics(text());
+                               if (!tm2.contains(pit()))
+                                       tm2.newParMetricsUp();
+                               ParagraphMetrics const & pmcur = tm2.parMetrics(pit());
                                next_row = pmcur.rows().size() - 1;
                        }
                } else {
@@ -2152,9 +2205,9 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                                ++next_row;
                        } else if (pit() + 1 < int(text()->paragraphs().size())) {
                                ++pit();
-                               TextMetrics & tm = bv_->textMetrics(text());
-                               if (!tm.contains(pit()))
-                                       tm.newParMetricsDown();
+                               TextMetrics & tm2 = bv_->textMetrics(text());
+                               if (!tm2.contains(pit()))
+                                       tm2.newParMetricsDown();
                                next_row = 0;
                        }
                }
@@ -2232,6 +2285,12 @@ void Cursor::screenUpdateFlags(Update::flags f) const
 }
 
 
+void Cursor::noScreenUpdate() const
+{
+       disp_.screenUpdate(Update::None);
+}
+
+
 void Cursor::forceBufferUpdate() const
 {
        disp_.forceBufferUpdate();
@@ -2250,12 +2309,6 @@ bool Cursor::needBufferUpdate() const
 }
 
 
-void Cursor::noScreenUpdate() const
-{
-       disp_.screenUpdate(Update::None);
-}
-
-
 Font Cursor::getFont() const
 {
        // The logic here should more or less match to the
@@ -2293,9 +2346,8 @@ Font Cursor::getFont() const
 
 void Cursor::sanitize()
 {
-       setBuffer(buffer());
+       setBuffer(&bv_->buffer());
        CursorData::sanitize();
-       new_word_.sanitize();
 }