]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiView.cpp
Fix a crash when closing LyX while a master and a dirty child were open, and if the...
[lyx.git] / src / frontends / qt4 / GuiView.cpp
index 496a4b5f9afd25d83102741d7d89e1442194f926..df9986b29e7fab6bc735549aab8417e6a54110bb 100644 (file)
@@ -604,21 +604,22 @@ bool GuiView::closeBufferAll(bool tolastopened)
                if (twa->count() == 0)
                        ++empty_twa;
 
-               for (; twa_count; --twa_count) {
+               for (; twa == d.tabWorkArea(empty_twa) && twa_count; --twa_count) {
                        twa->setCurrentIndex(twa_count-1);
 
                        GuiWorkArea * wa = twa->currentWorkArea();
                        bool const is_active_wa = active_wa == wa;
-                       Buffer * b = &wa->bufferView().buffer();
-                       if (b->parent()) {
+                       Buffer & b = wa->bufferView().buffer();
+
+                       if (b.parent()) {
                                // This is a child document, just close the tab
                                // after saving but keep the file loaded.
-                               if (!closeBuffer(*b, false, tolastopened, is_active_wa))
+                               if (!closeWorkArea(wa, false, tolastopened, is_active_wa))
                                        return false;
                                continue;
                        }
 
-                       vector<Buffer *> clist = b->getChildren();
+                       vector<Buffer *> clist = b.getChildren();
                        for (vector<Buffer *>::const_iterator it = clist.begin();
                                 it != clist.end(); ++it) {
                                if ((*it)->isClean())
@@ -627,7 +628,7 @@ bool GuiView::closeBufferAll(bool tolastopened)
                                // If a child is dirty, do not close
                                // without user intervention
                                //FIXME: should buffers be closed or not?
-                               if (!closeBuffer(*c, false, false))
+                               if (!closeWorkArea(workArea(*c), false, false))
                                        return false;
                        }
 
@@ -637,7 +638,7 @@ bool GuiView::closeBufferAll(bool tolastopened)
 
                        // closeBuffer() needs buffer workArea still alive and
                        // set as currrent one, and destroys it
-                       if (b && !closeBuffer(*b, close_buffer, tolastopened, is_active_wa))
+                       if (!closeWorkArea(wa, close_buffer, tolastopened, is_active_wa))
                                return false;
                }
        }
@@ -1917,19 +1918,19 @@ bool GuiView::saveBuffer(Buffer & b)
 
 bool GuiView::hideWorkArea(GuiWorkArea * wa)
 {
-       Buffer & buf = wa->bufferView().buffer();
-       return closeBuffer(buf, false);
+       return closeWorkArea(wa, false);
 }
 
 
 bool GuiView::closeBuffer()
 {
-       Buffer * buf = buffer();
-       return buf && closeBuffer(*buf, !buf->parent());
+       GuiWorkArea * wa = currentMainWorkArea();
+       Buffer & buf = wa->bufferView().buffer();
+       return wa && closeWorkArea(wa, !buf.parent());
 }
 
 
-bool GuiView::closeBuffer(Buffer & buf, bool close_buffer,
+bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
        bool tolastopened, bool mark_active)
 {
        // goto bookmark to update bookmark pit.
@@ -1938,14 +1939,19 @@ bool GuiView::closeBuffer(Buffer & buf, bool close_buffer,
        for (size_t i = 0; i < theSession().bookmarks().size(); ++i)
                theLyXFunc().gotoBookmark(i+1, false, false);
 
-       if (saveBufferIfNeeded(buf, !close_buffer)) {
+       // if we are only hiding the buffer and there are multiple views
+       // of the buffer, then we do not need to ensure a clean buffer.
+       bool const allow_dirty = inMultiTabs(wa) && !close_buffer;
+
+       Buffer & buf = wa->bufferView().buffer();
+       if (allow_dirty || saveBufferIfNeeded(buf, !close_buffer)) {
                // save in sessions if requested
                // do not save childs if their master
                // is opened as well
                if (tolastopened)
                        theSession().lastOpened().add(buf.fileName(), mark_active);
                if (!close_buffer)
-                       removeWorkArea(currentMainWorkArea());
+                       removeWorkArea(wa);
                else
                        theBufferList().release(&buf);
                return true;
@@ -2012,6 +2018,19 @@ bool GuiView::saveBufferIfNeeded(Buffer & buf, bool hiding)
 }
 
 
+bool GuiView::inMultiTabs(GuiWorkArea * wa)
+{
+       Buffer & buf = wa->bufferView().buffer();
+
+       for (int i = 0; i != d.splitter_->count(); ++i) {
+               GuiWorkArea * wa_ = d.tabWorkArea(i)->workArea(buf);
+               if (wa_ && wa_ != wa)
+                       return true;
+       }
+       return inMultiViews(wa);
+}
+
+
 bool GuiView::inMultiViews(GuiWorkArea * wa)
 {
        QList<int> const ids = guiApp->viewIds();