On Wed, Mar 15, 2006 at 04:52:59PM +0100, Jean-Marc Lasgouttes wrote:
> >>>>> "Martin" == Martin Vermeer <[EMAIL PROTECTED]> writes:
> 
> Martin> This is the patch posted on bugzilla (880) to allow
> Martin> backspacing over a paragraph break inserted under change
> Martin> tracking.
> 
> Martin> It works, but Jürgen reported a cursor positioning issue, for
> Martin> which I didn't see any obvious reason or fix.
> 
> Martin> Can this go into 1.5?
> 
> I think you have some freedom about what goes in 1.5. 

OK, here is a patch fixing several small interrelated CT issues (one an
assert, i.e., not so small) and documentation improvements. This goes in
soon unless someone spots a problem.

- Martin

(BTW tip: alias svndiff='svn diff --diff-cmd /usr/bin/diff -x -up' 
in .bashrc)

Index: ChangeLog
===================================================================
--- ChangeLog   (revision 13383)
+++ ChangeLog   (working copy)
@@ -1,3 +1,13 @@
+2006-03-15  Martin Vermeer  <[EMAIL PROTECTED]>
+
+       * CutAndPaste.C (pasteSelectionHelper): comments
+       * paragraph_funcs.C (mergeParagraph): fix Juergen's cut&paste bug
+       * changes.h: comments
+       * paragraph.C (stripLeadingSpaces): remove unnecessary setChange
+       * text.C (backspace): allow deletion of inserted para break
+       Change tracking -related bug fixes (reported by Juergen) and 
+       some documentation work
+
 2006-03-15  Jean-Marc Lasgouttes  <[EMAIL PROTECTED]>
 
        * MenuBackend.C (expand): make sure the menu is empty before
Index: CutAndPaste.C
===================================================================
--- CutAndPaste.C       (revision 13383)
+++ CutAndPaste.C       (working copy)
@@ -234,7 +234,8 @@ pasteSelectionHelper(Buffer const & buff
        pit = last_paste;
        pos = pars[last_paste].size();
 
-       // Maybe some pasting.
+       // Join (conditionally) last pasted paragraph with next one, i.e.,
+       // the tail of the spliced document paragraph
        if (!empty && last_paste + 1 != pit_type(pars.size())) {
                if (pars[last_paste + 1].hasSameLayout(pars[last_paste])) {
                        mergeParagraph(buffer.params(), pars, last_paste);
Index: paragraph_funcs.C
===================================================================
--- paragraph_funcs.C   (revision 13383)
+++ paragraph_funcs.C   (working copy)
@@ -236,6 +236,19 @@ void mergeParagraph(BufferParams const &
        pos_type pos_end = next.size() - 1;
        pos_type pos_insert = par.size();
 
+       // What happens is the following. Later on, moveItem() will copy
+       // over characters from the next paragraph to be inserted into this
+       // position. Now, if the first char to be so copied is "red" (i.e.,
+       // marked deleted) and the paragraph break is marked "blue",
+       // insertChar will trigger (eventually, through record(), and see
+       // del() and erase() in changes.C) a "hard" character deletion.
+       // Which doesn't make sense of course at this pos, but the effect is
+       // to shorten the change range to which this para break belongs, by
+       // one. It will (should) remain "orphaned", having no CT info to it,
+       // and check() in changes.C will assert. Setting the para break
+       // forcibly to "black" prevents this scenario. -- MV 13.3.2006
+       par.setChange(par.size(), Change::UNCHANGED);
+
        Change::Type cr = next.lookupChange(next.size());
        // ok, now copy the paragraph
        for (pos_type i = 0, j = 0; i <= pos_end; ++i) {
Index: changes.h
===================================================================
--- changes.h   (revision 13383)
+++ changes.h   (working copy)
@@ -84,7 +84,8 @@ public:
        /// return true if there is a deleted or unchanged range contained
        bool isChangeEdited(lyx::pos_type start, lyx::pos_type end) const;
 
-       /// remove the given entry
+       /// remove the given entry. This implies that a character was
+       /// deleted at pos, and will adjust all range bounds past it
        void erase(lyx::pos_type pos);
 
        /// output latex to mark a transition between two changetypes
@@ -134,22 +135,23 @@ private:
 
        typedef std::vector<ChangeRange> ChangeTable;
 
-       /// our table of changes
+       /// our table of changes, every row a range and change descriptor
        ChangeTable table_;
 
        /// change type for an empty paragraph
        Change::Type empty_type_;
 
-       /// handle a delete
+       /// handle a delete, either logical or physical (see erase)
        void del(Change change, ChangeTable::size_type pos);
 
-       /// handle an add
+       /// handle an add, adjusting range bounds past it
        void add(Change change, ChangeTable::size_type pos);
 
-       /// merge neighbouring ranges
+       /// merge neighbouring ranges, assuming that they are abutting
+       /// (as done by set())
        void merge();
 
-       /// consistency check
+       /// consistency check, needed before merge()
        void check() const;
 
 };
Index: paragraph.C
===================================================================
--- paragraph.C (revision 13383)
+++ paragraph.C (working copy)
@@ -564,8 +564,6 @@ int Paragraph::stripLeadingSpaces()
 
        int i = 0;
        while (!empty() && (isNewline(0) || isLineSeparator(0))) {
-               // Set Change::Type to Change::INSERTED to quietly remove it
-               setChange(0, Change::INSERTED);
                erase(0);
                ++i;
        }
Index: text.C
===================================================================
--- text.C      (revision 13383)
+++ text.C      (working copy)
@@ -1681,9 +1681,12 @@ bool LyXText::backspace(LCursor & cur)
                        // Previous paragraph, mark "carriage return" as
                        // deleted:
                        Paragraph & par = pars_[cur.pit() - 1];
-                       par.setChange(par.size(), Change::DELETED);
-                       setCursorIntern(cur, cur.pit() - 1, par.size());
-                       return false;
+                       // Take care of a just inserted para break:
+                       if (par.lookupChange(par.size()) != Change::INSERTED) {
+                               par.setChange(par.size(), Change::DELETED);
+                               setCursorIntern(cur, cur.pit() - 1, par.size());
+                               return false;
+                       }
                }
 
                needsUpdate = backspacePos0(cur);

Attachment: pgpV8PAZE67wt.pgp
Description: PGP signature

Reply via email to