diff libgui/src/documentation.cc @ 29330:b92614cfdfed

add bookmark functionality to the documentation browser (bug #54938) * libgui/src/documentation-bookmarks.cc: new file for the bookmarks tab; (documentation_bookmarks): initialize the tab, the filter and the tree; prepare the bookmark file and read existing bookmarks; (~documentation_bookmarks): empty destructor; (add_bookmark): slot for the adding bookmark action, get current title and url; (add_bookmark): do the adding, possibly as child of a parent item; (add_folder): slot for context menu action for adding a folder, check current position where to insert the new folder; (add_folder): do the folder adding; (filter_bookmarks): filter bookmarks following the changed filter text; (filter_activate): enable/disable filter; (update_filter_history): save a search term when acknowledged by return; (handle_double_click): open the clicked bookmark; (ctx_menu): show context menu at current mouse position; (open): open a bookmark via context menu; (edit): edit a bookmark via context menu; (remove): remove selected bookmarks via context menu; (show_filter): toggle visibility of the filter; (save_settings): save settings and initiate writing the bookmarks; (write_bookmarks): open file and initiate writing all top level items; (write_tree_item): write a single item and its children; (read_bookmarks): open the file, check if it is valid and loop over all top level items for reading them from the file; (read_next_item): read an item and its children in case of a folder; * documentation-bookmarks.h: class documentation_bookmarks derived from QWidget, declaration of all required functions and class variables; * documentation-dock-widget.cc (save_settings): new derived method, emitting a signal for saving setting in child widgets and callinf the original method * documentation-dock-widget.h: derived method save_settings and signal for child widgets * documentation.cc: include documentation-bookmarks.h; (documentation): add bookmark tab, connect signal for saving settings; (add_action): check reveiver before connection the actions signal; (construct_tool_bar): add toolbar button for adding a bookmark, connect its signal the add_bookmark slot and connect signal for saving settings; (notice_settings): add shortcut for adding a bookmark; (update_history): move combining page title and current anchor into a more specific title ... (title_and_anchor): to here; * documentation.h: new function title_and_anchor, new action * gui-preferences-dc.h: new file with constants for some bookmark settings and for the xbel file syntax * gui-preferences-sc.h: default value for bookmark action * bookmark-new.png/bookmark-new.svg: icon for tool bar button * icons_license: add new icon * module.mk: add new files * shortcut-manager.cc (init_data): initialize new short for bookmarking
author Torsten Lilge <ttl-octave@mailbox.org>
date Sun, 10 Jan 2021 14:04:35 +0100
parents 4ca50ceb9576
children 7854d5752dd2
line wrap: on
line diff
--- a/libgui/src/documentation.cc	Tue Jan 26 16:41:36 2021 +0100
+++ b/libgui/src/documentation.cc	Sun Jan 10 14:04:35 2021 +0100
@@ -50,6 +50,7 @@
 #include <QVBoxLayout>
 
 #include "documentation.h"
+#include "documentation-bookmarks.h"
 #include "gui-preferences-global.h"
 #include "gui-preferences-sc.h"
 #include "octave-qobject.h"
@@ -253,6 +254,16 @@
         connect (m_filter->lineEdit (), SIGNAL (editingFinished (void)),
                  this, SLOT(filter_update_history (void)));
 
+        // Bookmarks (own class)
+        documentation_bookmarks *bookmarks
+          = new documentation_bookmarks (this, m_doc_browser, m_octave_qobj, navi);
+        navi->addTab (bookmarks, tr ("Bookmarks"));
+
+        connect (m_action_bookmark, SIGNAL (triggered ()),
+                 bookmarks, SLOT (add_bookmark ()));
+        connect (p, SIGNAL (save_settings_signal (void)),
+                 bookmarks, SLOT (save_settings (void)));
+
         // Search
         QHelpSearchEngine *search_engine = m_help_engine->searchEngine ();
         QHelpSearchQueryWidget *search = search_engine->queryWidget ();
@@ -324,7 +335,9 @@
       r = receiver;
 
     a = new QAction (icon, text, this);
-    connect (a, SIGNAL (triggered ()), r, member);
+
+    if (member)
+      connect (a, SIGNAL (triggered ()), r, member);
 
     if (tool_bar)
       tool_bar->addAction (a);
@@ -414,6 +427,12 @@
     m_action_zoom_original
       = add_action (rmgr.icon ("zoom-original"), tr ("Zoom original"),
                     SLOT (zoom_original (void)), m_doc_browser, m_tool_bar);
+
+    // Bookmarks (connect slots later)
+    m_tool_bar->addSeparator ();
+    m_action_bookmark
+      = add_action (rmgr.icon ("bookmark-new"), tr ("Bookmark current page"),
+                    nullptr, nullptr, m_tool_bar);
   }
 
   void documentation::global_search (void)
@@ -613,6 +632,7 @@
     scmgr.set_shortcut (m_action_go_home, sc_doc_go_home);
     scmgr.set_shortcut (m_action_go_prev, sc_doc_go_back);
     scmgr.set_shortcut (m_action_go_next, sc_doc_go_next);
+    scmgr.set_shortcut (m_action_bookmark, sc_doc_bookmark);
   }
 
   void documentation::copyClipboard (void)
@@ -870,37 +890,9 @@
     // Fill used menu entries
     for (int i = 0; i < count; i++)
       {
-        QString title = m_doc_browser->historyTitle (prev_next*(i+1));
-        title.remove (QRegExp ("\\s*\\(*GNU Octave \\(version [^\\)]*\\)[: \\)]*"));
-
-        // Since the title only contains the section name and not the
-        // specific anchor, extract the latter from the url and append
-        // it to the title
-        QString url = m_doc_browser->historyUrl (prev_next*(i+1)).toString ();
-        if (url.contains ('#'))
-          {
-            // Get the anchor from the url
-            QString anchor = url.split ('#').last ();
-
-            // Remove internal string parts
-            anchor.remove (QRegExp ("^index-"));
-            anchor.remove (QRegExp ("^SEC_"));
-            anchor.remove (QRegExp ("^XREF"));
-            anchor.remove ("Concept-Index_cp_letter-");
-            anchor.replace ("-"," ");
-
-            // replace encoded special chars by their unencoded versions
-            QRegExp rx = QRegExp ("_00([0-7][0-9a-f])");
-            int pos = 0;
-            while ((pos = rx.indexIn(anchor, pos)) != -1)
-              {
-                anchor.replace ("_00"+rx.cap (1), QChar (rx.cap (1).toInt (nullptr,16)));
-                pos += rx.matchedLength();
-              }
-
-            if (title != anchor)
-              title = title + ": " + anchor;
-          }
+        QString title
+          = title_and_anchor (m_doc_browser->historyTitle (prev_next*(i+1)),
+                              m_doc_browser->historyUrl (prev_next*(i+1)));
 
         if (i == 0)
           a->setText (title); // set tool tip for prev/next buttons
@@ -924,8 +916,51 @@
     m_doc_browser->setSource (a->data ().toUrl ());
   }
 
+  // Utility functions
 
+  QString documentation::title_and_anchor (const QString& title, const QUrl& url)
+  {
+    QString retval = title;
+    QString u = url.toString ();
+
+    retval.remove (QRegExp ("\\s*\\(*GNU Octave \\(version [^\\)]*\\)[: \\)]*"));
+
+    // Since the title only contains the section name and not the
+    // specific anchor, extract the latter from the url and append
+    // it to the title
+    if (u.contains ('#'))
+      {
+        // Get the anchor from the url
+        QString anchor = u.split ('#').last ();
+        // Remove internal string parts
+        anchor.remove (QRegExp ("^index-"));
+        anchor.remove (QRegExp ("^SEC_"));
+        anchor.remove (QRegExp ("^XREF"));
+        anchor.remove ("Concept-Index_cp_letter-");
+        anchor.replace ("-"," ");
+
+        // replace encoded special chars by their unencoded versions
+        QRegExp rx = QRegExp ("_00([0-7][0-9a-f])");
+        int pos = 0;
+        while ((pos = rx.indexIn(anchor, pos)) != -1)
+          {
+            anchor.replace ("_00"+rx.cap (1), QChar (rx.cap (1).toInt (nullptr,16)));
+            pos += rx.matchedLength();
+          }
+
+        if (retval != anchor)
+          retval = retval + ": " + anchor;
+      }
+
+    return retval;
+  }
+
+
+
+  //
   // The documentation browser
+  //
+
   documentation_browser::documentation_browser (QHelpEngine *he, QWidget *p)
     : QTextBrowser (p), m_help_engine (he), m_zoom_level (0)
   {