26 #if defined (HAVE_CONFIG_H)
31 #include <QApplication>
33 #include <QDesktopServices>
37 #include <QHelpContentWidget>
38 #include <QHelpIndexWidget>
39 #if defined (HAVE_NEW_QHELPINDEXWIDGET_API) \
40 || defined (HAVE_QHELPENGINE_DOCUMENTSFORIDENTIFIER)
43 #include <QHelpSearchEngine>
44 #include <QHelpSearchQueryWidget>
45 #include <QHelpSearchResultWidget>
48 #include <QMessageBox>
50 #include <QVBoxLayout>
68 m_octave_qobj (oct_qobj), m_doc_widget (p),
69 m_tool_bar (new QToolBar (p)),
70 m_query_string (QString ()),
71 m_prev_pages_menu (new
QMenu (p)),
72 m_next_pages_menu (new
QMenu (p)),
73 m_prev_pages_count (0),
74 m_next_pages_count (0),
75 m_findnext_shortcut (new QShortcut (p)),
76 m_findprev_shortcut (new QShortcut (p))
79 QString collection = getenv (
"OCTAVE_QTHELP_COLLECTION");
80 if (collection.isEmpty ())
83 +
"octave_interpreter.qhc");
92 QVariant::fromValue<bool> (
true));
94 QString tmpdir = QDir::tempPath();
108 tr (
"Could not copy help collection to temporary\n"
109 "file. Search capabilities may be affected.\n"
120 tr (
"Could not setup the data required for the\n"
121 "documentation viewer. Only help texts in\n"
122 "the Command Window will be available."));
134 connect (
m_doc_browser, SIGNAL (cursorPositionChanged (
void)),
142 QLabel *find_label =
new QLabel (tr (
"Find:"), find_footer);
145 this, SLOT(
find (
void)));
149 forward_button->setText (tr (
"Search forward"));
150 forward_button->setToolTip (tr (
"Search forward"));
152 forward_button->setIcon (rmgr.
icon (
"go-down"));
153 connect (forward_button, SIGNAL (pressed (
void)),
154 this, SLOT(
find (
void)));
156 backward_button->setText (tr (
"Search backward"));
157 backward_button->setToolTip (tr (
"Search backward"));
158 backward_button->setIcon (rmgr.
icon (
"go-up"));
159 connect (backward_button, SIGNAL (pressed (
void)),
161 QHBoxLayout *h_box_find_footer =
new QHBoxLayout (find_footer);
162 h_box_find_footer->addWidget (find_label);
164 h_box_find_footer->addWidget (forward_button);
165 h_box_find_footer->addWidget (backward_button);
166 h_box_find_footer->setMargin (2);
167 find_footer->setLayout (h_box_find_footer);
169 QVBoxLayout *v_box_browser_find =
new QVBoxLayout (browser_find);
172 v_box_browser_find->addWidget (find_footer);
173 browser_find->setLayout (v_box_browser_find);
179 this, SLOT(
find (
void)));
184 find_footer->hide ();
189 #if defined (HAVE_NEW_QHELPINDEXWIDGET_API)
195 navi->setTabsClosable (
false);
196 navi->setMovable (
true);
199 QHelpContentWidget *content =
m_help_engine->contentWidget ();
200 content->setObjectName (
"documentation_tab_contents");
201 navi->addTab (content, tr (
"Contents"));
204 SIGNAL (linkActivated (
const QUrl&)),
211 m_filter->setToolTip (tr (
"Enter text to search the indices"));
213 m_filter->setInsertPolicy (QComboBox::NoInsert);
216 m_filter->setSizeAdjustPolicy (QComboBox::AdjustToMinimumContentsLengthWithIcon);
217 QSizePolicy sizePol (QSizePolicy::Expanding, QSizePolicy::Preferred);
219 m_filter->completer ()->setCaseSensitivity (Qt::CaseSensitive);
220 QLabel *filter_label =
new QLabel (tr (
"Search"));
223 QHBoxLayout *h_box_index =
new QHBoxLayout (filter_all);
224 h_box_index->addWidget (filter_label);
226 h_box_index->setMargin (2);
227 filter_all->setLayout (h_box_index);
230 index_all->setObjectName (
"documentation_tab_index");
231 QVBoxLayout *v_box_index =
new QVBoxLayout (index_all);
232 v_box_index->addWidget (filter_all);
233 v_box_index->addWidget (index);
234 index_all->setLayout (v_box_index);
236 navi->addTab (index_all, tr (
"Function Index"));
238 #if defined (HAVE_NEW_QHELPINDEXWIDGET_API)
240 &QHelpIndexWidget::documentActivated,
241 this, [
this](
const QHelpLink &
link) {
242 m_doc_browser->handle_index_clicked (link.url);});
245 SIGNAL (linkActivated (
const QUrl&,
const QString&)),
250 connect (
m_filter, SIGNAL (editTextChanged (
const QString&)),
253 connect (
m_filter->lineEdit (), SIGNAL (editingFinished (
void)),
257 QHelpSearchEngine *search_engine =
m_help_engine->searchEngine ();
258 QHelpSearchQueryWidget *
search = search_engine->queryWidget ();
259 QHelpSearchResultWidget *result = search_engine->resultWidget ();
261 QVBoxLayout *v_box_search =
new QVBoxLayout (search_all);
262 v_box_search->addWidget (
search);
263 v_box_search->addWidget (result);
264 search_all->setLayout (v_box_search);
265 search_all->setObjectName (
"documentation_tab_search");
266 navi->addTab (search_all, tr (
"Search"));
271 connect (search_engine, SIGNAL (searchingStarted (
void)),
273 connect (search_engine, SIGNAL (searchingFinished (
int)),
276 connect (search_engine->resultWidget (),
277 SIGNAL (requestShowLink (
const QUrl&)),
282 insertWidget (0, navi);
283 insertWidget (1, browser_find);
284 setStretchFactor (1, 1);
289 (QUrl (
"qthelp://org.octave.interpreter-1.0/doc/octave.html/index.html"));
301 QFileInfo finfo (file);
302 QString bname = finfo.fileName ();
303 QDir dir = finfo.absoluteDir ();
304 dir.setFilter (QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden);
305 QStringList namefilter;
306 namefilter.append (
"*" + bname +
"*");
307 for (
const auto&
fi : dir.entryInfoList (namefilter))
309 std::string file_name =
fi.absoluteFilePath ().toStdString ();
318 const char *member,
QWidget *receiver,
323 if (receiver !=
nullptr)
326 a =
new QAction (icon,
text,
this);
327 connect (a, SIGNAL (triggered ()),
r, member);
330 tool_bar->addAction (a);
333 a->setShortcutContext (Qt::WidgetWithChildrenShortcut);
343 =
add_action (rmgr.
icon (
"go-home"), tr (
"Go home"), SLOT (home (
void)),
352 popdown_button_prev_pages->setToolTip (tr (
"Previous pages"));
354 popdown_button_prev_pages->setPopupMode (QToolButton::InstantPopup);
355 popdown_button_prev_pages->setToolButtonStyle (Qt::ToolButtonTextOnly);
356 popdown_button_prev_pages->setCheckable (
false);
357 popdown_button_prev_pages->setArrowType(Qt::DownArrow);
358 m_tool_bar->addWidget (popdown_button_prev_pages);
366 popdown_button_next_pages->setToolTip (tr (
"Next pages"));
368 popdown_button_next_pages->setPopupMode (QToolButton::InstantPopup);
369 popdown_button_next_pages->setToolButtonStyle (Qt::ToolButtonTextOnly);
370 popdown_button_next_pages->setArrowType(Qt::DownArrow);
371 m_tool_bar->addWidget (popdown_button_next_pages);
376 popdown_button_prev_pages, SLOT (setEnabled (
bool)));
380 popdown_button_next_pages, SLOT (setEnabled (
bool)));
424 QString query_string;
425 #if defined (HAVE_QHELPSEARCHQUERYWIDGET_SEARCHINPUT)
427 =
m_help_engine->searchEngine ()->queryWidget ()->searchInput ();
428 query_string = queries;
433 if (queries.count ())
434 query_string = queries.first ().wordList.join (
" ");
439 if (query_string.isEmpty ())
443 QRegExp rx (
"\"([^\"]*)\"");
444 if (rx.indexIn (query_string, 0) != -1)
447 #if defined (HAVE_QT_SPLITBEHAVIOR_ENUM)
458 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
470 QHelpSearchEngine *search_engine =
m_help_engine->searchEngine ();
473 #if defined (HAVE_QHELPSEARCHQUERYWIDGET_SEARCHINPUT)
474 QVector<QHelpSearchResult> res
475 = search_engine->searchResults (0, search_engine->searchResultCount ());
478 = search_engine->hits (0, search_engine->hitCount ());
485 if (res.count () == 1)
486 #if defined (HAVE_QHELPSEARCHQUERYWIDGET_SEARCHINPUT)
487 url = res.front ().url ();
489 url = res.front ().first;
496 for (
auto r = res.begin ();
r != res.end ();
r++)
498 #if defined (HAVE_QHELPSEARCHQUERYWIDGET_SEARCHINPUT)
499 QString title =
r->title ().toLower ();
500 QUrl tmpurl =
r->url ();
502 QString title =
r->second.toLower ();
503 QUrl tmpurl =
r->first;
505 if (title.contains (search_string.toLower ()))
507 if (title.indexOf (search_string.toLower ()) == 0)
512 else if (url.isEmpty ())
518 if (! url.isEmpty ())
532 qApp->restoreOverrideCursor();
557 QTextDocument::FindBackward));
564 QPalette pal = QApplication::palette ();
566 QColor col = pal.color (QPalette::Highlight);
567 col.setAlphaF (0.25);
568 format.setBackground (QBrush (col));
569 format.setForeground (QBrush (pal.color (QPalette::Text)));
578 QTextEdit::ExtraSelection selected_item;
580 selected_item.format =
format;
581 selected.append (selected_item);
598 size_idx = (size_idx > 0) - (size_idx < 0) + 1;
600 QStyle *st = style ();
602 m_tool_bar->setIconSize (QSize (icon_size, icon_size));
635 #if defined (HAVE_QHELPENGINE_DOCUMENTSFORIDENTIFIER)
645 if (found_links.count() > 0)
648 #if defined (HAVE_QHELPENGINE_DOCUMENTSFORIDENTIFIER)
649 QUrl first_url = found_links.constFirst().url;
651 QUrl first_url = found_links.constBegin().value ();
659 = navi->findChild<
QWidget*> (
"documentation_tab_index");
660 navi->setCurrentWidget (index_tab);
665 QHelpSearchEngine *search_engine =
m_help_engine->searchEngine ();
666 QHelpSearchQueryWidget *search_query = search_engine->queryWidget ();
668 #if defined (HAVE_QHELPSEARCHQUERYWIDGET_SEARCHINPUT)
669 QString query = ref_name;
670 query.prepend (
"\"").append (
"\"");
673 query << QHelpSearchQuery (QHelpSearchQuery::DEFAULT,
674 QStringList (QString(
"\"") + ref_name + QString(
"\"")));
677 search_engine->search (query);
680 #if defined (HAVE_QHELPSEARCHQUERYWIDGET_SEARCHINPUT)
681 search_query->setSearchInput (query);
683 search_query->setQuery (query);
686 = navi->findChild<
QWidget*> (
"documentation_tab_search");
687 navi->setCurrentWidget (search_tab);
712 if (expression.contains (QLatin1Char(
'*')))
713 wildcard = expression;
715 m_help_engine->indexWidget ()->filterIndices(expression, wildcard);
740 QTextDocument::FindFlags find_flags;
742 find_flags = QTextDocument::FindBackward;
749 textcur.movePosition (QTextCursor::End);
751 textcur.movePosition (QTextCursor::Start);
772 textcur.movePosition (QTextCursor::Start);
800 bool do_setup =
true;
801 if (
m_help_engine->registeredDocumentations ().contains (ns))
814 tr (
"Unable to register help file %1.").
871 for (
int i = 0; i < count; i++)
873 QString title =
m_doc_browser->historyTitle (prev_next*(i+1));
874 title.remove (QRegExp (
"\\s*\\(*GNU Octave \\(version [^\\)]*\\)[: \\)]*"));
879 QString url =
m_doc_browser->historyUrl (prev_next*(i+1)).toString ();
880 if (url.contains (
'#'))
883 QString anchor = url.split (
'#').last ();
886 anchor.remove (QRegExp (
"^index-"));
887 anchor.remove (QRegExp (
"^SEC_"));
888 anchor.remove (QRegExp (
"^XREF"));
889 anchor.remove (
"Concept-Index_cp_letter-");
890 anchor.replace (
"-",
" ");
893 QRegExp rx = QRegExp (
"_00([0-7][0-9a-f])");
895 while ((pos = rx.indexIn(anchor, pos)) != -1)
897 anchor.replace (
"_00"+rx.cap (1), QChar (rx.cap (1).toInt (
nullptr,16)));
898 pos += rx.matchedLength();
902 title = title +
": " + anchor;
908 actions[i]->setText (title);
909 actions[i]->setData (
m_doc_browser->historyUrl (prev_next*(i+1)));
910 actions[i]->setEnabled (
true);
911 actions[i]->setVisible (
true);
917 actions[j]->setEnabled (
false);
918 actions[j]->setVisible (
false);
930 :
QTextBrowser (p), m_help_engine (he), m_zoom_level (0)
932 setOpenLinks (
false);
933 connect (
this, SIGNAL (anchorClicked (QUrl)),
943 if (url.scheme () ==
"qthelp")
946 QDesktopServices::openUrl (url);
957 return QTextBrowser::loadResource(
type, url);
986 if (
we->modifiers () == Qt::ControlModifier)
988 #if defined (HAVE_QWHEELEVENT_ANGLEDELTA)
989 if (
we->angleDelta().y () > 0)
1000 QTextEdit::wheelEvent (
we);
Base class for Octave interfaces that use Qt.
resource_manager & get_resource_manager(void)
shortcut_manager & get_shortcut_manager(void)
Documentation browser derived from Textbrowser.
void zoom_original(void)
Zooming in and out while taking care of the zoom level.
void zoom_out(void)
Zooming in and out while taking care of the zoom level.
QHelpEngine * m_help_engine
int m_zoom_level
Store the current zoom level.
void handle_index_clicked(const QUrl &url, const QString &keyword=QString())
void zoom_in(void)
Zooming in and out while taking care of the zoom level.
~documentation_browser(void)
void notice_settings(const gui_settings *settings)
documentation_browser(QHelpEngine *help_engine, QWidget *parent=nullptr)
virtual QVariant loadResource(int type, const QUrl &url)
void wheelEvent(QWheelEvent *we)
QAction * m_action_go_next
void filter_update_history(void)
documentation(QWidget *parent, base_qobject &oct_qobj)
void filter_update(const QString &expression)
QShortcut * m_findprev_shortcut
QMenu * m_prev_pages_menu
void find_forward_from_anchor(const QString &text)
void global_search_started(void)
int m_search_anchor_position
QHelpEngine * m_help_engine
QAction * m_action_zoom_out
QAction * m_prev_pages_actions[max_history_entries]
QAction * m_next_pages_actions[max_history_entries]
documentation_browser * m_doc_browser
void construct_tool_bar(void)
base_qobject & m_octave_qobj
void handle_search_result_clicked(const QUrl &url)
QShortcut * m_findnext_shortcut
void pasteClipboard(void)
void update_history_menus(void)
void handle_cursor_position_change(void)
void record_anchor_position(void)
QAction * m_action_zoom_original
QAction * m_action_go_prev
QAction * m_action_go_home
void load_ref(const QString &name)
QMenu * m_next_pages_menu
QAction * add_action(const QIcon &icon, const QString &text, const char *member, QWidget *receiver=nullptr, QToolBar *tool_bar=nullptr)
void open_hist_url(QAction *a)
QAction * m_action_zoom_in
QString m_internal_search
void update_history(int new_count, QAction **actions)
void global_search_finished(int hits)
void select_all_occurrences(const QString &text)
Select all occurrences of a string in the doc browser.
void find(bool backward=false)
void show_single_result(const QUrl &)
void notice_settings(const gui_settings *settings)
QLineEdit * m_find_line_edit
void registerDoc(const QString &name)
void unregisterDoc(const QString &name)
gui_settings * get_settings(void) const
QIcon icon(const QString &icon_name, bool fallback=true)
void shortcut(QShortcut *sc, const sc_pref &scpref)
void set_shortcut(QAction *action, const sc_pref &scpref)
static octave_idx_type link(octave_idx_type s, octave_idx_type t, octave_idx_type *pp)
void warning(const char *fmt,...)
const QStyle::PixelMetric global_icon_sizes[3]
const gui_pref global_icon_size("toolbar_icon_size", QVariant(0))
const sc_pref sc_doc_go_home(sc_doc+":go_home", Qt::AltModifier+Qt::Key_Home)
const sc_pref sc_doc_go_back(sc_doc+":go_back", QKeySequence::Back)
const sc_pref sc_edit_view_zoom_normal(sc_edit_view_zoom+"_normal", CTRL+Qt::Key_Period)
const sc_pref sc_edit_edit_find_replace(sc_edit_edit_find+"_replace", QKeySequence::Find)
const sc_pref sc_edit_edit_find_next(sc_edit_edit_find+"_next", QKeySequence::FindNext)
const sc_pref sc_edit_edit_find_previous(sc_edit_edit_find+"_previous", QKeySequence::FindPrevious)
const sc_pref sc_edit_view_zoom_in(sc_edit_view_zoom+"_in", QKeySequence::ZoomIn)
const sc_pref sc_doc_go_next(sc_doc+":go_next", QKeySequence::Forward)
const sc_pref sc_edit_view_zoom_out(sc_edit_view_zoom+"_out", QKeySequence::ZoomOut)
static std::list< std::string > search(const std::string &path, const std::string &original_name, bool all)
QString fromStdString(const std::string &s)
std::string oct_doc_dir(void)
std::string dir_sep_str(void)
std::string tempnam(const std::string &dir, const std::string &pfx)
int recursive_rmdir(const std::string &name)
size_t format(std::ostream &os, const char *fmt,...)