]> git.lyx.org Git - lyx.git/blobdiff - src/Cursor.cpp
* GuiDocument.cpp:
[lyx.git] / src / Cursor.cpp
index 4f915d653d76f0a177415de36e181f20a66fdce2..4785ce32643df208e1bdaa22dc8cd9113faf7e68 100644 (file)
@@ -321,6 +321,15 @@ void Cursor::dispatch(FuncRequest const & cmd0)
        // object will be used again.
        if (!disp_.dispatched()) {
                LYXERR(Debug::DEBUG, "RESTORING OLD CURSOR!");
+               // We might have invalidated the cursor when removing an empty
+               // paragraph while the cursor could not be moved out the inset
+               // while we initially thought we could. This might happen when
+               // a multiline inset becomes an inline inset when the second 
+               // paragraph is removed.
+               if (safe.pit() > safe.lastpit()) {
+                       safe.pit() = safe.lastpit();
+                       safe.pos() = safe.lastpos();
+               }
                operator=(safe);
                disp_.update(Update::None);
                disp_.dispatched(false);
@@ -396,7 +405,10 @@ int Cursor::currentMode()
        LASSERT(!empty(), /**/);
        for (int i = depth() - 1; i >= 0; --i) {
                int res = operator[](i).inset().currentMode();
-               if (res != Inset::UNDECIDED_MODE)
+               bool locked_mode = operator[](i).inset().lockedMode();
+               // Also return UNDECIDED_MODE when the mode is locked,
+               // as in this case it is treated the same as TEXT_MODE
+               if (res != Inset::UNDECIDED_MODE || locked_mode)
                        return res;
        }
        return Inset::TEXT_MODE;
@@ -426,6 +438,12 @@ void Cursor::resetAnchor()
 }
 
 
+void Cursor::setCursorToAnchor()
+{
+       if (selection())
+               setCursor(anchor_);
+}
+
 
 bool Cursor::posBackward()
 {
@@ -908,6 +926,8 @@ void Cursor::posVisToRowExtremity(bool left)
 
 CursorSlice Cursor::anchor() const
 {
+       if (!selection())
+               return top();
        LASSERT(anchor_.depth() >= depth(), /**/);
        CursorSlice normal = anchor_[depth() - 1];
        if (depth() < anchor_.depth() && top() <= normal) {
@@ -1769,8 +1789,34 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
        else
                row = pm.pos2row(pos());
                
-       if (atFirstOrLastRow(up))
+       if (atFirstOrLastRow(up)) {
+               // Is there a place for the cursor to go ? If yes, we
+               // can execute the DEPM, otherwise we should keep the
+               // paragraph to host the cursor.
+               Cursor dummy = *this;
+               bool valid_destination = false;
+               for(; dummy.depth(); dummy.pop())
+                       if (!dummy.atFirstOrLastRow(up)) {
+                               valid_destination = true;
+                               break;
+                       }
+
+               // will a next dispatch follow and if there is a new 
+               // dispatch will it move the cursor out ?
+               if (depth() > 1 && valid_destination) {
+                       // The cursor hasn't changed yet. This happens when
+                       // you e.g. move out of an inset. And to give the 
+                       // DEPM the possibility of doing something we must
+                       // provide it with two different cursors. (Lgb, vfr)
+                       dummy = *this;
+                       dummy.pos() = dummy.pos() == 0 ? dummy.lastpos() : 0;
+                       dummy.pit() = dummy.pit() == 0 ? dummy.lastpit() : 0;
+
+                       updateNeeded |= bv().checkDepm(dummy, *this);
+                       updateTextTargetOffset();
+               }
                return false;
+       }
 
        // with and without selection are handled differently
        if (!selection()) {
@@ -1783,16 +1829,16 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                        tm.editXY(*this, xo, yo + textRow().descent() + 1);
                clearSelection();
                
-               // This happens when you move out of an inset.
-               // And to give the DEPM the possibility of doing
-               // something we must provide it with two different
-               // cursors. (Lgb)
+               // This happens when you move out of an inset.  
+               // And to give the DEPM the possibility of doing  
+               // something we must provide it with two different  
+               // cursors. (Lgb)  
                Cursor dummy = *this;
                if (dummy == old)
                        ++dummy.pos();
                if (bv().checkDepm(dummy, old)) {
                        updateNeeded = true;
-                       // Make sure that cur gets back whatever happened to dummy(Lgb)
+                       // Make sure that cur gets back whatever happened to dummy(Lgb) 
                        operator=(dummy);
                }
        } else {
@@ -2047,7 +2093,7 @@ bool notifyCursorLeavesOrEnters(Cursor const & old, Cursor & cur)
            && !cur.buffer()->isClean()
            && cur.inTexted() && old.inTexted()
            && cur.pit() != old.pit()) {
-               old.paragraph().updateWords(old.top());
+               old.paragraph().updateWords();
        }
 
        // notify everything on top of the common part in old cursor,