lyx_mirror/src/Undo.cpp

442 lines
11 KiB
C++
Raw Normal View History

/**
* \file Undo.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Asger Alstrup
* \author Lars Gullik Bj<EFBFBD>nnes
* \author John Levon
* \author Andr<EFBFBD> P<EFBFBD>nitz
* \author J<EFBFBD>rgen Vigna
* \author Abdelrazak Younes
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "Undo.h"
#include "Buffer.h"
#include "BufferParams.h"
#include "buffer_funcs.h"
#include "DocIterator.h"
#include "Paragraph.h"
#include "ParagraphList.h"
#include "Text.h"
#include "mathed/MathSupport.h"
#include "mathed/MathData.h"
#include "insets/Inset.h"
#include "support/lassert.h"
#include "support/debug.h"
#include <algorithm>
#include <deque>
using namespace std;
using namespace lyx::support;
namespace lyx {
/**
These are the elements put on the undo stack. Each object contains complete
paragraphs from some cell and sufficient information to restore the cursor
state.
The cell is given by a DocIterator pointing to this cell, the 'interesting'
range of paragraphs by counting them from begin and end of cell,
respectively.
The cursor is also given as DocIterator and should point to some place in
the stored paragraph range. In case of math, we simply store the whole
cell, as there usually is just a simple paragraph in a cell.
The idea is to store the contents of 'interesting' paragraphs in some
structure ('Undo') _before_ it is changed in some edit operation.
Obviously, the stored ranged should be as small as possible. However, it
there is a lower limit: The StableDocIterator pointing stored in the undo
class must be valid after the changes, too, as it will used as a pointer
where to insert the stored bits when performining undo.
*/
struct UndoElement
{
///
UndoElement(UndoKind kin, StableDocIterator const & cur,
StableDocIterator const & cel,
pit_type fro, pit_type en, ParagraphList * pl,
MathData * ar, BufferParams const & bp,
bool ifb) :
kind(kin), cursor(cur), cell(cel), from(fro), end(en),
I've had to revert r25548 because of: 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
2008-07-14 16:12:12 +00:00
pars(pl), array(ar), bparams(bp), isFullBuffer(ifb)
{}
/// Which kind of operation are we recording for?
UndoKind kind;
/// the position of the cursor
StableDocIterator cursor;
/// the position of the cell described
StableDocIterator cell;
/// counted from begin of cell
pit_type from;
/// complement to end of this cell
pit_type end;
/// the contents of the saved Paragraphs (for texted)
ParagraphList * pars;
/// the contents of the saved MathData (for mathed)
MathData * array;
/// Only used in case of full backups
I've had to revert r25548 because of: 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
2008-07-14 16:12:12 +00:00
BufferParams bparams;
/// Only used in case of full backups
bool isFullBuffer;
private:
/// Protect construction
UndoElement();
};
class UndoElementStack
{
public:
/// limit is the maximum size of the stack
UndoElementStack(size_t limit = 100) { limit_ = limit; }
/// limit is the maximum size of the stack
~UndoElementStack() { clear(); }
/// Return the top element.
UndoElement & top() { return c_.front(); }
/// Pop and throw away the top element.
void pop() { c_.pop_front(); }
/// Return true if the stack is empty.
bool empty() const { return c_.empty(); }
/// Clear all elements, deleting them.
void clear() {
for (size_t i = 0; i != c_.size(); ++i) {
delete c_[i].array;
delete c_[i].pars;
}
c_.clear();
}
/// Push an item on to the stack, deleting the
/// bottom item on overflow.
void push(UndoElement const & v) {
c_.push_front(v);
if (c_.size() > limit_)
c_.pop_back();
}
private:
/// Internal contents.
std::deque<UndoElement> c_;
/// The maximum number elements stored.
size_t limit_;
};
struct Undo::Private
{
Private(Buffer & buffer) : buffer_(buffer), undo_finished_(true) {}
// Returns false if no undo possible.
bool textUndoOrRedo(DocIterator & cur, bool isUndoOperation);
///
void doRecordUndo(UndoKind kind,
DocIterator const & cell,
pit_type first_pit,
pit_type last_pit,
DocIterator const & cur,
bool isFullBuffer,
bool isUndoOperation);
///
void recordUndo(UndoKind kind,
DocIterator & cur,
pit_type first_pit,
pit_type last_pit);
///
Buffer & buffer_;
/// Undo stack.
UndoElementStack undostack_;
/// Redo stack.
UndoElementStack redostack_;
/// The flag used by Undo::finishUndo().
bool undo_finished_;
};
/////////////////////////////////////////////////////////////////////
//
// Undo
//
/////////////////////////////////////////////////////////////////////
Undo::Undo(Buffer & buffer)
: d(new Undo::Private(buffer))
{}
Undo::~Undo()
{
delete d;
}
bool Undo::hasUndoStack() const
{
return !d->undostack_.empty();
}
bool Undo::hasRedoStack() const
{
return !d->redostack_.empty();
}
static bool samePar(StableDocIterator const & i1, StableDocIterator const & i2)
{
StableDocIterator tmpi2 = i2;
tmpi2.pos() = i1.pos();
return i1 == tmpi2;
}
/////////////////////////////////////////////////////////////////////
//
// Undo::Private
//
///////////////////////////////////////////////////////////////////////
void Undo::Private::doRecordUndo(UndoKind kind,
DocIterator const & cell,
pit_type first_pit, pit_type last_pit,
DocIterator const & cur,
bool isFullBuffer,
bool isUndoOperation)
{
if (first_pit > last_pit)
swap(first_pit, last_pit);
// Undo::ATOMIC are always recorded (no overlapping there).
// As nobody wants all removed character appear one by one when undoing,
// we want combine 'similar' non-ATOMIC undo recordings to one.
pit_type from = first_pit;
pit_type end = cell.lastpit() - last_pit;
UndoElementStack & stack = isUndoOperation ? undostack_ : redostack_;
if (!undo_finished_
&& kind != ATOMIC_UNDO
&& !stack.empty()
&& samePar(stack.top().cell, cell)
&& stack.top().kind == kind
&& stack.top().from == from
&& stack.top().end == end)
return;
// create the position information of the Undo entry
UndoElement undo(kind, cur, cell, from, end, 0, 0,
buffer_.params(), isFullBuffer);
// fill in the real data to be saved
if (cell.inMathed()) {
// simply use the whole cell
undo.array = new MathData(cell.cell());
} else {
// some more effort needed here as 'the whole cell' of the
// main Text _is_ the whole document.
// record the relevant paragraphs
Text const * text = cell.text();
LASSERT(text, /**/);
ParagraphList const & plist = text->paragraphs();
ParagraphList::const_iterator first = plist.begin();
advance(first, first_pit);
ParagraphList::const_iterator last = plist.begin();
advance(last, last_pit + 1);
undo.pars = new ParagraphList(first, last);
}
// push the undo entry to undo stack
stack.push(undo);
//lyxerr << "undo record: " << stack.top() << endl;
// next time we'll try again to combine entries if possible
undo_finished_ = false;
}
void Undo::Private::recordUndo(UndoKind kind, DocIterator & cur,
pit_type first_pit, pit_type last_pit)
{
LASSERT(first_pit <= cur.lastpit(), /**/);
LASSERT(last_pit <= cur.lastpit(), /**/);
doRecordUndo(kind, cur, first_pit, last_pit, cur,
false, true);
undo_finished_ = false;
redostack_.clear();
//lyxerr << "undostack:\n";
//for (size_t i = 0, n = buf.undostack().size(); i != n && i < 6; ++i)
// lyxerr << " " << i << ": " << buf.undostack()[i] << endl;
}
bool Undo::Private::textUndoOrRedo(DocIterator & cur, bool isUndoOperation)
{
undo_finished_ = true;
UndoElementStack & stack = isUndoOperation ? undostack_ : redostack_;
if (stack.empty())
// Nothing to do.
return false;
UndoElementStack & otherstack = isUndoOperation ? redostack_ : undostack_;
// Adjust undo stack and get hold of current undo data.
UndoElement & undo = stack.top();
// We'll pop the stack only when we're done with this element. So do NOT
// try to return early.
// We will store in otherstack the part of the document under 'undo'
DocIterator cell_dit = undo.cell.asDocIterator(&buffer_.inset());
doRecordUndo(ATOMIC_UNDO, cell_dit,
undo.from, cell_dit.lastpit() - undo.end, cur,
undo.isFullBuffer, !isUndoOperation);
// This does the actual undo/redo.
//LYXERR0("undo, performing: " << undo);
bool labelsUpdateNeeded = false;
DocIterator dit = undo.cell.asDocIterator(&buffer_.inset());
if (undo.isFullBuffer) {
LASSERT(undo.pars, /**/);
// This is a full document
I've had to revert r25548 because of: 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
2008-07-14 16:12:12 +00:00
otherstack.top().bparams = buffer_.params();
buffer_.params() = undo.bparams;
swap(buffer_.paragraphs(), *undo.pars);
delete undo.pars;
undo.pars = 0;
} else if (dit.inMathed()) {
// We stored the full cell here as there is not much to be
// gained by storing just 'a few' paragraphs (most if not
// all math inset cells have just one paragraph!)
//LYXERR0("undo.array: " << *undo.array);
LASSERT(undo.array, /**/);
dit.cell().swap(*undo.array);
delete undo.array;
undo.array = 0;
} else {
// Some finer machinery is needed here.
Text * text = dit.text();
LASSERT(text, /**/);
LASSERT(undo.pars, /**/);
ParagraphList & plist = text->paragraphs();
// remove new stuff between first and last
ParagraphList::iterator first = plist.begin();
advance(first, undo.from);
ParagraphList::iterator last = plist.begin();
advance(last, plist.size() - undo.end);
plist.erase(first, last);
// re-insert old stuff instead
first = plist.begin();
advance(first, undo.from);
// this ugly stuff is needed until we get rid of the
// inset_owner backpointer
ParagraphList::iterator pit = undo.pars->begin();
ParagraphList::iterator const end = undo.pars->end();
for (; pit != end; ++pit)
pit->setInsetOwner(dit.realInset());
plist.insert(first, undo.pars->begin(), undo.pars->end());
delete undo.pars;
undo.pars = 0;
labelsUpdateNeeded = true;
}
LASSERT(undo.pars == 0, /**/);
LASSERT(undo.array == 0, /**/);
cur = undo.cursor.asDocIterator(&buffer_.inset());
// Now that we're done with undo, we pop it off the stack.
stack.pop();
if (labelsUpdateNeeded)
updateLabels(buffer_);
undo_finished_ = true;
return true;
}
void Undo::finishUndo()
{
// Make sure the next operation will be stored.
d->undo_finished_ = true;
}
bool Undo::textUndo(DocIterator & cur)
{
return d->textUndoOrRedo(cur, true);
}
bool Undo::textRedo(DocIterator & cur)
{
return d->textUndoOrRedo(cur, false);
}
void Undo::recordUndo(DocIterator & cur, UndoKind kind)
{
d->recordUndo(kind, cur, cur.pit(), cur.pit());
}
void Undo::recordUndoInset(DocIterator & cur, UndoKind kind)
{
DocIterator c = cur;
c.pop_back();
d->doRecordUndo(kind, c, c.pit(), c.pit(), cur, false, true);
}
void Undo::recordUndo(DocIterator & cur, UndoKind kind, pit_type from)
{
d->recordUndo(kind, cur, cur.pit(), from);
}
void Undo::recordUndo(DocIterator & cur, UndoKind kind,
pit_type from, pit_type to)
{
d->recordUndo(kind, cur, from, to);
}
void Undo::recordUndoFullDocument(DocIterator & cur)
{
d->doRecordUndo(
ATOMIC_UNDO,
doc_iterator_begin(d->buffer_.inset()),
0, d->buffer_.paragraphs().size() - 1,
cur,
true,
true
);
}
} // namespace lyx