The code in InsetLabel::updateReferences code changes reference insets
in potentially several buffers. When recording undo, it is important
to use the right undo stack, otherwise crashes can ensue.
Once it is done, it is neccessary to create undo groups as needed.
This is done using UndoGroupHelper. This demonstrates a shortcoming of
UndoGroup helper: if a buffer is encountered in two seperate
occasions, two undo groups will be created for this buffer. This is
not correct.
Fixes bug #10643.
With this patch, the cursor position before undo can be saved when
creating an undo group. Any such value will supercede parameters
passed to recordUndo. Only the first such cursor set by nested
beginUndoGoup takes effect.
Fixes bug #9663.
The recipe for reproducing this crash is to do a search and replace
that changes a string present in a collapsed inset, and then undo.
This is a followup to 17e435c4, which used editable() instead of
isActive(); this commit was amended at c2f785bd, since editable() is
not set properly in mathed.
Truth is, editable() is not the right property to test against, since
it is false for a collapsed inset, which does not prevent a cursor
from pointing inside. Therefore sanitize should not change the cursor
in this case.
Hopefuly, this is the last word on the subject. Alternative would be
to drop this if()-clause completely.
Create new helper class UndoGroupHelper, which simplifies a lot the
handling of undo groups in cases like this one. The class tracks open
undo buffers and allows to switch buffers transparently.
Using the class for advanced search and replace is trivial. THe class
may be useful in some other classes.
Fixes ticket #8658
The cleanup in 11ca1406 was not correct. It is actually not possible to implement recordUndoInset from the undo API, since the cursor may not be at a different level than the text to be saved.
Fixes ticket #9553
* Remove the UndoKind parameter in the general interface
* move recordUndoInset to Cursor
* remove one variant of Undo::recordUndo.
* get rid of Text::recUndo.
The old scheme was:
* multiple insertions are undone by groups of 20
* multiple deletions are undone in one big block
The new scheme is to stop merging undo elements after 2 seconds of elapsed time.
Moreover, the merging of undo elements stops when the cursor has moved. Potentially, this could allow to remove many of the finishUndo() calls.
Fixes bug #9204.
Rename recordUndoFullDocument to recordUndoFullBuffer.
Separate the notion of recording changes to paragraphs and recording changes in buffer parameters.
Audit every user of recordUndoFullDocument and replace it with either recordUndoBufferParams or recordUndoFullBuffer. Add comments to identify remaining work.
each failure.
There are several places I was not sure what to do. These are marked
by comments beginning "LASSERT:" so they can be found easily. At the
moment, they are at:
Author.cpp:105: // LASSERT: What should we do here?
Author.cpp:121: // LASSERT: What should we do here?
Buffer.cpp:4525: // LASSERT: Is it safe to continue here, or should we just return?
Cursor.cpp:345: // LASSERT: Is it safe to continue here, or should we return?
Cursor.cpp:403: // LASSERT: Is it safe to continue here, or should we return?
Cursor.cpp:1143: // LASSERT: There have been several bugs around this code, that seem
CursorSlice.cpp:83: // LASSERT: This should only ever be called from an InsetMath.
CursorSlice.cpp:92: // LASSERT: This should only ever be called from an InsetMath.
LayoutFile.cpp:303: // LASSERT: Why would this fail?
Text.cpp:995: // LASSERT: Is it safe to continue here?
Fix thinko in Undo::endUndoGroup.
Do not reset undo groups in Undo::clean
The underlying problem remains: the various VC functions should not
always reload the buffer or at least should use the parameter
clearUndo=false.
This commit does a bit more than fix selection, since it saves the full cursor state
in the undo stack. This means that undo now restores:
* the selection
* the current font
* transient mark (shall we keep this one?), logical position...
In order to do that, it introduces an intermediate class between Cursor and DotIterator: CursorData.
The new inheritance diagram is thus
DocIteraator -> CursorData -> Cursor
CursorData contains all the members of Cursor that define the current position, but not the stuff
related to current view of dispatch mechanism. It may make sense in the future to move members
between CursorData and Cursor and to move some member functions to CursorData.
Now UndoElement uses CursorData for cur_before and cur_after, but not for the cell. The undo API uses
also CursorData instead of DocIterator.
The undo range is extended to encompass all the paragraph after the end that
are a non-zero depth. The reason is that these paragraphs may see their depth
reduced if the last paragraph sees its depth reduced.
Note that there is a memory cost, since we store paragraphs than may not be
modified in practice. This may matter for some pathological files (people
putting all their document at depth 1 for a weird reason?)
I tried to be careful, but this can introduce new bugs. Please test.
http://www.lyx.org/trac/ticket/6367
* Undo.cpp:
- rename cur member of UndoElement to cur_before
- add new member cur_after, which is set by Undo::endUndoGroup
- create a new Undo::endUndoGroup variant that takes a Cursor as parameter. We cannot get rid of the old one because it is used for LFUN_COMMAND_SEQUENCE.
* Cursor.cpp:
- use endUndoGroup(Dociterator const &) for dispatch
- update Cursor::endUndoGroup to pass cursor.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@40713 a592a061-630c-0410-9148-cb99ea01b6c8
- In GuiApplication::dispatch, do not call markDirty() for lfuns that are not ReadOnly
- In Undo::Private::recordUndo, call markDirty(). The indicator of dirtyness is now the existence of an undo element.
- In lyxfind, remove several markDirty calls that are not needed anymore.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36772 a592a061-630c-0410-9148-cb99ea01b6c8
- whitespace and typos in comments
- make sure that the Undo::recordUndoXXX functions all go through
Undo::Private::recordUndo
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36771 a592a061-630c-0410-9148-cb99ea01b6c8
THis is a consequence of the new AtPoint mechanism. In the old
world, recordUndoInset was called before INSET_MODIFY. I reintroduced
manual recordUndoInset calls in all places that matter. I suspect
that this issue should be revisited later.
Note that recordUndoInset can now take an optional parameter that tells
what inset is concerned. This is useful because the cursor can be
either just inside the inset or in front of it.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@36580 a592a061-630c-0410-9148-cb99ea01b6c8
* src/LyXAction.cpp: add ReadOnly flag to LFUN_UNDO and LFUN_REDO, since
we do not want the dispatch mechanism to mark buffer dirty after them.
* src/BufferView.cpp: handle "by hand" the activation of undo/redo
* src/Undo.cpp: add lyx_clean member to UndoElement and make sure to
maintain it with undo operations; add a new markDirty() member for UndoStack
* src/Buffer.cpp: when saving a document, mark the undo and redo stacks
elements as dirty.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@35068 a592a061-630c-0410-9148-cb99ea01b6c8
DispatchResult to store a flag that tells us whether we need a buffer
update or not.
So: If you find a missing one, go to an appropriate place in the
dispatch and call cur.forceBufferUpdate() or, if you don't have a cursor
but do have a DispatchResult, call dr.forceBufferUpdate().
There is one remaining call I could not move, in
TextMetrics::redoParagraph. But this looks like an emergency call when
the macro context has not been set. There are also a couple calls that
are connected with buffer creation that I commented out, since the same
call is done again almost immediately. But I'm not positive about those.
Now the nice thing would be to do the same for updateMacros().
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@34826 a592a061-630c-0410-9148-cb99ea01b6c8
This patch encapsulates the needed call in Buffer::setBuffersForInsets(),
and calls it from Undo::Private::textUndoOrRedo(). As noted in the FIXME,
this is still a bit of a "hammer" and ought to be replaced with the sort of
more refined approach taken in r28709. But I don't at the moment see how to
do that. The place to do it, though, is in doTextUndoOrRed().
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@28757 a592a061-630c-0410-9148-cb99ea01b6c8
http://bugzilla.lyx.org/show_bug.cgi?id=5173
* Undo.cpp (beginUndoGroup, endUndoGroup): new methods.
(UndoElement): add group_id member
(UndoElementStack): when removing old undo entries, make sure to
remove whole groups.
(Undo::Private): add group_id and group_level (for nesting) members.
(doTextUndoOrRedo): new method. Apply _one_ UndoElement.
(textUndoOrRedo): call doTextUndoOrRedo on each element of the current
group.
(recordUndoFullDocument): put inside an undo group
* Cursor.cpp (beginUndoGroup, endUndoGroup): new methods.
* LyXFunc.cpp (dispatch): add calls to (begin|end)UndoGroup.
* lyxfind.cpp (replaceAll): use several recordUndo instead
of one recordUndoFullDocument.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26178 a592a061-630c-0410-9148-cb99ea01b6c8
A call to updateLabels() was necessary (and safer) in all cases.
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@26081 a592a061-630c-0410-9148-cb99ea01b6c8
gdb /home/rgheck/cvs/lyx-devel/trunk/src/lyx --interpreter=mi2 -quiet
Using host libthread_db library "/lib64/libthread_db.so.1".
(gdb) bt
bt
#0 0x000000369a230ec5 in raise () from /lib64/libc.so.6
#1 0x000000369a232970 in abort () from /lib64/libc.so.6
#2 0x000000369a26b0db in __libc_message () from /lib64/libc.so.6
#3 0x000000369a272832 in _int_free () from /lib64/libc.so.6
#4 0x000000369a275f2c in free () from /lib64/libc.so.6
#5 0x00000000004ebbdc in std::_Rb_tree<int, std::pair<int const, lyx::Author>, std::_Select1st<std::pair<int const, lyx::Author> >, std::less<int>, std::allocator<std::pair<int const, lyx::Author> > >::_M_erase (this=0x32c7f68, __x=0x30ece10) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/ext/new_allocator.h:94
#6 0x00000000004ebe99 in ~map (this=0x32c7f68) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_tree.h:578
#7 0x00000000004df21f in lyx::BufferParams::MemoryTraits::destroy (ptr=0x32c7f60) at Author.h:50
#8 0x00000000004855e4 in ~copied_ptr (this=<value optimized out>) at ../../../src/support/copied_ptr.h:69
#9 0x0000000000488f93 in ~BufferParams (this=0x32c7b30) at ../../../src/BufferParams.h:52
#10 0x0000000000748585 in ~UndoElement (this=0x7fffc1aeebd0) at Undo.cpp:82
#11 0x0000000000745be8 in lyx::Undo::Private::doRecordUndo (this=0x2ef9630, kind=lyx::ATOMIC_UNDO, cell=<value optimized out>, first_pit=<value optimized out>, last_pit=<value optimized out>, cur=<value optimized out>, isFullBuffer=true, isUndoOperation=true) at Undo.cpp:278
#12 0x0000000000745ce7 in lyx::Undo::recordUndoFullDocument (this=0x2ea5620, cur=@0x2f04238) at Undo.cpp:443
#13 0x00000000007a73cc in lyx::Cursor::recordUndoFullDocument (this=0x2f04238) at Cursor.cpp:2139
#14 0x00000000006374e8 in lyx::LyXFunc::dispatch (this=0x2a431a0, cmd=@0x7fffc1af0e20) at LyXFunc.cpp:1426
#15 0x000000000060630c in lyx::dispatch (action=@0x7fffc1af0e20) at LyX.cpp:1131
#16 0x0000000000b1740a in lyx::frontend::Dialog::dispatch (this=<value optimized out>, fr=@0x7fffc1af0e20) at Dialog.cpp:62
#17 0x0000000000b6787b in dispatch_bufferparams (dialog=@0x30e1288, bp=@0x30e1470, lfun=lyx::LFUN_BUFFER_PARAMS_APPLY) at GuiDocument.cpp:2244
#18 0x0000000000b7825b in lyx::frontend::GuiDocument::dispatchParams (this=0x30e1260) at GuiDocument.cpp:2255
#19 0x0000000000b1766e in lyx::frontend::Dialog::apply (this=0x30e1288) at Dialog.cpp:159
#20 0x0000000000b647d8 in lyx::frontend::GuiDialog::slotOK (this=0x30e1260) at GuiDialog.cpp:56
#21 0x0000000000b64871 in lyx::frontend::GuiDialog::qt_metacall (this=0x30e1260, _c=QMetaObject::InvokeMetaMethod, _id=0, _a=0x7fffc1af2290) at GuiDialog_moc.cpp:73
#22 0x0000000000b83fed in lyx::frontend::GuiDocument::qt_metacall (this=0x4f17, _c=20247, _id=6, _a=0xffffffffffffffff) at GuiDocument_moc.cpp:90
#23 0x00000034e9cf3d71 in QMetaObject::activate () from /usr/lib64/libQtCore.so.4
#24 0x00000034ea5f3007 in QAbstractButton::clicked () from /usr/lib64/libQtGui.so.4
#25 0x00000034ea416c3b in QAbstractItemModel::sort () from /usr/lib64/libQtGui.so.4
#26 0x00000034ea4182c5 in QAbstractItemModel::sort () from /usr/lib64/libQtGui.so.4
#27 0x00000034ea4184cd in QAbstractButton::mouseReleaseEvent () from /usr/lib64/libQtGui.so.4
#28 0x00000034ea1cf35a in QWidget::event () from /usr/lib64/libQtGui.so.4
#29 0x00000034ea4177df in QAbstractButton::event () from /usr/lib64/libQtGui.so.4
#30 0x00000034ea491778 in QPushButton::event () from /usr/lib64/libQtGui.so.4
#31 0x00000034ea19274c in QApplicationPrivate::notify_helper () from /usr/lib64/libQtGui.so.4
#32 0x00000034ea198c1b in QApplication::notify () from /usr/lib64/libQtGui.so.4
#33 0x0000000000a8084a in lyx::frontend::GuiApplication::notify (this=0x4f17, receiver=0x4f17, event=0x6) at GuiApplication.cpp:1163
#34 0x00000034e9ce3700 in QCoreApplication::notifyInternal () from /usr/lib64/libQtCore.so.4
#35 0x00000034ea1df95d in QAbstractItemModel::sort () from /usr/lib64/libQtGui.so.4
#36 0x00000034ea1de900 in QApplication::x11ProcessEvent () from /usr/lib64/libQtGui.so.4
#37 0x00000034ea200778 in QAbstractItemModel::sort () from /usr/lib64/libQtGui.so.4
#38 0x000000369f62ef53 in g_main_context_dispatch () from /lib64/libglib-2.0.so.0
#39 0x000000369f63224d in QAbstractItemModel::sort () from /lib64/libglib-2.0.so.0
#40 0x000000369f63277e in g_main_context_iteration () from /lib64/libglib-2.0.so.0
#41 0x00000034e9d01930 in QEventDispatcherGlib::processEvents () from /usr/lib64/libQtCore.so.4
#42 0x00000034ea20057f in QAbstractItemModel::sort () from /usr/lib64/libQtGui.so.4
#43 0x00000034e9ce2da8 in QEventLoop::processEvents () from /usr/lib64/libQtCore.so.4
#44 0x00000034e9ce2ebd in QEventLoop::exec () from /usr/lib64/libQtCore.so.4
#45 0x00000034e9ce4e71 in QCoreApplication::exec () from /usr/lib64/libQtCore.so.4
#46 0x0000000000a7fb83 in lyx::frontend::GuiApplication::exec (this=<value optimized out>) at GuiApplication.cpp:1032
#47 0x00000000006101e4 in lyx::LyX::exec (this=0x7fffc1af4cf0, argc=@0x7fffc1af4cec, argv=<value optimized out>) at LyX.cpp:342
#48 0x0000000000433aa8 in main (argc=1, argv=0x7fffc1af4df8) at main.cpp:46
^done
I don't know at all what's up here with copied_ptr. Hadn't even heard of it until five minutes ago. ;-) You can cause this crash by opening a new document, opening Document>Settings and changing (say) the Bibliography settings, and then hitting "OK".
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@25617 a592a061-630c-0410-9148-cb99ea01b6c8