1 | // Copyright (C) 2020 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 |
3 | |
4 | #include "mainwindow.h" |
5 | |
6 | #include "aboutdialog.h" |
7 | #include "bookmarkmanager.h" |
8 | #include "centralwidget.h" |
9 | #include "cmdlineparser.h" |
10 | #include "contentwindow.h" |
11 | #include "globalactions.h" |
12 | #include "helpenginewrapper.h" |
13 | #include "indexwindow.h" |
14 | #include "openpagesmanager.h" |
15 | #include "preferencesdialog.h" |
16 | #include "qtdocinstaller.h" |
17 | #include "remotecontrol.h" |
18 | #include "searchwidget.h" |
19 | #include "topicchooser.h" |
20 | #include "tracer.h" |
21 | |
22 | #include <QtCore/QByteArray> |
23 | #include <QtCore/QDateTime> |
24 | #include <QtCore/QDebug> |
25 | #include <QtCore/QDir> |
26 | #include <QtCore/QPair> |
27 | #include <QtCore/QResource> |
28 | #include <QtCore/QStandardPaths> |
29 | #include <QtCore/QTextStream> |
30 | #include <QtCore/QTimer> |
31 | #include <QtCore/QBuffer> |
32 | #include <QtCore/QLibraryInfo> |
33 | #include <QtCore/QFileInfo> |
34 | #include <QtCore/QDir> |
35 | |
36 | #include <QtGui/QAction> |
37 | #include <QtGui/QFontDatabase> |
38 | #include <QtGui/QImageReader> |
39 | #include <QtGui/QScreen> |
40 | #include <QtGui/QShortcut> |
41 | |
42 | #include <QtWidgets/QComboBox> |
43 | #include <QtWidgets/QDockWidget> |
44 | #include <QtWidgets/QFileDialog> |
45 | #include <QtWidgets/QLabel> |
46 | #include <QtWidgets/QLayout> |
47 | #include <QtWidgets/QLineEdit> |
48 | #include <QtWidgets/QMenuBar> |
49 | #include <QtWidgets/QMessageBox> |
50 | #include <QtWidgets/QProgressBar> |
51 | #include <QtWidgets/QStatusBar> |
52 | #include <QtWidgets/QToolBar> |
53 | #include <QtWidgets/QToolButton> |
54 | |
55 | #include <QtHelp/QHelpContentModel> |
56 | #include <QtHelp/QHelpEngineCore> |
57 | #include <QtHelp/QHelpIndexModel> |
58 | #include <QtHelp/QHelpSearchEngine> |
59 | #include <QtHelp/QHelpFilterEngine> |
60 | |
61 | #include <cstdlib> |
62 | |
63 | QT_BEGIN_NAMESPACE |
64 | |
65 | enum { warnAboutMissingModules = 0 }; |
66 | |
67 | MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent) |
68 | : QMainWindow(parent) |
69 | , m_cmdLine(cmdLine) |
70 | { |
71 | TRACE_OBJ |
72 | |
73 | setToolButtonStyle(Qt::ToolButtonFollowStyle); |
74 | setDockOptions(dockOptions() | AllowNestedDocks); |
75 | |
76 | QString collectionFile; |
77 | if (usesDefaultCollection()) { |
78 | MainWindow::collectionFileDirectory(createDir: true); |
79 | collectionFile = MainWindow::defaultHelpCollectionFileName(); |
80 | } else { |
81 | collectionFile = cmdLine->collectionFile(); |
82 | } |
83 | HelpEngineWrapper &helpEngineWrapper = |
84 | HelpEngineWrapper::instance(collectionFile); |
85 | BookmarkManager *bookMarkManager = BookmarkManager::instance(); |
86 | |
87 | if (!initHelpDB(registerInternalDoc: !cmdLine->collectionFileGiven())) { |
88 | qDebug(msg: "Fatal error: Help engine initialization failed. " |
89 | "Error message was: %s\nAssistant will now exit." , |
90 | qPrintable(HelpEngineWrapper::instance().error())); |
91 | std::exit(status: 1); |
92 | } |
93 | |
94 | m_centralWidget = new CentralWidget(this); |
95 | setCentralWidget(m_centralWidget); |
96 | |
97 | m_indexWindow = new IndexWindow(this); |
98 | QDockWidget *indexDock = new QDockWidget(tr(s: "Index" ), this); |
99 | indexDock->setObjectName(QLatin1String("IndexWindow" )); |
100 | indexDock->setWidget(m_indexWindow); |
101 | addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: indexDock); |
102 | |
103 | m_contentWindow = new ContentWindow; |
104 | QDockWidget *contentDock = new QDockWidget(tr(s: "Contents" ), this); |
105 | contentDock->setObjectName(QLatin1String("ContentWindow" )); |
106 | contentDock->setWidget(m_contentWindow); |
107 | addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: contentDock); |
108 | |
109 | m_searchWindow = new SearchWidget(helpEngineWrapper.searchEngine()); |
110 | m_searchWindow->setFont(!helpEngineWrapper.usesBrowserFont() ? qApp->font() |
111 | : helpEngineWrapper.browserFont()); |
112 | QDockWidget *searchDock = new QDockWidget(tr(s: "Search" ), this); |
113 | searchDock->setObjectName(QLatin1String("SearchWindow" )); |
114 | searchDock->setWidget(m_searchWindow); |
115 | addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: searchDock); |
116 | |
117 | QDockWidget *bookmarkDock = new QDockWidget(tr(s: "Bookmarks" ), this); |
118 | bookmarkDock->setObjectName(QLatin1String("BookmarkWindow" )); |
119 | bookmarkDock->setWidget(m_bookmarkWidget |
120 | = bookMarkManager->bookmarkDockWidget()); |
121 | addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: bookmarkDock); |
122 | |
123 | QDockWidget *openPagesDock = new QDockWidget(tr(s: "Open Pages" ), this); |
124 | openPagesDock->setObjectName(QLatin1String("Open Pages" )); |
125 | OpenPagesManager *openPagesManager |
126 | = OpenPagesManager::createInstance(parent: this, defaultCollection: usesDefaultCollection(), cmdLineUrl: m_cmdLine->url()); |
127 | openPagesDock->setWidget(openPagesManager->openPagesWidget()); |
128 | addDockWidget(area: Qt::LeftDockWidgetArea, dockwidget: openPagesDock); |
129 | |
130 | connect(sender: m_centralWidget, signal: &CentralWidget::addBookmark, |
131 | context: bookMarkManager, slot: &BookmarkManager::addBookmark); |
132 | connect(sender: bookMarkManager, signal: &BookmarkManager::escapePressed, |
133 | context: this, slot: &MainWindow::activateCurrentCentralWidgetTab); |
134 | connect(sender: bookMarkManager, signal: &BookmarkManager::setSource, |
135 | context: m_centralWidget, slot: &CentralWidget::setSource); |
136 | connect(sender: bookMarkManager, signal: &BookmarkManager::setSourceInNewTab, |
137 | context: openPagesManager, slot: [openPagesManager](const QUrl &url){ openPagesManager->createPage(url); }); |
138 | |
139 | QHelpSearchEngine *searchEngine = helpEngineWrapper.searchEngine(); |
140 | connect(sender: searchEngine, signal: &QHelpSearchEngine::indexingStarted, |
141 | context: this, slot: &MainWindow::indexingStarted); |
142 | connect(sender: searchEngine, signal: &QHelpSearchEngine::indexingFinished, |
143 | context: this, slot: &MainWindow::indexingFinished); |
144 | |
145 | QString defWindowTitle = tr(s: "Qt Assistant" ); |
146 | setWindowTitle(defWindowTitle); |
147 | |
148 | setupActions(); |
149 | statusBar()->show(); |
150 | m_centralWidget->connectTabBar(); |
151 | |
152 | setupFilterToolbar(); |
153 | setupAddressToolbar(); |
154 | |
155 | const QString windowTitle = helpEngineWrapper.windowTitle(); |
156 | setWindowTitle(windowTitle.isEmpty() ? defWindowTitle : windowTitle); |
157 | QByteArray iconArray = helpEngineWrapper.applicationIcon(); |
158 | if (iconArray.size() > 0) { |
159 | QBuffer buffer(&iconArray); |
160 | QImageReader reader(&buffer); |
161 | QIcon appIcon; |
162 | do { |
163 | QPixmap pix; |
164 | pix.convertFromImage(img: reader.read()); |
165 | appIcon.addPixmap(pixmap: pix); |
166 | } while (reader.jumpToNextImage()); |
167 | qApp->setWindowIcon(appIcon); |
168 | } |
169 | #if !defined(Q_OS_MACOS) && !defined(Q_OS_WIN) |
170 | else { |
171 | QIcon appIcon(QLatin1String(":/qt-project.org/assistant/images/assistant-128.png" )); |
172 | qApp->setWindowIcon(appIcon); |
173 | } |
174 | #endif |
175 | |
176 | QToolBar *toolBar = addToolBar(title: tr(s: "Bookmark Toolbar" )); |
177 | toolBar->setObjectName(QLatin1String("Bookmark Toolbar" )); |
178 | bookMarkManager->setBookmarksToolbar(toolBar); |
179 | |
180 | toolBar->hide(); |
181 | toolBarMenu()->addAction(action: toolBar->toggleViewAction()); |
182 | |
183 | QByteArray ba(helpEngineWrapper.mainWindow()); |
184 | if (!ba.isEmpty()) |
185 | restoreState(state: ba); |
186 | |
187 | ba = helpEngineWrapper.mainWindowGeometry(); |
188 | if (!ba.isEmpty()) { |
189 | restoreGeometry(geometry: ba); |
190 | } else { |
191 | tabifyDockWidget(first: contentDock, second: indexDock); |
192 | tabifyDockWidget(first: indexDock, second: bookmarkDock); |
193 | tabifyDockWidget(first: bookmarkDock, second: searchDock); |
194 | contentDock->raise(); |
195 | const QRect screen = QGuiApplication::primaryScreen()->geometry(); |
196 | adjustSize(); // make sure we won't start outside of the screen |
197 | resize(w: 4 * screen.width() / 5, h: 4 * screen.height() / 5); |
198 | |
199 | move(screen.center() - rect().center()); |
200 | } |
201 | |
202 | if (!helpEngineWrapper.hasFontSettings()) { |
203 | helpEngineWrapper.setUseAppFont(false); |
204 | helpEngineWrapper.setUseBrowserFont(false); |
205 | helpEngineWrapper.setAppFont(qApp->font()); |
206 | helpEngineWrapper.setAppWritingSystem(QFontDatabase::Latin); |
207 | helpEngineWrapper.setBrowserFont(qApp->font()); |
208 | helpEngineWrapper.setBrowserWritingSystem(QFontDatabase::Latin); |
209 | } else { |
210 | updateApplicationFont(); |
211 | } |
212 | |
213 | updateAboutMenuText(); |
214 | |
215 | QTimer::singleShot(interval: 0, receiver: this, slot: &MainWindow::insertLastPages); |
216 | if (m_cmdLine->enableRemoteControl()) |
217 | (void)new RemoteControl(this); |
218 | |
219 | if (m_cmdLine->contents() == CmdLineParser::Show) |
220 | showContents(); |
221 | else if (m_cmdLine->contents() == CmdLineParser::Hide) |
222 | hideContents(); |
223 | |
224 | if (m_cmdLine->index() == CmdLineParser::Show) |
225 | showIndex(); |
226 | else if (m_cmdLine->index() == CmdLineParser::Hide) |
227 | hideIndex(); |
228 | |
229 | if (m_cmdLine->bookmarks() == CmdLineParser::Show) |
230 | showBookmarksDockWidget(); |
231 | else if (m_cmdLine->bookmarks() == CmdLineParser::Hide) |
232 | hideBookmarksDockWidget(); |
233 | |
234 | if (m_cmdLine->search() == CmdLineParser::Show) |
235 | showSearch(); |
236 | else if (m_cmdLine->search() == CmdLineParser::Hide) |
237 | hideSearch(); |
238 | |
239 | if (m_cmdLine->contents() == CmdLineParser::Activate) |
240 | showContents(); |
241 | else if (m_cmdLine->index() == CmdLineParser::Activate) |
242 | showIndex(); |
243 | else if (m_cmdLine->bookmarks() == CmdLineParser::Activate) |
244 | showBookmarksDockWidget(); |
245 | |
246 | if (!m_cmdLine->currentFilter().isEmpty()) { |
247 | const QString &curFilter = m_cmdLine->currentFilter(); |
248 | if (helpEngineWrapper.filterEngine()->filters().contains(str: curFilter)) |
249 | helpEngineWrapper.filterEngine()->setActiveFilter(curFilter); |
250 | } |
251 | |
252 | if (usesDefaultCollection()) |
253 | QTimer::singleShot(interval: 0, receiver: this, slot: &MainWindow::lookForNewQtDocumentation); |
254 | else |
255 | checkInitState(); |
256 | |
257 | connect(sender: &helpEngineWrapper, signal: &HelpEngineWrapper::documentationRemoved, |
258 | context: this, slot: &MainWindow::documentationRemoved); |
259 | connect(sender: &helpEngineWrapper, signal: &HelpEngineWrapper::documentationUpdated, |
260 | context: this, slot: &MainWindow::documentationUpdated); |
261 | |
262 | setTabPosition(areas: Qt::AllDockWidgetAreas, tabPosition: QTabWidget::North); |
263 | GlobalActions::instance()->updateActions(); |
264 | if (helpEngineWrapper.addressBarEnabled()) |
265 | showNewAddress(); |
266 | } |
267 | |
268 | MainWindow::~MainWindow() |
269 | { |
270 | TRACE_OBJ |
271 | delete m_qtDocInstaller; |
272 | } |
273 | |
274 | bool MainWindow::usesDefaultCollection() const |
275 | { |
276 | TRACE_OBJ |
277 | return m_cmdLine->collectionFile().isEmpty(); |
278 | } |
279 | |
280 | void MainWindow::closeEvent(QCloseEvent *e) |
281 | { |
282 | TRACE_OBJ |
283 | BookmarkManager::destroy(); |
284 | HelpEngineWrapper::instance().setMainWindow(saveState()); |
285 | HelpEngineWrapper::instance().setMainWindowGeometry(saveGeometry()); |
286 | QMainWindow::closeEvent(event: e); |
287 | } |
288 | |
289 | bool MainWindow::initHelpDB(bool registerInternalDoc) |
290 | { |
291 | TRACE_OBJ |
292 | HelpEngineWrapper &helpEngineWrapper = HelpEngineWrapper::instance(); |
293 | if (!helpEngineWrapper.setupData()) |
294 | return false; |
295 | |
296 | if (!registerInternalDoc && helpEngineWrapper.defaultHomePage() == QLatin1String("help" )) |
297 | helpEngineWrapper.setDefaultHomePage(QLatin1String("about:blank" )); |
298 | |
299 | return true; |
300 | } |
301 | |
302 | static const char *docs[] = { |
303 | "assistant" , "designer" , "linguist" , // Qt 4 |
304 | "qmake" , |
305 | "qt" , |
306 | "qtqmake" , |
307 | "activeqt" , |
308 | "qtandroidextras" , |
309 | "qtassistant" , |
310 | "qtbluetooth" , |
311 | "qtconcurrent" , |
312 | "qtconnectivity" , |
313 | "qtcore" , |
314 | "qtdbus" , |
315 | "qtdesigner" , |
316 | "qtdoc" , |
317 | "qtenginio" , |
318 | "qtgraphicaleffects" , |
319 | "qtgui" , |
320 | "qthelp" , |
321 | "qtimageformats" , |
322 | "qtlinguist" , |
323 | "qtlocation" , |
324 | "qtmacextras" , |
325 | "qtmultimedia" , |
326 | "qtmultimediawidgets" , |
327 | "qtnfc" , |
328 | "qtnetwork" , |
329 | "qtopengl" , |
330 | "qtpositioning" , |
331 | "qtprintsupport" , |
332 | "qtqml" , |
333 | "qtquick" , |
334 | "qtscript" , |
335 | "qtscripttools" , |
336 | "qtsensors" , |
337 | "qtsql" , |
338 | "qtsvg" , |
339 | "qttestlib" , |
340 | "qtuitools" , |
341 | "qtwebkit" , |
342 | "qtwebkitexamples" , |
343 | "qtwidgets" , |
344 | "qtxml" , |
345 | "qtxmlpatterns" , |
346 | "qdoc" , |
347 | "qtx11extras" , |
348 | "qtserialport" , |
349 | "qtquickcontrols" , |
350 | "qtquickcontrolsstyles" , |
351 | "qtquickdialogs" , |
352 | "qtquicklayouts" , |
353 | "qtwebsockets" , |
354 | "qtwinextras" |
355 | }; |
356 | |
357 | static QStringList newQtDocumentation() |
358 | { |
359 | QStringList result; |
360 | const QDir docDirectory(QLibraryInfo::path(p: QLibraryInfo::DocumentationPath)); |
361 | const QFileInfoList entries = docDirectory.entryInfoList(nameFilters: QStringList(QStringLiteral("*.qch" )), |
362 | filters: QDir::Files, sort: QDir::Name); |
363 | if (!entries.isEmpty()) { |
364 | result.reserve(asize: entries.size()); |
365 | for (const QFileInfo &fi : entries) |
366 | result.append(t: fi.baseName()); |
367 | return result; |
368 | } |
369 | if (warnAboutMissingModules) |
370 | qWarning() << "No documentation found in " << QDir::toNativeSeparators(pathName: docDirectory.absolutePath()); |
371 | const int docCount = int(sizeof(docs) / sizeof(docs[0])); |
372 | result.reserve(asize: docCount); |
373 | for (int d = 0; d < docCount; ++d) |
374 | result.append(t: QLatin1String(docs[d])); |
375 | return result; |
376 | } |
377 | |
378 | void MainWindow::lookForNewQtDocumentation() |
379 | { |
380 | TRACE_OBJ |
381 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
382 | |
383 | const QStringList &docs = newQtDocumentation(); |
384 | const int docCount = docs.size(); |
385 | QList<QtDocInstaller::DocInfo> qtDocInfos; |
386 | qtDocInfos.reserve(asize: docCount); |
387 | for (const QString &doc : docs) { |
388 | const QtDocInstaller::DocInfo docInfo(doc, helpEngine.qtDocInfo(component: doc)); |
389 | qtDocInfos.append(t: docInfo); |
390 | if (warnAboutMissingModules && (docInfo.second.isEmpty() || docInfo.second.first().isEmpty())) |
391 | qWarning() << "No documentation found for " << doc; |
392 | } |
393 | |
394 | m_qtDocInstaller = new QtDocInstaller(qtDocInfos); |
395 | connect(sender: m_qtDocInstaller, signal: &QtDocInstaller::docsInstalled, |
396 | context: this, slot: &MainWindow::qtDocumentationInstalled); |
397 | connect(sender: m_qtDocInstaller, signal: &QtDocInstaller::qchFileNotFound, |
398 | context: this, slot: &MainWindow::resetQtDocInfo); |
399 | connect(sender: m_qtDocInstaller, signal: &QtDocInstaller::registerDocumentation, |
400 | context: this, slot: &MainWindow::registerDocumentation); |
401 | if (helpEngine.qtDocInfo(component: QLatin1String("qt" )).size() != 2) |
402 | statusBar()->showMessage(text: tr(s: "Looking for Qt Documentation..." )); |
403 | m_qtDocInstaller->installDocs(); |
404 | } |
405 | |
406 | void MainWindow::qtDocumentationInstalled() |
407 | { |
408 | TRACE_OBJ |
409 | OpenPagesManager::instance()->resetHelpPage(); |
410 | statusBar()->clearMessage(); |
411 | checkInitState(); |
412 | } |
413 | |
414 | void MainWindow::checkInitState() |
415 | { |
416 | TRACE_OBJ |
417 | if (!m_cmdLine->enableRemoteControl()) { |
418 | HelpEngineWrapper::instance().initialDocSetupDone(); |
419 | return; |
420 | } |
421 | |
422 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
423 | if (helpEngine.contentModel()->isCreatingContents() |
424 | || helpEngine.indexModel()->isCreatingIndex()) { |
425 | if (!m_connectedInitSignals) { |
426 | connect(sender: helpEngine.contentModel(), signal: &QHelpContentModel::contentsCreated, |
427 | context: this, slot: &MainWindow::checkInitState); |
428 | connect(sender: helpEngine.indexModel(), signal: &QHelpIndexModel::indexCreated, |
429 | context: this, slot: &MainWindow::checkInitState); |
430 | m_connectedInitSignals = true; |
431 | } |
432 | } else { |
433 | if (m_connectedInitSignals) { |
434 | disconnect(sender: helpEngine.contentModel(), signal: nullptr, receiver: this, member: nullptr); |
435 | disconnect(sender: helpEngine.indexModel(), signal: nullptr, receiver: this, member: nullptr); |
436 | } |
437 | HelpEngineWrapper::instance().initialDocSetupDone(); |
438 | emit initDone(); |
439 | } |
440 | } |
441 | |
442 | void MainWindow::insertLastPages() |
443 | { |
444 | TRACE_OBJ |
445 | if (m_cmdLine->search() == CmdLineParser::Activate) |
446 | showSearch(); |
447 | } |
448 | |
449 | void MainWindow::setupActions() |
450 | { |
451 | TRACE_OBJ |
452 | QString resourcePath = QLatin1String(":/qt-project.org/assistant/images/" ); |
453 | #ifdef Q_OS_MAC |
454 | setUnifiedTitleAndToolBarOnMac(true); |
455 | resourcePath.append(QLatin1String("mac" )); |
456 | #else |
457 | resourcePath.append(s: QLatin1String("win" )); |
458 | #endif |
459 | |
460 | QMenu * = menuBar()->addMenu(title: tr(s: "&File" )); |
461 | OpenPagesManager *const openPages = OpenPagesManager::instance(); |
462 | m_newTabAction = menu->addAction(text: tr(s: "New &Tab" ), |
463 | args: openPages, args: &OpenPagesManager::createBlankPage); |
464 | m_newTabAction->setShortcut(QKeySequence::AddTab); |
465 | m_closeTabAction = menu->addAction(text: tr(s: "&Close Tab" ), |
466 | args: openPages, args: &OpenPagesManager::closeCurrentPage); |
467 | m_closeTabAction->setShortcuts(QKeySequence::Close); |
468 | m_closeTabAction->setEnabled(openPages->pageCount() > 1); |
469 | connect(sender: openPages, signal: &OpenPagesManager::pageClosed, |
470 | context: this, slot: &MainWindow::handlePageCountChanged); |
471 | connect(sender: openPages, signal: &OpenPagesManager::pageAdded, |
472 | context: this, slot: &MainWindow::handlePageCountChanged); |
473 | |
474 | menu->addSeparator(); |
475 | |
476 | m_pageSetupAction = menu->addAction(text: tr(s: "Page Set&up..." ), |
477 | args&: m_centralWidget, args: &CentralWidget::pageSetup); |
478 | m_printPreviewAction = menu->addAction(text: tr(s: "Print Preview..." ), |
479 | args&: m_centralWidget, args: &CentralWidget::printPreview); |
480 | |
481 | GlobalActions *globalActions = GlobalActions::instance(parent: this); |
482 | menu->addAction(action: globalActions->printAction()); |
483 | menu->addSeparator(); |
484 | |
485 | QIcon appExitIcon = QIcon::fromTheme(name: "application-exit" ); |
486 | QAction *tmp; |
487 | #ifdef Q_OS_WIN |
488 | tmp = menu->addAction(appExitIcon, tr("E&xit" ), |
489 | this, &QWidget::close); |
490 | tmp->setShortcut(QKeySequence(tr("CTRL+Q" ))); |
491 | #else |
492 | tmp = menu->addAction(icon: appExitIcon, text: tr(s: "&Quit" ), |
493 | args: this, args: &QWidget::close); |
494 | tmp->setShortcut(QKeySequence::Quit); |
495 | #endif |
496 | tmp->setMenuRole(QAction::QuitRole); |
497 | |
498 | menu = menuBar()->addMenu(title: tr(s: "&Edit" )); |
499 | #if QT_CONFIG(clipboard) |
500 | menu->addAction(action: globalActions->copyAction()); |
501 | #endif |
502 | menu->addAction(action: globalActions->findAction()); |
503 | |
504 | QAction *findNextAction = menu->addAction(text: tr(s: "Find &Next" ), |
505 | args&: m_centralWidget, args: &CentralWidget::findNext); |
506 | findNextAction->setShortcuts(QKeySequence::FindNext); |
507 | |
508 | QAction *findPreviousAction = menu->addAction(text: tr(s: "Find &Previous" ), |
509 | args&: m_centralWidget, args: &CentralWidget::findPrevious); |
510 | findPreviousAction->setShortcuts(QKeySequence::FindPrevious); |
511 | |
512 | menu->addSeparator(); |
513 | tmp = menu->addAction(text: tr(s: "Preferences..." ), |
514 | args: this, args: &MainWindow::showPreferences); |
515 | tmp->setMenuRole(QAction::PreferencesRole); |
516 | |
517 | m_viewMenu = menuBar()->addMenu(title: tr(s: "&View" )); |
518 | m_viewMenu->addAction(action: globalActions->zoomInAction()); |
519 | m_viewMenu->addAction(action: globalActions->zoomOutAction()); |
520 | |
521 | m_resetZoomAction = m_viewMenu->addAction(text: tr(s: "Normal &Size" ), |
522 | args&: m_centralWidget, args: &CentralWidget::resetZoom); |
523 | m_resetZoomAction->setPriority(QAction::LowPriority); |
524 | m_resetZoomAction->setIcon(QIcon(resourcePath + QLatin1String("/resetzoom.png" ))); |
525 | m_resetZoomAction->setShortcut(tr(s: "Ctrl+0" )); |
526 | |
527 | m_viewMenu->addSeparator(); |
528 | |
529 | m_viewMenu->addAction(text: tr(s: "Contents" ), shortcut: QKeySequence(tr(s: "ALT+C" )), |
530 | args: this, args: &MainWindow::showContents); |
531 | m_viewMenu->addAction(text: tr(s: "Index" ), shortcut: QKeySequence(tr(s: "ALT+I" )), |
532 | args: this, args: &MainWindow::showIndex); |
533 | m_viewMenu->addAction(text: tr(s: "Bookmarks" ), shortcut: QKeySequence(tr(s: "ALT+O" )), |
534 | args: this, args: &MainWindow::showBookmarksDockWidget); |
535 | m_viewMenu->addAction(text: tr(s: "Search" ), shortcut: QKeySequence(tr(s: "ALT+S" )), |
536 | args: this, args: &MainWindow::showSearch); |
537 | m_viewMenu->addAction(text: tr(s: "Open Pages" ), shortcut: QKeySequence(tr(s: "ALT+P" )), |
538 | args: this, args: &MainWindow::showOpenPages); |
539 | |
540 | menu = menuBar()->addMenu(title: tr(s: "&Go" )); |
541 | menu->addAction(action: globalActions->homeAction()); |
542 | menu->addAction(action: globalActions->backAction()); |
543 | menu->addAction(action: globalActions->nextAction()); |
544 | |
545 | m_syncAction = menu->addAction(text: tr(s: "Sync with Table of Contents" ), |
546 | args: this, args: &MainWindow::syncContents); |
547 | m_syncAction->setIconText(tr(s: "Sync" )); |
548 | m_syncAction->setIcon(QIcon(resourcePath + QLatin1String("/synctoc.png" ))); |
549 | |
550 | menu->addSeparator(); |
551 | |
552 | tmp = menu->addAction(text: tr(s: "Next Page" ), |
553 | args: openPages, args: &OpenPagesManager::nextPage); |
554 | tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr(s: "Ctrl+Alt+Right" )) |
555 | << QKeySequence(Qt::CTRL | Qt::Key_PageDown)); |
556 | |
557 | tmp = menu->addAction(text: tr(s: "Previous Page" ), |
558 | args: openPages, args: &OpenPagesManager::previousPage); |
559 | tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr(s: "Ctrl+Alt+Left" )) |
560 | << QKeySequence(Qt::CTRL | Qt::Key_PageUp)); |
561 | |
562 | const Qt::Modifier modifier = |
563 | #ifdef Q_OS_MAC |
564 | Qt::ALT; |
565 | #else |
566 | Qt::CTRL; |
567 | #endif |
568 | |
569 | QShortcut *sct = new QShortcut(QKeySequence(modifier | Qt::Key_Tab), this); |
570 | connect(sender: sct, signal: &QShortcut::activated, |
571 | context: openPages, slot: &OpenPagesManager::nextPageWithSwitcher); |
572 | sct = new QShortcut(QKeySequence(modifier | Qt::SHIFT | Qt::Key_Tab), this); |
573 | connect(sender: sct, signal: &QShortcut::activated, |
574 | context: openPages, slot: &OpenPagesManager::previousPageWithSwitcher); |
575 | |
576 | BookmarkManager::instance()->setBookmarksMenu(menuBar()->addMenu(title: tr(s: "&Bookmarks" ))); |
577 | |
578 | menu = menuBar()->addMenu(title: tr(s: "&Help" )); |
579 | m_aboutAction = menu->addAction(text: tr(s: "About..." ), |
580 | args: this, args: &MainWindow::showAboutDialog); |
581 | m_aboutAction->setMenuRole(QAction::AboutRole); |
582 | |
583 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) |
584 | m_resetZoomAction->setIcon(QIcon::fromTheme(name: "zoom-original" , fallback: m_resetZoomAction->icon())); |
585 | m_syncAction->setIcon(QIcon::fromTheme(name: "view-refresh" , fallback: m_syncAction->icon())); |
586 | #endif |
587 | |
588 | QToolBar *navigationBar = addToolBar(title: tr(s: "Navigation Toolbar" )); |
589 | navigationBar->setObjectName(QLatin1String("NavigationToolBar" )); |
590 | navigationBar->addAction(action: globalActions->backAction()); |
591 | navigationBar->addAction(action: globalActions->nextAction()); |
592 | navigationBar->addAction(action: globalActions->homeAction()); |
593 | navigationBar->addAction(action: m_syncAction); |
594 | navigationBar->addSeparator(); |
595 | #if QT_CONFIG(clipboard) |
596 | navigationBar->addAction(action: globalActions->copyAction()); |
597 | #endif |
598 | navigationBar->addAction(action: globalActions->printAction()); |
599 | navigationBar->addAction(action: globalActions->findAction()); |
600 | navigationBar->addSeparator(); |
601 | navigationBar->addAction(action: globalActions->zoomInAction()); |
602 | navigationBar->addAction(action: globalActions->zoomOutAction()); |
603 | navigationBar->addAction(action: m_resetZoomAction); |
604 | |
605 | #if defined(Q_OS_MAC) |
606 | QMenu *windowMenu = new QMenu(tr("&Window" ), this); |
607 | menuBar()->insertMenu(menu->menuAction(), windowMenu); |
608 | windowMenu->addAction(tr("Zoom" ), |
609 | this, &QWidget::showMaximized); |
610 | windowMenu->addAction(tr("Minimize" ), QKeySequence(tr("Ctrl+M" )), |
611 | this, &QWidget::showMinimized); |
612 | #endif |
613 | |
614 | // content viewer connections |
615 | #if QT_CONFIG(clipboard) |
616 | connect(sender: m_centralWidget, signal: &CentralWidget::copyAvailable, |
617 | context: globalActions, slot: &GlobalActions::setCopyAvailable); |
618 | #endif |
619 | connect(sender: m_centralWidget, signal: &CentralWidget::currentViewerChanged, |
620 | context: globalActions, slot: &GlobalActions::updateActions); |
621 | connect(sender: m_centralWidget, signal: &CentralWidget::forwardAvailable, |
622 | context: globalActions, slot: &GlobalActions::updateActions); |
623 | connect(sender: m_centralWidget, signal: &CentralWidget::backwardAvailable, |
624 | context: globalActions, slot: &GlobalActions::updateActions); |
625 | connect(sender: m_centralWidget, signal: &CentralWidget::highlighted, |
626 | context: this, slot: [this](const QUrl &link) { statusBar()->showMessage(text: link.toString());} ); |
627 | |
628 | // index window |
629 | connect(sender: m_indexWindow, signal: &IndexWindow::linkActivated, |
630 | context: m_centralWidget, slot: &CentralWidget::setSource); |
631 | connect(sender: m_indexWindow, signal: &IndexWindow::documentsActivated, |
632 | context: this, slot: &MainWindow::showTopicChooser); |
633 | connect(sender: m_indexWindow, signal: &IndexWindow::escapePressed, |
634 | context: this, slot: &MainWindow::activateCurrentCentralWidgetTab); |
635 | |
636 | // content window |
637 | connect(sender: m_contentWindow, signal: &ContentWindow::linkActivated, |
638 | context: m_centralWidget, slot: &CentralWidget::setSource); |
639 | connect(sender: m_contentWindow, signal: &ContentWindow::escapePressed, |
640 | context: this, slot: &MainWindow::activateCurrentCentralWidgetTab); |
641 | |
642 | // search window |
643 | connect(sender: m_searchWindow, signal: &SearchWidget::requestShowLink, |
644 | context: CentralWidget::instance(), slot: &CentralWidget::setSourceFromSearch); |
645 | connect(sender: m_searchWindow, signal: &SearchWidget::requestShowLinkInNewTab, |
646 | context: OpenPagesManager::instance(), slot: &OpenPagesManager::createNewPageFromSearch); |
647 | |
648 | #if defined(QT_NO_PRINTER) |
649 | m_pageSetupAction->setVisible(false); |
650 | m_printPreviewAction->setVisible(false); |
651 | globalActions->printAction()->setVisible(false); |
652 | #endif |
653 | } |
654 | |
655 | QMenu *MainWindow::toolBarMenu() |
656 | { |
657 | TRACE_OBJ |
658 | if (!m_toolBarMenu) { |
659 | m_viewMenu->addSeparator(); |
660 | m_toolBarMenu = m_viewMenu->addMenu(title: tr(s: "Toolbars" )); |
661 | } |
662 | return m_toolBarMenu; |
663 | } |
664 | |
665 | void MainWindow::setupFilterToolbar() |
666 | { |
667 | TRACE_OBJ |
668 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
669 | if (!helpEngine.filterFunctionalityEnabled()) |
670 | return; |
671 | |
672 | m_filterCombo = new QComboBox(this); |
673 | m_filterCombo->setMinimumWidth(QFontMetrics(QFont()). |
674 | horizontalAdvance(QLatin1String("MakeTheComboBoxWidthEnough" ))); |
675 | |
676 | QToolBar *filterToolBar = addToolBar(title: tr(s: "Filter Toolbar" )); |
677 | filterToolBar->setObjectName(QLatin1String("FilterToolBar" )); |
678 | filterToolBar->addWidget(widget: new QLabel(tr(s: "Filtered by:" ).append(c: QLatin1Char(' ')), |
679 | this)); |
680 | filterToolBar->addWidget(widget: m_filterCombo); |
681 | |
682 | if (!helpEngine.filterToolbarVisible()) |
683 | filterToolBar->hide(); |
684 | toolBarMenu()->addAction(action: filterToolBar->toggleViewAction()); |
685 | |
686 | connect(sender: &helpEngine, signal: &HelpEngineWrapper::setupFinished, |
687 | context: this, slot: &MainWindow::setupFilterCombo, type: Qt::QueuedConnection); |
688 | connect(sender: m_filterCombo, signal: &QComboBox::activated, |
689 | context: this, slot: &MainWindow::filterDocumentation); |
690 | connect(sender: helpEngine.filterEngine(), signal: &QHelpFilterEngine::filterActivated, |
691 | context: this, slot: &MainWindow::currentFilterChanged); |
692 | |
693 | setupFilterCombo(); |
694 | } |
695 | |
696 | void MainWindow::setupAddressToolbar() |
697 | { |
698 | TRACE_OBJ |
699 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
700 | if (!helpEngine.addressBarEnabled()) |
701 | return; |
702 | |
703 | m_addressLineEdit = new QLineEdit(this); |
704 | QToolBar *addressToolBar = addToolBar(title: tr(s: "Address Toolbar" )); |
705 | addressToolBar->setObjectName(QLatin1String("AddressToolBar" )); |
706 | insertToolBarBreak(before: addressToolBar); |
707 | |
708 | addressToolBar->addWidget(widget: new QLabel(tr(s: "Address:" ).append(c: QChar::Space), |
709 | this)); |
710 | addressToolBar->addWidget(widget: m_addressLineEdit); |
711 | |
712 | if (!helpEngine.addressBarVisible()) |
713 | addressToolBar->hide(); |
714 | toolBarMenu()->addAction(action: addressToolBar->toggleViewAction()); |
715 | |
716 | // address lineedit |
717 | connect(sender: m_addressLineEdit, signal: &QLineEdit::returnPressed, |
718 | context: this, slot: &MainWindow::gotoAddress); |
719 | connect(sender: m_centralWidget, signal: &CentralWidget::currentViewerChanged, |
720 | context: this, slot: QOverload<>::of(ptr: &MainWindow::showNewAddress)); |
721 | connect(sender: m_centralWidget, signal: &CentralWidget::sourceChanged, |
722 | context: this, slot: QOverload<>::of(ptr: &MainWindow::showNewAddress)); |
723 | } |
724 | |
725 | void MainWindow::updateAboutMenuText() |
726 | { |
727 | TRACE_OBJ |
728 | QByteArray ba = HelpEngineWrapper::instance().aboutMenuTexts(); |
729 | if (ba.size() > 0) { |
730 | QString lang; |
731 | QString str; |
732 | QString trStr; |
733 | QString currentLang = QLocale::system().name(); |
734 | int i = currentLang.indexOf(c: QLatin1Char('_')); |
735 | if (i > -1) |
736 | currentLang = currentLang.left(n: i); |
737 | QDataStream s(&ba, QIODevice::ReadOnly); |
738 | while (!s.atEnd()) { |
739 | s >> lang; |
740 | s >> str; |
741 | if (lang == QLatin1String("default" ) && trStr.isEmpty()) { |
742 | trStr = str; |
743 | } else if (lang == currentLang) { |
744 | trStr = str; |
745 | break; |
746 | } |
747 | } |
748 | if (!trStr.isEmpty()) |
749 | m_aboutAction->setText(trStr); |
750 | } |
751 | } |
752 | |
753 | void MainWindow::showNewAddress() |
754 | { |
755 | TRACE_OBJ |
756 | showNewAddress(url: m_centralWidget->currentSource()); |
757 | } |
758 | |
759 | void MainWindow::showNewAddress(const QUrl &url) |
760 | { |
761 | TRACE_OBJ |
762 | m_addressLineEdit->setText(url.toString()); |
763 | } |
764 | |
765 | void MainWindow::gotoAddress() |
766 | { |
767 | TRACE_OBJ |
768 | m_centralWidget->setSource(m_addressLineEdit->text()); |
769 | } |
770 | |
771 | void MainWindow::showTopicChooser(const QList<QHelpLink> &documents, |
772 | const QString &keyword) |
773 | { |
774 | TRACE_OBJ |
775 | TopicChooser tc(this, keyword, documents); |
776 | if (tc.exec() == QDialog::Accepted) { |
777 | m_centralWidget->setSource(tc.link()); |
778 | } |
779 | } |
780 | |
781 | void MainWindow::showPreferences() |
782 | { |
783 | TRACE_OBJ |
784 | PreferencesDialog dia(this); |
785 | connect(sender: &dia, signal: &PreferencesDialog::updateApplicationFont, |
786 | context: this, slot: &MainWindow::updateApplicationFont); |
787 | connect(sender: &dia, signal: &PreferencesDialog::updateBrowserFont, |
788 | context: m_centralWidget, slot: &CentralWidget::updateBrowserFont); |
789 | connect(sender: &dia, signal: &PreferencesDialog::updateUserInterface, |
790 | context: m_centralWidget, slot: &CentralWidget::updateUserInterface); |
791 | dia.exec(); |
792 | } |
793 | |
794 | void MainWindow::syncContents() |
795 | { |
796 | TRACE_OBJ |
797 | qApp->setOverrideCursor(QCursor(Qt::WaitCursor)); |
798 | const QUrl url = m_centralWidget->currentSource(); |
799 | showContents(); |
800 | if (!m_contentWindow->syncToContent(url)) |
801 | statusBar()->showMessage( |
802 | text: tr(s: "Could not find the associated content item." ), timeout: 3000); |
803 | qApp->restoreOverrideCursor(); |
804 | } |
805 | |
806 | void MainWindow::showAboutDialog() |
807 | { |
808 | TRACE_OBJ |
809 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
810 | QByteArray contents; |
811 | QByteArray ba = helpEngine.aboutTexts(); |
812 | if (!ba.isEmpty()) { |
813 | QString lang; |
814 | QByteArray cba; |
815 | QString currentLang = QLocale::system().name(); |
816 | int i = currentLang.indexOf(c: QLatin1Char('_')); |
817 | if (i > -1) |
818 | currentLang = currentLang.left(n: i); |
819 | QDataStream s(&ba, QIODevice::ReadOnly); |
820 | while (!s.atEnd()) { |
821 | s >> lang; |
822 | s >> cba; |
823 | if (lang == QLatin1String("default" ) && contents.isEmpty()) { |
824 | contents = cba; |
825 | } else if (lang == currentLang) { |
826 | contents = cba; |
827 | break; |
828 | } |
829 | } |
830 | } |
831 | |
832 | AboutDialog aboutDia(this); |
833 | |
834 | QByteArray iconArray; |
835 | if (!contents.isEmpty()) { |
836 | iconArray = helpEngine.aboutIcon(); |
837 | QByteArray resources = helpEngine.aboutImages(); |
838 | QPixmap pix; |
839 | pix.loadFromData(buf: iconArray); |
840 | aboutDia.setText(text: QString::fromUtf8(ba: contents), resources); |
841 | if (!pix.isNull()) |
842 | aboutDia.setPixmap(pix); |
843 | aboutDia.setWindowTitle(aboutDia.documentTitle()); |
844 | } else { |
845 | QByteArray resources; |
846 | #if defined(BROWSER_QTWEBKIT) |
847 | QString browser = QStringLiteral("Qt WebKit" ); |
848 | #else |
849 | QString browser = QStringLiteral("QTextBrowser" ); |
850 | #endif |
851 | if (m_centralWidget->currentHelpViewer()) |
852 | browser = QStringLiteral("QLiteHtmlWidget" ); |
853 | aboutDia.setText(text: tr(s: "<center>" |
854 | "<h3>%1</h3>" |
855 | "<p>Version %2</p>" |
856 | "<p>Browser: %3</p></center>" |
857 | "<p>Copyright (C) %4 The Qt Company Ltd.</p>" ) |
858 | .arg(args: tr(s: "Qt Assistant" ), args: QLatin1String(QT_VERSION_STR), args&: browser, QStringLiteral("2023" )), |
859 | resources); |
860 | QLatin1String path(":/qt-project.org/assistant/images/assistant-128.png" ); |
861 | aboutDia.setPixmap(QString(path)); |
862 | } |
863 | if (aboutDia.windowTitle().isEmpty()) |
864 | aboutDia.setWindowTitle(tr(s: "About %1" ).arg(a: windowTitle())); |
865 | aboutDia.exec(); |
866 | } |
867 | |
868 | void MainWindow::setContentsVisible(bool visible) |
869 | { |
870 | TRACE_OBJ |
871 | if (visible) |
872 | showContents(); |
873 | else |
874 | hideContents(); |
875 | } |
876 | |
877 | void MainWindow::showContents() |
878 | { |
879 | TRACE_OBJ |
880 | activateDockWidget(w: m_contentWindow); |
881 | } |
882 | |
883 | void MainWindow::hideContents() |
884 | { |
885 | TRACE_OBJ |
886 | m_contentWindow->parentWidget()->hide(); |
887 | } |
888 | |
889 | void MainWindow::setIndexVisible(bool visible) |
890 | { |
891 | TRACE_OBJ |
892 | if (visible) |
893 | showIndex(); |
894 | else |
895 | hideIndex(); |
896 | } |
897 | |
898 | void MainWindow::showIndex() |
899 | { |
900 | TRACE_OBJ |
901 | activateDockWidget(w: m_indexWindow); |
902 | } |
903 | |
904 | void MainWindow::hideIndex() |
905 | { |
906 | TRACE_OBJ |
907 | m_indexWindow->parentWidget()->hide(); |
908 | } |
909 | |
910 | void MainWindow::setBookmarksVisible(bool visible) |
911 | { |
912 | TRACE_OBJ |
913 | if (visible) |
914 | showBookmarksDockWidget(); |
915 | else |
916 | hideBookmarksDockWidget(); |
917 | } |
918 | |
919 | void MainWindow::showBookmarksDockWidget() |
920 | { |
921 | TRACE_OBJ |
922 | activateDockWidget(w: m_bookmarkWidget); |
923 | } |
924 | |
925 | void MainWindow::hideBookmarksDockWidget() |
926 | { |
927 | TRACE_OBJ |
928 | m_bookmarkWidget->parentWidget()->hide(); |
929 | } |
930 | |
931 | void MainWindow::setSearchVisible(bool visible) |
932 | { |
933 | TRACE_OBJ |
934 | if (visible) |
935 | showSearch(); |
936 | else |
937 | hideSearch(); |
938 | } |
939 | |
940 | void MainWindow::showSearch() |
941 | { |
942 | TRACE_OBJ |
943 | activateDockWidget(w: m_searchWindow); |
944 | } |
945 | |
946 | void MainWindow::showOpenPages() |
947 | { |
948 | TRACE_OBJ |
949 | activateDockWidget(w: OpenPagesManager::instance()->openPagesWidget()); |
950 | } |
951 | |
952 | void MainWindow::hideSearch() |
953 | { |
954 | TRACE_OBJ |
955 | m_searchWindow->parentWidget()->hide(); |
956 | } |
957 | |
958 | void MainWindow::activateDockWidget(QWidget *w) |
959 | { |
960 | TRACE_OBJ |
961 | w->parentWidget()->show(); |
962 | w->parentWidget()->raise(); |
963 | w->setFocus(); |
964 | } |
965 | |
966 | void MainWindow::setIndexString(const QString &str) |
967 | { |
968 | TRACE_OBJ |
969 | m_indexWindow->setSearchLineEditText(str); |
970 | } |
971 | |
972 | void MainWindow::activateCurrentBrowser() |
973 | { |
974 | TRACE_OBJ |
975 | CentralWidget::instance()->activateTab(); |
976 | } |
977 | |
978 | void MainWindow::activateCurrentCentralWidgetTab() |
979 | { |
980 | TRACE_OBJ |
981 | m_centralWidget->activateTab(); |
982 | } |
983 | |
984 | void MainWindow::updateApplicationFont() |
985 | { |
986 | TRACE_OBJ |
987 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
988 | QFont font = qApp->font(); |
989 | if (helpEngine.usesAppFont()) |
990 | font = helpEngine.appFont(); |
991 | |
992 | const QWidgetList &widgets = QApplication::allWidgets(); |
993 | for (QWidget *widget : widgets) |
994 | widget->setFont(font); |
995 | } |
996 | |
997 | void MainWindow::setupFilterCombo() |
998 | { |
999 | TRACE_OBJ |
1000 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
1001 | const QString currentFilter = helpEngine.filterEngine()->activeFilter(); |
1002 | m_filterCombo->clear(); |
1003 | m_filterCombo->addItem(atext: tr(s: "Unfiltered" )); |
1004 | const QStringList allFilters = helpEngine.filterEngine()->filters(); |
1005 | if (!allFilters.isEmpty()) |
1006 | m_filterCombo->insertSeparator(index: 1); |
1007 | for (const QString &filter : allFilters) |
1008 | m_filterCombo->addItem(atext: filter, auserData: filter); |
1009 | |
1010 | int idx = m_filterCombo->findData(data: currentFilter); |
1011 | if (idx < 0) |
1012 | idx = 0; |
1013 | m_filterCombo->setCurrentIndex(idx); |
1014 | } |
1015 | |
1016 | void MainWindow::filterDocumentation(int filterIndex) |
1017 | { |
1018 | TRACE_OBJ |
1019 | |
1020 | const QString filter = m_filterCombo->itemData(index: filterIndex).toString(); |
1021 | HelpEngineWrapper::instance().filterEngine()->setActiveFilter(filter); |
1022 | } |
1023 | |
1024 | void MainWindow::expandTOC(int depth) |
1025 | { |
1026 | TRACE_OBJ |
1027 | Q_ASSERT(depth >= -1); |
1028 | m_contentWindow->expandToDepth(depth); |
1029 | } |
1030 | |
1031 | void MainWindow::indexingStarted() |
1032 | { |
1033 | TRACE_OBJ |
1034 | if (!m_progressWidget) { |
1035 | m_progressWidget = new QWidget(); |
1036 | QLayout* hlayout = new QHBoxLayout(m_progressWidget); |
1037 | |
1038 | QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum); |
1039 | |
1040 | QLabel *label = new QLabel(tr(s: "Updating search index" )); |
1041 | label->setSizePolicy(sizePolicy); |
1042 | hlayout->addWidget(w: label); |
1043 | |
1044 | QProgressBar *progressBar = new QProgressBar(); |
1045 | progressBar->setRange(minimum: 0, maximum: 0); |
1046 | progressBar->setTextVisible(false); |
1047 | progressBar->setSizePolicy(sizePolicy); |
1048 | |
1049 | hlayout->setSpacing(6); |
1050 | hlayout->setContentsMargins(QMargins()); |
1051 | hlayout->addWidget(w: progressBar); |
1052 | |
1053 | statusBar()->addPermanentWidget(widget: m_progressWidget); |
1054 | } |
1055 | } |
1056 | |
1057 | void MainWindow::indexingFinished() |
1058 | { |
1059 | TRACE_OBJ |
1060 | statusBar()->removeWidget(widget: m_progressWidget); |
1061 | delete m_progressWidget; |
1062 | m_progressWidget = nullptr; |
1063 | } |
1064 | |
1065 | QString MainWindow::collectionFileDirectory(bool createDir, const QString &cacheDir) |
1066 | { |
1067 | TRACE_OBJ |
1068 | QString collectionPath = |
1069 | QStandardPaths::writableLocation(type: QStandardPaths::GenericDataLocation); |
1070 | if (collectionPath.isEmpty()) { |
1071 | if (cacheDir.isEmpty()) |
1072 | collectionPath = QDir::homePath() + QDir::separator() |
1073 | + QLatin1String(".assistant" ); |
1074 | else |
1075 | collectionPath = QDir::homePath() + QLatin1String("/." ) + cacheDir; |
1076 | } else { |
1077 | if (cacheDir.isEmpty()) |
1078 | collectionPath = collectionPath + QLatin1String("/QtProject/Assistant" ); |
1079 | else |
1080 | collectionPath = collectionPath + QDir::separator() + cacheDir; |
1081 | } |
1082 | if (createDir) { |
1083 | QDir dir; |
1084 | if (!dir.exists(name: collectionPath)) |
1085 | dir.mkpath(dirPath: collectionPath); |
1086 | } |
1087 | return collectionPath; |
1088 | } |
1089 | |
1090 | QString MainWindow::defaultHelpCollectionFileName() |
1091 | { |
1092 | TRACE_OBJ |
1093 | // forces creation of the default collection file path |
1094 | return collectionFileDirectory(createDir: true) + QDir::separator() + |
1095 | QString(QLatin1String("qthelpcollection_%1.qhc" )). |
1096 | arg(a: QLatin1String(QT_VERSION_STR)); |
1097 | } |
1098 | |
1099 | void MainWindow::currentFilterChanged(const QString &filter) |
1100 | { |
1101 | TRACE_OBJ |
1102 | int index = m_filterCombo->findData(data: filter); |
1103 | if (index < 0) |
1104 | index = 0; |
1105 | m_filterCombo->setCurrentIndex(index); |
1106 | } |
1107 | |
1108 | void MainWindow::documentationRemoved(const QString &namespaceName) |
1109 | { |
1110 | TRACE_OBJ |
1111 | OpenPagesManager::instance()->closePages(nameSpace: namespaceName); |
1112 | } |
1113 | |
1114 | void MainWindow::documentationUpdated(const QString &namespaceName) |
1115 | { |
1116 | TRACE_OBJ |
1117 | OpenPagesManager::instance()->reloadPages(nameSpace: namespaceName); |
1118 | } |
1119 | |
1120 | void MainWindow::resetQtDocInfo(const QString &component) |
1121 | { |
1122 | TRACE_OBJ |
1123 | HelpEngineWrapper::instance().setQtDocInfo(component, |
1124 | doc: QStringList(QDateTime().toString(format: Qt::ISODate))); |
1125 | } |
1126 | |
1127 | void MainWindow::registerDocumentation(const QString &component, |
1128 | const QString &absFileName) |
1129 | { |
1130 | TRACE_OBJ |
1131 | QString ns = QHelpEngineCore::namespaceName(documentationFileName: absFileName); |
1132 | if (ns.isEmpty()) |
1133 | return; |
1134 | |
1135 | HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance(); |
1136 | if (helpEngine.registeredDocumentations().contains(str: ns)) |
1137 | helpEngine.unregisterDocumentation(namespaceName: ns); |
1138 | if (!helpEngine.registerDocumentation(docFile: absFileName)) { |
1139 | QMessageBox::warning(parent: this, title: tr(s: "Qt Assistant" ), |
1140 | text: tr(s: "Could not register file '%1': %2" ). |
1141 | arg(a: absFileName).arg(a: helpEngine.error())); |
1142 | } else { |
1143 | QStringList docInfo; |
1144 | docInfo << QFileInfo(absFileName).lastModified().toString(format: Qt::ISODate) |
1145 | << absFileName; |
1146 | helpEngine.setQtDocInfo(component, doc: docInfo); |
1147 | } |
1148 | } |
1149 | |
1150 | void MainWindow::handlePageCountChanged() |
1151 | { |
1152 | m_closeTabAction->setEnabled(OpenPagesManager::instance()->pageCount() > 1); |
1153 | } |
1154 | |
1155 | QT_END_NAMESPACE |
1156 | |