]> git.lyx.org Git - features.git/blobdiff - src/Cursor.cpp
Fix bug #2213 (part 5): GuiChanges lacks "Previous Change" button.
[features.git] / src / Cursor.cpp
index 346062a470f8492e10c48c89c548c2f00d3699d2..afa8a9b30ffaa5ad36db6cccd198fe5405b51645 100644 (file)
@@ -426,6 +426,12 @@ void Cursor::resetAnchor()
 }
 
 
+void Cursor::setCursorToAnchor()
+{
+       if (selection())
+               setCursor(anchor_);
+}
+
 
 bool Cursor::posBackward()
 {
@@ -525,7 +531,8 @@ bool Cursor::posVisRight(bool skip_inset)
 
        bool moved = (new_cur.pos() != pos()
                                  || new_cur.pit() != pit()
-                                 || new_cur.boundary() != boundary());
+                                 || new_cur.boundary() != boundary()
+                                 || &new_cur.inset() != &inset());
        
        if (moved) {
                LYXERR(Debug::RTL, "moving to: " << new_cur.pos() 
@@ -643,7 +650,7 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
        // The cursor is painted *before* the character at pos(), or, if 'boundary'
        // is true, *after* the character at (pos() - 1). So we already have one
        // known position around the cursor:
-       pos_type known_pos = boundary() ? pos() - 1 : pos();
+       pos_type const known_pos = boundary() && pos() > 0 ? pos() - 1 : pos();
        
        // edge case: if we're at the end of the paragraph, things are a little 
        // different (because lastpos is a position which does not really "exist" 
@@ -652,8 +659,8 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
                if (par.isRTL(buf.params())) {
                        left_pos = -1;
                        right_pos = bidi.vis2log(row.pos());
-               }
-               else { // LTR paragraph
+               } else { 
+                       // LTR paragraph
                        right_pos = -1;
                        left_pos = bidi.vis2log(row.endpos() - 1);
                }
@@ -668,11 +675,10 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
        // For an RTL character, "before" means "to the right" and "after" means
        // "to the left"; and for LTR, it's the reverse. So, 'known_pos' is to the
        // right of the cursor if (RTL && boundary) or (!RTL && !boundary):
-       bool known_pos_on_right = (cur_is_RTL == boundary());
+       bool const known_pos_on_right = cur_is_RTL == boundary();
 
        // So we now know one of the positions surrounding the cursor. Let's 
-       // determine the other one:
-       
+       // determine the other one:     
        if (known_pos_on_right) {
                right_pos = known_pos;
                // *visual* position of 'left_pos':
@@ -686,9 +692,9 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
                if (bidi.inRange(v_left_pos) 
                                && bidi.vis2log(v_left_pos) + 1 == row.endpos() 
                                && row.endpos() < lastpos()
-                               && par.isSeparator(bidi.vis2log(v_left_pos))) {
+                               && par.isSeparator(bidi.vis2log(v_left_pos)))
                        --v_left_pos;
-               }
+
                // calculate the logical position of 'left_pos', if in row
                if (!bidi.inRange(v_left_pos))
                        left_pos = -1;
@@ -698,14 +704,14 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
                // separator", set 'right_pos' to the *next* position to the right.
                if (right_pos + 1 == row.endpos() && row.endpos() < lastpos() 
                                && par.isSeparator(right_pos)) {
-                       pos_type v_right_pos = bidi.log2vis(right_pos) + 1;
+                       pos_type const v_right_pos = bidi.log2vis(right_pos) + 1;
                        if (!bidi.inRange(v_right_pos))
                                right_pos = -1;
                        else
                                right_pos = bidi.vis2log(v_right_pos);
                }
-       } 
-       else { // known_pos is on the left
+       } else { 
+               // known_pos is on the left
                left_pos = known_pos;
                // *visual* position of 'right_pos'
                pos_type v_right_pos = bidi.log2vis(left_pos) + 1;
@@ -714,9 +720,9 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
                if (bidi.inRange(v_right_pos) 
                                && bidi.vis2log(v_right_pos) + 1 == row.endpos() 
                                && row.endpos() < lastpos()
-                               && par.isSeparator(bidi.vis2log(v_right_pos))) {
+                               && par.isSeparator(bidi.vis2log(v_right_pos)))
                        ++v_right_pos;
-               }
+
                // calculate the logical position of 'right_pos', if in row
                if (!bidi.inRange(v_right_pos)) 
                        right_pos = -1;
@@ -726,7 +732,7 @@ void Cursor::getSurroundingPos(pos_type & left_pos, pos_type & right_pos)
                // separator", set 'left_pos' to the *next* position to the left.
                if (left_pos + 1 == row.endpos() && row.endpos() < lastpos() 
                                && par.isSeparator(left_pos)) {
-                       pos_type v_left_pos = bidi.log2vis(left_pos) - 1;
+                       pos_type const v_left_pos = bidi.log2vis(left_pos) - 1;
                        if (!bidi.inRange(v_left_pos))
                                left_pos = -1;
                        else
@@ -833,32 +839,31 @@ void Cursor::posVisToRowExtremity(bool left)
                        // this non-separator-but-last-position-in-row is an inset, then
                        // we *do* want to stay to the left of it anyway: this is the 
                        // "boundary" which we simulate at insets.
+                       // Another exception is when row.endpos() is 0.
                        
-                       bool right_of_pos = false; // do we want to be to the right of pos?
-
+                       // do we want to be to the right of pos?
                        // as explained above, if at last pos in row, stay to the right
-                       if ((pos() == row.endpos() - 1) && !par.isInset(pos()))
-                               right_of_pos = true;
+                       bool const right_of_pos = row.endpos() > 0
+                               && pos() == row.endpos() - 1 && !par.isInset(pos());
 
                        // Now we know if we want to be to the left or to the right of pos,
                        // let's make sure we are where we want to be.
-                       bool new_pos_is_RTL = 
+                       bool const new_pos_is_RTL = 
                                par.getFontSettings(buf.params(), pos()).isVisibleRightToLeft();
 
-                       if (new_pos_is_RTL == !right_of_pos) {
+                       if (new_pos_is_RTL != right_of_pos) {
                                ++pos();
                                boundary(true);
                        }
-                       
                }
-       }
-       else { // move to rightmost position
+       } else { 
+               // move to rightmost position
                // if this is an LTR paragraph, and we're at the last row in the
                // paragraph, move to lastpos
                if (!par.isRTL(buf.params()) && row.endpos() == lastpos())
                        pos() = lastpos();
                else {
-                       pos() = bidi.vis2log(row.endpos() - 1);
+                       pos() = row.endpos() > 0 ? bidi.vis2log(row.endpos() - 1) : 0;
 
                        // Moving to the rightmost position in the row, the cursor should
                        // normally be placed to the *right* of the rightmost position.
@@ -883,16 +888,17 @@ void Cursor::posVisToRowExtremity(bool left)
                        // this non-separator-but-last-position-in-row is an inset, then
                        // we *do* want to stay to the right of it anyway: this is the 
                        // "boundary" which we simulate at insets.
+                       // Another exception is when row.endpos() is 0.
                        
-                       bool left_of_pos = false; // do we want to be to the left of pos?
-
-                       // as explained above, if at last pos in row, stay to the left
-                       if ((pos() == row.endpos() - 1) && !par.isInset(pos()))
-                               left_of_pos = true;
+                       // do we want to be to the left of pos?
+                       // as explained above, if at last pos in row, stay to the left,
+                       // unless the last position is the same as the first.
+                       bool const left_of_pos = row.endpos() > 0
+                               && pos() == row.endpos() - 1 && !par.isInset(pos());
 
                        // Now we know if we want to be to the left or to the right of pos,
                        // let's make sure we are where we want to be.
-                       bool new_pos_is_RTL = 
+                       bool const new_pos_is_RTL = 
                                par.getFontSettings(buf.params(), pos()).isVisibleRightToLeft();
 
                        if (new_pos_is_RTL == left_of_pos) {
@@ -1769,8 +1775,17 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
        else
                row = pm.pos2row(pos());
                
-       if (atFirstOrLastRow(up))
+       if (atFirstOrLastRow(up)) {
+               Cursor dummy = *this;
+               // 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.pos() = dummy.pos() == 0 ? dummy.lastpos() : 0;
+               dummy.pit() = dummy.pit() == 0 ? dummy.lastpit() : 0;
+               updateNeeded |= bv().checkDepm(dummy, *this);
                return false;
+       }
 
        // with and without selection are handled differently
        if (!selection()) {
@@ -1782,19 +1797,6 @@ bool Cursor::upDownInText(bool up, bool & updateNeeded)
                else
                        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)
-               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)
-                       operator=(dummy);
-               }
        } else {
                // if there is a selection, we stay out of any inset, and just jump to the right position:
                Cursor old = *this;
@@ -2210,6 +2212,10 @@ void Cursor::checkBufferStructure()
 {
        Buffer const * master = buffer()->masterBuffer();
        master->tocBackend().updateItem(*this);
+       if (master != buffer() && !master->hasGuiDelegate())
+               // In case the master has no gui associated with it, 
+               // the TocItem is not updated (part of bug 5699).
+               buffer()->tocBackend().updateItem(*this);
 }