]> git.lyx.org Git - features.git/commitdiff
Mostly fixed the 'empty paragraph deletion kills the cursor' problem; and initialise...
authorAllan Rae <rae@lyx.org>
Sat, 12 Jan 2002 21:03:30 +0000 (21:03 +0000)
committerAllan Rae <rae@lyx.org>
Sat, 12 Jan 2002 21:03:30 +0000 (21:03 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3347 a592a061-630c-0410-9148-cb99ea01b6c8

src/BufferView2.C
src/ChangeLog
src/insets/ChangeLog
src/insets/insettabular.C
src/lyxtext.h
src/text2.C

index 0eb2b4611c5383658a03560990f4ed5e7af8a4cc..bbfa04cadfa3967063f27626f7d1f39f6653f66e 100644 (file)
@@ -110,18 +110,45 @@ bool BufferView::removeAutoInsets()
 {
        LyXCursor tmpcursor = text->cursor;
        Paragraph * cur_par = tmpcursor.par();
+       Paragraph * cur_par_prev = cur_par ? cur_par->previous() : 0;
+       Paragraph * cur_par_next = cur_par ? cur_par->next() : 0;
        pos_type cur_pos = tmpcursor.pos();
-       
+
        bool found = false;
 
+       // Trap the deletion of the paragraph the cursor is in.
+       // It should be almost impossible for the new cursor par to be
+       // deleted later on in this function.
+       // This is the way to segfault this now. Although you may have to do this
+       // multiple times: Have an InsetERT with an unknown command in it.
+       // View->DVI, move cursor between Error box and InsetERT and hit <Enter>,
+       // <down-arrow>, <Enter> again, View->DVI, BANG!
+       //
+       while ((cur_par_prev || cur_par_next)
+              && text->setCursor(this,
+                                 cur_par_prev ? cur_par_prev : cur_par_next,
+                                 0)) {
+               // we just removed cur_par so have to fix the "cursor"
+               if (cur_par_prev) {
+                       cur_par = cur_par_prev;
+                       cur_pos = cur_par->size();
+               } else {
+                       cur_par = cur_par_next;
+                       cur_pos = 0;
+               }
+               cur_par_prev = cur_par->previous();
+               cur_par_next = cur_par->next();
+       }
+
        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;
 
-               text->setCursor(this, par, 0);
-               
+               bool dead = text->setCursor(this, par, 0);
+
                Paragraph::inset_iterator pit = par->inset_iterator_begin();
                Paragraph::inset_iterator pend = par->inset_iterator_end();
                while (pit != pend) {
@@ -142,6 +169,40 @@ bool BufferView::removeAutoInsets()
                        found = true;
                        text->redoParagraph(this);
                }
+               if (dead) {
+                       // Error box paragraphs appear to have a bad next_ pointer
+                       // especially when that's all that's in the paragraph..
+                       // Then if you are in an empty paragraph after an error box
+                       // which is in its own paragraph this will fail because
+                       // cur_prev_par was the one just deleted (I think).
+                       // That's the main reason why this clause makes almost no difference.
+                       // Feel free to delete this whole clause as my brain is asleep now.
+                       while ((cur_par_prev || cur_par_next)
+                              && text->setCursor(this,
+                                                 cur_par_prev ? cur_par_prev : cur_par_next,
+                                                 0)) {
+                               // we just removed cur_par so have to fix the "cursor"
+                               if (cur_par_prev == par) {
+                                       // attempting to solve the "prev par was deleted
+                                       // because it had only an error inset in it" problem
+                                       if (par_prev) {
+                                               cur_par = par_prev;
+                                               cur_pos = cur_par->size();
+                                       } else {
+                                               cur_par = cur_par_next;
+                                               cur_pos = 0;
+                                       }
+                               } else if (cur_par_prev) {
+                                       cur_par = cur_par_prev;
+                                       cur_pos = cur_par->size();
+                               } else {
+                                       cur_par = cur_par_next;
+                                       cur_pos = 0;
+                               }
+                               cur_par_prev = cur_par->previous();
+                               cur_par_next = cur_par->next();
+                       }
+               }
        }
 
        text->setCursorIntern(this, cur_par, cur_pos);
index 9de7590097096ecda26bb3130c2e31265efb45a5..0ecf8a48e1ae61e9920a1d8394b263f9c382fab0 100644 (file)
@@ -1,3 +1,18 @@
+2002-01-13  Allan Rae  <rae@lyx.org>
+
+       * BufferView2.C (removeAutoInsets): ensure we have a valid cursor if
+       the old cursor is now invalid due to deleteEmptyParagraphMechanism.
+       There is still a way to segfault this although you may have to do this
+       multiple times: Have an InsetERT with an unknown command in it. 
+       View->DVI, move cursor between Error box and InsetERT and hit <Enter>,
+       <down-arrow>, <Enter> again, View->DVI, BANG!
+
+       * text2.C (setCursor): 
+       (deleteEmptyParagraphMechanism): 
+       * lyxtext.h (setCursor): 
+       (deleteEmptyParagraphMechanism): return true if the paragraph was deleted.
+       Making use of the return value may help fix other bugs.
+
 2002-01-12  Jean-Marc Lasgouttes  <lasgouttes@freesurf.fr>
 
        * LyXAction.[Ch]: move isPseudoAction to the C file, since nobody
index c3c6f9bd9c3879c3fa886d464f8d89e761f247c3..7fa91dc48c5f94882648a5593c8a9d328093b159 100644 (file)
@@ -1,3 +1,8 @@
+2002-01-13  Allan Rae  <rae@lyx.org>
+
+       * insettabular.C (InsetTabular): Both constructors now initialise
+       all class variables.
+
 2002-01-11  Juergen Vigna  <jug@sad.it>
 
        * insettext.C (insetButtonPress): set the_locking_inset to 0.
index e748979ca765b9bf1de1306b70ee7e0c8d5be250..32b45f29f181b55cd89beda3b5de40721170141f 100644 (file)
@@ -138,6 +138,7 @@ InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
        // for now make it always display as display() inset
        // just for test!!!
        the_locking_inset = 0;
+       old_locking_inset = 0;
        locked = false;
        oldcell = -1;
        actrow = actcell = 0;
@@ -145,6 +146,8 @@ InsetTabular::InsetTabular(Buffer const & buf, int rows, int columns)
        need_update = INIT;
        in_update = false;
        in_reset_pos = false;
+       inset_x = 0;
+       inset_y = 0;
 }
 
 
@@ -154,6 +157,7 @@ InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf,
 {
        tabular.reset(new LyXTabular(this, *(tab.tabular), same_id));
        the_locking_inset = 0;
+       old_locking_inset = 0;
        locked = false;
        oldcell = -1;
        actrow = actcell = 0;
@@ -161,6 +165,8 @@ InsetTabular::InsetTabular(InsetTabular const & tab, Buffer const & buf,
        need_update = INIT;
        in_update = false;
        in_reset_pos = false;
+       inset_x = 0;
+       inset_y = 0;
 }
 
 
index 8c6114ea6241f02b5b2536f47f266d30b3df5723..f80c84b7d0698c610154413e0fb296fda12f8dee 100644 (file)
@@ -306,8 +306,8 @@ public:
        string const selectNextWordToSpellcheck(BufferView *, float & value) const;
        ///
        void selectSelectedWord(BufferView *);
-       ///
-       void setCursor(BufferView *, Paragraph * par,
+       /// returns true if par was empty and was removed
+       bool setCursor(BufferView *, Paragraph * par,
                       lyx::pos_type pos,
                       bool setfont = true,
                       bool boundary = false) const;
@@ -612,8 +612,8 @@ private:
                                  LyXCursor & cur,
                                  LyXCursor const & where) const;
        
-       /// delete double space or empty paragraphs around old_cursor 
-       void deleteEmptyParagraphMechanism(BufferView *,
+       /// delete double space (false) or empty paragraphs (true) around old_cursor 
+       bool deleteEmptyParagraphMechanism(BufferView *,
                                           LyXCursor const & old_cursor) const;
 
 public:
index 2437cf1570a22fa39762af7389e922135b6ff5d3..ce0fe04a3a8be7e5e5bd61a848d460db7a7653a1 100644 (file)
@@ -2090,13 +2090,13 @@ bool LyXText::updateInset(BufferView * bview, Inset * inset)
 }
 
 
-void LyXText::setCursor(BufferView * bview, Paragraph * par,
+bool LyXText::setCursor(BufferView * bview, Paragraph * par,
                         pos_type pos, 
                         bool setfont, bool boundary) const
 {
        LyXCursor old_cursor = cursor;
        setCursorIntern(bview, par, pos, setfont, boundary);
-       deleteEmptyParagraphMechanism(bview, old_cursor);
+       return deleteEmptyParagraphMechanism(bview, old_cursor);
 }
 
 
@@ -2373,21 +2373,19 @@ void LyXText::fixCursorAfterDelete(BufferView * bview,
 }
 
 
-void LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
+bool LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                                            LyXCursor const & old_cursor) const
 {
        // Would be wrong to delete anything if we have a selection.
-       if (selection.set()) return;
+       if (selection.set()) return false;
 
        // We allow all kinds of "mumbo-jumbo" when freespacing.
        if (textclasslist.Style(bview->buffer()->params.textclass,
                                old_cursor.par()->getLayout()).free_spacing
            || old_cursor.par()->isFreeSpacing())
        {
-               return;
+               return false;
        }
-
-       bool deleted = false;
        
        /* Ok I'll put some comments here about what is missing.
           I have fixed BackSpace (and thus Delete) to not delete
@@ -2442,23 +2440,27 @@ void LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                        fixCursorAfterDelete(bview, toggle_cursor, old_cursor);
                        fixCursorAfterDelete(bview, toggle_end_cursor,
                                             old_cursor);
-                       return;
+                       return false;
                }
        }
 
        // don't delete anything if this is the ONLY paragraph!
        if (!old_cursor.par()->next() && !old_cursor.par()->previous())
-               return;
+               return false;
        
        // Do not delete empty paragraphs with keepempty set.
        if ((textclasslist.Style(bview->buffer()->params.textclass,
                                 old_cursor.par()->getLayout())).keepempty)
-               return;
+               return false;
 
        // only do our magic if we changed paragraph
        if (old_cursor.par() == cursor.par()) 
-               return;
+               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()->size() == 0
             || (old_cursor.par()->size() == 1
                 && old_cursor.par()->isLineSeparator(0)))) {
@@ -2488,7 +2490,7 @@ void LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                        if (ownerParagraph() == old_cursor.par()) {
                                ownerParagraph(ownerParagraph()->next());
                        }
-                               // delete old par
+                       // delete old par
                        delete old_cursor.par();
                                        
                        /* Breakagain the next par. Needed because of
@@ -2538,7 +2540,7 @@ void LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                setCursorIntern(bview, cursor.par(), cursor.pos());
 
                if (selection.cursor.par()  == old_cursor.par()
-                   && selection.cursor.pos() == selection.cursor.pos()) {
+                   && selection.cursor.pos() == old_cursor.pos()) {
                        // correct selection
                        selection.cursor = cursor;
                }
@@ -2552,6 +2554,7 @@ void LyXText::deleteEmptyParagraphMechanism(BufferView * bview,
                        selection.cursor = cursor;
                }
        }
+       return deleted;
 }