On 17/09/12 08:57, Rainer M Krug wrote:
Agreed - that would make it clear, that it is simply "a new niew of the same document in the same LyX instance" and not a new LyX instance. Cheers, Rainer

Hi,

please, find attached the take 2 of this patch.

Changes:
-) LFUN renamed to "view-close"
-) when closing the last view, it can always close buffer, always hide it, or ask the user -) a preference "\close_buffer_with_last_view [yes|no|ask]" in ~/.lyx/preferences controls the behavior -) the GUI allows for setting the preference in Tools->Preferences->Look&Feel->User Interface
-) default value is: close buffer

-) Ctrl-w is now tied by default to the new LFUN.

On Ubuntu, the File->Close (buffer) menu gets automagically tied to Ctrl+F4, I don't know why

The only missing thing is the additional check-box on the dialog querying the user, that allows to automatically set and save the preference. If anyone wanted to write another Alert::xxx() convenience function popping out a dialog with such a checkbox, I'd use it of course :-).

Anyone willing to try it ? Comments ? Thanks,

Bye,

    Tommaso

commit 05d4863
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..6860bff 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"			"view-close"
 \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..d196d64 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_VIEW_CLOSE,		// Tommaso, 20120915
 	LFUN_LASTACTION                 // end of the table
 };
 
diff --git a/src/LyXAction.cpp b/src/LyXAction.cpp
index 20cbb83..929c352 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_VIEW_CLOSE
+ * \li Action: Close the current document work area.
+ * \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: view-close
+ * \li Origin: Tommaso, 15 Sep 2012
+ * \endvar
+ */
+		{ LFUN_VIEW_CLOSE, "view-close", 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/LyXRC.cpp b/src/LyXRC.cpp
index 4669f68..b7dd225 100644
--- a/src/LyXRC.cpp
+++ b/src/LyXRC.cpp
@@ -210,6 +210,7 @@ LexerKeyword lyxrcTags[] = {
 	{ "\\viewer", LyXRC::RC_VIEWER},
 	{ "\\viewer_alternatives", LyXRC::RC_VIEWER_ALTERNATIVES },
 	{ "\\visual_cursor", LyXRC::RC_VISUAL_CURSOR },
+	{ "\\close_buffer_with_last_view", LyXRC::RC_CLOSE_BUFFER_WITH_LAST_VIEW },
 	{ "format", LyXRC::RC_LYXRCFORMAT }
 };
 
@@ -370,6 +371,7 @@ void LyXRC::setDefaults()
 	default_decimal_point = ".";
 	default_length_unit = Length::CM;
 	cursor_width = 1;
+	close_buffer_with_last_view = "yes";
 }
 
 
@@ -1042,6 +1044,9 @@ LyXRC::ReturnValues LyXRC::read(Lexer & lexrc, bool check_format)
 		case RC_VISUAL_CURSOR:
 			lexrc >> visual_cursor;
 			break;
+		case RC_CLOSE_BUFFER_WITH_LAST_VIEW:
+			lexrc >> close_buffer_with_last_view;
+			break;
 		case RC_AUTO_NUMBER:
 			lexrc >> auto_number;
 			break;
@@ -2528,6 +2533,14 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
 		}
 		if (tag != RC_LAST)
 			break;
+	case RC_CLOSE_BUFFER_WITH_LAST_VIEW:
+		if (ignore_system_lyxrc ||
+			close_buffer_with_last_view != system_lyxrc.close_buffer_with_last_view) {
+			os << "# When closing last view, buffer closes (yes), hides (no), or ask the user (ask)\n";
+			os << "\\close_buffer_with_last_view " << close_buffer_with_last_view << '\n';
+		}
+		if (tag != RC_LAST)
+			break;
 	case RC_LANGUAGE_CUSTOM_PACKAGE:
 		if (ignore_system_lyxrc ||
 		    language_custom_package != system_lyxrc.language_custom_package) {
@@ -3025,6 +3038,7 @@ void actOnUpdatedPrefs(LyXRC const & lyxrc_orig, LyXRC const & lyxrc_new)
 	case LyXRC::RC_FULL_SCREEN_TOOLBARS:
 	case LyXRC::RC_FULL_SCREEN_WIDTH:
 	case LyXRC::RC_VISUAL_CURSOR:
+	case LyXRC::RC_CLOSE_BUFFER_WITH_LAST_VIEW:
 	case LyXRC::RC_VIEWER:
 	case LyXRC::RC_VIEWER_ALTERNATIVES:
 	case LyXRC::RC_FORWARD_SEARCH_DVI:
@@ -3387,6 +3401,10 @@ string const LyXRC::getDescription(LyXRCTags tag)
 		str = _("Select to have visual bidi cursor movement, unselect for logical movement.");
 		break;
 
+	case RC_CLOSE_BUFFER_WITH_LAST_VIEW:
+		str = _("Specify whether, closing the last view of an open document, LyX should close the document (yes), hide it (no), or ask the user (ask).");
+		break;
+
 	case RC_SCREEN_DPI:
 		str = _("DPI (dots per inch) of your monitor is auto-detected by LyX. If that goes wrong, override the setting here.");
 		break;
diff --git a/src/LyXRC.h b/src/LyXRC.h
index 4032e6b..dbda8d9 100644
--- a/src/LyXRC.h
+++ b/src/LyXRC.h
@@ -190,6 +190,7 @@ public:
 		RC_VIEWER,
 		RC_VIEWER_ALTERNATIVES,
 		RC_VISUAL_CURSOR,
+		RC_CLOSE_BUFFER_WITH_LAST_VIEW,
 		RC_LAST
 	};
 
@@ -547,6 +548,8 @@ public:
 	bool force_paint_single_char;
 	///
 	int cursor_width;
+	/// One of: yes, no, ask
+	std::string close_buffer_with_last_view;
 };
 
 
diff --git a/src/frontends/qt4/GuiPrefs.cpp b/src/frontends/qt4/GuiPrefs.cpp
index d377084..a65af05 100644
--- a/src/frontends/qt4/GuiPrefs.cpp
+++ b/src/frontends/qt4/GuiPrefs.cpp
@@ -2526,6 +2526,8 @@ PrefUserInterface::PrefUserInterface(GuiPreferences * form)
 		this, SIGNAL(changed()));
 	connect(iconSetCO, SIGNAL(activated(int)),
 		this, SIGNAL(changed()));
+	connect(closeLastViewCO, SIGNAL(activated(int)),
+		this, SIGNAL(changed()));
 	connect(restoreCursorCB, SIGNAL(clicked()),
 		this, SIGNAL(changed()));
 	connect(loadSessionCB, SIGNAL(clicked()),
@@ -2572,6 +2574,19 @@ void PrefUserInterface::apply(LyXRC & rc) const
 #if QT_VERSION < 0x040500
 	rc.single_close_tab_button = true;
 #endif
+	switch (closeLastViewCO->currentIndex()) {
+	case 0:
+		rc.close_buffer_with_last_view = "yes";
+		break;
+	case 1:
+		rc.close_buffer_with_last_view = "no";
+		break;
+	case 2:
+		rc.close_buffer_with_last_view = "ask";
+		break;
+	default:
+		;
+	}
 }
 
 
@@ -2601,6 +2616,12 @@ void PrefUserInterface::update(LyXRC const & rc)
 	singleInstanceCB->setChecked(rc.single_instance && !rc.lyxpipes.empty());
 	singleInstanceCB->setEnabled(!rc.lyxpipes.empty());
 	singleCloseTabButtonCB->setChecked(rc.single_close_tab_button);
+	if (rc.close_buffer_with_last_view == "yes")
+		closeLastViewCO->setCurrentIndex(0);
+	else if (rc.close_buffer_with_last_view == "no")
+		closeLastViewCO->setCurrentIndex(1);
+	else if (rc.close_buffer_with_last_view == "ask")
+		closeLastViewCO->setCurrentIndex(2);
 }
 
 
diff --git a/src/frontends/qt4/GuiView.cpp b/src/frontends/qt4/GuiView.cpp
index fe69318..3eda540 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_VIEW_CLOSE:
 		enable = doc_buffer;
 		break;
 
@@ -2458,10 +2471,45 @@ 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 last_wa = d.countWorkAreasOf(buf) == 1
+		&& !inOtherView(buf) && !buf.parent();
+
+	bool close_buffer = last_wa;
+
+	if (last_wa) {
+		if (lyxrc.close_buffer_with_last_view == "yes")
+			; // Nothing to do
+		else if (lyxrc.close_buffer_with_last_view == "no")
+			close_buffer = false;
+		else {
+			docstring file;
+			if (buf.isUnnamed())
+				file = from_utf8(buf.fileName().onlyFileName());
+			else
+				file = buf.fileName().displayName(30);
+			docstring const text = bformat(
+				_("Last view on document %1$s is being closed.\n"
+				  "Would you like to close or hide the document?\n"
+				  "\n"
+				  "Hidden documents can be displayed back through\n"
+				  "the menu: View->Hidden->...\n"
+				  "\n"
+				  "To remove this question, set your preference in:\n"
+				  "  Tools->Preferences->Look&Feel->UserInterface\n"
+				), file);
+			int ret = Alert::prompt(_("Close or hide document?"),
+				text, 0, 1, _("&Close"), _("&Hide"));
+			close_buffer = (ret == 0);
+		}
+	}
+
+	return closeWorkArea(wa, close_buffer);
 }
 
 
@@ -3570,6 +3618,21 @@ void GuiView::dispatch(FuncRequest const & cmd, DispatchResult & dr)
 			}
 			break;
 
+		case LFUN_VIEW_CLOSE:
+			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);
diff --git a/src/frontends/qt4/ui/PrefUi.ui b/src/frontends/qt4/ui/PrefUi.ui
index fe50bcf..17a7ca9 100644
--- a/src/frontends/qt4/ui/PrefUi.ui
+++ b/src/frontends/qt4/ui/PrefUi.ui
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
 <ui version="4.0">
  <class>PrefUi</class>
  <widget class="QWidget" name="PrefUi">
@@ -5,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>413</width>
-    <height>408</height>
+    <width>604</width>
+    <height>559</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -52,20 +53,21 @@
      </property>
     </spacer>
    </item>
-   <item row="1" column="0" >
-    <widget class="QLabel" name="iconSetLA" >
-     <property name="text" >
+   <item row="1" column="0">
+    <widget class="QLabel" name="iconSetLA">
+     <property name="text">
       <string>&amp;Icon Set:</string>
      </property>
-     <property name="buddy" >
+     <property name="buddy">
       <cstring>iconSetCO</cstring>
      </property>
     </widget>
    </item>
-   <item row="1" column="1" >
-    <widget class="QComboBox" name="iconSetCO" >
-     <property name="toolTip" >
-      <string>The icon set to use. Warning: normal size of icons may be&#x0a;wrong until you save the preferences and restart LyX.</string>
+   <item row="1" column="1">
+    <widget class="QComboBox" name="iconSetCO">
+     <property name="toolTip">
+      <string>The icon set to use. Warning: normal size of icons may be
+wrong until you save the preferences and restart LyX.</string>
      </property>
     </widget>
    </item>
@@ -259,7 +261,8 @@
       <item row="5" column="0" colspan="2">
        <widget class="QCheckBox" name="singleInstanceCB">
         <property name="toolTip">
-         <string>Whether to open documents in an already running instance of LyX.&#x0a;(Set the LyXServer pipe path and restart LyX to enable this feature)</string>
+         <string>Whether to open documents in an already running instance of LyX.
+(Set the LyXServer pipe path and restart LyX to enable this feature)</string>
         </property>
         <property name="text">
          <string>S&amp;ingle instance</string>
@@ -276,6 +279,32 @@
         </property>
        </widget>
       </item>
+      <item row="7" column="0">
+       <widget class="QLabel" name="label">
+        <property name="text">
+         <string>Closing last view:</string>
+        </property>
+       </widget>
+      </item>
+      <item row="7" column="1" colspan="4">
+       <widget class="QComboBox" name="closeLastViewCO">
+        <item>
+         <property name="text">
+          <string>Closes document</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Hides document</string>
+         </property>
+        </item>
+        <item>
+         <property name="text">
+          <string>Ask the user</string>
+         </property>
+        </item>
+       </widget>
+      </item>
      </layout>
     </widget>
    </item>

Reply via email to