On 11/09/12 20:42, Tommaso Cucinotta wrote:
I just noticed that when you type C-w, LyX closes the buffer, along with all views.

Also, if you have a split window and multiple tabbed views on both splits, pushing the "X" button on one of the tabs triggers a close of the buffer, so also the view(s) on the other splits on that buffer disappear.

Shouldn't we close the view only, in such cases, and only when closing the last view, close the buffer ?

Please, find attached a patch that I think implements a better behaviour.

1) C-w now closes only the current workarea
2) Pressing `X' on a tabbed workarea only closes that WA
3) Typing `close-tab' in the minibuffer only closes the current WA

In all cases, if other WAs exist showing the same buffer, they are not closed; the user is not queried about saving changes in such a case. Only when the last WA is closed, user is queried and buffer is closed as well.

4) Original File->Close menu entry is still tied to BUFFER_CLOSE, closing all WAs of the buffer

Any comment is welcome.

    T.

commit 91146f9
Author: Tommaso Cucinotta <tomm...@lyx.org>
Date:   Sat Sep 15 23:37:55 2012 +0100

    Don't force closing buffer when only a single workarea needs to be closed.
    For discussion, see http://comments.gmane.org/gmane.editors.lyx.devel/142638

diff --git a/lib/bind/cua.bind b/lib/bind/cua.bind
index f224af6..cd17cbb 100644
--- a/lib/bind/cua.bind
+++ b/lib/bind/cua.bind
@@ -39,7 +39,7 @@ Format 1
 \bind "C-n"			"buffer-new"
 \bind "C-S-N"			"buffer-new-template"
 \bind "C-o"			"file-open"
-\bind "C-w"			"buffer-close"
+\bind "C-w"			"close-tab"
 \bind "C-s"			"buffer-write"
 \bind "C-S-S"			"buffer-write-as"
 \bind "C-p"			"dialog-show print"
diff --git a/src/FuncCode.h b/src/FuncCode.h
index 4924ad2..0c097b1 100644
--- a/src/FuncCode.h
+++ b/src/FuncCode.h
@@ -456,6 +456,7 @@ enum FuncCode
 	LFUN_IN_IPA,                    // spitz, 20120520
 	LFUN_IPAMACRO_INSERT,           // spitz, 20120822
 	// 355
+	LFUN_CLOSE_TAB,			// Tommaso, 20120915
 	LFUN_LASTACTION                 // end of the table
 };
 
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 20cbb83..c2e248f 100644
--- a/src/LyXAction.cpp
+++ b/src/LyXAction.cpp
@@ -2685,6 +2685,18 @@ void LyXAction::init()
  * \endvar
  */
 		{ LFUN_CLOSE_TAB_GROUP, "close-tab-group", ReadOnly, Buffer },
+
+/*!
+ * \var lyx::FuncCode lyx::LFUN_CLOSE_TAB
+ * \li Action: Close the current tab.
+ * \li Notion: Close the current work area. If no other work areas are showing the buffer,
+               then close the associated buffer as well.
+ * \li Syntax: close-tab
+ * \li Origin: Tommaso, 15 Sep 2012
+ * \endvar
+ */
+		{ LFUN_CLOSE_TAB, "close-tab", ReadOnly, Buffer },
+
 /*!
  * \var lyx::FuncCode lyx::LFUN_DIALOG_SHOW
  * \li Action: Shows hidden dialog or creates new one for a given function/inset settings etc.
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index fe69318..b5a56ff 100644
--- a/src/frontends/qt4/GuiView.cpp
+++ b/src/frontends/qt4/GuiView.cpp
@@ -330,6 +330,18 @@ struct GuiView::GuiViewPrivate
 		return tabWorkArea(0);
 	}
 
+	int countWorkAreasOf(Buffer & buf)
+	{
+		int areas = tabWorkAreaCount();
+		int count = 0;
+		for (int i = 0; i != areas;  ++i) {
+			TabWorkArea * twa = tabWorkArea(i);
+			if (twa->workArea(buf))
+				++count;
+		}
+		return count;
+	}
+
 #if (QT_VERSION >= 0x040400)
 	void setPreviewFuture(QFuture<Buffer::ExportStatus> const & f)
 	{
@@ -1688,6 +1700,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
 		break;
 
 	case LFUN_BUFFER_CLOSE:
+	case LFUN_CLOSE_TAB:
 		enable = doc_buffer;
 		break;
 
@@ -2458,10 +2471,15 @@ bool GuiView::hideWorkArea(GuiWorkArea * wa)
 }
 
 
+// We only want to close the buffer if it is not visible in other workareas
+// of the same view, nor in other views, and if this is not a child
 bool GuiView::closeWorkArea(GuiWorkArea * wa)
 {
 	Buffer & buf = wa->bufferView().buffer();
-	return closeWorkArea(wa, !buf.parent());
+
+	bool close_buffer = d.countWorkAreasOf(buf) == 1
+		&& !inOtherView(buf) && !buf.parent();
+	return closeWorkArea(wa, close_buffer);
 }
 
 
@@ -3570,6 +3588,21 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			}
 			break;
 
+		case LFUN_CLOSE_TAB:
+			if (TabWorkArea * twa = d.currentTabWorkArea()) {
+				closeWorkArea(twa->currentWorkArea());
+				d.current_work_area_ = 0;
+				twa = d.currentTabWorkArea();
+				// Switch to the next GuiWorkArea in the found TabWorkArea.
+				if (twa) {
+					// Make sure the work area is up to date.
+					setCurrentWorkArea(twa->currentWorkArea());
+				} else {
+					setCurrentWorkArea(0);
+				}
+			}
+			break;
+
 		case LFUN_COMPLETION_INLINE:
 			if (d.current_work_area_)
 				d.current_work_area_->completer().showInline();
diff --git a/src/frontends/qt4/GuiView.h b/src/frontends/qt4/GuiView.h
index bc7b9ec..dff2fb6 100644
--- a/src/frontends/qt4/GuiView.h
+++ b/src/frontends/qt4/GuiView.h
@@ -145,7 +145,7 @@ public:
 
 	/// hides the workarea and makes sure it is clean
 	bool hideWorkArea(GuiWorkArea * wa);
-	/// closes the workarea
+	/// closes workarea; close buffer only if no other workareas point to it
 	bool closeWorkArea(GuiWorkArea * wa);
 	/// closes the buffer
 	bool closeBuffer(Buffer & buf);

Reply via email to