changeset 23322:c4aebfe51a17

provide a context menu and shortcuts for the doc browser tab bar (bug #44605) * documentation-dock-widget.cc (constructor): set focus proxy to _webinfo; (notice_settings): new slot, just calling the settings method in _webinfo; * documentation-dock-widget.h: new slot notice_settings * webinfo.cc (webinfo::webinfo): add close actions to the tab bar; (webinfo::add_action): new helper function for adding actions to a menu; (webinfo::request_close_tab): new slot for tab closing action; (webinfo::request_close_other_tabs): new slot for closing all other tabs; (webinfo::tab_state_changed): function called when a new tab gets focus for dis-/enabling actions and setting the focus to the new tab; (webinfo::current_tab_changed, webinfo::addNewTab, webinfo::close_tab): use new function tab_state_changed; (webinfo::notice_settings): new function called from dock widget when settings have changed, sets the close shortcuts (same as in editor); (webinfo_tab_bar::webinfo_tab_bar): initialize the new context menu; (webinfo_tab_bar::~webinfo_tab_bar): delete the context menu; (webinfo_tab_bar::mousePressEvent): extend event handler by the right click for showing the context menu * webinfo.h (webinfo_tab_bar): class variable _context_menu and public method returning this menu, constructor and destructor in webinfo.cc (webinfo): new methods add_action and notice_settings, new slots request_close_tab and request_close_other_tabs, new actions for tab closing
author Torsten <mttl@mailbox.org>
date Tue, 21 Mar 2017 20:25:27 +0100
parents ac4d0a72927a
children 4adb9517d56a
files libgui/src/documentation-dock-widget.cc libgui/src/documentation-dock-widget.h libgui/src/qtinfo/webinfo.cc libgui/src/qtinfo/webinfo.h
diffstat 4 files changed, 183 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/documentation-dock-widget.cc	Tue Mar 21 20:25:26 2017 +0100
+++ b/libgui/src/documentation-dock-widget.cc	Tue Mar 21 20:25:27 2017 +0100
@@ -36,6 +36,7 @@
 
   _webinfo = new webinfo (this);
   setWidget (_webinfo);
+  setFocusProxy (_webinfo);
 
   connect (p, SIGNAL (show_doc_signal (const QString &)),
            this, SLOT (showDoc (const QString &)));
@@ -68,3 +69,9 @@
   _webinfo->load_ref (name);
 
 }
+
+void
+documentation_dock_widget::notice_settings (const QSettings *settings)
+{
+  _webinfo->notice_settings (settings);
+}
--- a/libgui/src/documentation-dock-widget.h	Tue Mar 21 20:25:26 2017 +0100
+++ b/libgui/src/documentation-dock-widget.h	Tue Mar 21 20:25:27 2017 +0100
@@ -35,12 +35,17 @@
 
   documentation_dock_widget (QWidget *parent = 0);
 
+public slots:
+
+  void notice_settings (const QSettings *settings);
+
 protected slots:
   void copyClipboard ();
   void pasteClipboard ();
   void selectAll ();
 
   void showDoc (const QString & name);
+
 private:
 
   webinfo *_webinfo;
--- a/libgui/src/qtinfo/webinfo.cc	Tue Mar 21 20:25:26 2017 +0100
+++ b/libgui/src/qtinfo/webinfo.cc	Tue Mar 21 20:25:27 2017 +0100
@@ -38,6 +38,7 @@
 #include "help.h"
 #include "defaults.h"
 #include "resource-manager.h"
+#include "shortcut-manager.h"
 
 
 webinfo::webinfo (QWidget *p)
@@ -87,6 +88,15 @@
   _search_check_box = new QCheckBox (tr ("Global search"));
   hbox_layout->addWidget (_search_check_box);
 
+  _close_action = add_action (_tab_bar->get_context_menu (),
+        resource_manager::icon ("window-close",false), tr ("&Close"),
+        SLOT (request_close_tab (bool)));
+  _close_others_action = add_action (_tab_bar->get_context_menu (),
+        resource_manager::icon ("window-close",false), tr ("Close &Other Tabs"),
+        SLOT (request_close_other_tabs (bool)));
+  _close_action->setEnabled (false);
+  _close_others_action->setEnabled (false);
+
   connect (_tab_bar, SIGNAL (tabCloseRequested (int)), this,
            SLOT (close_tab (int)));
   connect (_tab_bar, SIGNAL (currentChanged (int)), this,
@@ -112,6 +122,47 @@
     }
 }
 
+// Add an action to a menu or the widget itself
+QAction*
+webinfo::add_action (QMenu *menu, const QIcon &icon, const QString &text,
+                         const char *member)
+{
+  QAction *a;
+
+  if (menu)
+    a = menu->addAction (icon, text, this, member);
+  else
+    {
+      a = new QAction (this);
+      connect (a, SIGNAL (triggered ()), this, member);
+    }
+
+  addAction (a);  // important for shortcut context
+  a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
+
+  return a;
+}
+
+// Slot for the close tab action
+void
+webinfo::request_close_tab (bool)
+{
+  close_tab (_tab_bar->currentIndex ());
+}
+
+// Slot for the close other tabs action
+void
+webinfo::request_close_other_tabs (bool)
+{
+  int current = _tab_bar->currentIndex ();
+
+  for (int index = _tab_bar->count ()-1; index >= 0; index--)
+  {
+    if (current != index)
+      close_tab (index);
+  }
+}
+
 bool
 webinfo::set_info_path (const QString& info_path)
 {
@@ -163,6 +214,14 @@
 }
 
 void
+webinfo::tab_state_changed ()
+{
+  _close_action->setEnabled (_tab_bar->count () > 1);
+  _close_others_action->setEnabled (_tab_bar->count () > 1);
+  setFocusProxy (_stacked_widget->currentWidget ());
+}
+
+void
 webinfo::current_tab_changed (int index)
 {
   QVariant tab_data = _tab_bar->tabData (index);
@@ -174,6 +233,8 @@
     {
       _text_browser->setFont (_font_web);
     }
+
+  tab_state_changed ();
 }
 
 QTextBrowser *
@@ -200,6 +261,8 @@
   connect (_tab_bar, SIGNAL (currentChanged (int)), this,
            SLOT (current_tab_changed (int)));
 
+  tab_state_changed ();
+
   if (_text_browser->font () != _font_web)
     {
       _text_browser->setFont (_font_web);
@@ -219,6 +282,8 @@
 
       _tab_bar->removeTab (index);
     }
+
+  tab_state_changed ();
 }
 
 void
@@ -313,31 +378,98 @@
     }
 }
 
+void
+webinfo::notice_settings (const QSettings* settings)
+{
+  shortcut_manager::set_shortcut (_close_action, "editor_file:close");
+  shortcut_manager::set_shortcut (_close_others_action, "editor_file:close_other");
+}
 
 //
 // Functions of the the reimplemented tab bar
 //
 
+webinfo_tab_bar::webinfo_tab_bar (QWidget *p) : QTabBar (p)
+{
+  // prepare the context menu of the tab bar
+  _context_menu = new QMenu (this);
+}
+
+webinfo_tab_bar::~webinfo_tab_bar ()
+{
+  delete _context_menu;
+}
+
 // Reimplement mouse event for filtering out the desired mouse clicks
 void
 webinfo_tab_bar::mousePressEvent (QMouseEvent *me)
 {
-  if (count () > 1 &&
-      ((me->type () == QEvent::MouseButtonDblClick &&
-        me->button() == Qt::LeftButton) ||
-       (me->type () != QEvent::MouseButtonDblClick &&
-        me->button() == Qt::MidButton)))
+  QPoint click_pos;
+  int clicked_idx = -1;
+
+  // detect the tab where the click occured
+  for (int i = 0; i < count (); i++)
+    {
+      click_pos = mapToGlobal (me->pos ());
+      if (tabRect (i).contains (mapFromGlobal (click_pos)))
+        {
+          clicked_idx = i;
+          break;
+        }
+    }
+
+  // If a tab was clicked
+  if (clicked_idx >= 0)
     {
-      // Middle click into the tabbar -> close the tab
-      for (int i = 0; i < count (); i++)
+      int current_idx = currentIndex ();
+      // detect the mouse click
+      if ((me->type () == QEvent::MouseButtonDblClick &&
+           me->button() == Qt::LeftButton) ||
+          (me->type () != QEvent::MouseButtonDblClick &&
+           me->button() == Qt::MidButton))
+        {
+          // Middle click or double click -> close the tab
+          // Make the clicked tab the current one and close it
+          emit tabCloseRequested (clicked_idx);
+          // Was the closed tab before or after the previously current tab?
+          // According to the result, use previous index or reduce it by one
+          if (current_idx - clicked_idx > 0)
+            setCurrentIndex (current_idx - 1);
+          else if (current_idx - clicked_idx < 0)
+            setCurrentIndex (current_idx);
+        }
+      else if (me->type () != QEvent::MouseButtonDblClick &&
+               me->button() == Qt::RightButton)
         {
-          QPoint clickPos = mapToGlobal (me->pos ());
-          if (tabRect (i).contains (mapFromGlobal (clickPos)))
+          setCurrentIndex (clicked_idx);
+          if (! _context_menu->exec (click_pos))
+            {
+              // No action selected, back to previous tab
+              setCurrentIndex (current_idx);
+            }
+          else
             {
-              emit tabCloseRequested (i);
-              break;
+              // Was the possibly only closed tab before or after the
+              // previously current tab? According to the result, use previous
+              // index or reduce it by one. Also prevent using a too large
+              // if other or all files were closed.
+              int new_idx = count () - 1;
+              if (new_idx > 0)
+                {
+                  if (current_idx - clicked_idx > 0)
+                    new_idx = current_idx - 1;
+                  else if (current_idx - clicked_idx < 0)
+                    new_idx = current_idx;
+                }
+              if (new_idx >= 0)
+                setCurrentIndex (new_idx);
             }
         }
+      else
+        {
+          // regular handling of the mouse event
+          QTabBar::mousePressEvent (me);
+        }
     }
   else
     {
--- a/libgui/src/qtinfo/webinfo.h	Tue Mar 21 20:25:26 2017 +0100
+++ b/libgui/src/qtinfo/webinfo.h	Tue Mar 21 20:25:27 2017 +0100
@@ -35,7 +35,10 @@
 #include <QLineEdit>
 #include <QCheckBox>
 #include <QToolButton>
+#include <QMenu>
+#include <QAction>
 #include <QMouseEvent>
+#include <QSettings>
 
 // subclassed QTabWidget for usable tab-bar and reimplemented mouse event
 class webinfo_tab_bar : public QTabBar
@@ -44,27 +47,38 @@
 
 public:
 
-  webinfo_tab_bar (QWidget *p) : QTabBar (p) { }
+  webinfo_tab_bar (QWidget *p);
+  ~webinfo_tab_bar ();
+  QMenu *get_context_menu () { return _context_menu; }
 
-  ~webinfo_tab_bar () { }
+public slots:
 
 protected:
 
   void mousePressEvent(QMouseEvent *event);
+
+private:
+
+  QMenu *_context_menu;
+
 };
 
+
 // The webinfo class
 class webinfo : public QWidget
 {
   Q_OBJECT
+
 public:
+
   webinfo (QWidget *parent = 0);
   bool set_info_path (const QString& info_path);
   void load_node (const QString& node_name);
-
   void load_ref (const QString &ref_name);
+  void notice_settings (const QSettings *settings);
 
 public slots:
+
   void link_clicked (const QUrl& link);
   void current_tab_changed (int index);
   void close_tab (int index);
@@ -76,7 +90,15 @@
   void pasteClipboard ();
   void selectAll ();
 
+  void request_close_tab (bool);
+  void request_close_other_tabs (bool);
+
 private:
+
+  QAction *add_action (QMenu *menu, const QIcon &icon, const QString &text,
+                       const char *member);
+  void tab_state_changed (void);
+
   QTextBrowser        *_text_browser;
   webinfo_tab_bar     *_tab_bar;
   QStackedWidget      *_stacked_widget;
@@ -89,6 +111,9 @@
   QFont               _font_web;
 
   QTextBrowser *addNewTab (const QString& name);
+  QAction *_close_action;
+  QAction *_close_others_action;
+
 };
 
 #endif