Mercurial > octave
changeset 25042:ba5af45bbfc4 stable
documentation widget based on qt help engine (bug #53006)
author | Torsten <mttl@mailbox.org> |
---|---|
date | Wed, 28 Mar 2018 21:46:11 +0200 |
parents | d5d61f1b6de0 |
children | cc20786d2165 b6aea95a7bf9 |
files | libgui/src/documentation-dock-widget.cc libgui/src/documentation-dock-widget.h libgui/src/documentation.cc libgui/src/documentation.h libgui/src/m-editor/file-editor.cc libgui/src/main-window.cc libgui/src/module.mk m4/acinclude.m4 |
diffstat | 8 files changed, 397 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/libgui/src/documentation-dock-widget.cc Wed Mar 28 13:41:48 2018 -0700 +++ b/libgui/src/documentation-dock-widget.cc Wed Mar 28 21:46:11 2018 +0200 @@ -39,42 +39,38 @@ set_title (tr ("Documentation")); setStatusTip (tr ("See the documentation for help.")); - m_webinfo = new octave::webinfo (this); - setWidget (m_webinfo); - setFocusProxy (m_webinfo); + m_docs = new octave::documentation (this); + setWidget (m_docs); + setFocusProxy (m_docs); connect (p, SIGNAL (show_doc_signal (const QString&)), this, SLOT (showDoc (const QString&))); } - void documentation_dock_widget::notice_settings (const QSettings *settings) + documentation_dock_widget::~documentation_dock_widget (void) { - m_webinfo->notice_settings (settings); + if (m_docs) + delete m_docs; } - void documentation_dock_widget::load_info_file (void) + void documentation_dock_widget::notice_settings (const QSettings *settings) { - octave::help_system& help_sys - = octave::__get_help_system__ ("doc widget: load_info_file"); - - QString info_file = QString::fromStdString (help_sys.info_file ()); - - m_webinfo->load_info_file (info_file); + m_docs->notice_settings (settings); } void documentation_dock_widget::copyClipboard (void) { - m_webinfo->copyClipboard (); + m_docs->copyClipboard (); } void documentation_dock_widget::pasteClipboard (void) { - m_webinfo->pasteClipboard (); + m_docs->pasteClipboard (); } void documentation_dock_widget::selectAll (void) { - m_webinfo->selectAll (); + m_docs->selectAll (); } void documentation_dock_widget::showDoc (const QString& name) @@ -85,6 +81,6 @@ raise (); - m_webinfo->load_ref (name); + m_docs->load_ref (name); } }
--- a/libgui/src/documentation-dock-widget.h Wed Mar 28 13:41:48 2018 -0700 +++ b/libgui/src/documentation-dock-widget.h Wed Mar 28 21:46:11 2018 +0200 @@ -24,8 +24,7 @@ #define octave_documentation_dock_widget_h 1 #include "octave-dock-widget.h" - -#include "webinfo.h" +#include "documentation.h" namespace octave { @@ -36,13 +35,12 @@ public: documentation_dock_widget (QWidget *parent = nullptr); + ~documentation_dock_widget (void); public slots: void notice_settings (const QSettings *settings); - void load_info_file (void); - protected slots: void copyClipboard (void); @@ -53,7 +51,7 @@ private: - octave::webinfo *m_webinfo; + octave::documentation *m_docs; }; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/documentation.cc Wed Mar 28 21:46:11 2018 +0200 @@ -0,0 +1,256 @@ +/* + +Copyright (C) 2018 Torsten <mttl@maibox.org> + +This file is part of Octave. + +Octave is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Octave is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include <QApplication> +#include <QCompleter> +#include <QHelpContentWidget> +#include <QHelpIndexWidget> +#include <QHelpSearchEngine> +#include <QHelpSearchQueryWidget> +#include <QHelpSearchResultWidget> +#include <QLabel> +#include <QLineEdit> +#include <QTabWidget> +#include <QMessageBox> +#include <QVBoxLayout> + +#include "documentation.h" + +namespace octave +{ + // The documentation splitter, which is the main widget + // of the doc dock widget + documentation::documentation (QWidget *p) + : QSplitter (Qt::Horizontal, p) + { + QString collection = getenv ("OCTAVE_QTHELP_COLLECTION"); + + // Setup the help engine and load the help data + m_help_engine = new QHelpEngine (collection, this); + + connect(m_help_engine, SIGNAL(setupFinished()), + m_help_engine->searchEngine(), SLOT(indexDocumentation())); + + if (! m_help_engine->setupData()) + { + QMessageBox::warning (this, tr ("Octave Documentation"), + tr ("Could not setup the data required for the\n" + "documentation viewer. Only help texts in\n" + "the Console Widget will be available.")); + if (m_help_engine) + { + delete m_help_engine; + m_help_engine = 0; + } + } + + // The browser + m_doc_browser = new documentation_browser (m_help_engine, this); + + // Layout contents, index and search + QTabWidget *navi = new QTabWidget (this); + navi->setTabsClosable (false); + navi->setMovable (true); + + // Contents + QHelpContentWidget *content = m_help_engine->contentWidget (); + navi->addTab (content, tr ("Contents")); + + connect(m_help_engine->contentWidget (), + SIGNAL (linkActivated (const QUrl&)), + m_doc_browser, SLOT(handle_index_clicked (const QUrl&))); + + // Index + QHelpIndexWidget *index = m_help_engine->indexWidget (); + + m_filter = new QComboBox (this); + m_filter->setToolTip (tr ("Enter text to search the indices")); + m_filter->setEditable (true); + m_filter->setInsertPolicy (QComboBox::NoInsert); + m_filter->setMaxCount (10); + m_filter->setMaxVisibleItems (10); + m_filter->setSizeAdjustPolicy ( + QComboBox::AdjustToMinimumContentsLengthWithIcon); + QSizePolicy sizePol (QSizePolicy::Expanding, QSizePolicy::Preferred); + m_filter->setSizePolicy (sizePol); + m_filter->completer ()->setCaseSensitivity (Qt::CaseSensitive); + QLabel *filter_label = new QLabel (tr ("Search")); + + QWidget *filter_all = new QWidget (navi); + QHBoxLayout *h_box_index = new QHBoxLayout (filter_all); + h_box_index->addWidget (filter_label); + h_box_index->addWidget (m_filter); + h_box_index->setMargin (2); + filter_all->setLayout (h_box_index); + + QWidget *index_all = new QWidget (navi); + QVBoxLayout *v_box_index = new QVBoxLayout (index_all); + v_box_index->addWidget (filter_all); + v_box_index->addWidget (index); + index_all->setLayout (v_box_index); + + navi->addTab (index_all, tr ("Index")); + + connect(m_help_engine->indexWidget (), + SIGNAL (linkActivated (const QUrl&, const QString&)), + m_doc_browser, SLOT(handle_index_clicked (const QUrl&, + const QString&))); + + connect (m_filter, SIGNAL (editTextChanged (const QString&)), + this, SLOT(filter_update (const QString&))); + + connect (m_filter->lineEdit (), SIGNAL (editingFinished (void)), + this, SLOT(filter_update_history (void))); + + // Search + QHelpSearchEngine *search_engine = m_help_engine->searchEngine (); + QHelpSearchQueryWidget *search = search_engine->queryWidget (); + QHelpSearchResultWidget *result = search_engine->resultWidget (); + QWidget *search_all = new QWidget (navi); + QVBoxLayout *v_box_search = new QVBoxLayout (search_all); + v_box_search->addWidget (search); + v_box_search->addWidget (result); + search_all->setLayout (v_box_search); + navi->addTab (search_all, tr ("Search")); + + connect (search, SIGNAL (search (void)), + this, SLOT(global_search (void))); + + connect (search_engine, SIGNAL (searchingStarted (void)), + this, SLOT(global_search_started (void))); + connect (search_engine, SIGNAL (searchingFinished (int)), + this, SLOT(global_search_finished (int))); + + connect (search_engine->resultWidget (), + SIGNAL (requestShowLink (const QUrl&)), + m_doc_browser, + SLOT(handle_index_clicked (const QUrl&))); + + // Fill the splitter + insertWidget (0, navi); + insertWidget (1, m_doc_browser); + setStretchFactor (1, 1); + + // Initial view: Contents + m_doc_browser->setSource (QUrl ( + "qthelp://org.octave.interpreter-1.0/doc/octave.html/index.html")); + } + + documentation::~documentation (void) + { + if (m_help_engine) + delete m_help_engine; + } + + void documentation::global_search (void) + { + QList<QHelpSearchQuery> queries + = m_help_engine->searchEngine ()->queryWidget ()->query (); + m_help_engine->searchEngine ()->search (queries); + } + + void documentation::global_search_started (void) + { + qApp->setOverrideCursor(QCursor(Qt::WaitCursor)); + } + + void documentation::global_search_finished (int) + { + qApp->restoreOverrideCursor(); + } + + void documentation::notice_settings (const QSettings *) { } + + void documentation::copyClipboard (void) { } + + void documentation::pasteClipboard (void) { } + + void documentation::selectAll (void) { } + + void documentation::load_ref (const QString& ref_name) + { + if (m_help_engine) + { + QMap<QString, QUrl> found_links + = m_help_engine->linksForIdentifier (ref_name); + if (found_links.count() > 0) + m_doc_browser->setSource (found_links.constBegin().value()); + } + } + + void documentation::filter_update (const QString& expression) + { + if (! m_help_engine) + return; + + QString wildcard; + if (expression.contains(QLatin1Char('*'))) + wildcard = expression; + + m_help_engine->indexWidget ()->filterIndices(expression, wildcard); + } + + void documentation::filter_update_history (void) + { + QString text = m_filter->currentText (); // get current text + int index = m_filter->findText (text); // and its actual index + + if (index > -1) + m_filter->removeItem (index); // remove if already existing + + m_filter->insertItem (0, text); // (re)insert at beginning + m_filter->setCurrentIndex (0); + } + + + + // The documentation browser + documentation_browser::documentation_browser (QHelpEngine *he, QWidget *p) + : QTextBrowser (p), m_help_engine (he) + { } + + documentation_browser::~documentation_browser (void) + { } + + void documentation_browser::handle_index_clicked (const QUrl& url, + const QString&) + { + setSource (url); + } + + void documentation_browser::notice_settings (const QSettings *) + { } + + QVariant documentation_browser::loadResource (int type, + const QUrl &url) + { + if (url.scheme () == "qthelp") + return QVariant (m_help_engine->fileData(url)); + else + return QTextBrowser::loadResource(type, url); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libgui/src/documentation.h Wed Mar 28 21:46:11 2018 +0200 @@ -0,0 +1,98 @@ +/* + +Copyright (C) 2018 Torsten <mttl@maibox.org> + +This file is part of Octave. + +Octave is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Octave is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<https://www.gnu.org/licenses/>. + +*/ + +#if ! defined (octave_documentation_h) +#define octave_documentation_h 1 + +#include <QComboBox> +#include <QWidget> +#include <QSettings> +#include <QSplitter> +#include <QTextBrowser> +#include <QtHelp/QHelpEngine> + +namespace octave +{ + // The documentation browser + class documentation_browser : public QTextBrowser + { + Q_OBJECT + + public: + + documentation_browser (QHelpEngine *help_engine, QWidget *parent = nullptr); + ~documentation_browser (void); + + virtual QVariant loadResource (int type, const QUrl &url); + + public slots: + + void handle_index_clicked (const QUrl& url, + const QString& keyword = QString ()); + void notice_settings (const QSettings *settings); + + private: + + QHelpEngine *m_help_engine; + + }; + + + // The documentaiton main class (splitter) + class documentation : public QSplitter + { + Q_OBJECT + + public: + + documentation (QWidget *parent = nullptr); + ~documentation (void); + + public slots: + + void notice_settings (const QSettings *settings); + + void copyClipboard (void); + void pasteClipboard (void); + void selectAll (void); + + void load_ref (const QString & name); + + private slots: + + void global_search (void); + void global_search_started (void); + void global_search_finished (int hits); + void filter_update (const QString& expression); + void filter_update_history (void); + + private: + + QHelpEngine *m_help_engine; + documentation_browser *m_doc_browser; + QComboBox *m_filter; + + }; + +} + +#endif
--- a/libgui/src/m-editor/file-editor.cc Wed Mar 28 13:41:48 2018 -0700 +++ b/libgui/src/m-editor/file-editor.cc Wed Mar 28 21:46:11 2018 +0200 @@ -37,6 +37,7 @@ #include <QMessageBox> #include <QMimeData> #include <QProcess> +#include <QPushButton> #include <QStyle> #include <QTabBar> #include <QTextStream> @@ -987,15 +988,15 @@ m_tool_bar->setIconSize (QSize (icon_size,icon_size)); int tab_width_min = settings->value ("editor/notebook_tab_width_min", 160) - .toInt (); + .toInt (); int tab_width_max = settings->value ("editor/notebook_tab_width_max", 300) - .toInt (); + .toInt (); if (settings->value ("editor/longWindowTitle", false).toBool ()) { QString style_sheet = QString ("QTabBar::tab " "{min-width: %1px; max-width: %2px;}") - .arg (tab_width_min).arg (tab_width_max); + .arg (tab_width_min).arg (tab_width_max); m_tab_widget->setElideMode (Qt::ElideLeft); m_tab_widget->setStyleSheet (style_sheet); } @@ -1516,7 +1517,7 @@ QSettings *settings = resource_manager::get_settings (); m_mru_files = settings->value ("editor/mru_file_list").toStringList (); m_mru_files_encodings = settings->value ("editor/mru_file_encodings") - .toStringList (); + .toStringList (); if (m_mru_files_encodings.count () != m_mru_files.count ()) {
--- a/libgui/src/main-window.cc Wed Mar 28 13:41:48 2018 -0700 +++ b/libgui/src/main-window.cc Wed Mar 28 21:46:11 2018 +0200 @@ -40,6 +40,7 @@ #include <QFileDialog> #include <QMessageBox> #include <QIcon> +#include <QTextBrowser> #include <QTextStream> #include <QThread> #include <QDateTime> @@ -211,9 +212,6 @@ connect (m_interpreter, SIGNAL (octave_ready_signal (void)), this, SLOT (handle_octave_ready (void))); - connect (m_interpreter, SIGNAL (octave_ready_signal (void)), - m_doc_browser_window, SLOT (load_info_file (void))); - connect (m_interpreter, SIGNAL (octave_finished_signal (int)), this, SLOT (handle_octave_finished (int))); @@ -662,14 +660,14 @@ } widget_icon_data[] = - { - // array of possible icon sets (name, path (complete for NONE)) - // the first entry here is the default! - {"NONE", ":/actions/icons/logo.png"}, - {"GRAPHIC", ":/actions/icons/graphic_logo_"}, - {"LETTER", ":/actions/icons/letter_logo_"}, - {"", ""} // end marker has empty name - }; + { + // array of possible icon sets (name, path (complete for NONE)) + // the first entry here is the default! + {"NONE", ":/actions/icons/logo.png"}, + {"GRAPHIC", ":/actions/icons/graphic_logo_"}, + {"LETTER", ":/actions/icons/letter_logo_"}, + {"", ""} // end marker has empty name + }; int count = 0; int icon_set_found = 0; // default @@ -691,7 +689,8 @@ { QString name = widget->objectName (); if (! name.isEmpty ()) - { // if children has a name + { + // if children has a name icon = widget_icon_data[icon_set_found].path; // prefix | octave-logo if (widget_icon_data[icon_set_found].name != "NONE") icon += name + ".png"; // add widget name and ext. @@ -700,7 +699,7 @@ } if (widget_icon_data[icon_set_found].name != "NONE") m_release_notes_icon = widget_icon_data[icon_set_found].path - + "ReleaseWidget.png"; + + "ReleaseWidget.png"; else m_release_notes_icon = ":/actions/icons/logo.png"; @@ -2571,7 +2570,8 @@ // file menu shortcut_manager::set_shortcut (m_open_action, "main_file:open_file"); shortcut_manager::set_shortcut (m_new_script_action, "main_file:new_file"); - shortcut_manager::set_shortcut (m_new_function_action, "main_file:new_function"); + shortcut_manager::set_shortcut (m_new_function_action, + "main_file:new_function"); shortcut_manager::set_shortcut (m_new_function_action, "main_file:new_figure"); shortcut_manager::set_shortcut (m_load_workspace_action, "main_file:load_workspace"); @@ -2611,7 +2611,8 @@ "main_window:show_workspace"); shortcut_manager::set_shortcut (m_show_file_browser_action, "main_window:show_file_browser"); - shortcut_manager::set_shortcut (m_show_editor_action, "main_window:show_editor"); + shortcut_manager::set_shortcut (m_show_editor_action, + "main_window:show_editor"); shortcut_manager::set_shortcut (m_show_documentation_action, "main_window:show_doc"); shortcut_manager::set_shortcut (m_show_variable_editor_action, @@ -2623,7 +2624,8 @@ "main_window:file_browser"); shortcut_manager::set_shortcut (m_editor_action, "main_window:editor"); shortcut_manager::set_shortcut (m_documentation_action, "main_window:doc"); - shortcut_manager::set_shortcut (m_variable_editor_action, "main_window:variable_editor"); + shortcut_manager::set_shortcut (m_variable_editor_action, + "main_window:variable_editor"); shortcut_manager::set_shortcut (m_reset_windows_action, "main_window:reset"); // help menu
--- a/libgui/src/module.mk Wed Mar 28 13:41:48 2018 -0700 +++ b/libgui/src/module.mk Wed Mar 28 21:46:11 2018 +0200 @@ -106,6 +106,7 @@ %reldir%/moc-external-editor-interface.cc \ %reldir%/moc-dialog.cc \ %reldir%/moc-documentation-dock-widget.cc \ + %reldir%/moc-documentation.cc \ %reldir%/moc-files-dock-widget.cc \ %reldir%/moc-history-dock-widget.cc \ %reldir%/moc-main-window.cc \ @@ -152,6 +153,7 @@ %reldir%/dialog.h \ %reldir%/octave-dock-widget.h \ %reldir%/documentation-dock-widget.h \ + %reldir%/documentation.h \ %reldir%/external-editor-interface.h \ %reldir%/files-dock-widget.h \ %reldir%/history-dock-widget.h \ @@ -187,6 +189,7 @@ %canon_reldir%_%canon_reldir%_la_SOURCES = \ %reldir%/dialog.cc \ %reldir%/documentation-dock-widget.cc \ + %reldir%/documentation.cc \ %reldir%/external-editor-interface.cc \ %reldir%/files-dock-widget.cc \ %reldir%/history-dock-widget.cc \
--- a/m4/acinclude.m4 Wed Mar 28 13:41:48 2018 -0700 +++ b/m4/acinclude.m4 Wed Mar 28 21:46:11 2018 +0200 @@ -1835,10 +1835,10 @@ ## Check for Qt libraries case "$qt_version" in 4) - QT_MODULES="QtCore QtGui QtNetwork QtOpenGL" + QT_MODULES="QtCore QtGui QtNetwork QtOpenGL QtHelp" ;; 5) - QT_MODULES="Qt5Core Qt5Gui Qt5Network Qt5OpenGL Qt5PrintSupport" + QT_MODULES="Qt5Core Qt5Gui Qt5Network Qt5OpenGL Qt5PrintSupport Qt5Help" ;; *) AC_MSG_ERROR([Unrecognized Qt version $qt_version])