From 8a2e3e4d73ff646ca7bdf4d5ad12bf38f88e904c Mon Sep 17 00:00:00 2001 From: Asger Ottar Alstrup Date: Fri, 25 Jul 2003 11:58:47 +0000 Subject: [PATCH] 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 --- src/ChangeLog | 6 ++++++ src/undo_funcs.C | 51 ++++++++++++++++++++++-------------------------- src/undo_funcs.h | 26 +++++++++++++++++++----- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 3d78a74912..54873047ed 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,9 @@ +2003-07-25 Asger Alstrup + + * 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 * factory.C (createInset): InsetExternal::setParams now takes a diff --git a/src/undo_funcs.C b/src/undo_funcs.C index e029ab8a7f..556c702701 100644 --- a/src/undo_funcs.C +++ b/src/undo_funcs.C @@ -114,15 +114,11 @@ bool textHandleUndo(BufferView * bv, Undo & undo) //LyXText * text = inset ? inset->getLyXText(bv) : bv->text; LyXText * text = bv->text; lyxerr << "handle: text: " << text << "\n"; - if (undo.first_par_offset) { - ParagraphList::iterator redo = plist->begin(); - lyxerr << "handle: 1\n"; - advance(redo, undo.first_par_offset); - lyxerr << "handle: 2\n"; - text->setCursorIntern(plist->begin(), 0); - } + // The cursor should be sane, so we will put it to the top + text->setCursorIntern(plist->begin(), 0); lyxerr << "handle: 3\n"; - text->redoParagraphs(text->cursor, plist->end()); + // Rebreak the entire document + text->fullRebreak(); lyxerr << "handle: after redo\n"; if (inset) { @@ -192,6 +188,7 @@ void createUndo(BufferView * bv, Undo::undo_kind kind, plist = &buf->paragraphs; // 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) { + // This does not work if we are nested twice or more if (it->id() == first->id()) first = it.outerPar(); if (it->id() == last->id()) @@ -208,25 +205,23 @@ void createUndo(BufferView * bv, Undo::undo_kind kind, } - // Undo::EDIT and Undo::FINISH are - // always finished. (no overlapping there) + // Undo::EDIT and Undo::FINISH are always finished. + // (no overlapping there) // overlapping only with insert and delete inside one paragraph: - // Nobody wants all removed character - // appear one by one when undoing. + // Nobody wants all removed character appear one by one when undoing. // EDIT is special since only layout information, not the // 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. - if (!buf->undostack.empty() && - buf->undostack.top().kind == kind && - buf->undostack.top().first_par_offset == first_offset && - buf->undostack.top().last_par_offset == last_offset) { - // No undo needed. + if (! buf->undostack.empty() + && buf->undostack.top().kind == kind + && buf->undostack.top().first_par_offset == first_offset + && buf->undostack.top().last_par_offset == last_offset) { + // No undo recording needed. return; } } - // Create a new Undo. int const cursor_offset = std::distance (text->ownerParagraphs().begin(), text->cursor.par()); @@ -344,9 +339,13 @@ bool textRedo(BufferView * bv) } -void setUndo(BufferView * bv, Undo::undo_kind kind) +void setUndo(BufferView * bv, Undo::undo_kind kind, + ParagraphList::iterator first, ParagraphList::iterator last) { - setUndo(bv, kind, bv->text->cursor.par()); + if (!undo_frozen) { + createUndo(bv, kind, first, last, bv->buffer()->undostack); + bv->buffer()->redostack.clear(); + } } @@ -357,17 +356,13 @@ void setUndo(BufferView * bv, Undo::undo_kind kind, } -void setUndo(BufferView * bv, Undo::undo_kind kind, - ParagraphList::iterator first, ParagraphList::iterator last) +void setUndo(BufferView * bv, Undo::undo_kind kind) { - if (!undo_frozen) { - createUndo(bv, kind, first, last, bv->buffer()->undostack); - bv->buffer()->redostack.clear(); - } + setUndo(bv, kind, bv->text->cursor.par()); } void setCursorParUndo(BufferView * bv) { - setUndo(bv, Undo::FINISH, bv->text->cursor.par()); + setUndo(bv, Undo::FINISH); } diff --git a/src/undo_funcs.h b/src/undo_funcs.h index 9e0cc85398..1a9aea9de5 100644 --- a/src/undo_funcs.h +++ b/src/undo_funcs.h @@ -19,23 +19,39 @@ class Paragraph; /// returns false if no undo possible bool textUndo(BufferView *); + /// returns false if no redo possible bool textRedo(BufferView *); + /// makes sure the next operation will be stored 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(); + /// Track undos again 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, ParagraphList::iterator first, ParagraphList::iterator last); +/// Convienience: Prepare undo when change in a single paragraph. void setUndo(BufferView *, Undo::undo_kind kind, 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); -/// FIXME + +/// Convienience: Prepare and finish undo for the paragraph that contains the cursor void setCursorParUndo(BufferView *); /// Are we avoiding tracking undos currently ? -- 2.39.2