]> git.lyx.org Git - features.git/blobdiff - src/Undo.cpp
Better handling of multiple buffers in UndoGroupHelper
[features.git] / src / Undo.cpp
index a479728ebde2b280e519e3c09734f292f709386f..2eb35a29d04de95fc5f4f6161d4c310246d7343b 100644 (file)
@@ -40,6 +40,7 @@
 
 #include <algorithm>
 #include <deque>
+#include <set>
 
 using namespace std;
 using namespace lyx::support;
@@ -497,6 +498,15 @@ void Undo::Private::doTextUndoOrRedo(CursorData & cur, UndoElementStack & stack,
                for (; pit != end; ++pit)
                        pit->setInsetOwner(dit.realInset());
                plist.insert(first, undo.pars->begin(), undo.pars->end());
+
+               // set the buffers for insets we created
+               ParagraphList::iterator fpit = plist.begin();
+               advance(fpit, undo.from);
+               ParagraphList::iterator fend = fpit;
+               advance(fend, undo.pars->size());
+               for (; fpit != fend; ++fpit)
+                       fpit->setInsetBuffers(buffer_);
+
                delete undo.pars;
                undo.pars = 0;
        }
@@ -531,9 +541,6 @@ bool Undo::Private::textUndoOrRedo(CursorData & cur, bool isUndoOperation)
        const size_t gid = stack.top().group_id;
        while (!stack.empty() && stack.top().group_id == gid)
                doTextUndoOrRedo(cur, stack, otherstack);
-
-       // Adapt the new material to current buffer.
-       buffer_.setBuffersForInsets(); // FIXME This shouldn't be here.
        return true;
 }
 
@@ -643,22 +650,31 @@ void Undo::recordUndoFullBuffer(CursorData const & cur)
 
 /// UndoGroupHelper class stuff
 
-/** FIXME: handle restarted groups
- * It may happen that the buffers are visited in order buffer1,
- * buffer2, buffer1. In this case, we want to have only one undo group
- * in buffer1. One solution is to replace buffer_ with a set<Buffer*>,
- * but I am not sure yet how to do it. A use case is
- * InsetLabel::updateReferences.
- */
+class UndoGroupHelper::Impl {
+       friend class UndoGroupHelper;
+       set<Buffer *> buffers_;
+};
+
+
+UndoGroupHelper::UndoGroupHelper(Buffer * buf) : d(new UndoGroupHelper::Impl)
+{
+       resetBuffer(buf);
+}
+
+
+UndoGroupHelper::~UndoGroupHelper()
+{
+       for (Buffer * buf : d->buffers_)
+               buf->undo().endUndoGroup();
+       delete d;
+}
+
 void UndoGroupHelper::resetBuffer(Buffer * buf)
 {
-       if (buf == buffer_)
-               return;
-       if (buffer_)
-               buffer_->undo().endUndoGroup();
-       buffer_ = buf;
-       if (buffer_)
-               buffer_->undo().beginUndoGroup();
+       if (buf && d->buffers_.count(buf) == 0) {
+               d->buffers_.insert(buf);
+               buf->undo().beginUndoGroup();
+       }
 }