]> git.lyx.org Git - features.git/commitdiff
Unhide buffers that are marked dirty as a result of external modifications
authorGuillaume MM <gm@lyx.org>
Sat, 10 Jun 2017 19:51:44 +0000 (21:51 +0200)
committerGuillaume MM <gm@lyx.org>
Sun, 11 Jun 2017 17:51:17 +0000 (19:51 +0200)
Several comments in the code point to the fact that hidden buffers are assumed
to be clean.

The other solution was to adapt the closing & saving code to take into account
hidden dirty buffers. Experience shows that it is more useful to unhide the
buffers at the moment of the external modification, in the context of a git
workflow where one has to reload the modified children buffers one-by-one.

Fixes crash at #10603

src/Buffer.cpp
src/frontends/Application.h
src/frontends/WorkAreaManager.cpp
src/frontends/WorkAreaManager.h
src/frontends/qt4/GuiApplication.cpp
src/frontends/qt4/GuiApplication.h
src/frontends/qt4/GuiView.cpp
src/frontends/qt4/GuiView.h

index 6a29a9613b89488f6abf75da89c201d87d23a2e2..61b89200c17a7b784205965985077d02fdb2e9a6 100644 (file)
@@ -380,7 +380,7 @@ public:
        void refreshFileMonitor();
 
        /// Notify or clear of external modification
-       void fileExternallyModified(bool exists) const;
+       void fileExternallyModified(bool exists);
 
        /// has been externally modified? Can be reset by the user.
        mutable bool externally_modified_;
@@ -5332,7 +5332,7 @@ void Buffer::Impl::refreshFileMonitor()
 }
 
 
-void Buffer::Impl::fileExternallyModified(bool const exists) const
+void Buffer::Impl::fileExternallyModified(bool const exists)
 {
        // ignore notifications after our own saving operations
        if (checksum_ == filename.checksum()) {
@@ -5346,8 +5346,13 @@ void Buffer::Impl::fileExternallyModified(bool const exists) const
        // location, then the externally modified warning will appear then.
        if (exists)
                        externally_modified_ = true;
-       if (wa_)
+       // Update external modification notification.
+       // Dirty buffers must be visible at all times.
+       if (wa_ && wa_->unhide(owner_))
                wa_->updateTitles();
+       else
+               // Unable to unhide the buffer (e.g. no GUI or not current View)
+               lyx_clean = true;
 }
 
 
index b321052ddb7661255d7d76585dc75e468b8daf4b..26fad07e8465c362eb25f4bd1522cb716fef921c 100644 (file)
@@ -251,6 +251,8 @@ public:
        /// A started long operation is still in progress ?
        virtual bool longOperationStarted() = 0;
 
+       // Add a buffer to the current view, do not switch to it.
+       virtual bool unhide(Buffer * buf) = 0;
 };
 
 /// Return the list of loadable formats.
index a1c244ece7215c716771f39d9e2ac59999ec0bd2..b98163ceccc26a4ef03c31158b3c5d33811e9bc4 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "WorkAreaManager.h"
 
+#include "Application.h"
 #include "WorkArea.h"
 
 
@@ -46,6 +47,14 @@ void WorkAreaManager::closeAll()
 }
 
 
+bool WorkAreaManager::unhide(Buffer * buf)
+{
+       if (!work_areas_.empty())
+               return true;
+       return theApp()->unhide(buf);
+}
+
+
 void WorkAreaManager::updateTitles()
 {
        for (WorkArea * wa : work_areas_)
index e8952f2eae2276a4884f5a7f5db91b06ddc8eca1..0434074ab45769fa9944972a304f1c4bbf5e0c87 100644 (file)
@@ -15,6 +15,9 @@
 #include <list>
 
 namespace lyx {
+
+class Buffer;
+
 namespace frontend {
 
 class WorkArea;
@@ -41,6 +44,9 @@ public:
        /// Update window titles of all users and the external modifications
        /// warning.
        void updateTitles();
+       /// If there is no work area, create a new one in the current view using the
+       /// buffer buf. Returns false if not possible.
+       bool unhide(Buffer * buf);
 
 private:
        typedef std::list<WorkArea *>::iterator iterator;
index 700fc0303e4d6e13765fbee723ceac6995c2ebbf..8b43169aae5be486763a496920458a9b5c03de6b 100644 (file)
@@ -2410,6 +2410,15 @@ void GuiApplication::createView(QString const & geometry_arg, bool autoShow,
 }
 
 
+bool GuiApplication::unhide(Buffer * buf)
+{
+       if (!currentView())
+               return false;
+       currentView()->setBuffer(buf, false);
+       return true;
+}
+
+
 Clipboard & GuiApplication::clipboard()
 {
        return d->clipboard_;
index de6013d4c7e691fa127e128d9de5a37fcc0fbcb3..fafdd46eea25478b49b6fd8f598e9e3c7db0f601 100644 (file)
@@ -77,6 +77,7 @@ public:
        void unregisterSocketCallback(int fd);
        bool searchMenu(FuncRequest const & func, docstring_list & names) const;
        void handleKeyFunc(FuncCode action);
+       bool unhide(Buffer * buf); //override
        //@}
 
        ///
index 34e342a48b90c27b709429949dd320aa44758fc2..a2ef74bf53209a139a7c4ee7192ac910127144b0 100644 (file)
@@ -1587,7 +1587,7 @@ void GuiView::updateToolbars()
 }
 
 
-void GuiView::setBuffer(Buffer * newBuffer)
+void GuiView::setBuffer(Buffer * newBuffer, bool switch_to)
 {
        LYXERR(Debug::DEBUG, "Setting buffer: " << newBuffer << endl);
        LASSERT(newBuffer, return);
@@ -1610,7 +1610,8 @@ void GuiView::setBuffer(Buffer * newBuffer)
        }
        connectBuffer(*newBuffer);
        connectBufferView(wa->bufferView());
-       setCurrentWorkArea(wa);
+       if (switch_to)
+               setCurrentWorkArea(wa);
 }
 
 
index b30cdac49782ded8941515de5a2c6dd709549484..fbb886696a8851f7ce17d1013116e6edb1ff5daf 100644 (file)
@@ -130,8 +130,10 @@ public:
 
        ///
        void focusInEvent(QFocusEvent * e);
-       /// set a buffer to the current workarea.
-       void setBuffer(Buffer * b); ///< \c Buffer to set.
+       /// Add a Buffer to the View
+       /// \param b Buffer to set.
+       /// \param switch_to Whether to set it to the current workarea.
+       void setBuffer(Buffer * b, bool switch_to = true);
 
        /// load a document into the current workarea.
        Buffer * loadDocument(