Fixed undo crash in first paragraph by avoiding special case and doing a

full rebreak on every undo. Undo still is unpredictable in nested insets,
but hey, one less crash is worth a beer anyway.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@7355 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Asger Ottar Alstrup 2003-07-25 11:58:47 +00:00
parent 192f2c94b2
commit 8a2e3e4d73
3 changed files with 55 additions and 38 deletions

View File

@ -1,3 +1,9 @@
2003-07-25 Asger Alstrup <alstrup@lyx.org>
* undo_funcs.C (textHandleUndo): Fix undo crash in first paragraph
by not having a special case, and always doing a full rebreak of
the document after undo.
2003-07-23 Angus Leeming <leeming@lyx.org> 2003-07-23 Angus Leeming <leeming@lyx.org>
* factory.C (createInset): InsetExternal::setParams now takes a * factory.C (createInset): InsetExternal::setParams now takes a

View File

@ -114,15 +114,11 @@ bool textHandleUndo(BufferView * bv, Undo & undo)
//LyXText * text = inset ? inset->getLyXText(bv) : bv->text; //LyXText * text = inset ? inset->getLyXText(bv) : bv->text;
LyXText * text = bv->text; LyXText * text = bv->text;
lyxerr << "handle: text: " << text << "\n"; lyxerr << "handle: text: " << text << "\n";
if (undo.first_par_offset) { // The cursor should be sane, so we will put it to the top
ParagraphList::iterator redo = plist->begin(); text->setCursorIntern(plist->begin(), 0);
lyxerr << "handle: 1\n";
advance(redo, undo.first_par_offset);
lyxerr << "handle: 2\n";
text->setCursorIntern(plist->begin(), 0);
}
lyxerr << "handle: 3\n"; lyxerr << "handle: 3\n";
text->redoParagraphs(text->cursor, plist->end()); // Rebreak the entire document
text->fullRebreak();
lyxerr << "handle: after redo\n"; lyxerr << "handle: after redo\n";
if (inset) { if (inset) {
@ -192,6 +188,7 @@ void createUndo(BufferView * bv, Undo::undo_kind kind,
plist = &buf->paragraphs; plist = &buf->paragraphs;
// this is what we'd like to have in the end for small grained undo // this is what we'd like to have in the end for small grained undo
for (ParIterator it = buf->par_iterator_begin(); it != null; ++it) { for (ParIterator it = buf->par_iterator_begin(); it != null; ++it) {
// This does not work if we are nested twice or more
if (it->id() == first->id()) if (it->id() == first->id())
first = it.outerPar(); first = it.outerPar();
if (it->id() == last->id()) if (it->id() == last->id())
@ -208,25 +205,23 @@ void createUndo(BufferView * bv, Undo::undo_kind kind,
} }
// Undo::EDIT and Undo::FINISH are // Undo::EDIT and Undo::FINISH are always finished.
// always finished. (no overlapping there) // (no overlapping there)
// overlapping only with insert and delete inside one paragraph: // overlapping only with insert and delete inside one paragraph:
// Nobody wants all removed character // Nobody wants all removed character appear one by one when undoing.
// appear one by one when undoing.
// EDIT is special since only layout information, not the // EDIT is special since only layout information, not the
// contents of a paragaph are stored. // contents of a paragaph are stored.
if (!undo_finished && kind != Undo::EDIT && kind != Undo::FINISH) { if (! undo_finished && kind != Undo::EDIT && kind != Undo::FINISH) {
// Check whether storing is needed. // Check whether storing is needed.
if (!buf->undostack.empty() && if (! buf->undostack.empty()
buf->undostack.top().kind == kind && && buf->undostack.top().kind == kind
buf->undostack.top().first_par_offset == first_offset && && buf->undostack.top().first_par_offset == first_offset
buf->undostack.top().last_par_offset == last_offset) { && buf->undostack.top().last_par_offset == last_offset) {
// No undo needed. // No undo recording needed.
return; return;
} }
} }
// Create a new Undo.
int const cursor_offset = std::distance int const cursor_offset = std::distance
(text->ownerParagraphs().begin(), text->cursor.par()); (text->ownerParagraphs().begin(), text->cursor.par());
@ -344,19 +339,6 @@ bool textRedo(BufferView * bv)
} }
void setUndo(BufferView * bv, Undo::undo_kind kind)
{
setUndo(bv, kind, bv->text->cursor.par());
}
void setUndo(BufferView * bv, Undo::undo_kind kind,
ParagraphList::iterator first)
{
setUndo(bv, kind, first, first);
}
void setUndo(BufferView * bv, Undo::undo_kind kind, void setUndo(BufferView * bv, Undo::undo_kind kind,
ParagraphList::iterator first, ParagraphList::iterator last) ParagraphList::iterator first, ParagraphList::iterator last)
{ {
@ -367,7 +349,20 @@ void setUndo(BufferView * bv, Undo::undo_kind kind,
} }
void setUndo(BufferView * bv, Undo::undo_kind kind,
ParagraphList::iterator first)
{
setUndo(bv, kind, first, first);
}
void setUndo(BufferView * bv, Undo::undo_kind kind)
{
setUndo(bv, kind, bv->text->cursor.par());
}
void setCursorParUndo(BufferView * bv) void setCursorParUndo(BufferView * bv)
{ {
setUndo(bv, Undo::FINISH, bv->text->cursor.par()); setUndo(bv, Undo::FINISH);
} }

View File

@ -19,23 +19,39 @@ class Paragraph;
/// returns false if no undo possible /// returns false if no undo possible
bool textUndo(BufferView *); bool textUndo(BufferView *);
/// returns false if no redo possible /// returns false if no redo possible
bool textRedo(BufferView *); bool textRedo(BufferView *);
/// makes sure the next operation will be stored /// makes sure the next operation will be stored
void finishUndo(); void finishUndo();
/// Whilst undo is frozen, all actions do not get added
/// to the undo stack /**
* Whilst undo is frozen, all actions do not get added
* to the undo stack
*/
void freezeUndo(); void freezeUndo();
/// Track undos again /// Track undos again
void unFreezeUndo(); void unFreezeUndo();
/// FIXME
/**
* Record undo information - call with the first paragraph that will be changed
* and the last paragraph that will be changed. So we give an inclusive
* range.
* This is called before you make the changes to the paragraph, and it
* will record the original information of the paragraphs in the undo stack.
*/
void setUndo(BufferView *, Undo::undo_kind kind, void setUndo(BufferView *, Undo::undo_kind kind,
ParagraphList::iterator first, ParagraphList::iterator last); ParagraphList::iterator first, ParagraphList::iterator last);
/// Convienience: Prepare undo when change in a single paragraph.
void setUndo(BufferView *, Undo::undo_kind kind, void setUndo(BufferView *, Undo::undo_kind kind,
ParagraphList::iterator first); ParagraphList::iterator first);
// set undo for containing paragraph
/// Convienience: Prepare undo for the paragraph that contains the cursor
void setUndo(BufferView *, Undo::undo_kind kind); void setUndo(BufferView *, Undo::undo_kind kind);
/// FIXME
/// Convienience: Prepare and finish undo for the paragraph that contains the cursor
void setCursorParUndo(BufferView *); void setCursorParUndo(BufferView *);
/// Are we avoiding tracking undos currently ? /// Are we avoiding tracking undos currently ?