changeset 25060:1cd3aeda7598 stable

Allow registering compressed help at run time (bug #53006). * octave-link.h/cc (octave_link::register_doc, octave_link::unregister_doc): New methods. (octave_link::do_register_doc, octave_link::do_unregister_doc): New virtual methods. * octave-qt-link.h/cc (octave_qt_link::do_register_doc, octave_qt_link::do_unregister_doc): Reimplement methods. (register_doc_signal, unregister_doc_signal): New signals. * main-window.cc/h (handle_register_doc, handle_unregister_doc): New methods. (main_window::register_doc_signal, main_window::unregister_doc_signal): New signals. (main_window::construct_octave_qt_link): Connect qt-link's (un)register_doc_signal to corresponding handle_ method. * documentation-dock-widget.cc/h (documentation_dock_widget::registerDoc, documentation_dock_widget::unregisterDoc): New methods. * documentation.cc/h (documentation::registerDoc, documentation::unregisterDoc): New methods. (documentation::documentation): Read collection from oct_doc_dir if necessary. Make a smart copy of the original collection in a writable file and use the latter for further operations. (documentation::~documentation): Delete temporary collection file and hidden temporary directory.
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Fri, 30 Mar 2018 15:15:08 +0200
parents 85867171af5f
children 5fef743c34d7
files libgui/src/documentation-dock-widget.cc libgui/src/documentation-dock-widget.h libgui/src/documentation.cc libgui/src/documentation.h libgui/src/main-window.cc libgui/src/main-window.h libgui/src/octave-qt-link.cc libgui/src/octave-qt-link.h libinterp/corefcn/octave-link.cc libinterp/corefcn/octave-link.h run-octave.in
diffstat 11 files changed, 204 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/documentation-dock-widget.cc	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/documentation-dock-widget.cc	Fri Mar 30 15:15:08 2018 +0200
@@ -45,6 +45,12 @@
 
     connect (p, SIGNAL (show_doc_signal (const QString&)),
              this, SLOT (showDoc (const QString&)));
+
+    connect (p, SIGNAL (register_doc_signal (const QString&)),
+             this, SLOT (registerDoc (const QString&)));
+
+    connect (p, SIGNAL (unregister_doc_signal (const QString&)),
+             this, SLOT (unregisterDoc (const QString&)));
   }
 
   documentation_dock_widget::~documentation_dock_widget (void)
@@ -83,4 +89,14 @@
 
     m_docs->load_ref (name);
   }
+
+  void documentation_dock_widget::registerDoc (const QString& name)
+  {
+    m_docs->registerDoc (name);
+  }
+
+  void documentation_dock_widget::unregisterDoc (const QString& name)
+  {
+    m_docs->unregisterDoc (name);
+  }
 }
--- a/libgui/src/documentation-dock-widget.h	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/documentation-dock-widget.h	Fri Mar 30 15:15:08 2018 +0200
@@ -48,6 +48,8 @@
     void selectAll (void);
 
     void showDoc (const QString & name);
+    void registerDoc (const QString & name);
+    void unregisterDoc (const QString & name);
 
   private:
 
--- a/libgui/src/documentation.cc	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/documentation.cc	Fri Mar 30 15:15:08 2018 +0200
@@ -24,8 +24,15 @@
 #  include "config.h"
 #endif
 
+#include "defaults.h"
+#include "file-ops.h"
+#include "oct-env.h"
+
 #include <QApplication>
 #include <QCompleter>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
 #include <QHelpContentWidget>
 #include <QHelpIndexWidget>
 #include <QHelpSearchEngine>
@@ -33,8 +40,8 @@
 #include <QHelpSearchResultWidget>
 #include <QLabel>
 #include <QLineEdit>
+#include <QMessageBox>
 #include <QTabWidget>
-#include <QMessageBox>
 #include <QVBoxLayout>
 
 #include "documentation.h"
@@ -46,10 +53,28 @@
   documentation::documentation (QWidget *p)
     : QSplitter (Qt::Horizontal, p)
   {
+    // Get original collection
     QString collection = getenv ("OCTAVE_QTHELP_COLLECTION");
+    if (collection.isEmpty ())
+      collection = QString::fromStdString (octave::config::oct_doc_dir ()
+                                         + octave::sys::file_ops::dir_sep_str ()
+                                         + "octave_interpreter.qhc");
+
+    // Setup the help engine with the original collection, use a writable copy
+    // of the original collection and load the help data
+    m_help_engine = new QHelpEngine (collection, this);
 
-    // Setup the help engine and load the help data
-    m_help_engine = new QHelpEngine (collection, this);
+    std::string tmpdir (octave::sys::env::getenv ("TMPDIR"));
+    m_collection
+      = QString::fromStdString (octave::sys::tempnam (tmpdir, "oct-qhelp-"));
+
+    if (m_help_engine->copyCollectionFile (m_collection))
+      m_help_engine->setCollectionFile (m_collection);
+    else
+      QMessageBox::warning (this, tr ("Octave Documentation"),
+                            tr ("Could not copy help collection to temporary\n"
+                                "file. Search capabilities may be affected.\n"
+                                "%1").arg (m_help_engine->error ()));
 
     connect(m_help_engine, SIGNAL(setupFinished()),
             m_help_engine->searchEngine(), SLOT(indexDocumentation()));
@@ -162,7 +187,25 @@
   documentation::~documentation (void)
   {
     if (m_help_engine)
-      delete m_help_engine;
+      {
+        delete m_help_engine;
+
+        // Cleanup temporary file and directory
+        QFile file (m_collection);
+        QFileInfo finfo (file);
+        QString bname = finfo.fileName ();
+        QDir dir = finfo.absoluteDir ();
+        dir.setFilter (QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden);
+        QStringList namefilter;
+        namefilter.append ("*" + bname + "*");
+        foreach (QFileInfo fi, dir.entryInfoList (namefilter))
+          {
+            QDir tmpdir (fi.absoluteFilePath ());
+            tmpdir.removeRecursively ();
+          }
+
+        file.remove();
+      }
   }
 
   void documentation::global_search (void)
@@ -225,6 +268,47 @@
     m_filter->setCurrentIndex (0);
   }
 
+  void documentation::registerDoc (const QString& qch)
+  {
+    if (m_help_engine)
+      {
+        QString ns = m_help_engine->namespaceName (qch);
+        bool do_setup = true;
+        if (m_help_engine->registeredDocumentations ().contains (ns))
+          {
+            if (m_help_engine->documentationFileName (ns) == qch)
+              do_setup = false;
+            else
+              {
+                m_help_engine->unregisterDocumentation (ns);
+                m_help_engine->registerDocumentation (qch);
+              }
+          }
+        else if (! m_help_engine->registerDocumentation (qch))
+          {
+            QMessageBox::warning (this, tr ("Octave Documentation"),
+                                  tr ("Unable to register help file %1.").
+                                  arg (qch));
+            do_setup = false;
+            return;
+          }
+
+        if (do_setup)
+          m_help_engine->setupData();
+      }
+  }
+
+  void documentation::unregisterDoc (const QString& qch)
+  {
+    QString ns = m_help_engine->namespaceName (qch);
+    if (m_help_engine
+        && m_help_engine->registeredDocumentations ().contains (ns)
+        && m_help_engine->documentationFileName (ns) == qch)
+      {
+        m_help_engine->unregisterDocumentation (ns);
+        m_help_engine->setupData ();
+      }
+  }
 
 
   // The documentation browser
--- a/libgui/src/documentation.h	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/documentation.h	Fri Mar 30 15:15:08 2018 +0200
@@ -76,6 +76,8 @@
     void selectAll (void);
 
     void load_ref (const QString & name);
+    void registerDoc (const QString & name);
+    void unregisterDoc (const QString & name);
 
   private slots:
 
@@ -90,6 +92,7 @@
     QHelpEngine *m_help_engine;
     documentation_browser *m_doc_browser;
     QComboBox *m_filter;
+    QString m_collection;
 
   };
 
--- a/libgui/src/main-window.cc	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/main-window.cc	Fri Mar 30 15:15:08 2018 +0200
@@ -1476,6 +1476,16 @@
     emit show_doc_signal (file);
   }
 
+  void main_window::handle_register_doc (const QString& file)
+  {
+    emit register_doc_signal (file);
+  }
+
+  void main_window::handle_unregister_doc (const QString& file)
+  {
+    emit unregister_doc_signal (file);
+  }
+
   void main_window::handle_octave_ready (void)
   {
     // actions after the startup files are executed
@@ -1984,6 +1994,14 @@
         connect (m_octave_qt_link,
                  SIGNAL (show_doc_signal (const QString &)),
                  this, SLOT (handle_show_doc (const QString &)));
+
+        connect (m_octave_qt_link,
+                 SIGNAL (register_doc_signal (const QString &)),
+                 this, SLOT (handle_register_doc (const QString &)));
+
+        connect (m_octave_qt_link,
+                 SIGNAL (unregister_doc_signal (const QString &)),
+                 this, SLOT (handle_unregister_doc (const QString &)));
       }
 
     // Defer initializing and executing the interpreter until after the main
--- a/libgui/src/main-window.h	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/main-window.h	Fri Mar 30 15:15:08 2018 +0200
@@ -127,6 +127,8 @@
     void open_file_signal (const QString& file, const QString& enc, int line);
 
     void show_doc_signal (const QString&);
+    void register_doc_signal (const QString&);
+    void unregister_doc_signal (const QString&);
 
     void insert_debugger_pointer_signal (const QString& file, int line);
     void delete_debugger_pointer_signal (const QString& file, int line);
@@ -243,6 +245,8 @@
                                    const QString& multimode);
 
     void handle_show_doc (const QString& file);
+    void handle_register_doc (const QString& file);
+    void handle_unregister_doc (const QString& file);
 
     void handle_octave_ready ();
     void handle_octave_finished (int);
--- a/libgui/src/octave-qt-link.cc	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/octave-qt-link.cc	Fri Mar 30 15:15:08 2018 +0200
@@ -587,6 +587,16 @@
     emit show_doc_signal (QString::fromStdString (file));
   }
 
+  void octave_qt_link::do_register_doc (const std::string& file)
+  {
+    emit register_doc_signal (QString::fromStdString (file));
+  }
+
+  void octave_qt_link::do_unregister_doc (const std::string& file)
+  {
+    emit unregister_doc_signal (QString::fromStdString (file));
+  }
+
   void octave_qt_link::do_edit_variable (const std::string& expr,
                                          const octave_value& val)
   {
--- a/libgui/src/octave-qt-link.h	Fri Mar 30 11:12:40 2018 -0700
+++ b/libgui/src/octave-qt-link.h	Fri Mar 30 15:15:08 2018 +0200
@@ -142,6 +142,8 @@
     void do_show_preferences (void);
 
     void do_show_doc (const std::string& file);
+    void do_register_doc (const std::string& file);
+    void do_unregister_doc (const std::string& file);
 
     void do_edit_variable (const std::string& name, const octave_value& val);
 
@@ -196,6 +198,10 @@
 
     void show_doc_signal (const QString& file);
 
+    void register_doc_signal (const QString& file);
+
+    void unregister_doc_signal (const QString& file);
+
     void edit_variable_signal (const QString& name, const octave_value& val);
 
     void refresh_variable_editor_signal (void);
--- a/libinterp/corefcn/octave-link.cc	Fri Mar 30 11:12:40 2018 -0700
+++ b/libinterp/corefcn/octave-link.cc	Fri Mar 30 15:15:08 2018 +0200
@@ -432,3 +432,31 @@
 
   return ovl (octave_link::show_doc (file));
 }
+
+DEFUN (__octave_link_register_doc__, args, ,
+       doc: /* -*- texinfo -*-
+@deftypefn {} {} __octave_link_register_doc__ (@var{filename})
+Undocumented internal function.
+@end deftypefn */)
+{
+  std::string file;
+
+  if (args.length () >= 1)
+    file = args(0).string_value();
+
+  return ovl (octave_link::register_doc (file));
+}
+
+DEFUN (__octave_link_unregister_doc__, args, ,
+       doc: /* -*- texinfo -*-
+@deftypefn {} {} __octave_link_unregister_doc__ (@var{filename})
+Undocumented internal function.
+@end deftypefn */)
+{
+  std::string file;
+
+  if (args.length () >= 1)
+    file = args(0).string_value();
+
+  return ovl (octave_link::unregister_doc (file));
+}
--- a/libinterp/corefcn/octave-link.h	Fri Mar 30 11:12:40 2018 -0700
+++ b/libinterp/corefcn/octave-link.h	Fri Mar 30 15:15:08 2018 +0200
@@ -426,6 +426,30 @@
       }
     else
       return false;
+  }
+
+  static bool
+  register_doc (const std::string & file)
+  {
+    if (enabled ())
+      {
+        instance->do_register_doc (file);
+        return true;
+      }
+    else
+      return false;
+  }
+
+  static bool
+  unregister_doc (const std::string & file)
+  {
+    if (enabled ())
+      {
+        instance->do_unregister_doc (file);
+        return true;
+      }
+    else
+      return false;
 
   }
 
@@ -602,6 +626,10 @@
 
   virtual void do_show_doc (const std::string& file) = 0;
 
+  virtual void do_register_doc (const std::string& file) = 0;
+
+  virtual void do_unregister_doc (const std::string& file) = 0;
+
   virtual void
   do_edit_variable (const std::string& name, const octave_value& val) = 0;
 };
--- a/run-octave.in	Fri Mar 30 11:12:40 2018 -0700
+++ b/run-octave.in	Fri Mar 30 15:15:08 2018 +0200
@@ -107,7 +107,7 @@
 OCTAVE_FONTS_DIR="$top_srcdir/etc/fonts"; export OCTAVE_FONTS_DIR
 OCTAVE_JAVA_DIR="$builddir/scripts/java"; export OCTAVE_JAVA_DIR
 OCTAVE_LOCALE_DIR="$builddir/libgui/languages"; export OCTAVE_LOCALE_DIR
-OCTAVE_QTHELP_COLLECTION="$builddir/doc/interpreter/octave_interpreter.qhc"; export OCTAVE_QTHELP_COLLECTION
+OCTAVE_QTHELP_FILE="$builddir/doc/interpreter/octave_interpreter.qch"; export OCTAVE_QTHELP_FILE
 OCTAVE_SITE_INITFILE="$top_srcdir/scripts/startup/site-rcfile"; export OCTAVE_SITE_INITFILE
 OCTAVE_VERSION_INITFILE="$top_srcdir/scripts/startup/version-rcfile"; export OCTAVE_VERSION_INITFILE