]> git.lyx.org Git - lyx.git/blobdiff - src/frontends/qt4/GuiView.cpp
File->Close All now really closes all buffers. That is, all visible buffers in all...
[lyx.git] / src / frontends / qt4 / GuiView.cpp
index d44065f07c506500c1cf353fcd8754a2af812b84..c92103062a2825b8e5ac76032da303c7e8ca9d83 100644 (file)
@@ -544,10 +544,12 @@ void GuiView::closeEvent(QCloseEvent * close_event)
        LYXERR(Debug::DEBUG, "GuiView::closeEvent()");
        closing_ = true;
 
+       writeSession();
+
        // it can happen that this event arrives without selecting the view,
        // e.g. when clicking the close button on a background window.
        setFocus();
-       if (!closeBufferAll(true)) {
+       if (!closeWorkAreaAll()) {
                closing_ = false;
                close_event->ignore();
                return;
@@ -584,34 +586,6 @@ void GuiView::closeEvent(QCloseEvent * close_event)
 }
 
 
-bool GuiView::closeBufferAll(bool in_close_event)
-{
-       GuiWorkArea * active_wa = currentMainWorkArea();
-       setCurrentWorkArea(active_wa);
-
-       // We might be in a situation that there is still a tabWorkArea, but
-       // there are no tabs anymore. This can happen when we get here after a 
-       // TabWorkArea::lastWorkAreaRemoved() signal. Therefore we count how
-       // many TabWorkArea's have no documents anymore.
-       int empty_twa = 0;
-
-       // We have to call count() each time, because it can happen that
-       // more than one splitter will disappear in one iteration (bug 5998).
-       for (; d.splitter_->count() > empty_twa; ) {
-               TabWorkArea * twa = d.tabWorkArea(empty_twa);
-                               
-               if (twa->count() == 0)
-                       ++empty_twa;
-               else {
-                       setCurrentWorkArea(twa->currentWorkArea());
-                       if (!closeTabWorkArea(twa, true, active_wa))
-                               return false;
-               }
-       }
-       return true;
-}
-
-
 void GuiView::dragEnterEvent(QDragEnterEvent * event)
 {
        if (event->mimeData()->hasUrls())
@@ -1108,7 +1082,7 @@ void GuiView::connectBuffer(Buffer & buf)
 void GuiView::disconnectBuffer()
 {
        if (d.current_work_area_)
-               d.current_work_area_->bufferView().setGuiDelegate(0);
+               d.current_work_area_->bufferView().buffer().setGuiDelegate(0);
 }
 
 
@@ -1214,21 +1188,9 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
                enable = buf;
                break;
 
-       case LFUN_BUFFER_CLOSE_ALL: {
-               enable = false;
-               BufferList::iterator it = theBufferList().begin();
-               BufferList::iterator end = theBufferList().end();
-               int visible_buffers = 0;
-               for (; it != end; ++it) {
-                       if (workArea(**it))
-                               ++visible_buffers;
-                       if (visible_buffers > 1) {
-                               enable = true;
-                               break;
-                       }
-               }
+       case LFUN_BUFFER_CLOSE_ALL:
+               enable = theBufferList().last() != theBufferList().first();
                break;
-       }
 
        case LFUN_SPLIT_VIEW:
                if (cmd.getArg(0) == "vertical")
@@ -1903,22 +1865,91 @@ bool GuiView::closeBuffer()
 }
 
 
+void GuiView::writeSession() const {
+       GuiWorkArea const * active_wa = currentMainWorkArea();
+       for (int i = 0; i < d.splitter_->count(); ++i) {
+               TabWorkArea * twa = d.tabWorkArea(i);
+               for (int j = 0; j < twa->count(); ++j) {
+                       GuiWorkArea * wa = static_cast<GuiWorkArea *>(twa->widget(j));
+                       Buffer & buf = wa->bufferView().buffer();
+                       theSession().lastOpened().add(buf.fileName(), wa == active_wa);
+               }
+       }
+}
+
+
+bool GuiView::closeBufferAll()
+{
+       // Close the workareas in all other views
+       QList<int> const ids = guiApp->viewIds();
+       for (int i = 0; i != ids.size(); ++i) {
+               if (id_ != ids[i] && !guiApp->view(ids[i]).closeWorkAreaAll())
+                       return false;
+       }
+
+       // Close our own workareas
+       if (!closeWorkAreaAll())
+               return false;
+
+       // Now close the hidden buffers. We prevent hidden buffers from being
+       // dirty, so we can just close them.
+       theBufferList().closeAll();
+       return true;
+}
+
+
+bool GuiView::closeWorkAreaAll()
+{
+       // To write in the session file which workarea was active.
+       GuiWorkArea * active_wa = currentMainWorkArea();
+       setCurrentWorkArea(active_wa);
+
+       // We might be in a situation that there is still a tabWorkArea, but
+       // there are no tabs anymore. This can happen when we get here after a 
+       // TabWorkArea::lastWorkAreaRemoved() signal. Therefore we count how
+       // many TabWorkArea's have no documents anymore.
+       int empty_twa = 0;
+
+       // We have to call count() each time, because it can happen that
+       // more than one splitter will disappear in one iteration (bug 5998).
+       for (; d.splitter_->count() > empty_twa; ) {
+               TabWorkArea * twa = d.tabWorkArea(empty_twa);
+
+               if (twa->count() == 0)
+                       ++empty_twa;
+               else {
+                       setCurrentWorkArea(twa->currentWorkArea());
+                       if (!closeTabWorkArea(twa, active_wa))
+                               return false;
+               }
+       }
+       return true;
+}
+
+
 bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
-       bool in_close_event, bool mark_active)
+       bool is_active)
 {
        Buffer & buf = wa->bufferView().buffer();
 
-       if (close_buffer && !in_close_event) {
+       // If we are in a close_event all children will be closed in some time,
+       // so no need to do it here. This will ensure that the children end up
+       // in the session file in the correct order. If we close the master
+       // buffer, we can close or release the child buffers here too.
+       if (close_buffer && !closing_) {
                vector<Buffer *> clist = buf.getChildren();
                for (vector<Buffer *>::const_iterator it = clist.begin();
                         it != clist.end(); ++it) {
                        // If a child is dirty, do not close
                        // without user intervention
-                       //FIXME: should buffers be closed or not?
                        //FIXME: should we look in other tabworkareas?
-                       GuiWorkArea * child_wa = workArea(**it);
-                       if (child_wa && !closeWorkArea(child_wa, !close_buffer, false))
-                               return false;
+                       Buffer * child_buf = *it;
+                       GuiWorkArea * child_wa = workArea(*child_buf);
+                       if (child_wa) {
+                               if (!closeWorkArea(child_wa, true))
+                                       return false;
+                       } else
+                               theBufferList().releaseChild(&buf, child_buf);
                }
        }
        // goto bookmark to update bookmark pit.
@@ -1935,8 +1966,8 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
                // save in sessions if requested
                // do not save childs if their master
                // is opened as well
-               if (in_close_event)
-                       theSession().lastOpened().add(buf.fileName(), mark_active);
+               if (closing_)
+                       theSession().lastOpened().add(buf.fileName(), is_active);
                if (!close_buffer)
                        removeWorkArea(wa);
                else
@@ -1947,8 +1978,7 @@ bool GuiView::closeWorkArea(GuiWorkArea * wa, bool close_buffer,
 }
 
 
-bool GuiView::closeTabWorkArea(TabWorkArea * twa, bool in_close_event,
-                                                          GuiWorkArea * main_work_area)
+bool GuiView::closeTabWorkArea(TabWorkArea * twa, GuiWorkArea * main_work_area)
 {
        while (twa == d.currentTabWorkArea()) {
                twa->setCurrentIndex(twa->count()-1);
@@ -1961,11 +1991,9 @@ bool GuiView::closeTabWorkArea(TabWorkArea * twa, bool in_close_event,
                // in another view, and if this is not a child and if we are closing
                // a view (not a tabgroup).
                bool const close_buffer = 
-                       !inMultiViews(wa) && !b.parent() && in_close_event;
+                       !inMultiViews(wa) && !b.parent() && closing_;
 
-               // closeBuffer() needs buffer workArea still alive and
-               // set as currrent one, and destroys it
-               if (!closeWorkArea(wa, close_buffer, true, is_active_wa))
+               if (!closeWorkArea(wa, close_buffer, is_active_wa))
                        return false;
        }
        return true;