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