]> git.lyx.org Git - features.git/commitdiff
* src/text.C: implement rejectChange() as the inverse of acceptChange()
authorMichael Schmitt <michael.schmitt@teststep.org>
Tue, 23 Jan 2007 13:25:50 +0000 (13:25 +0000)
committerMichael Schmitt <michael.schmitt@teststep.org>
Tue, 23 Jan 2007 13:25:50 +0000 (13:25 +0000)
(requires some further testing)

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@16825 a592a061-630c-0410-9148-cb99ea01b6c8

src/text.C

index 69b16de8648167b4eec2ccec136c69acf66842c1..fef9e5035d58cbe9e366f8d8a076832889541617 100644 (file)
@@ -934,42 +934,88 @@ void LyXText::acceptChange(LCursor & cur)
 
 void LyXText::rejectChange(LCursor & cur)
 {
-       // FIXME: change tracking (MG)
-
        BOOST_ASSERT(this == cur.text());
 
-       if (!cur.selection() && cur.lastpos() != 0)
+       if (!cur.selection())
                return;
 
-       // FIXME: we must handle start = end = 0
+       recordUndoSelection(cur, Undo::ATOMIC);
 
-       recordUndoSelection(cur, Undo::INSERT);
+       DocIterator beg = cur.selectionBegin();
+       DocIterator end = cur.selectionEnd();
+
+       // first, accept changes within each individual paragraph (do not consider end-of-par)
+       
+       for (pit_type pit = beg.pit(); pit <= end.pit(); ++pit) {
+               // ignore empty paragraphs; otherwise, an assertion will fail for acceptChanges(0, 0) 
+               if (pars_[pit].size() == 0)
+                       continue;
 
-       DocIterator it = cur.selectionBegin();
-       DocIterator et = cur.selectionEnd();
-       pit_type pit = it.pit();
-       for (; pit <= et.pit(); ++pit) {
-               pos_type left  = (pit == it.pit() ? it.pos() : 0);
-               pos_type right = (pit == et.pit() ? et.pos() : pars_[pit].size());
+               // do not consider first paragraph if the cursor starts at pos size()
+               if (pit == beg.pit() && beg.pos() == pars_[pit].size())
+                       continue;
 
-               // handle imaginary end-of-par character first
-               if (right == pars_[pit].size() && !pars_[pit].isUnchanged(right)) {
-                       if (pars_[pit].isDeleted(right)) {
-                               pars_[pit].setChange(right, Change(Change::UNCHANGED));
-                       } else {
-                               // if (pit + 1 < et.pit()) {
-                               //      setCursorIntern(cur, pit + 1, 0);
-                               //      backspacePos0(cur);
-                               // }
+               // do not consider last paragraph if the cursor ends at pos 0
+               if (pit == end.pit() && end.pos() == 0) 
+                       break; // last iteration anyway
+
+               pos_type left  = (pit == beg.pit() ? beg.pos() : 0);
+               pos_type right = (pit == end.pit() ? end.pos() : pars_[pit].size());
+               pars_[pit].rejectChanges(left, right);
+       }
+       
+       // next, accept imaginary end-of-par characters
+       // iterate from last to first paragraph such that we don't have to care for a changing 'end' 
+       pos_type endpit = end.pit();    
+       for (pit_type pit = endpit; pit >= beg.pit(); --pit) {
+               pos_type pos = pars_[pit].size();
+
+               // last paragraph of the selection requires special handling
+               if (pit == end.pit()) {
+                       // skip if the selection ends before the end-of-par
+                       if (end.pos() < pos)
+                               continue;
+
+                       // skip if the selection ends with the end-of-par and this is not the
+                       // last paragraph of the document
+                       // note: the user must be able to accept the end-of-par of the last par!
+                       if (end.pos() == pos && pit != pars_.size() - 1)
+                               continue;
+               }
+
+
+               if (!pars_[pit].isUnchanged(pos)) {
+                       if (pars_[pit].isDeleted(pos)) {
+                               pars_[pit].setChange(pos, Change(Change::UNCHANGED));
+                       } else { // isInserted
+                               if (pit == pars_.size()) {
+                                       // we cannot remove a par break at the end of the last paragraph
+                                       // instead, we mark it unchanged
+                                       pars_[pit].setChange(pos, Change(Change::UNCHANGED));
+                               } else {
+                                       mergeParagraph(cur.buffer().params(), pars_, pit);
+                                       endpit--;
+                               }
                        }
                }
-               
-               pars_[pit].rejectChanges(left, right);
        }
+
+       // finally, invoke the DEPM
+       // FIXME: the following code will be changed in the near future
+       setCursorIntern(cur, endpit, 0);
+       for (pit_type pit = endpit - 1; pit >= beg.pit(); --pit) {
+               bool dummy;
+               LCursor old = cur;
+               setCursorIntern(cur, pit, 0);
+               deleteEmptyParagraphMechanism(cur, old, dummy);
+       }
+
        finishUndo();
        cur.clearSelection();
-       setCursorIntern(cur, it.pit(), it.pos());
+       setCursorIntern(cur, beg.pit(), beg.pos());
        cur.updateFlags(Update::Force);
+       updateLabels(cur.buffer());
 }