Mostly fixed the 'empty paragraph deletion kills the cursor' problem; and initialise a few more vars in tabulars

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@3347 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Allan Rae 2002-01-12 21:03:30 +00:00
parent 8b8741cd5d
commit 17e8d4dfd8
6 changed files with 110 additions and 20 deletions

View 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);

View 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

View 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.

View 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;
}

View 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:

View 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;
}