]> git.lyx.org Git - lyx.git/commitdiff
Now LyX closes the current document WA only by default (other WAs remain open).
authorTommaso Cucinotta <tommaso@lyx.org>
Sat, 15 Sep 2012 22:37:55 +0000 (23:37 +0100)
committerTommaso Cucinotta <tommaso@lyx.org>
Fri, 28 Sep 2012 22:12:38 +0000 (23:12 +0100)
If the WA is the last one showing a buffer, then the buffer may either be
closed or kept hidden, or the user is asked. The behaviour is controlled
by a new preference option.
For discussion, see http://comments.gmane.org/gmane.editors.lyx.devel/142638

RELEASE-NOTES
lib/bind/cua.bind
src/FuncCode.h
src/LyXAction.cpp
src/LyXRC.cpp
src/LyXRC.h
src/frontends/qt4/GuiPrefs.cpp
src/frontends/qt4/GuiView.cpp
src/frontends/qt4/GuiView.h
src/frontends/qt4/ui/PrefUi.ui

index ee523fb21ccd52fceeb0f3f39cb4a5b8a4109bd2..3d5d7469cd7d6e6f2489f603d58d3306c47aaf43 100644 (file)
@@ -6,6 +6,17 @@ when upgrading from earlier versions to a version of the 2.1.x series.
 Interface changes
 -----------------
 
+Whenever the user closes a (tabbed) view on a document, either by
+clicking on the tab close button, or by using the File->Close menu,
+LyX now closes exclusively that specific view. If there are other
+views showing the same document, they are not closed. When the user
+closes the last view, LyX can be configured for either closing the
+document, or keeping it into memory as a hidden document (that can be
+shown again through the View->Hidden-> submenu).
+
+A new configurable preference option has been added, allowing for either
+(close_buffer_with_last_view)
+
 There have been some changes to the LyX command line. The following new
 options have been added:
 
@@ -27,6 +38,11 @@ search operation by hitting the ESC key.
 
 The following pref variables were changed in 2.1:
 
+- \\close_buffer_with_last_view [yes|no|ask]
+  When user closes the last view on a document, close the document
+  as well ("yes"), or hide the document ("no"), or ask the user
+  ("ask").
+
 The following pref variables are obsoleted in 2.1:
 
 - \\default_language
@@ -45,6 +61,10 @@ The following new LyX functions have been introduced:
   This is also available through a new menu voice within the
   [Edit]->[Paste Special...] sub-menu.
 
+- LFUN_VIEW_CLOSE
+  Close the current document view only, if there are no more views
+  on the document, either close or hide it (see the new preference
+  option \\close_buffer_with_last_view)
 
 The following LyX functions have been removed:
 
index f224af6f8b3b5cf42943e290276bb106741a7f55..6860bff84c4195c67fbf553dd707fd0ef9767b6c 100644 (file)
@@ -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"
index 4924ad2c5d58c4ca63a8cf952f033fea8998f522..d196d641affcd5a66a8f9052d04bff4bf327ea86 100644 (file)
@@ -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
 };
 
index 20cbb833f0a3f1459cd9c0aa7e8307bb644599e6..929c35236b6b54e663784a417ff49b070b9e34b0 100644 (file)
@@ -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.
index 4669f68babbfd9016ce578f8dbb6d4c85fab351f..b7dd2250fefb9d0ff7d4b2e0c1d9d90464771297 100644 (file)
@@ -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;
index 4032e6bebc01b89aa29334210064c96ba22f5cee..dbda8d9153740f4bddde3427c2ee1a4462fa94bf 100644 (file)
@@ -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;
 };
 
 
index d3770847504143b75319a641604a1cf9d5caf69c..a65af05d76703ff4cb08ee2d8b8d2418459303c9 100644 (file)
@@ -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);
 }
 
 
index fe69318f990d208d3eb7a1f1090bcccb9b984df2..3eda5409a27cd6e0f4382abdb946e9e009ce7a4e 100644 (file)
@@ -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();
index bc7b9ecc1e59e19759a332a35097ff6d479d7ccc..dff2fb63db2f57b0805d76665b09e12a667a8342 100644 (file)
@@ -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);
index fe50bcf0c620349119235afaeb33c48324894838..17a7ca9c9061e3a174064ffd586b063a69161ebf 100644 (file)
@@ -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">
      </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>
       <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>
         </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>