On Wed, Mar 12, 2003 at 11:35:16AM +0100, Alfredo Braunstein wrote:

> > I'm making a minimal kill-depm right now.

Here it is (I'm still building it, but more testers would be great !)

john


Index: BufferView.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/BufferView.C,v
retrieving revision 1.125
diff -u -p -r1.125 BufferView.C
--- BufferView.C        12 Mar 2003 05:46:32 -0000      1.125
+++ BufferView.C        12 Mar 2003 10:58:46 -0000
@@ -334,135 +334,50 @@ bool BufferView::insertLyXFile(string co
 
 bool BufferView::removeAutoInsets()
 {
-       // keep track of which pos and par the cursor was on
-       Paragraph * cursor_par = text->cursor.par();
-       Paragraph * cursor_par_prev = cursor_par ? cursor_par->previous() : 0;
-       Paragraph * cursor_par_next = cursor_par ? cursor_par->next() : 0;
-       pos_type cursor_pos = text->cursor.pos();
-
        bool found = false;
 
-       // Trap the deletion of the paragraph the cursor is in.
-       // Iterate until we find a paragraph that won't be immediately deleted.
-       // In reality this should mean we only execute the body of the while
-       // loop once at most.  However for safety we iterate rather than just
-       // make this an if () conditional.
-       while ((cursor_par_prev || cursor_par_next)
-              && text->setCursor(this,
-                                 cursor_par_prev ? cursor_par_prev : cursor_par_next,
-                                 0)) {
-               // We just removed cursor_par so have to fix the "cursor"
-               if (cursor_par_prev) {
-                       // '.' = cursor_par
-                       //  a -> a.
-                       // .
-                       cursor_par = cursor_par_prev;
-                       cursor_pos = cursor_par->size();
-               } else {
-                       // .  -> .a
-                       //  a
-                       cursor_par = cursor_par_next;
-                       cursor_pos = 0;
-               }
-               cursor_par_prev = cursor_par->previous();
-               cursor_par_next = cursor_par->next();
-       }
-
        // Iterate through the paragraphs removing autoDelete insets as we go.
-       // If the paragraph ends up empty after all the autoDelete insets are
-       // removed that paragraph will be removed by the next setCursor() call.
        ParIterator it = buffer()->par_iterator_begin();
        ParIterator end = buffer()->par_iterator_end();
        for (; it != end; ++it) {
                Paragraph * par = *it;
-               Paragraph * par_prev = par ? par->previous() : 0;
-               bool removed = false;
-
-               if (text->setCursor(this, par, 0)
-                   && cursor_par == par_prev) {
-                       // The previous setCursor line was deleted and that
-                       // was the cursor_par line.  This can only happen if an
-                       // error box was the sole item on cursor_par.
-                       // It is possible for cursor_par_prev to be stray if
-                       // the line it pointed to only had a error box on it
-                       // so we have to set it to a known correct value.
-                       // This is often the same value it already had.
-                       cursor_par_prev = par->previous();
-                       if (cursor_par_prev) {
-                               // '|' = par, '.' = cursor_par, 'E' = error box
-                               // First step below may occur before while{}
-                               //  a    |a      a     a     a.
-                               //  E -> .E -> |.E -> .  -> |b
-                               // .      b      b    |b
-                               //  b
-                               cursor_par = cursor_par_prev;
-                               cursor_pos = cursor_par_prev->size();
-                               cursor_par_prev = cursor_par->previous();
-                               // cursor_par_next remains the same
-                       } else if (cursor_par_next) {
-                               // First step below may occur before while{}
-                               // .
-                               //  E -> |.E -> |.  -> . -> .|a
-                               //  a      a      a    |a
-                               cursor_par = cursor_par_next;
-                               cursor_pos = 0;
-                               // cursor_par_prev remains unset
-                               cursor_par_next = cursor_par->next();
-                       } else {
-                               // I can't find a way to trigger this
-                               // so it should be unreachable code
-                               // unless the buffer is corrupted.
-                               lyxerr << "BufferView::removeAutoInsets() is bad\n";
-                       }
-               }
 
                InsetList::iterator pit = par->insetlist.begin();
                InsetList::iterator pend = par->insetlist.end();
 
+               bool removed = false;
+
                while (pit != pend) {
-                       if (pit.getInset()->autoDelete()) {
-                               removed = true;
-                               pos_type const pos = pit.getPos();
-
-                               par->erase(pos);
-                               // We just invalidated par's inset iterators so
-                               // we get the next valid iterator position
-                               pit = par->insetlist.insetIterator(pos);
-                               // and ensure we have a valid end iterator.
-                               pend = par->insetlist.end();
-
-                               if (cursor_par == par) {
-                                       // update the saved cursor position
-                                       if (cursor_pos > pos)
-                                               --cursor_pos;
-                               }
-                       } else {
+                       if (!pit.getInset()->autoDelete()) {
                                ++pit;
+                               continue;
                        }
+
+                       pos_type const pos = pit.getPos();
+
+                       par->erase(pos);
+                       removed = true;
+                       found = true;
+
+                       // We just invalidated par's inset iterators so
+                       // we get the next valid iterator position
+                       // FIXME: erase should return the next iterator like STL
+                       pit = par->insetlist.insetIterator(pos);
+
+                       // and ensure we have a valid end iterator.
+                       pend = par->insetlist.end();
+
+                       ++pit;
                }
+
                if (removed) {
-                       found = true;
+                       // don't leave cursor in an impossible position
+                       if (par == text->cursor.par())
+                               text->cursor.pos(0);
+
                        text->redoParagraph(this);
                }
        }
-
-       // It is possible that the last line is empty if it was cursor_par
-       // and/or only had an error inset on it.  So we set the cursor to the
-       // start of the doc to force its removal and ensure a valid saved cursor
-       if (text->setCursor(this, text->ownerParagraph(), 0)
-           && 0 == cursor_par_next) {
-               cursor_par = cursor_par_prev;
-               cursor_pos = cursor_par->size();
-       } else if (cursor_pos > cursor_par->size()) {
-               // Some C-Enter lines were removed by the setCursor call which
-               // then invalidated cursor_pos. It could still be "wrong" because
-               // the cursor may appear to have jumped but since we collapsed
-               // some C-Enter lines this should be a reasonable compromise.
-               cursor_pos = cursor_par->size();
-       }
-
-       // restore the original cursor in its corrected location.
-       text->setCursorIntern(this, cursor_par, cursor_pos);
 
        return found;
 }
Index: lyxtext.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/lyxtext.h,v
retrieving revision 1.139
diff -u -p -r1.139 lyxtext.h
--- lyxtext.h   10 Mar 2003 00:05:05 -0000      1.139
+++ lyxtext.h   12 Mar 2003 10:58:47 -0000
@@ -306,7 +306,7 @@ public:
        ///
        void selectSelectedWord(BufferView *);
        /// returns true if par was empty and was removed
-       bool setCursor(BufferView *, Paragraph * par,
+       void setCursor(BufferView *, Paragraph * par,
                       lyx::pos_type pos,
                       bool setfont = true,
                       bool boundary = false) const;
@@ -536,14 +536,13 @@ private:
        void setHeightOfRow(BufferView *, Row * row_ptr) const;
 
        // fix the cursor `cur' after a characters has been deleted at `where'
-       // position. Called by deleteEmptyParagraphMechanism
+       // position. Called by deleteExtraSpaces
        void fixCursorAfterDelete(BufferView * bv,
                                  LyXCursor & cur,
                                  LyXCursor const & where) const;
 
-       /// delete double space (false) or empty paragraphs (true) around old_cursor
-       bool deleteEmptyParagraphMechanism(BufferView *,
-                                          LyXCursor const & old_cursor) const;
+       /// delete double spaces
+       void deleteExtraSpaces(BufferView *, LyXCursor const & old_cursor) const;
 
 public:
        /** Updates all counters starting BEHIND the row. Changed paragraphs
Index: paragraph.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph.C,v
retrieving revision 1.249
diff -u -p -r1.249 paragraph.C
--- paragraph.C 12 Mar 2003 06:53:49 -0000      1.249
+++ paragraph.C 12 Mar 2003 10:58:50 -0000
@@ -24,6 +24,7 @@
 #include "ParameterStruct.h"
 #include "gettext.h"
 #include "changes.h"
+#include "paragraph_funcs.h"
 
 #include "insets/insetbibitem.h"
 #include "insets/insetoptarg.h"
@@ -146,6 +147,9 @@ void Paragraph::write(Buffer const * buf
                          BufferParams const & bparams,
                          depth_type & dth) const
 {
+       if (ignorePar(*this))
+               return;
+
        // The beginning or end of a deeper (i.e. nested) area?
        if (dth != params().depth()) {
                if (params().depth() > dth) {
Index: paragraph_funcs.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph_funcs.C,v
retrieving revision 1.18
diff -u -p -r1.18 paragraph_funcs.C
--- paragraph_funcs.C   10 Mar 2003 17:49:24 -0000      1.18
+++ paragraph_funcs.C   12 Mar 2003 10:58:53 -0000
@@ -714,3 +714,12 @@ void latexParagraphs(Buffer const * buf,
                texrow.newline();
        }
 }
+
+
+bool ignorePar(Paragraph const & par)
+{
+       if (!par.empty())
+               return false;
+
+       return !par.layout()->free_spacing && !par.isFreeSpacing();
+}
Index: paragraph_funcs.h
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/paragraph_funcs.h,v
retrieving revision 1.13
diff -u -p -r1.13 paragraph_funcs.h
--- paragraph_funcs.h   10 Mar 2003 17:49:24 -0000      1.13
+++ paragraph_funcs.h   12 Mar 2003 10:58:53 -0000
@@ -86,4 +86,7 @@ void latexParagraphs(Buffer const * buf,
                     TexRow & texrow,
                     bool moving_arg = false);
 
+/// Return true if this paragraph should not be saved/exported
+bool ignorePar(Paragraph const & par);
+
 #endif // PARAGRAPH_FUNCS_H
Index: text.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text.C,v
retrieving revision 1.307
diff -u -p -r1.307 text.C
--- text.C      11 Mar 2003 15:01:27 -0000      1.307
+++ text.C      12 Mar 2003 10:58:59 -0000
@@ -178,30 +178,6 @@ unsigned char LyXText::transformChar(uns
        }
 }
 
-// This is the comments that some of the warnings below refers to.
-// There are some issues in this file and I don't think they are
-// really related to the FIX_DOUBLE_SPACE patch. I'd rather think that
-// this is a problem that has been here almost from day one and that a
-// larger userbase with differenct access patters triggers the bad
-// behaviour. (segfaults.) What I think happen is: In several places
-// we store the paragraph in the current cursor and then moves the
-// cursor. This movement of the cursor will delete paragraph at the
-// old position if it is now empty. This will make the temporary
-// pointer to the old cursor paragraph invalid and dangerous to use.
-// And is some cases this will trigger a segfault. I have marked some
-// of the cases where this happens with a warning, but I am sure there
-// are others in this file and in text2.C. There is also a note in
-// Delete() that you should read. In Delete I store the paragraph->id
-// instead of a pointer to the paragraph. I am pretty sure this faulty
-// use of temporary pointers to paragraphs that might have gotten
-// invalidated (through a cursor movement) before they are used, are
-// the cause of the strange crashes we get reported often.
-//
-// It is very tiresom to change this code, especially when it is as
-// hard to read as it is. Help to fix all the cases where this is done
-// would be greately appreciated.
-//
-// Lgb
 
 int LyXText::singleWidth(BufferView * bview, Paragraph * par,
                         pos_type pos) const
@@ -2390,26 +2366,13 @@ void LyXText::Delete(BufferView * bview)
        // just move to the right
        cursorRight(bview);
 
-       // CHECK Look at the comment here.
-       // This check is not very good...
-       // The cursorRightIntern calls DeleteEmptyParagrapgMechanism
-       // and that can very well delete the par or par->previous in
-       // old_cursor. Will a solution where we compare paragraph id's
-       //work better?
-       if ((cursor.par()->previous() ? cursor.par()->previous()->id() : -1)
-           == old_cur_par_prev_id
-           && cursor.par()->id() != old_cur_par_id) {
-               // delete-empty-paragraph-mechanism has done it
-               return;
-       }
-
        // if you had success make a backspace
        if (old_cursor.par() != cursor.par() || old_cursor.pos() != cursor.pos()) {
                LyXCursor tmpcursor = cursor;
                // to make sure undo gets the right cursor position
                cursor = old_cursor;
                setUndo(bview, Undo::DELETE,
-                       cursor.par(), cursor.par()->next());
+                       cursor.par(), cursor.par()->next());
                cursor = tmpcursor;
                backspace(bview);
        }
@@ -2432,41 +2395,6 @@ void LyXText::backspace(BufferView * bvi
                if (cursor.par()->isChangeEdited(0, cursor.par()->size()))
                        return;
 
-               // we may paste some paragraphs
-
-               // is it an empty paragraph?
-
-               if ((lastpos == 0
-                    || (lastpos == 1 && cursor.par()->isSeparator(0)))) {
-                       // This is an empty paragraph and we delete it just by moving 
the cursor one step
-                       // left and let the DeleteEmptyParagraphMechanism handle the 
actual deletion
-                       // of the paragraph.
-
-                       if (cursor.par()->previous()) {
-                               Paragraph * tmppar = cursor.par()->previous();
-                               if (cursor.par()->layout() == tmppar->layout()
-                                   && cursor.par()->getAlign() == tmppar->getAlign()) 
{
-                                       // Inherit bottom DTD from the paragraph below.
-                                       // (the one we are deleting)
-                                       
tmppar->params().lineBottom(cursor.par()->params().lineBottom());
-                                       
tmppar->params().spaceBottom(cursor.par()->params().spaceBottom());
-                                       
tmppar->params().pagebreakBottom(cursor.par()->params().pagebreakBottom());
-                               }
-
-                               cursorLeft(bview);
-
-                               // the layout things can change the height of a row !
-                               int const tmpheight = cursor.row()->height();
-                               setHeightOfRow(bview, cursor.row());
-                               if (cursor.row()->height() != tmpheight) {
-                                       refresh_y = cursor.y() - 
cursor.row()->baseline();
-                                       refresh_row = cursor.row();
-                                       status(bview, LyXText::NEED_MORE_REFRESH);
-                               }
-                               return;
-                       }
-               }
-
                if (cursor.par()->previous()) {
                        setUndo(bview, Undo::DELETE,
                                cursor.par()->previous(), cursor.par()->next());
@@ -2475,12 +2403,8 @@ void LyXText::backspace(BufferView * bvi
                Paragraph * tmppar = cursor.par();
                Row * tmprow = cursor.row();
 
-               // We used to do cursorLeftIntern() here, but it is
-               // not a good idea since it triggers the auto-delete
-               // mechanism. So we do a cursorLeftIntern()-lite,
-               // without the dreaded mechanism. (JMarc)
+               // step to the end of the previous paragraph
                if (cursor.par()->previous()) {
-                       // steps into the above paragraph.
                        setCursorIntern(bview, cursor.par()->previous(),
                                        cursor.par()->previous()->size(),
                                        false);
@@ -2519,14 +2443,6 @@ void LyXText::backspace(BufferView * bvi
                        refresh_row = cursor.row();
                        refresh_y = cursor.y() - cursor.row()->baseline();
 
-                       // remove the lost paragraph
-                       // This one is not safe, since the paragraph that the tmprow 
and the
-                       // following rows belong to has been deleted by the 
PasteParagraph
-                       // above. The question is... could this be moved in front of 
the
-                       // PasteParagraph?
-                       //RemoveParagraph(tmprow);
-                       //RemoveRow(tmprow);
-
                        // This rebuilds the rows.
                        appendParagraph(bview, cursor.row());
                        updateCounters(bview);
@@ -2539,10 +2455,7 @@ void LyXText::backspace(BufferView * bvi
                // any paragraphs
                setUndo(bview, Undo::DELETE,
                        cursor.par(), cursor.par()->next());
-               // We used to do cursorLeftIntern() here, but it is
-               // not a good idea since it triggers the auto-delete
-               // mechanism. So we do a cursorLeftIntern()-lite,
-               // without the dreaded mechanism. (JMarc)
+
                setCursorIntern(bview, cursor.par(), cursor.pos()- 1,
                                false, cursor.boundary());
 
Index: text2.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/text2.C,v
retrieving revision 1.286
diff -u -p -r1.286 text2.C
--- text2.C     11 Mar 2003 16:38:37 -0000      1.286
+++ text2.C     12 Mar 2003 10:59:03 -0000
@@ -850,10 +850,6 @@ void LyXText::fullRebreak(BufferView * b
 // important for the screen
 
 
-// the cursor set functions have a special mechanism. When they
-// realize, that you left an empty paragraph, they will delete it.
-// They also delete the corresponding row
-
 // need the selection cursor:
 void LyXText::setSelection(BufferView * bview)
 {
@@ -1743,7 +1739,7 @@ bool LyXText::setCursor(BufferView * bvi
 {
        LyXCursor old_cursor = cursor;
        setCursorIntern(bview, par, pos, setfont, boundary);
-       return deleteEmptyParagraphMechanism(bview, old_cursor);
+       deleteExtraSpaces(bview, old_cursor);
 }
 
 
@@ -2061,7 +2057,7 @@ void LyXText::setCursorFromCoordinates(B
 
        setCursorFromCoordinates(bview, cursor, x, y);
        setCurrentFont(bview);
-       deleteEmptyParagraphMechanism(bview, old_cursor);
+       deleteExtraSpaces(bview, old_cursor);
 }
 
 
@@ -2217,7 +2213,7 @@ void LyXText::cursorDownParagraph(Buffer
 }
 
 // fix the cursor `cur' after a characters has been deleted at `where'
-// position. Called by deleteEmptyParagraphMechanism
+// position. Called by deleteExtraSpaces
 void LyXText::fixCursorAfterDelete(BufferView * bview,
                                   LyXCursor & cur,
                                   LyXCursor const & where) const
@@ -2242,8 +2238,8 @@ void LyXText::fixCursorAfterDelete(Buffe
 }
 
 
-bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
-                                           LyXCursor const & old_cursor) const
+void LyXText::deleteExtraSpaces(BufferView * bview,
+                                LyXCursor const & old_cursor) const
 {
        // Would be wrong to delete anything if we have a selection.
        if (selection.set())
@@ -2311,117 +2307,6 @@ bool LyXText::deleteEmptyParagraphMechan
                        return false;
                }
        }
-
-       // don't delete anything if this is the ONLY paragraph!
-       if (!old_cursor.par()->next() && !old_cursor.par()->previous())
-               return false;
-
-       // Do not delete empty paragraphs with keepempty set.
-       if (old_cursor.par()->layout()->keepempty)
-               return false;
-
-       // only do our magic if we changed paragraph
-       if (old_cursor.par() == cursor.par())
-               return false;
-
-       // record if we have deleted a paragraph
-       // we can't possibly have deleted a paragraph before this point
-       bool deleted = false;
-
-       if ((old_cursor.par()->empty()
-            || (old_cursor.par()->size() == 1
-                && old_cursor.par()->isLineSeparator(0)))) {
-               // ok, we will delete anything
-               LyXCursor tmpcursor;
-
-               // make sure that you do not delete any environments
-               status(bview, LyXText::NEED_MORE_REFRESH);
-               deleted = true;
-
-               if (old_cursor.row()->previous()) {
-                       refresh_row = old_cursor.row()->previous();
-                       refresh_y = old_cursor.y() - old_cursor.row()->baseline() - 
refresh_row->height();
-                       tmpcursor = cursor;
-                       cursor = old_cursor; // that undo can restore the right cursor 
position
-                       Paragraph * endpar = old_cursor.par()->next();
-                       if (endpar && endpar->getDepth()) {
-                               while (endpar && endpar->getDepth()) {
-                                       endpar = endpar->next();
-                               }
-                       }
-                       setUndo(bview, Undo::DELETE, old_cursor.par(), endpar);
-                       cursor = tmpcursor;
-
-                       // delete old row
-                       removeRow(old_cursor.row());
-                       if (ownerParagraph() == old_cursor.par()) {
-                               ownerParagraph(ownerParagraph()->next());
-                       }
-                       // delete old par
-                       delete old_cursor.par();
-
-                       /* Breakagain the next par. Needed because of
-                        * the parindent that can occur or dissappear.
-                        * The next row can change its height, if
-                        * there is another layout before */
-                       if (refresh_row->next()) {
-                               breakAgain(bview, refresh_row->next());
-                               updateCounters(bview);
-                       }
-                       setHeightOfRow(bview, refresh_row);
-               } else {
-                       refresh_row = old_cursor.row()->next();
-                       refresh_y = old_cursor.y() - old_cursor.row()->baseline();
-
-                       tmpcursor = cursor;
-                       cursor = old_cursor; // that undo can restore the right cursor 
position
-                       Paragraph * endpar = old_cursor.par()->next();
-                       if (endpar && endpar->getDepth()) {
-                               while (endpar && endpar->getDepth()) {
-                                       endpar = endpar->next();
-                               }
-                       }
-                       setUndo(bview, Undo::DELETE, old_cursor.par(), endpar);
-                       cursor = tmpcursor;
-
-                       // delete old row
-                       removeRow(old_cursor.row());
-                       // delete old par
-                       if (ownerParagraph() == old_cursor.par()) {
-                               ownerParagraph(ownerParagraph()->next());
-                       }
-
-                       delete old_cursor.par();
-
-                       /* Breakagain the next par. Needed because of
-                          the parindent that can occur or dissappear.
-                          The next row can change its height, if
-                          there is another layout before */
-                       if (refresh_row) {
-                               breakAgain(bview, refresh_row);
-                               updateCounters(bview);
-                       }
-               }
-
-               // correct cursor y
-               setCursorIntern(bview, cursor.par(), cursor.pos());
-
-               if (selection.cursor.par()  == old_cursor.par()
-                   && selection.cursor.pos() == old_cursor.pos()) {
-                       // correct selection
-                       selection.cursor = cursor;
-               }
-       }
-       if (!deleted) {
-               if (old_cursor.par()->stripLeadingSpaces()) {
-                       redoParagraphs(bview, old_cursor,
-                                      old_cursor.par()->next());
-                       // correct cursor y
-                       setCursorIntern(bview, cursor.par(), cursor.pos());
-                       selection.cursor = cursor;
-               }
-       }
-       return deleted;
 }
 
 
Index: insets/insettext.C
===================================================================
RCS file: /usr/local/lyx/cvsroot/lyx-devel/src/insets/insettext.C,v
retrieving revision 1.353
diff -u -p -r1.353 insettext.C
--- insets/insettext.C  12 Mar 2003 05:46:35 -0000      1.353
+++ insets/insettext.C  12 Mar 2003 10:59:11 -0000
@@ -820,6 +820,7 @@ void InsetText::insetUnlock(BufferView *
        } else
                bv->owner()->setLayout(bv->text->cursor.par()->layout()->name());
        // hack for deleteEmptyParMech
+#warning FIXME, DEPM is dead - now what ?
        if (!paragraphs.begin()->empty()) {
                lt->setCursor(bv, &*(paragraphs.begin()), 0);
        } else if (paragraphs.begin()->next()) {

Reply via email to