commit 02b248d2708a412ac855b73925a676eb9f0c3b20
Author: Jean-Marc Lasgouttes <[email protected]>
Date:   Wed Dec 13 10:38:47 2017 +0100

    Handle properly undo groups in embedded work areas
    
    When a buffer is in an embedded work area (adv. find&replace), it is
    not found by BufferList:::exists(), and therefore the undo group
    created in GuiApplication::dispatch and in the handling of
    LFUN_COMMAND_SEQUENCE will not be closed. Crashes can ensue, as
    described in Ubuntu bug:
    https://bugs.launchpad.net/bugs/1737429
    
    The solution is to introduce BufferList::isInternal and act on it.
    
    Fixes bug #10847.
    
    (cherry picked from commit 8b107f0490e61b4390e925f08d21661ef50d6f49)
---
 src/BufferList.cpp                   |   12 +++++++++++-
 src/BufferList.h                     |    3 +++
 src/Undo.cpp                         |    6 ++++--
 src/frontends/qt4/GuiApplication.cpp |    4 ++--
 status.22x                           |    3 +++
 5 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/src/BufferList.cpp b/src/BufferList.cpp
index bcdec59..d28a342 100644
--- a/src/BufferList.cpp
+++ b/src/BufferList.cpp
@@ -271,7 +271,7 @@ bool BufferList::exists(FileName const & fname) const
 }
 
 
- bool BufferList::isLoaded(Buffer const * b) const
+bool BufferList::isLoaded(Buffer const * b) const
 {
        if (!b)
                return false;
@@ -281,6 +281,16 @@ bool BufferList::exists(FileName const & fname) const
 }
 
 
+bool BufferList::isInternal(Buffer const * b) const
+{
+       if (!b)
+               return false;
+       BufferStorage::const_iterator cit =
+               find(binternal.begin(), binternal.end(), b);
+       return cit != binternal.end();
+}
+
+
 bool BufferList::isOthersChild(Buffer * parent, Buffer * child)
 {
        LASSERT(parent, return false);
diff --git a/src/BufferList.h b/src/BufferList.h
index d4ae186..68f22ef 100644
--- a/src/BufferList.h
+++ b/src/BufferList.h
@@ -84,6 +84,9 @@ public:
        /// returns true if the buffer is loaded
        bool isLoaded(Buffer const * b) const;
 
+       /// returns true if the buffer is known as internal buffer
+       bool isInternal(Buffer const * b) const;
+
        /// \return index of named buffer in buffer list
        int bufferNum(support::FileName const & name) const;
 
diff --git a/src/Undo.cpp b/src/Undo.cpp
index a479728..f7ee482 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -562,7 +562,8 @@ void Undo::beginUndoGroup()
        if (d->group_level_ == 0) {
                // create a new group
                ++d->group_id_;
-               LYXERR(Debug::UNDO, "+++++++Creating new group " << 
d->group_id_);
+               LYXERR(Debug::UNDO, "+++++++ Creating new group " << 
d->group_id_
+                      << " for buffer " << &d->buffer_);
        }
        ++d->group_level_;
 }
@@ -586,7 +587,8 @@ void Undo::endUndoGroup()
        if (d->group_level_ == 0) {
                // real end of the group
                d->group_cur_before_ = CursorData();
-               LYXERR(Debug::UNDO, "-------End of group " << d->group_id_);
+               LYXERR(Debug::UNDO, "------- End of group " << d->group_id_
+                      << " of buffer " << &d->buffer_);
        }
 }
 
diff --git a/src/frontends/qt4/GuiApplication.cpp 
b/src/frontends/qt4/GuiApplication.cpp
index f473176..734ef36 100644
--- a/src/frontends/qt4/GuiApplication.cpp
+++ b/src/frontends/qt4/GuiApplication.cpp
@@ -1388,7 +1388,7 @@ DispatchResult const & 
GuiApplication::dispatch(FuncRequest const & cmd)
        updateCurrentView(cmd, dr);
 
        // the buffer may have been closed by one action
-       if (theBufferList().isLoaded(buffer))
+       if (theBufferList().isLoaded(buffer) || 
theBufferList().isInternal(buffer))
                buffer->undo().endUndoGroup();
 
        d->dispatch_result_ = dr;
@@ -1863,7 +1863,7 @@ void GuiApplication::dispatch(FuncRequest const & cmd, 
DispatchResult & dr)
                        dispatch(func);
                }
                // the buffer may have been closed by one action
-               if (theBufferList().isLoaded(buffer))
+               if (theBufferList().isLoaded(buffer) || 
theBufferList().isInternal(buffer))
                        buffer->undo().endUndoGroup();
                break;
        }
diff --git a/status.22x b/status.22x
index b5af1fe..7fc5405 100644
--- a/status.22x
+++ b/status.22x
@@ -100,6 +100,9 @@ What's new
 
 - Fix crash with undo and child documents (bug 10643).
 
+- Fix completely broken undo in Advanced Find & Replace edit areas
+  (bug 10847).
+
 - Fix crash when changing preview preferences while previewable
   external inset is open (bug 10785).
 

Reply via email to