]> git.lyx.org Git - features.git/commitdiff
Fix bug #8242: undo fails for longest label width
authorJean-Marc Lasgouttes <lasgouttes@lyx.org>
Mon, 16 Jul 2012 21:39:24 +0000 (23:39 +0200)
committerJean-Marc Lasgouttes <lasgouttes@lyx.org>
Tue, 21 Aug 2012 10:08:27 +0000 (12:08 +0200)
In the existing code for setting layout of pragraph parameters,
Text::undoSpan is used to "guess" which paragraphs should be saved in Undo.
With this patch the approach is more precise: before every explicit change
to a paragraph, a Cursor::recordUndo call is inserted. This is much more robust than trying to guess.

In particular, we do not look at depth changes at all, since they are now
handled in updateBuffer since #8159 has been fixed.

src/Text.cpp
src/Text.h
src/Text2.cpp
status.20x

index 4aba18420744e16e07653e503c5a767731fd721a..93c7c234ff66a6fb13fb98c464a2294a6bc77f8e 100644 (file)
@@ -700,8 +700,7 @@ void Text::breakParagraph(Cursor & cur, bool inverse_logic)
                return;
        }
 
-       // a layout change may affect also the following paragraph
-       recUndo(cur, cur.pit(), undoSpan(cur.pit()) - 1);
+       cur.recordUndo();
 
        // Always break behind a space
        // It is better to erase the space (Dekel)
index 7b9ca3d05e623b87443e382fa40395ab7f5d1a2a..30a90f3ebc1f5b6c8321304c6c8eebd93edeb66d 100644 (file)
@@ -82,8 +82,8 @@ public:
        /// set layout over selection
        void setLayout(pit_type start, pit_type end,
                docstring const & layout);
-       /// Set given layout to current cursor position.
-       /// FIXME: replace Cursor with DocIterator.
+       /// Set given layout to current cursor position or selection.
+       /// Handles undo.
        void setLayout(Cursor & cur, docstring const & layout);
 
        /// what type of depth change to make
@@ -343,10 +343,6 @@ private:
        /// The InsetText owner shall have access to everything.
        friend class InsetText;
 
-       /// return past-the-last paragraph influenced by a layout
-       /// change on pit
-       pit_type undoSpan(pit_type pit);
-
        // fix the cursor `cur' after a characters has been deleted at `where'
        // position. Called by deleteEmptyParagraphMechanism
        static void fixCursorAfterDelete(CursorSlice & cur, CursorSlice const & where);
@@ -375,7 +371,7 @@ private:
        void readParagraph(Paragraph & par, Lexer & lex, ErrorList & errorList);
        /// Set Label Width string to all paragraphs of the same layout
     /// and depth in a sequence.
-       void setLabelWidthStringToSequence(pit_type const par_offset, docstring const & s);
+       void setLabelWidthStringToSequence(Cursor const & cur, docstring const & s);
 
        /// Owner Inset.
        InsetText * owner_;
index e26d448a7059046b8d9e9e0474b635145c4c3e30..cd918841c127708f7128bab32351bca8cee0eb2c 100644 (file)
@@ -183,25 +183,6 @@ void Text::setInsetFont(BufferView const & bv, pit_type pit,
 }
 
 
-// return past-the-last paragraph influenced by a layout change on pit
-pit_type Text::undoSpan(pit_type pit)
-{
-       pit_type const end = paragraphs().size();
-       pit_type nextpit = pit + 1;
-       if (nextpit == end)
-               return nextpit;
-       //because of parindents
-       if (!pars_[pit].getDepth())
-               return boost::next(nextpit);
-       //because of depth constrains
-       for (; nextpit != end; ++pit, ++nextpit) {
-               if (!pars_[pit].getDepth())
-                       break;
-       }
-       return nextpit;
-}
-
-
 void Text::setLayout(pit_type start, pit_type end,
                     docstring const & layout)
 {
@@ -227,8 +208,7 @@ void Text::setLayout(Cursor & cur, docstring const & layout)
 
        pit_type start = cur.selBegin().pit();
        pit_type end = cur.selEnd().pit() + 1;
-       pit_type undopit = undoSpan(end - 1);
-       recUndo(cur, start, undopit - 1);
+       cur.recordUndoSelection();
        setLayout(start, end, layout);
        cur.forceBufferUpdate();
 }
@@ -431,31 +411,31 @@ docstring Text::getStringToIndex(Cursor const & cur)
 }
 
 
-void Text::setLabelWidthStringToSequence(pit_type const par_offset,
+void Text::setLabelWidthStringToSequence(Cursor const & cur,
                docstring const & s)
 {
-       pit_type offset = par_offset;
+       Cursor c = cur;
        // Find first of same layout in sequence
-       while (!isFirstInSequence(offset)) {
-               offset = depthHook(offset, pars_[offset].getDepth());
+       while (!isFirstInSequence(c.pit())) {
+               c.pit() = depthHook(c.pit(), c.paragraph().getDepth());
        }
 
        // now apply label width string to every par
        // in sequence
-       pit_type const end = pars_.size();
-       depth_type const depth = pars_[offset].getDepth();
-       Layout const & layout = pars_[offset].layout();
-       for (pit_type pit = offset; pit != end; ++pit) {
-               while (pars_[pit].getDepth() > depth) {
-                       ++pit;
-                       if (pit == end)
+       depth_type const depth = c.paragraph().getDepth();
+       Layout const & layout = c.paragraph().layout();
+       for ( ; c.pit() <= c.lastpit() ; ++c.pit()) {
+               while (c.paragraph().getDepth() > depth) {
+                       ++c.pit();
+                       if (c.pit() > c.lastpit())
                                return;
                }
-               if (pars_[pit].getDepth() < depth)
+               if (c.paragraph().getDepth() < depth)
                        return;
-               if (pars_[pit].layout() != layout)
+               if (c.paragraph().layout() != layout)
                        return;
-               pars_[pit].setLabelWidthString(s);
+               c.recordUndo();
+               c.paragraph().setLabelWidthString(s);
        }
 }
 
@@ -463,26 +443,25 @@ void Text::setLabelWidthStringToSequence(pit_type const par_offset,
 void Text::setParagraphs(Cursor & cur, docstring arg, bool merge) 
 {
        LASSERT(cur.text(), /**/);
-       // make sure that the depth behind the selection are restored, too
-       pit_type undopit = undoSpan(cur.selEnd().pit());
-       recUndo(cur, cur.selBegin().pit(), undopit - 1);
 
        //FIXME UNICODE
        string const argument = to_utf8(arg);
        depth_type priordepth = -1;
        Layout priorlayout;
-       for (pit_type pit = cur.selBegin().pit(), end = cur.selEnd().pit();
-            pit <= end; ++pit) {
-               Paragraph & par = pars_[pit];
+       Cursor c(cur.bv());
+       c.setCursor(cur.selectionBegin());
+       for ( ; c <= cur.selectionEnd() ; ++c.pit()) {
+               Paragraph & par = c.paragraph();
                ParagraphParameters params = par.params();
                params.read(argument, merge);
                // Changes to label width string apply to all paragraphs
                // with same layout in a sequence.
                // Do this only once for a selected range of paragraphs
                // of the same layout and depth.
-               if (par.getDepth() != priordepth || par.layout() != priorlayout)
-                       setLabelWidthStringToSequence(pit, params.labelWidthString());
+               cur.recordUndo();
                par.params().apply(params, par.layout());
+               if (par.getDepth() != priordepth || par.layout() != priorlayout)
+                       setLabelWidthStringToSequence(c, params.labelWidthString());
                priordepth = par.getDepth();
                priorlayout = par.layout();
        }
@@ -495,23 +474,22 @@ void Text::setParagraphs(Cursor & cur, docstring arg, bool merge)
 void Text::setParagraphs(Cursor & cur, ParagraphParameters const & p) 
 {
        LASSERT(cur.text(), /**/);
-       // make sure that the depth behind the selection are restored, too
-       pit_type undopit = undoSpan(cur.selEnd().pit());
-       recUndo(cur, cur.selBegin().pit(), undopit - 1);
 
        depth_type priordepth = -1;
        Layout priorlayout;
-       for (pit_type pit = cur.selBegin().pit(), end = cur.selEnd().pit();
-            pit <= end; ++pit) {
-               Paragraph & par = pars_[pit];
+       Cursor c(cur.bv());
+       c.setCursor(cur.selectionBegin());
+       for ( ; c < cur.selectionEnd() ; ++c.pit()) {
+               Paragraph & par = c.paragraph();
                // Changes to label width string apply to all paragraphs
                // with same layout in a sequence.
                // Do this only once for a selected range of paragraphs
                // of the same layout and depth.
+               cur.recordUndo();
+               par.params().apply(p, par.layout());
                if (par.getDepth() != priordepth || par.layout() != priorlayout)
-                       setLabelWidthStringToSequence(pit,
+                       setLabelWidthStringToSequence(c,
                                par.params().labelWidthString());
-               par.params().apply(p, par.layout());
                priordepth = par.getDepth();
                priorlayout = par.layout();
        }
index 3b3c514d8a10962886dffac5462774dc06ceb1e3..d15a55ef1679870798542ee83170b8c58267fa89 100644 (file)
@@ -109,14 +109,17 @@ What's new
 - Fix various crashes when single document is edited in more windows
   (bug 8203).
 
-- Fix crash when using undo in a paragraph with layout Bibliography (bug 7111).
-
 - Fix crash when renaming a child buffer.
 
-- Replace current selection when pasting (bug 8027).
+- Fix crash when using undo in a paragraph with layout Bibliography (bug 7111).
 
 - Make sure that undo restores environment depth correctly (bug 8159).
 
+- Make sure that undo restores paragraph longest label width correctly
+  (bug 8242).
+
+- Replace current selection when pasting (bug 8027).
+
 - Fix enumitem module translation (bug #8201).
 
 - Set math display format when showing XHTML in View>Source.