VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpBrowserWidget.cpp@ 102493

Last change on this file since 102493 was 102269, checked in by vboxsync, 11 months ago

FE/Qt: bugref:10450: macOS: No need to QIToolBar layout/paint hacks since Qt6.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 75.1 KB
Line 
1/* $Id: UIHelpBrowserWidget.cpp 102269 2023-11-22 18:50:08Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIHelpBrowserWidget class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28/* Qt includes: */
29#include <QClipboard>
30#include <QComboBox>
31#include <QtGlobal>
32#include <QtHelp/QHelpEngine>
33#include <QtHelp/QHelpContentWidget>
34#include <QtHelp/QHelpIndexWidget>
35#include <QtHelp/QHelpSearchEngine>
36#include <QtHelp/QHelpSearchQueryWidget>
37#include <QtHelp/QHelpSearchResultWidget>
38#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
39# include <QtHelp/QHelpLink>
40#endif
41
42#include <QLabel>
43#include <QListWidget>
44#include <QMenu>
45#include <QMouseEvent>
46#include <QtPrintSupport/QPrintDialog>
47#include <QtPrintSupport/QPrinter>
48#include <QSplitter>
49#include <QVBoxLayout>
50#ifdef RT_OS_SOLARIS
51# include <QFontDatabase>
52#endif
53#include <QWidgetAction>
54
55/* GUI includes: */
56#include "QIAdvancedSlider.h"
57#include "QITabWidget.h"
58#include "QIToolBar.h"
59#include "QIToolButton.h"
60#include "UIActionPool.h"
61#include "UIExtraDataManager.h"
62#include "UIHelpViewer.h"
63#include "UIHelpBrowserWidget.h"
64#include "UIIconPool.h"
65
66
67/* COM includes: */
68#include "COMEnums.h"
69#include "CSystemProperties.h"
70
71
72enum HelpBrowserTabs
73{
74 HelpBrowserTabs_TOC = 0,
75 HelpBrowserTabs_Search,
76 HelpBrowserTabs_Bookmarks,
77 HelpBrowserTabs_Index,
78 HelpBrowserTabs_Max
79};
80Q_DECLARE_METATYPE(HelpBrowserTabs);
81
82static const int iBookmarkUrlDataType = 6;
83
84static int iZoomPercentageStep = 20;
85const QPair<int, int> zoomPercentageMinMax = QPair<int, int>(20, 300);
86
87
88/*********************************************************************************************************************************
89* UIZoomMenuAction definition. *
90*********************************************************************************************************************************/
91class UIZoomMenuAction : public QIWithRetranslateUI<QWidgetAction>
92{
93
94 Q_OBJECT;
95
96signals:
97
98 void sigZoomChanged(int iOperation);
99
100public:
101
102 UIZoomMenuAction(QWidget *pParent = 0);
103 void setZoomPercentage(int iZoomPercentage);
104
105protected:
106
107 void retranslateUi() RT_OVERRIDE;
108
109private slots:
110
111 void sltZoomOperation();
112
113private:
114
115 void prepare();
116
117 QIToolButton *m_pMinusButton;
118 QIToolButton *m_pResetButton;
119 QIToolButton *m_pPlusButton;
120 QLabel *m_pValueLabel;
121 QLabel *m_pLabel;
122};
123
124
125/*********************************************************************************************************************************
126* UIBookmarksListWidget definition. *
127*********************************************************************************************************************************/
128class UIBookmarksListWidget : public QListWidget
129{
130
131 Q_OBJECT;
132
133signals:
134
135 void sigBookmarkDoubleClick(const QUrl &url);
136
137public:
138
139 UIBookmarksListWidget(QWidget *pParent = 0);
140
141protected:
142
143 void mouseDoubleClickEvent(QMouseEvent *event) RT_OVERRIDE;
144 void mousePressEvent(QMouseEvent *pEvent) RT_OVERRIDE;
145};
146
147
148/*********************************************************************************************************************************
149* UIBookmarksListContainer definition. *
150*********************************************************************************************************************************/
151class UIBookmarksListContainer : public QIWithRetranslateUI<QWidget>
152{
153
154 Q_OBJECT;
155
156signals:
157
158 void sigBookmarkDoubleClick(const QUrl &url);
159 void sigListWidgetContextMenuRequest(const QPoint &listWidgetLocalPos);
160
161public:
162
163 UIBookmarksListContainer(QWidget *pParent = 0);
164 void addBookmark(const QUrl &url, const QString &strTitle);
165 /** Return all bookmarks a url, title pair list. */
166 QStringList bookmarks() const;
167 QUrl currentBookmarkUrl();
168
169public:
170
171 void sltDeleteSelectedBookmark();
172 void sltDeleteAllBookmarks();
173
174protected:
175
176 void retranslateUi() RT_OVERRIDE;
177
178private slots:
179
180private:
181
182 void prepare();
183 int itemIndex(const QUrl &url);
184
185 QVBoxLayout *m_pMainLayout;
186 UIBookmarksListWidget *m_pListWidget;
187};
188
189/*********************************************************************************************************************************
190* UIHelpBrowserTab definition. *
191*********************************************************************************************************************************/
192
193class UIHelpBrowserTab : public QIWithRetranslateUI<QWidget>
194{
195 Q_OBJECT;
196
197signals:
198
199 void sigSourceChanged(const QUrl &url);
200 void sigCopyAvailableChanged(bool fAvailable);
201 void sigTitleUpdate(const QString &strTitle);
202 void sigOpenLinkInNewTab(const QUrl &url, bool fBackground);
203 void sigAddBookmark(const QUrl &url, const QString &strTitle);
204 void sigLinkHighlighted(const QUrl &url);
205 void sigFindInPageWidgetVisibilityChanged(bool fVisible);
206 void sigHistoryChanged(bool fBackwardAvailable, bool fForwardAvailable);
207 void sigMouseOverImage(const QString &strImageName);
208 void sigZoomRequest(UIHelpViewer::ZoomOperation enmZoomOperation);
209
210public:
211
212 UIHelpBrowserTab(const QHelpEngine *pHelpEngine, const QUrl &homeUrl,
213 const QUrl &initialUrl, QWidget *pParent = 0);
214
215 QUrl source() const;
216 void setSource(const QUrl &url);
217 QString documentTitle() const;
218 void setToolBarVisible(bool fVisible);
219 void print(QPrinter &printer);
220 void setZoomPercentage(int iZoomPercentage);
221 void setHelpFileList(const QList<QUrl> &helpFileList);
222 void copySelectedText() const;
223 bool hasSelectedText() const;
224 bool isFindInPageWidgetVisible() const;
225 void findNext();
226 void findPrevious();
227
228public slots:
229
230 void sltFindInPageAction(bool fToggled);
231 void sltHomeAction();
232 void sltForwardAction();
233 void sltBackwardAction();
234 void sltAddBookmarkAction();
235 void sltReloadPageAction();
236
237private slots:
238
239 void sltHistoryChanged();
240 void sltAddressBarIndexChanged(int index);
241 void sltAnchorClicked(const QUrl &link);
242 void sltFindInPageWidgetVisibilityChanged(bool fVisible);
243
244private:
245
246 void prepare(const QUrl &initialUrl);
247 void prepareWidgets(const QUrl &initialUrl);
248 void prepareToolBarAndAddressBar();
249 virtual void retranslateUi() RT_OVERRIDE;
250 void setActionTextAndToolTip(QAction *pAction, const QString &strText, const QString &strToolTip);
251
252 QAction *m_pHomeAction;
253 QAction *m_pForwardAction;
254 QAction *m_pBackwardAction;
255 QAction *m_pAddBookmarkAction;
256 QAction *m_pFindInPageAction;
257 QAction *m_pReloadPageAction;
258
259 QVBoxLayout *m_pMainLayout;
260 QIToolBar *m_pToolBar;
261 QComboBox *m_pAddressBar;
262 UIHelpViewer *m_pContentViewer;
263 const QHelpEngine* m_pHelpEngine;
264 QUrl m_homeUrl;
265};
266
267
268/*********************************************************************************************************************************
269* UIHelpBrowserTabManager definition. *
270*********************************************************************************************************************************/
271
272class UIHelpBrowserTabManager : public QITabWidget
273{
274 Q_OBJECT;
275
276signals:
277
278 void sigSourceChanged(const QUrl &url);
279 void sigAddBookmark(const QUrl &url, const QString &strTitle);
280 /** list.first is tab title and list.second is tab's index. */
281 void sigTabsListChanged(const QStringList &titleList);
282 void sigLinkHighlighted(const QUrl &url);
283 void sigZoomPercentageChanged(int iPercentage);
284 void sigCopyAvailableChanged(bool fAvailable);
285 void sigFindInPageWidgetVisibilityChanged(bool fVisible);
286 void sigHistoryChanged(bool fBackwardAvailable, bool fForwardAvailable);
287 void sigMouseOverImage(const QString &strImageName);
288
289public:
290
291 UIHelpBrowserTabManager(const QHelpEngine *pHelpEngine, const QUrl &homeUrl,
292 const QStringList &urlList, QWidget *pParent = 0);
293 /* Returns the list of urls of all open tabs as QStringList. */
294 QStringList tabUrlList() const;
295 QStringList tabTitleList() const;
296
297 /** Either start with a single tab showin the home url or saved tab(s). Depending on the params. passed to ctor. */
298 void initializeTabs();
299 /* Url of the current tab. */
300 QUrl currentSource() const;
301 void setSource(const QUrl &url, bool fNewTab = false);
302 void setToolBarVisible(bool fVisible);
303 void printCurrent(QPrinter &printer);
304 void switchToTab(int iIndex);
305 int zoomPercentage() const;
306 void setZoomPercentage(int iZoomPercentage);
307 void setHelpFileList(const QList<QUrl> &helpFileList);
308 void copySelectedText() const;
309 bool hasCurrentTabSelectedText() const;
310 bool isFindInPageWidgetVisible() const;
311 void toggleFindInPage(bool fTrigger);
312 void findNext();
313 void findPrevious();
314
315public slots:
316
317 void sltCloseCurrentTab();
318 void sltCloseOtherTabs();
319 void sltHomeAction();
320 void sltAddBookmarkAction();
321 void sltForwardAction();
322 void sltBackwardAction();
323 void sltReloadPageAction();
324 void sltHandleZoomRequest(UIHelpViewer::ZoomOperation enmOperation);
325
326private slots:
327
328 void sltTabTitleChange(const QString &strTitle);
329 void sltOpenLinkInNewTab(const QUrl &url, bool fBackground);
330 void sltTabClose(int iTabIndex);
331 void sltContextMenuTabClose();
332 void sltCurrentChanged(int iTabIndex);
333 void sltShowTabBarContextMenu(const QPoint &pos);
334 void sltCloseOtherTabsContextMenuAction();
335 void sltCopyAvailableChanged(bool fAvailable);
336
337private:
338
339 void prepare();
340 void clearAndDeleteTabs();
341 void addNewTab(const QUrl &initialUrl, bool fBackground);
342 /** Check if lists of tab url/title has changed. if so emit a signal. */
343 void updateTabUrlTitleList();
344 /** Closes all tabs other than the one with index @param iTabIndex. */
345 void closeAllTabsBut(int iTabIndex);
346 /* Returns the tab index with @Url if there is one. Returns -1 otherwise. */
347 int findTab(const QUrl &Url) const;
348
349 const QHelpEngine* m_pHelpEngine;
350 QUrl m_homeUrl;
351 QStringList m_savedUrlList;
352 /** Immediately switch the newly created tab. Otherwise open the tab in background. */
353 bool m_fSwitchToNewTab;
354 bool m_fToolBarVisible;
355 QStringList m_tabTitleList;
356 QList<QUrl> m_helpFileList;
357 /** As percentage. */
358 int m_iZoomPercentage;
359};
360
361
362/*********************************************************************************************************************************
363* UIZoomMenuAction implementation. *
364*********************************************************************************************************************************/
365UIZoomMenuAction::UIZoomMenuAction(QWidget *pParent /* = 0 */)
366 :QIWithRetranslateUI<QWidgetAction>(pParent)
367 , m_pMinusButton(0)
368 , m_pResetButton(0)
369 , m_pPlusButton(0)
370 , m_pValueLabel(0)
371 , m_pLabel(0)
372{
373 prepare();
374 retranslateUi();
375}
376
377void UIZoomMenuAction::setZoomPercentage(int iZoomPercentage)
378{
379 if (m_pValueLabel)
380 m_pValueLabel->setText(QString("%1%2").arg(QString::number(iZoomPercentage)).arg("%"));
381}
382
383void UIZoomMenuAction::retranslateUi()
384{
385 if (m_pLabel)
386 m_pLabel->setText(UIHelpBrowserWidget::tr("Zoom"));
387}
388
389void UIZoomMenuAction::prepare()
390{
391 QWidget *pWidget = new QWidget;
392 setDefaultWidget(pWidget);
393
394 QHBoxLayout *pMainLayout = new QHBoxLayout(pWidget);
395 pMainLayout->setSpacing(0);
396 AssertReturnVoid(pMainLayout);
397
398 m_pLabel = new QLabel;
399 m_pMinusButton = new QIToolButton;
400 m_pResetButton = new QIToolButton;
401 m_pPlusButton = new QIToolButton;
402 m_pValueLabel = new QLabel;
403 m_pValueLabel->setAlignment(Qt::AlignCenter);
404 m_pValueLabel->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
405 AssertReturnVoid(m_pMinusButton &&
406 m_pResetButton &&
407 m_pPlusButton &&
408 m_pValueLabel);
409
410 m_pMinusButton->setIcon(UIIconPool::iconSet(":/help_browser_minus_16px.png", ":/help_browser_minus_disabled_16px.png"));
411 m_pResetButton->setIcon(UIIconPool::iconSet(":/help_browser_reset_16px.png", ":/help_browser_reset_disabled_16px.png"));
412 m_pPlusButton->setIcon(UIIconPool::iconSet(":/help_browser_plus_16px.png", ":/help_browser_plus_disabled_16px.png"));
413
414 connect(m_pPlusButton, &QIToolButton::pressed, this, &UIZoomMenuAction::sltZoomOperation);
415 connect(m_pMinusButton, &QIToolButton::pressed, this, &UIZoomMenuAction::sltZoomOperation);
416 connect(m_pResetButton, &QIToolButton::pressed, this, &UIZoomMenuAction::sltZoomOperation);
417
418 pMainLayout->addWidget(m_pLabel);
419 pMainLayout->addWidget(m_pResetButton);
420 pMainLayout->addWidget(m_pMinusButton);
421 pMainLayout->addWidget(m_pValueLabel, Qt::AlignCenter);
422 pMainLayout->addWidget(m_pPlusButton);
423 setZoomPercentage(100);
424}
425
426void UIZoomMenuAction::sltZoomOperation()
427{
428 if (!sender())
429 return;
430 UIHelpViewer::ZoomOperation enmOperation = UIHelpViewer::ZoomOperation_In;
431 if (sender() == m_pMinusButton)
432 enmOperation = UIHelpViewer::ZoomOperation_Out;
433 else if (sender() == m_pPlusButton)
434 enmOperation = UIHelpViewer::ZoomOperation_In;
435 else if (sender() == m_pResetButton)
436 enmOperation = UIHelpViewer::ZoomOperation_Reset;
437 emit sigZoomChanged((int)enmOperation);
438}
439
440
441/*********************************************************************************************************************************
442* UIBookmarksListWidget implementation. *
443*********************************************************************************************************************************/
444UIBookmarksListWidget::UIBookmarksListWidget(QWidget *pParent /* = 0 */)
445 :QListWidget(pParent)
446{
447 setSelectionMode(QAbstractItemView::SingleSelection);
448}
449
450void UIBookmarksListWidget::mouseDoubleClickEvent(QMouseEvent *event)
451{
452 QListWidgetItem *pItem = currentItem();
453 if (!pItem)
454 return;
455 emit sigBookmarkDoubleClick(pItem->data(iBookmarkUrlDataType).toUrl());
456 QListWidget::mouseDoubleClickEvent(event);
457}
458
459void UIBookmarksListWidget::mousePressEvent(QMouseEvent *pEvent)
460{
461 if (!indexAt(pEvent->position().toPoint()).isValid())
462 {
463 clearSelection();
464 setCurrentItem(0);
465 }
466 QListWidget::mousePressEvent(pEvent);
467}
468
469
470/*********************************************************************************************************************************
471* UIBookmarksListContainer implementation. *
472*********************************************************************************************************************************/
473
474UIBookmarksListContainer::UIBookmarksListContainer(QWidget *pParent /* = 0 */)
475 :QIWithRetranslateUI<QWidget>(pParent)
476 , m_pMainLayout(0)
477 , m_pListWidget(0)
478{
479 prepare();
480}
481
482void UIBookmarksListContainer::addBookmark(const QUrl &url, const QString &strTitle)
483{
484 if (!m_pListWidget)
485 return;
486 if (itemIndex(url) != -1)
487 return;
488 QListWidgetItem *pNewItem = new QListWidgetItem(strTitle, m_pListWidget);
489 pNewItem->setData(iBookmarkUrlDataType, url);
490 pNewItem->setToolTip(url.toString());
491}
492
493QStringList UIBookmarksListContainer::bookmarks() const
494{
495 if (!m_pListWidget)
496 return QStringList();
497 QStringList bookmarks;
498 for (int i = 0; i < m_pListWidget->count(); ++i)
499 {
500 QListWidgetItem *pItem = m_pListWidget->item(i);
501 if (!pItem)
502 continue;
503 bookmarks << pItem->data(iBookmarkUrlDataType).toUrl().toString() << pItem->text();
504 }
505 return bookmarks;
506}
507
508QUrl UIBookmarksListContainer::currentBookmarkUrl()
509{
510 if (!m_pListWidget || !m_pListWidget->currentItem())
511 return QUrl();
512 return m_pListWidget->currentItem()->data(iBookmarkUrlDataType).toUrl();
513}
514
515void UIBookmarksListContainer::sltDeleteSelectedBookmark()
516{
517 if (!m_pListWidget || !m_pListWidget->currentItem())
518 return;
519 QListWidgetItem *pCurrentItem = m_pListWidget->takeItem(m_pListWidget->currentRow());
520 delete pCurrentItem;
521}
522
523void UIBookmarksListContainer::sltDeleteAllBookmarks()
524{
525 if (m_pListWidget)
526 m_pListWidget->clear();
527}
528
529void UIBookmarksListContainer::retranslateUi()
530{
531}
532
533void UIBookmarksListContainer::prepare()
534{
535 m_pMainLayout = new QVBoxLayout(this);
536 AssertReturnVoid(m_pMainLayout);
537 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
538
539 m_pListWidget = new UIBookmarksListWidget;
540 AssertReturnVoid(m_pListWidget);
541 m_pMainLayout->addWidget(m_pListWidget);
542 m_pListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
543 connect(m_pListWidget, &UIBookmarksListWidget::sigBookmarkDoubleClick,
544 this, &UIBookmarksListContainer::sigBookmarkDoubleClick);
545 connect(m_pListWidget, &UIBookmarksListWidget::customContextMenuRequested,
546 this, &UIBookmarksListContainer::sigListWidgetContextMenuRequest);
547}
548
549int UIBookmarksListContainer::itemIndex(const QUrl &url)
550{
551 if (!m_pListWidget || !url.isValid())
552 return -1;
553 for (int i = 0; i < m_pListWidget->count(); ++i)
554 {
555 if (m_pListWidget->item(i)->data(iBookmarkUrlDataType).toUrl() == url)
556 return i;
557 }
558 return -1;
559}
560
561/*********************************************************************************************************************************
562* UIHelpBrowserTab implementation. *
563*********************************************************************************************************************************/
564
565UIHelpBrowserTab::UIHelpBrowserTab(const QHelpEngine *pHelpEngine, const QUrl &homeUrl,
566 const QUrl &initialUrl, QWidget *pParent /* = 0 */)
567 : QIWithRetranslateUI<QWidget>(pParent)
568 , m_pHomeAction(0)
569 , m_pForwardAction(0)
570 , m_pBackwardAction(0)
571 , m_pAddBookmarkAction(0)
572 , m_pFindInPageAction(0)
573 , m_pReloadPageAction(0)
574 , m_pMainLayout(0)
575 , m_pToolBar(0)
576 , m_pAddressBar(0)
577 , m_pContentViewer(0)
578 , m_pHelpEngine(pHelpEngine)
579 , m_homeUrl(homeUrl)
580{
581 if (initialUrl.isValid())
582 prepare(initialUrl);
583 else
584 prepare(m_homeUrl);
585}
586
587QUrl UIHelpBrowserTab::source() const
588{
589 if (!m_pContentViewer)
590 return QUrl();
591 return m_pContentViewer->source();
592}
593
594void UIHelpBrowserTab::setSource(const QUrl &url)
595{
596 if (m_pContentViewer)
597 {
598 m_pContentViewer->blockSignals(true);
599 m_pContentViewer->setSource(url);
600 m_pContentViewer->blockSignals(false);
601 /* emit historyChanged signal explicitly since we have blocked the signals: */
602 m_pContentViewer->emitHistoryChangedSignal();
603 }
604}
605
606QString UIHelpBrowserTab::documentTitle() const
607{
608 if (!m_pContentViewer)
609 return QString();
610 return m_pContentViewer->documentTitle();
611}
612
613void UIHelpBrowserTab::setToolBarVisible(bool fVisible)
614{
615 if (m_pToolBar)
616 m_pToolBar->setVisible(fVisible);
617 if (m_pAddressBar)
618 m_pAddressBar->setVisible(fVisible);
619}
620
621void UIHelpBrowserTab::print(QPrinter &printer)
622{
623 if (m_pContentViewer)
624 m_pContentViewer->print(&printer);
625}
626
627void UIHelpBrowserTab::setZoomPercentage(int iZoomPercentage)
628{
629 if (m_pContentViewer)
630 m_pContentViewer->setZoomPercentage(iZoomPercentage);
631}
632
633void UIHelpBrowserTab::setHelpFileList(const QList<QUrl> &helpFileList)
634{
635 if (m_pContentViewer)
636 m_pContentViewer->setHelpFileList(helpFileList);
637}
638
639void UIHelpBrowserTab::copySelectedText() const
640{
641 if (m_pContentViewer && m_pContentViewer->hasSelectedText())
642 m_pContentViewer->copy();
643}
644
645bool UIHelpBrowserTab::hasSelectedText() const
646{
647 if (m_pContentViewer)
648 return m_pContentViewer->textCursor().hasSelection();
649 return false;
650}
651
652bool UIHelpBrowserTab::isFindInPageWidgetVisible() const
653{
654 if (m_pContentViewer)
655 return m_pContentViewer->isFindInPageWidgetVisible();
656 return false;
657}
658
659void UIHelpBrowserTab::findNext()
660{
661 if (m_pContentViewer)
662 return m_pContentViewer->sltSelectNextMatch();
663}
664
665void UIHelpBrowserTab::findPrevious()
666{
667 if (m_pContentViewer)
668 return m_pContentViewer->sltSelectPreviousMatch();
669}
670
671void UIHelpBrowserTab::prepare(const QUrl &initialUrl)
672{
673 m_pMainLayout = new QVBoxLayout(this);
674 AssertReturnVoid(m_pMainLayout);
675 prepareToolBarAndAddressBar();
676 prepareWidgets(initialUrl);
677 retranslateUi();
678}
679
680void UIHelpBrowserTab::prepareWidgets(const QUrl &initialUrl)
681{
682 m_pContentViewer = new UIHelpViewer(m_pHelpEngine);
683 AssertReturnVoid(m_pContentViewer);
684 setFocusProxy(m_pContentViewer);
685 m_pMainLayout->setContentsMargins(0, 0, 0, 0);
686 m_pMainLayout->setSpacing(0);
687
688 m_pMainLayout->addWidget(m_pContentViewer);
689 m_pContentViewer->setOpenExternalLinks(false);
690 connect(m_pContentViewer, &UIHelpViewer::sourceChanged,
691 this, &UIHelpBrowserTab::sigSourceChanged);
692 connect(m_pContentViewer, &UIHelpViewer::historyChanged,
693 this, &UIHelpBrowserTab::sltHistoryChanged);
694 connect(m_pContentViewer, &UIHelpViewer::anchorClicked,
695 this, &UIHelpBrowserTab::sltAnchorClicked);
696 connect(m_pContentViewer, &UIHelpViewer::sigOpenLinkInNewTab,
697 this, &UIHelpBrowserTab::sigOpenLinkInNewTab);
698 connect(m_pContentViewer, &UIHelpViewer::sigGoBackward,
699 this, &UIHelpBrowserTab::sltBackwardAction);
700 connect(m_pContentViewer, &UIHelpViewer::sigGoForward,
701 this, &UIHelpBrowserTab::sltForwardAction);
702 connect(m_pContentViewer, &UIHelpViewer::sigGoHome,
703 this, &UIHelpBrowserTab::sltHomeAction);
704 connect(m_pContentViewer, &UIHelpViewer::sigAddBookmark,
705 this, &UIHelpBrowserTab::sltAddBookmarkAction);
706 connect(m_pContentViewer, &UIHelpViewer::highlighted,
707 this, &UIHelpBrowserTab::sigLinkHighlighted);
708 connect(m_pContentViewer, &UIHelpViewer::copyAvailable,
709 this, &UIHelpBrowserTab::sigCopyAvailableChanged);
710 connect(m_pContentViewer, &UIHelpViewer::sigFindInPageWidgetToogle,
711 this, &UIHelpBrowserTab::sltFindInPageWidgetVisibilityChanged);
712 connect(m_pContentViewer, &UIHelpViewer::sigMouseOverImage,
713 this, &UIHelpBrowserTab::sigMouseOverImage);
714 connect(m_pContentViewer, &UIHelpViewer::sigZoomRequest,
715 this, &UIHelpBrowserTab::sigZoomRequest);
716
717 m_pContentViewer->setSource(initialUrl);
718}
719
720void UIHelpBrowserTab::prepareToolBarAndAddressBar()
721{
722 m_pHomeAction =
723 new QAction(UIIconPool::iconSetFull(":/help_browser_home_32px.png", ":/help_browser_home_16px.png",
724 ":/help_browser_home_disabled_32px.png", ":/help_browser_home_disabled_16px.png"), QString(), this);
725 m_pForwardAction =
726 new QAction(UIIconPool::iconSetFull(":/help_browser_forward_32px.png", ":/help_browser_forward_16px.png",
727 ":/help_browser_forward_disabled_32px.png", ":/help_browser_forward_disabled_16px.png"), QString(), this);
728 m_pBackwardAction =
729 new QAction(UIIconPool::iconSetFull(":/help_browser_backward_32px.png", ":/help_browser_backward_16px.png",
730 ":/help_browser_backward_disabled_32px.png", ":/help_browser_backward_disabled_16px.png"), QString(), this);
731 m_pAddBookmarkAction =
732 new QAction(UIIconPool::iconSetFull(":/help_browser_add_bookmark_32px.png", ":/help_browser_add_bookmark_16px.png",
733 ":/help_browser_add_bookmark_disabled_32px.png", ":/help_browser_add_bookmark_disabled_16px.png"), QString(), this);
734 m_pFindInPageAction =
735 new QAction(UIIconPool::iconSetFull(":/help_browser_search_32px.png", ":/help_browser_search_16px.png",
736 ":/help_browser_search_disabled_32px.png", ":/help_browser_search_disabled_16px.png"), QString(), this);
737 m_pReloadPageAction =
738 new QAction(UIIconPool::iconSetFull(":/help_browser_reload_32px.png", ":/help_browser_reload_16px.png",
739 ":/help_browser_reload_disabled_32px.png", ":/help_browser_reload_disabled_16px.png"), QString(), this);
740
741 AssertReturnVoid(m_pHomeAction && m_pForwardAction &&
742 m_pBackwardAction && m_pAddBookmarkAction &&
743 m_pFindInPageAction);
744 m_pFindInPageAction->setCheckable(true);
745
746 connect(m_pHomeAction, &QAction::triggered, this, &UIHelpBrowserTab::sltHomeAction);
747 connect(m_pAddBookmarkAction, &QAction::triggered, this, &UIHelpBrowserTab::sltAddBookmarkAction);
748 connect(m_pForwardAction, &QAction::triggered, this, &UIHelpBrowserTab::sltForwardAction);
749 connect(m_pBackwardAction, &QAction::triggered, this, &UIHelpBrowserTab::sltBackwardAction);
750 connect(m_pFindInPageAction, &QAction::toggled, this, &UIHelpBrowserTab::sltFindInPageAction);
751 connect(m_pReloadPageAction, &QAction::triggered, this, &UIHelpBrowserTab::sltReloadPageAction);
752
753 m_pForwardAction->setEnabled(false);
754 m_pBackwardAction->setEnabled(false);
755
756 m_pToolBar = new QIToolBar;
757 AssertReturnVoid(m_pToolBar);
758 m_pToolBar->addAction(m_pBackwardAction);
759 m_pToolBar->addAction(m_pForwardAction);
760 m_pToolBar->addAction(m_pHomeAction);
761 m_pToolBar->addAction(m_pReloadPageAction);
762 m_pToolBar->addAction(m_pAddBookmarkAction);
763 m_pToolBar->addAction(m_pFindInPageAction);
764
765 m_pAddressBar = new QComboBox();
766 m_pAddressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
767 connect(m_pAddressBar, &QComboBox::currentIndexChanged,
768 this, &UIHelpBrowserTab::sltAddressBarIndexChanged);
769
770 QHBoxLayout *pTopLayout = new QHBoxLayout;
771 pTopLayout->addWidget(m_pToolBar);
772 pTopLayout->addWidget(m_pAddressBar);
773 m_pMainLayout->addLayout(pTopLayout);
774}
775
776void UIHelpBrowserTab::setActionTextAndToolTip(QAction *pAction, const QString &strText, const QString &strToolTip)
777{
778 if (!pAction)
779 return;
780 pAction->setText(strText);
781 pAction->setToolTip(strToolTip);
782}
783
784void UIHelpBrowserTab::retranslateUi()
785{
786 setActionTextAndToolTip(m_pHomeAction, UIHelpBrowserWidget::tr("Home"), UIHelpBrowserWidget::tr("Return to Start Page"));
787 setActionTextAndToolTip(m_pBackwardAction, UIHelpBrowserWidget::tr("Backward"), UIHelpBrowserWidget::tr("Go Back to Previous Page"));
788 setActionTextAndToolTip(m_pForwardAction, UIHelpBrowserWidget::tr("Forward"), UIHelpBrowserWidget::tr("Go Forward to Next Page"));
789 setActionTextAndToolTip(m_pAddBookmarkAction, UIHelpBrowserWidget::tr("Add Bookmark"), UIHelpBrowserWidget::tr("Add a New Bookmark"));
790 setActionTextAndToolTip(m_pReloadPageAction, UIHelpBrowserWidget::tr("Reload"), UIHelpBrowserWidget::tr("Reload the Current Page"));
791 setActionTextAndToolTip(m_pFindInPageAction, UIHelpBrowserWidget::tr("Find in Page"), UIHelpBrowserWidget::tr("Find a String in the Current Page"));
792}
793
794void UIHelpBrowserTab::sltHomeAction()
795{
796 if (!m_pContentViewer)
797 return;
798 m_pContentViewer->setSource(m_homeUrl);
799}
800
801void UIHelpBrowserTab::sltForwardAction()
802{
803 if (m_pContentViewer)
804 {
805 m_pContentViewer->forward();
806 /* when we dont reload our overload imag hack does not work and images look ugly: */
807 m_pContentViewer->reload();
808 }
809}
810
811void UIHelpBrowserTab::sltBackwardAction()
812{
813 if (m_pContentViewer)
814 {
815 m_pContentViewer->backward();
816 /* when we dont reload our overload imag hack does not work and images look ugly: */
817 m_pContentViewer->reload();
818 }
819}
820
821void UIHelpBrowserTab::sltFindInPageAction(bool fToggled)
822{
823 if (m_pContentViewer)
824 m_pContentViewer->toggleFindInPageWidget(fToggled);
825}
826
827void UIHelpBrowserTab::sltReloadPageAction()
828{
829 if (m_pContentViewer)
830 m_pContentViewer->reload();
831}
832
833void UIHelpBrowserTab::sltHistoryChanged()
834{
835 if (!m_pContentViewer)
836 return;
837 int iCurrentIndex = 0;
838 /* QTextBrower history has negative and positive indices for bacward and forward items, respectively.
839 * 0 is the current item: */
840 m_pAddressBar->blockSignals(true);
841 m_pAddressBar->clear();
842 for (int i = -1 * m_pContentViewer->backwardHistoryCount(); i <= m_pContentViewer->forwardHistoryCount(); ++i)
843 {
844 int iIndex = m_pAddressBar->count();
845 m_pAddressBar->addItem(m_pContentViewer->historyUrl(i).toString(), i);
846 m_pAddressBar->setItemData(iIndex, m_pContentViewer->historyTitle(i), Qt::ToolTipRole);
847 if (i == 0)
848 iCurrentIndex = m_pAddressBar->count();
849 }
850 /* Make sure address bar show the current item: */
851 m_pAddressBar->setCurrentIndex(iCurrentIndex - 1);
852 m_pAddressBar->blockSignals(false);
853
854 if (m_pBackwardAction)
855 m_pBackwardAction->setEnabled(m_pContentViewer->isBackwardAvailable());
856 if (m_pForwardAction)
857 m_pForwardAction->setEnabled(m_pContentViewer->isForwardAvailable());
858
859 emit sigTitleUpdate(m_pContentViewer->historyTitle(0));
860 emit sigHistoryChanged(m_pContentViewer->isBackwardAvailable(), m_pContentViewer->isForwardAvailable());
861}
862
863void UIHelpBrowserTab::sltAddressBarIndexChanged(int iIndex)
864{
865 if (!m_pAddressBar || iIndex >= m_pAddressBar->count())
866 return;
867 int iHistoryIndex = m_pAddressBar->itemData(iIndex).toInt();
868 /* There seems to be no way to one-step-jump to a history item: */
869 if (iHistoryIndex == 0)
870 return;
871 if (iHistoryIndex > 0)
872 for (int i = 0; i < iHistoryIndex; ++i)
873 m_pContentViewer->forward();
874 else
875 for (int i = 0; i > iHistoryIndex ; --i)
876 m_pContentViewer->backward();
877}
878
879void UIHelpBrowserTab::sltAddBookmarkAction()
880{
881 emit sigAddBookmark(source(), documentTitle());
882}
883
884void UIHelpBrowserTab::sltAnchorClicked(const QUrl &link)
885{
886 Q_UNUSED(link);
887}
888
889void UIHelpBrowserTab::sltFindInPageWidgetVisibilityChanged(bool fVisible)
890{
891 if (m_pFindInPageAction)
892 {
893 m_pFindInPageAction->blockSignals(true);
894 m_pFindInPageAction->setChecked(fVisible);
895 m_pFindInPageAction->blockSignals(false);
896 }
897 emit sigFindInPageWidgetVisibilityChanged(fVisible);
898}
899
900
901/*********************************************************************************************************************************
902* UIHelpBrowserTabManager definition. *
903*********************************************************************************************************************************/
904
905UIHelpBrowserTabManager::UIHelpBrowserTabManager(const QHelpEngine *pHelpEngine, const QUrl &homeUrl,
906 const QStringList &urlList, QWidget *pParent /* = 0 */)
907 : QITabWidget(pParent)
908 , m_pHelpEngine(pHelpEngine)
909 , m_homeUrl(homeUrl)
910 , m_savedUrlList(urlList)
911 , m_fSwitchToNewTab(true)
912 , m_fToolBarVisible(true)
913 , m_iZoomPercentage(100)
914{
915 Q_UNUSED(m_fSwitchToNewTab);
916 prepare();
917}
918
919void UIHelpBrowserTabManager::addNewTab(const QUrl &initialUrl, bool fBackground)
920{
921 /* If there is already a tab with a source which is equal to @initialUrl then make it current: */
922 int iExistIndex = findTab(initialUrl);
923 if (iExistIndex != -1)
924 {
925 setCurrentIndex(iExistIndex);
926 return;
927 }
928
929 UIHelpBrowserTab *pTabWidget = new UIHelpBrowserTab(m_pHelpEngine, m_homeUrl, initialUrl);
930 AssertReturnVoid(pTabWidget);
931 pTabWidget->setToolBarVisible(m_fToolBarVisible);
932 int index = addTab(pTabWidget, pTabWidget->documentTitle());
933 connect(pTabWidget, &UIHelpBrowserTab::sigSourceChanged,
934 this, &UIHelpBrowserTabManager::sigSourceChanged);
935 connect(pTabWidget, &UIHelpBrowserTab::sigTitleUpdate,
936 this, &UIHelpBrowserTabManager::sltTabTitleChange);
937 connect(pTabWidget, &UIHelpBrowserTab::sigOpenLinkInNewTab,
938 this, &UIHelpBrowserTabManager::sltOpenLinkInNewTab);
939 connect(pTabWidget, &UIHelpBrowserTab::sigAddBookmark,
940 this, &UIHelpBrowserTabManager::sigAddBookmark);
941 connect(pTabWidget, &UIHelpBrowserTab::sigLinkHighlighted,
942 this, &UIHelpBrowserTabManager::sigLinkHighlighted);
943 connect(pTabWidget, &UIHelpBrowserTab::sigCopyAvailableChanged,
944 this, &UIHelpBrowserTabManager::sltCopyAvailableChanged);
945 connect(pTabWidget, &UIHelpBrowserTab::sigFindInPageWidgetVisibilityChanged,
946 this, &UIHelpBrowserTabManager::sigFindInPageWidgetVisibilityChanged);
947 connect(pTabWidget, &UIHelpBrowserTab::sigHistoryChanged,
948 this, &UIHelpBrowserTabManager::sigHistoryChanged);
949 connect(pTabWidget, &UIHelpBrowserTab::sigMouseOverImage,
950 this, &UIHelpBrowserTabManager::sigMouseOverImage);
951 connect(pTabWidget, &UIHelpBrowserTab::sigZoomRequest,
952 this, &UIHelpBrowserTabManager::sltHandleZoomRequest);
953
954 pTabWidget->setZoomPercentage(zoomPercentage());
955 pTabWidget->setHelpFileList(m_helpFileList);
956 setFocusProxy(pTabWidget);
957 if (!fBackground)
958 setCurrentIndex(index);
959}
960
961void UIHelpBrowserTabManager::updateTabUrlTitleList()
962{
963 QList<QPair<QString, int> > newList;
964
965 QStringList titles = tabTitleList();
966
967 if (titles == m_tabTitleList)
968 return;
969
970 m_tabTitleList = titles;
971 emit sigTabsListChanged(m_tabTitleList);
972}
973
974void UIHelpBrowserTabManager::closeAllTabsBut(int iTabIndex)
975{
976 QString strTitle = tabText(iTabIndex);
977 QList<QWidget*> widgetList;
978 for (int i = 0; i < count(); ++i)
979 widgetList.append(widget(i));
980 clear();
981 for (int i = 0; i < widgetList.size(); ++i)
982 {
983 if (i != iTabIndex)
984 delete widgetList[i];
985 }
986 addTab(widgetList[iTabIndex], strTitle);
987 updateTabUrlTitleList();
988}
989
990int UIHelpBrowserTabManager::findTab(const QUrl &Url) const
991{
992 for (int i = 0; i < count(); ++i)
993 {
994 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
995 if (!pTab || !pTab->source().isValid())
996 continue;
997 if (pTab->source() == Url)
998 return i;
999 }
1000 return -1;
1001}
1002
1003void UIHelpBrowserTabManager::initializeTabs()
1004{
1005 clearAndDeleteTabs();
1006 /* Start with a single tab showing the home URL: */
1007 if (m_savedUrlList.isEmpty())
1008 addNewTab(QUrl(), false);
1009 /* Start with saved tab(s): */
1010 else
1011 for (int i = 0; i < m_savedUrlList.size(); ++i)
1012 addNewTab(m_savedUrlList[i], false);
1013 updateTabUrlTitleList();
1014}
1015
1016QUrl UIHelpBrowserTabManager::currentSource() const
1017{
1018 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1019 if (!pTab)
1020 return QUrl();
1021 return pTab->source();
1022}
1023
1024void UIHelpBrowserTabManager::setSource(const QUrl &url, bool fNewTab /* = false */)
1025{
1026 if (!fNewTab)
1027 {
1028 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1029 if (!pTab)
1030 return;
1031 pTab->setSource(url);
1032 }
1033 else
1034 addNewTab(url, false);
1035 updateTabUrlTitleList();
1036}
1037
1038QStringList UIHelpBrowserTabManager::tabUrlList() const
1039{
1040 QStringList list;
1041 for (int i = 0; i < count(); ++i)
1042 {
1043 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
1044 if (!pTab || !pTab->source().isValid())
1045 continue;
1046 list << pTab->source().toString();
1047 }
1048 return list;
1049}
1050
1051QStringList UIHelpBrowserTabManager::tabTitleList() const
1052{
1053 QStringList list;
1054 for (int i = 0; i < count(); ++i)
1055 {
1056 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
1057 if (!pTab || !pTab->source().isValid())
1058 continue;
1059 list << pTab->documentTitle();
1060 }
1061 return list;
1062}
1063
1064void UIHelpBrowserTabManager::setToolBarVisible(bool fVisible)
1065{
1066 /* Make sure existing tabs are configured: */
1067 for (int i = 0; i < count(); ++i)
1068 {
1069 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
1070 if (!pTab)
1071 continue;
1072 pTab->setToolBarVisible(fVisible);
1073 }
1074 /* This is for the tabs that will be created later: */
1075 m_fToolBarVisible = fVisible;
1076}
1077
1078void UIHelpBrowserTabManager::printCurrent(QPrinter &printer)
1079{
1080 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1081 if (!pTab)
1082 return;
1083 return pTab->print(printer);
1084}
1085
1086void UIHelpBrowserTabManager::switchToTab(int iIndex)
1087{
1088 if (iIndex == currentIndex())
1089 return;
1090 setCurrentIndex(iIndex);
1091}
1092
1093int UIHelpBrowserTabManager::zoomPercentage() const
1094{
1095 return m_iZoomPercentage;
1096}
1097
1098void UIHelpBrowserTabManager::setHelpFileList(const QList<QUrl> &helpFileList)
1099{
1100 m_helpFileList = helpFileList;
1101}
1102
1103void UIHelpBrowserTabManager::copySelectedText() const
1104{
1105 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1106 if (!pTab)
1107 return;
1108 return pTab->copySelectedText();
1109}
1110
1111bool UIHelpBrowserTabManager::hasCurrentTabSelectedText() const
1112{
1113 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1114 if (!pTab)
1115 return false;
1116 return pTab->hasSelectedText();
1117}
1118
1119bool UIHelpBrowserTabManager::isFindInPageWidgetVisible() const
1120{
1121 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1122 if (!pTab)
1123 return false;
1124 return pTab->isFindInPageWidgetVisible();
1125}
1126
1127void UIHelpBrowserTabManager::toggleFindInPage(bool fTrigger)
1128{
1129 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1130 if (pTab)
1131 pTab->sltFindInPageAction(fTrigger);
1132}
1133
1134void UIHelpBrowserTabManager::findNext()
1135{
1136 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1137 if (pTab)
1138 pTab->findNext();
1139}
1140
1141void UIHelpBrowserTabManager::findPrevious()
1142{
1143 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1144 if (pTab)
1145 pTab->findPrevious();
1146}
1147
1148void UIHelpBrowserTabManager::sltTabTitleChange(const QString &strTitle)
1149{
1150 for (int i = 0; i < count(); ++i)
1151 {
1152 if (sender() == widget(i))
1153 {
1154 setTabText(i, strTitle);
1155 setTabToolTip(i, strTitle);
1156 continue;
1157 }
1158 }
1159 updateTabUrlTitleList();
1160}
1161
1162void UIHelpBrowserTabManager::sltOpenLinkInNewTab(const QUrl &url, bool fBackground)
1163{
1164 if (url.isValid())
1165 addNewTab(url, fBackground);
1166 updateTabUrlTitleList();
1167}
1168
1169void UIHelpBrowserTabManager::sltCopyAvailableChanged(bool fAvailable)
1170{
1171 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1172 /* Emit coresponding signal only if sender is the current tab: */
1173 if (pTab && sender() == pTab)
1174 emit sigCopyAvailableChanged(fAvailable);
1175}
1176
1177void UIHelpBrowserTabManager::sltTabClose(int iTabIndex)
1178{
1179 if (count() <= 1)
1180 return;
1181 QWidget *pWidget = widget(iTabIndex);
1182 if (!pWidget)
1183 return;
1184 removeTab(iTabIndex);
1185 delete pWidget;
1186 updateTabUrlTitleList();
1187}
1188
1189void UIHelpBrowserTabManager::sltContextMenuTabClose()
1190{
1191 QAction *pAction = qobject_cast<QAction*>(sender());
1192 if (!pAction)
1193 return;
1194 int iTabIndex = pAction->data().toInt();
1195 if (iTabIndex < 0 || iTabIndex >= count())
1196 return;
1197 sltTabClose(iTabIndex);
1198}
1199
1200void UIHelpBrowserTabManager::sltCloseOtherTabsContextMenuAction()
1201{
1202 /* Find the index of the sender tab. we will close all tabs but sender tab: */
1203 QAction *pAction = qobject_cast<QAction*>(sender());
1204 if (!pAction)
1205 return;
1206 int iTabIndex = pAction->data().toInt();
1207 if (iTabIndex < 0 || iTabIndex >= count())
1208 return;
1209 closeAllTabsBut(iTabIndex);
1210}
1211
1212void UIHelpBrowserTabManager::sltCloseCurrentTab()
1213{
1214 sltTabClose(currentIndex());
1215}
1216
1217void UIHelpBrowserTabManager::sltCloseOtherTabs()
1218{
1219 closeAllTabsBut(currentIndex());
1220}
1221
1222void UIHelpBrowserTabManager::sltCurrentChanged(int iTabIndex)
1223{
1224 Q_UNUSED(iTabIndex);
1225 emit sigSourceChanged(currentSource());
1226}
1227
1228void UIHelpBrowserTabManager::sltShowTabBarContextMenu(const QPoint &pos)
1229{
1230 if (!tabBar())
1231 return;
1232 QMenu menu;
1233 QAction *pCloseAll = menu.addAction(UIHelpBrowserWidget::tr("Close Other Tabs"));
1234 connect(pCloseAll, &QAction::triggered, this, &UIHelpBrowserTabManager::sltCloseOtherTabsContextMenuAction);
1235 pCloseAll->setData(tabBar()->tabAt(pos));
1236
1237 QAction *pClose = menu.addAction(UIHelpBrowserWidget::tr("Close Tab"));
1238 connect(pClose, &QAction::triggered, this, &UIHelpBrowserTabManager::sltContextMenuTabClose);
1239 pClose->setData(tabBar()->tabAt(pos));
1240
1241 menu.exec(tabBar()->mapToGlobal(pos));
1242}
1243
1244void UIHelpBrowserTabManager::sltHomeAction()
1245{
1246 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1247 if (pTab)
1248 pTab->sltHomeAction();
1249}
1250
1251void UIHelpBrowserTabManager::sltAddBookmarkAction()
1252{
1253 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1254 if (pTab)
1255 pTab->sltAddBookmarkAction();
1256}
1257
1258void UIHelpBrowserTabManager::sltForwardAction()
1259{
1260 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1261 if (pTab)
1262 pTab->sltForwardAction();
1263}
1264
1265void UIHelpBrowserTabManager::sltBackwardAction()
1266{
1267 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1268 if (pTab)
1269 pTab->sltBackwardAction();
1270}
1271
1272void UIHelpBrowserTabManager::sltHandleZoomRequest(UIHelpViewer::ZoomOperation enmOperation)
1273{
1274 int iZoomPercentage = m_iZoomPercentage;
1275 switch (enmOperation)
1276 {
1277 case UIHelpViewer::ZoomOperation_In:
1278 iZoomPercentage += iZoomPercentageStep;
1279 break;
1280 case UIHelpViewer::ZoomOperation_Out:
1281 iZoomPercentage -= iZoomPercentageStep;
1282 break;
1283 case UIHelpViewer::ZoomOperation_Reset:
1284 default:
1285 iZoomPercentage = 100;
1286 break;
1287 }
1288 setZoomPercentage(iZoomPercentage);
1289}
1290
1291void UIHelpBrowserTabManager::setZoomPercentage(int iZoomPercentage)
1292{
1293
1294 if (iZoomPercentage > zoomPercentageMinMax.second ||
1295 iZoomPercentage < zoomPercentageMinMax.first)
1296 return;
1297
1298 m_iZoomPercentage = iZoomPercentage;
1299
1300 for (int i = 0; i < count(); ++i)
1301 {
1302 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
1303 if (pTab)
1304 pTab->setZoomPercentage(m_iZoomPercentage);
1305 }
1306 emit sigZoomPercentageChanged(m_iZoomPercentage);
1307}
1308
1309void UIHelpBrowserTabManager::sltReloadPageAction()
1310{
1311 UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
1312 if (pTab)
1313 pTab->sltReloadPageAction();
1314}
1315
1316void UIHelpBrowserTabManager::prepare()
1317{
1318 setTabsClosable(true);
1319 setTabBarAutoHide(true);
1320 connect(this, &UIHelpBrowserTabManager::tabCloseRequested, this, &UIHelpBrowserTabManager::sltTabClose);
1321 connect(this, &UIHelpBrowserTabManager::currentChanged, this, &UIHelpBrowserTabManager::sltCurrentChanged);
1322 if (tabBar())
1323 {
1324 tabBar()->setContextMenuPolicy(Qt::CustomContextMenu);
1325 connect(tabBar(), &QTabBar::customContextMenuRequested, this, &UIHelpBrowserTabManager::sltShowTabBarContextMenu);
1326 }
1327}
1328
1329void UIHelpBrowserTabManager::clearAndDeleteTabs()
1330{
1331 QList<QWidget*> tabList;
1332 for (int i = 0; i < count(); ++i)
1333 tabList << widget(i);
1334 /* QTabWidget::clear() does not delete tab widgets: */
1335 clear();
1336 foreach (QWidget *pWidget, tabList)
1337 delete pWidget;
1338}
1339
1340
1341/*********************************************************************************************************************************
1342* UIHelpBrowserWidget implementation. *
1343*********************************************************************************************************************************/
1344
1345UIHelpBrowserWidget::UIHelpBrowserWidget(EmbedTo enmEmbedding, const QString &strHelpFilePath, QWidget *pParent /* = 0 */)
1346 : QIWithRetranslateUI<QWidget>(pParent)
1347 , m_enmEmbedding(enmEmbedding)
1348 , m_fIsPolished(false)
1349 , m_pMainLayout(0)
1350 , m_pTopLayout(0)
1351 , m_pTabWidget(0)
1352 , m_pToolBar(0)
1353 , m_strHelpFilePath(strHelpFilePath)
1354 , m_pHelpEngine(0)
1355 , m_pSplitter(0)
1356 , m_pFileMenu(0)
1357 , m_pEditMenu(0)
1358 , m_pViewMenu(0)
1359 , m_pTabsMenu(0)
1360 , m_pNavigationMenu(0)
1361 , m_pContentWidget(0)
1362 , m_pIndexWidget(0)
1363 , m_pContentModel(0)
1364 , m_pSearchEngine(0)
1365 , m_pSearchQueryWidget(0)
1366 , m_pSearchResultWidget(0)
1367 , m_pTabManager(0)
1368 , m_pBookmarksWidget(0)
1369 , m_pSearchContainerWidget(0)
1370 , m_pPrintAction(0)
1371 , m_pShowHideSideBarAction(0)
1372 , m_pShowHideToolBarAction(0)
1373 , m_pShowHideStatusBarAction(0)
1374 , m_pCopySelectedTextAction(0)
1375 , m_pFindInPageAction(0)
1376 , m_pFindNextInPageAction(0)
1377 , m_pFindPreviousInPageAction(0)
1378 , m_pBackwardAction(0)
1379 , m_pForwardAction(0)
1380 , m_pHomeAction(0)
1381 , m_pReloadPageAction(0)
1382 , m_pAddBookmarkAction(0)
1383 , m_pZoomMenuAction(0)
1384 , m_fModelContentCreated(false)
1385 , m_fIndexingFinished(false)
1386{
1387 qRegisterMetaType<HelpBrowserTabs>("HelpBrowserTabs");
1388 prepare();
1389 loadOptions();
1390}
1391
1392UIHelpBrowserWidget::~UIHelpBrowserWidget()
1393{
1394 cleanup();
1395}
1396
1397QList<QMenu*> UIHelpBrowserWidget::menus() const
1398{
1399 QList<QMenu*> menuList;
1400 menuList
1401 << m_pFileMenu
1402 << m_pEditMenu
1403 << m_pNavigationMenu
1404 << m_pViewMenu
1405 << m_pTabsMenu;
1406 return menuList;
1407}
1408
1409void UIHelpBrowserWidget::showHelpForKeyword(const QString &strKeyword)
1410{
1411 if (m_fIndexingFinished)
1412 findAndShowUrlForKeyword(strKeyword);
1413 else
1414 m_keywordList.append(strKeyword);
1415}
1416
1417int UIHelpBrowserWidget::zoomPercentage() const
1418{
1419 if (m_pTabManager)
1420 return m_pTabManager->zoomPercentage();
1421 return 0;
1422}
1423
1424bool UIHelpBrowserWidget::shouldBeMaximized() const
1425{
1426 return gEDataManager->logWindowShouldBeMaximized();
1427}
1428
1429void UIHelpBrowserWidget::prepare()
1430{
1431 m_pMainLayout = new QVBoxLayout(this);
1432 m_pMainLayout->setContentsMargins(0.2 * qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
1433 qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin),
1434 0.2 * qApp->style()->pixelMetric(QStyle::PM_LayoutRightMargin),
1435 0.2 * qApp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin));
1436
1437 AssertReturnVoid(m_pMainLayout);
1438
1439 prepareActions();
1440 prepareMenu();
1441 prepareWidgets();
1442 prepareConnections();
1443 prepareSearchWidgets();
1444 loadBookmarks();
1445 retranslateUi();
1446}
1447
1448void UIHelpBrowserWidget::prepareActions()
1449{
1450 m_pShowHideSideBarAction = new QAction(this);
1451 m_pShowHideSideBarAction->setCheckable(true);
1452 m_pShowHideSideBarAction->setChecked(true);
1453 connect(m_pShowHideSideBarAction, &QAction::toggled,
1454 this, &UIHelpBrowserWidget::sltWidgetVisibilityToggle);
1455
1456 m_pShowHideToolBarAction = new QAction(this);
1457 m_pShowHideToolBarAction->setCheckable(true);
1458 m_pShowHideToolBarAction->setChecked(true);
1459 connect(m_pShowHideToolBarAction, &QAction::toggled,
1460 this, &UIHelpBrowserWidget::sltWidgetVisibilityToggle);
1461
1462 m_pShowHideStatusBarAction = new QAction(this);
1463 m_pShowHideStatusBarAction->setCheckable(true);
1464 m_pShowHideStatusBarAction->setChecked(true);
1465 connect(m_pShowHideStatusBarAction, &QAction::toggled,
1466 this, &UIHelpBrowserWidget::sltWidgetVisibilityToggle);
1467
1468 m_pCopySelectedTextAction = new QAction(this);
1469 connect(m_pCopySelectedTextAction, &QAction::triggered,
1470 this, &UIHelpBrowserWidget::sltCopySelectedText);
1471 m_pCopySelectedTextAction->setShortcut(QString("Ctrl+C"));
1472
1473 m_pFindInPageAction = new QAction(this);
1474 m_pFindInPageAction->setCheckable(true);
1475 m_pFindInPageAction->setChecked(false);
1476 connect(m_pFindInPageAction, &QAction::triggered,
1477 this, &UIHelpBrowserWidget::sltFindInPage);
1478 m_pFindInPageAction->setShortcut(QKeySequence::Find);
1479
1480 m_pFindNextInPageAction = new QAction(this);
1481 m_pFindNextInPageAction->setEnabled(false);
1482 connect(m_pFindNextInPageAction, &QAction::triggered,
1483 this, &UIHelpBrowserWidget::sltFindNextInPage);
1484 m_pFindNextInPageAction->setShortcut(QKeySequence::FindNext);
1485
1486 m_pFindPreviousInPageAction = new QAction(this);
1487 m_pFindPreviousInPageAction->setEnabled(false);
1488 connect(m_pFindPreviousInPageAction, &QAction::triggered,
1489 this, &UIHelpBrowserWidget::sltFindPreviousInPage);
1490 m_pFindPreviousInPageAction->setShortcut(QKeySequence::FindPrevious);
1491
1492 m_pPrintAction = new QAction(this);
1493 connect(m_pPrintAction, &QAction::triggered,
1494 this, &UIHelpBrowserWidget::sltShowPrintDialog);
1495 m_pPrintAction->setShortcut(QString("Ctrl+P"));
1496
1497 m_pQuitAction = new QAction(this);
1498 connect(m_pQuitAction, &QAction::triggered,
1499 this, &UIHelpBrowserWidget::sigCloseDialog);
1500 m_pQuitAction->setShortcut(QString("Ctrl+Q"));
1501
1502 m_pBackwardAction = new QAction(this);
1503 m_pBackwardAction->setShortcut(QKeySequence::Back);
1504 connect(m_pBackwardAction, &QAction::triggered,
1505 this, &UIHelpBrowserWidget::sigGoBackward);
1506 m_pBackwardAction->setEnabled(false);
1507
1508 m_pForwardAction = new QAction(this);
1509 m_pForwardAction->setShortcut(QKeySequence::Forward);
1510 connect(m_pForwardAction, &QAction::triggered,
1511 this, &UIHelpBrowserWidget::sigGoForward);
1512 m_pForwardAction->setEnabled(false);
1513
1514 m_pHomeAction = new QAction(this);
1515 connect(m_pHomeAction, &QAction::triggered,
1516 this, &UIHelpBrowserWidget::sigGoHome);
1517
1518 m_pReloadPageAction = new QAction(this);
1519 m_pReloadPageAction->setShortcut(QKeySequence::Refresh);
1520 connect(m_pReloadPageAction, &QAction::triggered,
1521 this, &UIHelpBrowserWidget::sigReloadPage);
1522
1523 m_pAddBookmarkAction = new QAction(this);
1524 m_pAddBookmarkAction->setShortcut(QKeySequence("Ctrl+D"));
1525 connect(m_pAddBookmarkAction, &QAction::triggered,
1526 this, &UIHelpBrowserWidget::sigAddBookmark);
1527
1528 m_pZoomMenuAction = new UIZoomMenuAction(this);
1529 connect(m_pZoomMenuAction, &UIZoomMenuAction::sigZoomChanged,
1530 this, &UIHelpBrowserWidget::sltZoomActions);
1531}
1532
1533void UIHelpBrowserWidget::prepareConnections()
1534{
1535 if (m_pTabManager)
1536 {
1537 connect(m_pHomeAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltHomeAction);
1538 connect(m_pAddBookmarkAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltAddBookmarkAction);
1539 connect(m_pForwardAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltForwardAction);
1540 connect(m_pBackwardAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltBackwardAction);
1541 connect(m_pReloadPageAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltReloadPageAction);
1542 }
1543}
1544
1545void UIHelpBrowserWidget::prepareWidgets()
1546{
1547 m_pSplitter = new QSplitter;
1548 AssertReturnVoid(m_pSplitter);
1549
1550 m_pMainLayout->addWidget(m_pSplitter);
1551 m_pHelpEngine = new QHelpEngine(m_strHelpFilePath, this);
1552 m_pBookmarksWidget = new UIBookmarksListContainer(this);
1553 m_pTabWidget = new QITabWidget;
1554 m_pTabManager = new UIHelpBrowserTabManager(m_pHelpEngine, findIndexHtml(), loadSavedUrlList());
1555 m_pTabManager->setHelpFileList(m_pHelpEngine->files(m_pHelpEngine->namespaceName(m_strHelpFilePath), QStringList()));
1556
1557 AssertReturnVoid(m_pTabWidget &&
1558 m_pHelpEngine &&
1559 m_pBookmarksWidget &&
1560 m_pTabManager);
1561
1562 m_pContentWidget = m_pHelpEngine->contentWidget();
1563 m_pIndexWidget = m_pHelpEngine->indexWidget();
1564 m_pContentModel = m_pHelpEngine->contentModel();
1565
1566 AssertReturnVoid(m_pContentWidget && m_pIndexWidget && m_pContentModel);
1567 m_pSplitter->addWidget(m_pTabWidget);
1568 m_pContentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
1569
1570 m_pTabWidget->insertTab(HelpBrowserTabs_TOC, m_pContentWidget, QString());
1571 m_pTabWidget->insertTab(HelpBrowserTabs_Bookmarks, m_pBookmarksWidget, QString());
1572 /* Dont insert the index widget since we only have automatically generated indexes: */
1573#if 0
1574 m_pTabWidget->insertTab(HelpBrowserTabs_Index, m_pIndexWidget, QString());
1575#endif
1576
1577 m_pSplitter->addWidget(m_pTabManager);
1578 m_pSplitter->setStretchFactor(0,0);
1579 m_pSplitter->setStretchFactor(1,1);
1580
1581 m_pSplitter->setChildrenCollapsible(false);
1582
1583 connect(m_pTabManager, &UIHelpBrowserTabManager::sigSourceChanged,
1584 this, &UIHelpBrowserWidget::sltViewerSourceChange);
1585 connect(m_pTabManager, &UIHelpBrowserTabManager::sigAddBookmark,
1586 this, &UIHelpBrowserWidget::sltAddNewBookmark);
1587 connect(m_pTabManager, &UIHelpBrowserTabManager::sigTabsListChanged,
1588 this, &UIHelpBrowserWidget::sltTabListChanged);
1589 connect(m_pTabManager, &UIHelpBrowserTabManager::currentChanged,
1590 this, &UIHelpBrowserWidget::sltCurrentTabChanged);
1591 connect(m_pTabManager, &UIHelpBrowserTabManager::sigLinkHighlighted,
1592 this, &UIHelpBrowserWidget::sltLinkHighlighted);
1593 connect(m_pTabManager, &UIHelpBrowserTabManager::sigZoomPercentageChanged,
1594 this, &UIHelpBrowserWidget::sltZoomPercentageChanged);
1595 connect(m_pTabManager, &UIHelpBrowserTabManager::sigCopyAvailableChanged,
1596 this, &UIHelpBrowserWidget::sltCopyAvailableChanged);
1597 connect(m_pTabManager, &UIHelpBrowserTabManager::sigFindInPageWidgetVisibilityChanged,
1598 this, &UIHelpBrowserWidget::sltFindInPageWidgetVisibilityChanged);
1599 connect(m_pTabManager, &UIHelpBrowserTabManager::sigHistoryChanged,
1600 this, &UIHelpBrowserWidget::sltHistoryChanged);
1601 connect(m_pTabManager, &UIHelpBrowserTabManager::sigMouseOverImage,
1602 this, &UIHelpBrowserWidget::sltMouseOverImage);
1603
1604 connect(m_pHelpEngine, &QHelpEngine::setupFinished,
1605 this, &UIHelpBrowserWidget::sltHelpEngineSetupFinished);
1606 connect(m_pContentWidget, &QHelpContentWidget::clicked,
1607 this, &UIHelpBrowserWidget::sltContentWidgetItemClicked);
1608 connect(m_pContentModel, &QHelpContentModel::contentsCreated,
1609 this, &UIHelpBrowserWidget::sltContentsCreated);
1610 connect(m_pContentWidget, &QHelpContentWidget::customContextMenuRequested,
1611 this, &UIHelpBrowserWidget::sltShowLinksContextMenu);
1612 connect(m_pBookmarksWidget, &UIBookmarksListContainer::sigBookmarkDoubleClick,
1613 this, &UIHelpBrowserWidget::sltOpenLinkWithUrl);
1614 connect(m_pBookmarksWidget, &UIBookmarksListContainer::sigListWidgetContextMenuRequest,
1615 this, &UIHelpBrowserWidget::sltShowLinksContextMenu);
1616
1617 if (QFile(m_strHelpFilePath).exists() && m_pHelpEngine)
1618 m_pHelpEngine->setupData();
1619}
1620
1621void UIHelpBrowserWidget::prepareSearchWidgets()
1622{
1623 AssertReturnVoid(m_pTabWidget && m_pHelpEngine);
1624
1625 m_pSearchContainerWidget = new QWidget;
1626 m_pTabWidget->insertTab(HelpBrowserTabs_Search, m_pSearchContainerWidget, QString());
1627 m_pTabWidget->setTabPosition(QTabWidget::South);
1628
1629 m_pSearchEngine = m_pHelpEngine->searchEngine();
1630 AssertReturnVoid(m_pSearchEngine);
1631
1632 m_pSearchQueryWidget = m_pSearchEngine->queryWidget();
1633 m_pSearchResultWidget = m_pSearchEngine->resultWidget();
1634 AssertReturnVoid(m_pSearchQueryWidget && m_pSearchResultWidget);
1635 m_pSearchResultWidget->setContextMenuPolicy(Qt::CustomContextMenu);
1636 m_pSearchQueryWidget->setCompactMode(false);
1637
1638 QVBoxLayout *pSearchLayout = new QVBoxLayout(m_pSearchContainerWidget);
1639 pSearchLayout->addWidget(m_pSearchQueryWidget);
1640 pSearchLayout->addWidget(m_pSearchResultWidget);
1641 m_pSearchQueryWidget->expandExtendedSearch();
1642
1643 connect(m_pSearchQueryWidget, &QHelpSearchQueryWidget::search,
1644 this, &UIHelpBrowserWidget::sltSearchStart);
1645 connect(m_pSearchResultWidget, &QHelpSearchResultWidget::requestShowLink,
1646 this, &UIHelpBrowserWidget::sltOpenLinkWithUrl);
1647 connect(m_pSearchResultWidget, &QHelpContentWidget::customContextMenuRequested,
1648 this, &UIHelpBrowserWidget::sltShowLinksContextMenu);
1649 connect(m_pSearchEngine, &QHelpSearchEngine::indexingStarted,
1650 this, &UIHelpBrowserWidget::sltIndexingStarted);
1651 connect(m_pSearchEngine, &QHelpSearchEngine::indexingFinished,
1652 this, &UIHelpBrowserWidget::sltIndexingFinished);
1653 connect(m_pSearchEngine, &QHelpSearchEngine::searchingStarted,
1654 this, &UIHelpBrowserWidget::sltSearchingStarted);
1655
1656 m_pSearchEngine->reindexDocumentation();
1657}
1658
1659void UIHelpBrowserWidget::prepareToolBar()
1660{
1661 m_pTopLayout = new QHBoxLayout;
1662 m_pToolBar = new QIToolBar(parentWidget());
1663 if (m_pToolBar)
1664 {
1665 m_pToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
1666 const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize));
1667 m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
1668
1669#ifdef VBOX_WS_MAC
1670 /* Check whether we are embedded into a stack: */
1671 if (m_enmEmbedding == EmbedTo_Stack)
1672 {
1673 /* Add into layout: */
1674 m_pTopLayout->addWidget(m_pToolBar);
1675 m_pMainLayout->addLayout(m_pTopLayout);
1676 }
1677#else
1678 /* Add into layout: */
1679 m_pTopLayout->addWidget(m_pToolBar);
1680 m_pMainLayout->addLayout(m_pTopLayout);
1681#endif
1682 }
1683}
1684
1685void UIHelpBrowserWidget::prepareMenu()
1686{
1687 m_pFileMenu = new QMenu(tr("&File"), this);
1688 m_pEditMenu = new QMenu(tr("&Edit"), this);
1689 m_pNavigationMenu = new QMenu(tr("&Navigation"), this);
1690 m_pViewMenu = new QMenu(tr("&View"), this);
1691 m_pTabsMenu = new QMenu(tr("&Tabs"), this);
1692
1693 AssertReturnVoid(m_pFileMenu && m_pViewMenu &&
1694 m_pTabsMenu && m_pNavigationMenu);
1695
1696 addActionToMenu(m_pFileMenu, m_pPrintAction);
1697 addActionToMenu(m_pFileMenu, m_pQuitAction);
1698
1699 addActionToMenu(m_pEditMenu, m_pCopySelectedTextAction);
1700 addActionToMenu(m_pEditMenu, m_pFindInPageAction);
1701 addActionToMenu(m_pEditMenu, m_pFindNextInPageAction);
1702 addActionToMenu(m_pEditMenu, m_pFindPreviousInPageAction);
1703
1704 addActionToMenu(m_pViewMenu, m_pZoomMenuAction);
1705 addActionToMenu(m_pViewMenu, m_pShowHideSideBarAction);
1706 addActionToMenu(m_pViewMenu, m_pShowHideToolBarAction);
1707 addActionToMenu(m_pViewMenu, m_pShowHideStatusBarAction);
1708
1709 addActionToMenu(m_pNavigationMenu, m_pBackwardAction);
1710 addActionToMenu(m_pNavigationMenu, m_pForwardAction);
1711 addActionToMenu(m_pNavigationMenu, m_pHomeAction);
1712 addActionToMenu(m_pNavigationMenu, m_pReloadPageAction);
1713 addActionToMenu(m_pNavigationMenu, m_pAddBookmarkAction);
1714}
1715
1716void UIHelpBrowserWidget::loadOptions()
1717{
1718 if (m_pTabManager)
1719 m_pTabManager->setZoomPercentage(gEDataManager->helpBrowserZoomPercentage());
1720}
1721
1722QStringList UIHelpBrowserWidget::loadSavedUrlList()
1723{
1724 return gEDataManager->helpBrowserLastUrlList();
1725}
1726
1727void UIHelpBrowserWidget::loadBookmarks()
1728{
1729 if (!m_pBookmarksWidget)
1730 return;
1731
1732 QStringList bookmarks = gEDataManager->helpBrowserBookmarks();
1733 /* bookmarks list is supposed to have url title pair: */
1734 for (int i = 0; i < bookmarks.size(); ++i)
1735 {
1736 const QString &url = bookmarks[i];
1737 if (i+1 >= bookmarks.size())
1738 break;
1739 ++i;
1740 const QString &strTitle = bookmarks[i];
1741 m_pBookmarksWidget->addBookmark(url, strTitle);
1742 }
1743}
1744
1745void UIHelpBrowserWidget::saveBookmarks()
1746{
1747 if (!m_pBookmarksWidget)
1748 return;
1749 gEDataManager->setHelpBrowserBookmarks(m_pBookmarksWidget->bookmarks());
1750}
1751
1752void UIHelpBrowserWidget::saveOptions()
1753{
1754 if (m_pTabManager)
1755 {
1756 gEDataManager->setHelpBrowserLastUrlList(m_pTabManager->tabUrlList());
1757 gEDataManager->setHelpBrowserZoomPercentage(m_pTabManager->zoomPercentage());
1758 }
1759}
1760
1761QUrl UIHelpBrowserWidget::findIndexHtml() const
1762{
1763 QList<QUrl> files = m_pHelpEngine->files(m_pHelpEngine->namespaceName(m_strHelpFilePath), QStringList());
1764 int iIndex = -1;
1765 for (int i = 0; i < files.size(); ++i)
1766 {
1767 if (files[i].toString().contains("index.html", Qt::CaseInsensitive))
1768 {
1769 iIndex = i;
1770 break;
1771 }
1772 }
1773 if (iIndex == -1)
1774 {
1775 /* If index html/htm could not be found try to find a html file at least: */
1776 for (int i = 0; i < files.size(); ++i)
1777 {
1778 if (files[i].toString().contains(".html", Qt::CaseInsensitive) ||
1779 files[i].toString().contains(".htm", Qt::CaseInsensitive))
1780 {
1781 iIndex = i;
1782 break;
1783 }
1784 }
1785 }
1786 if (iIndex != -1 && files.size() > iIndex)
1787 return files[iIndex];
1788 else
1789 return QUrl();
1790}
1791
1792QUrl UIHelpBrowserWidget::contentWidgetUrl(const QModelIndex &itemIndex)
1793{
1794 QHelpContentModel *pContentModel =
1795 qobject_cast<QHelpContentModel*>(m_pContentWidget->model());
1796 if (!pContentModel)
1797 return QUrl();
1798 QHelpContentItem *pItem = pContentModel->contentItemAt(itemIndex);
1799 if (!pItem)
1800 return QUrl();
1801 return pItem->url();
1802}
1803
1804void UIHelpBrowserWidget::cleanup()
1805{
1806 saveOptions();
1807 saveBookmarks();
1808}
1809
1810void UIHelpBrowserWidget::retranslateUi()
1811{
1812 if (m_pTabWidget)
1813 {
1814 m_pTabWidget->setTabText(HelpBrowserTabs_TOC, tr("Contents"));
1815 m_pTabWidget->setTabText(HelpBrowserTabs_Index, tr("Index"));
1816 m_pTabWidget->setTabText(HelpBrowserTabs_Search, tr("Search"));
1817 m_pTabWidget->setTabText(HelpBrowserTabs_Bookmarks, tr("Bookmarks"));
1818 }
1819
1820 if (m_pShowHideSideBarAction)
1821 m_pShowHideSideBarAction->setText(tr("Show &Side Bar"));
1822 if (m_pShowHideToolBarAction)
1823 m_pShowHideToolBarAction->setText(tr("Show &Tool Bar"));
1824 if (m_pShowHideStatusBarAction)
1825 m_pShowHideStatusBarAction->setText(tr("Show St&atus Bar"));
1826
1827 if (m_pPrintAction)
1828 m_pPrintAction->setText(tr("&Print..."));
1829 if (m_pQuitAction)
1830 m_pQuitAction->setText(tr("&Quit"));
1831
1832 if (m_pCopySelectedTextAction)
1833 m_pCopySelectedTextAction->setText(tr("&Copy Selected Text"));
1834 if (m_pFindInPageAction)
1835 m_pFindInPageAction->setText(tr("&Find in Page"));
1836 if (m_pFindNextInPageAction)
1837 m_pFindNextInPageAction->setText(tr("Find Ne&xt"));
1838 if (m_pFindPreviousInPageAction)
1839 m_pFindPreviousInPageAction->setText(tr("Find &Previous"));
1840
1841 if (m_pBackwardAction)
1842 m_pBackwardAction->setText(tr("Go Backward"));
1843 if (m_pForwardAction)
1844 m_pForwardAction->setText(tr("Go Forward"));
1845 if (m_pHomeAction)
1846 m_pHomeAction->setText(tr("Go to Start Page"));
1847 if (m_pReloadPageAction)
1848 m_pReloadPageAction->setText(tr("Reload Page"));
1849 if (m_pAddBookmarkAction)
1850 m_pAddBookmarkAction->setText(tr("Add Bookmark"));
1851}
1852
1853
1854void UIHelpBrowserWidget::showEvent(QShowEvent *pEvent)
1855{
1856 QWidget::showEvent(pEvent);
1857 if (m_fIsPolished)
1858 return;
1859 m_fIsPolished = true;
1860 if (m_pTabManager)
1861 m_pTabManager->setFocus();
1862}
1863
1864void UIHelpBrowserWidget::keyPressEvent(QKeyEvent *pEvent)
1865{
1866 QWidget::keyPressEvent(pEvent);
1867}
1868
1869void UIHelpBrowserWidget::findAndShowUrlForKeyword(const QString &strKeyword)
1870{
1871#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
1872 QList<QHelpLink> links = m_pHelpEngine->documentsForIdentifier(strKeyword);
1873 if (!links.isEmpty())
1874 {
1875 /* We have to a have a single url per keyword in this case: */
1876 m_pTabManager->setSource(links.first().url, true /* new tab */);
1877 }
1878#else
1879 QMap<QString, QUrl> map = m_pHelpEngine->linksForIdentifier(strKeyword);
1880 if (!map.isEmpty())
1881 {
1882 /* We have to a have a single url per keyword in this case: */
1883 QUrl keywordUrl = map.first();
1884 m_pTabManager->setSource(keywordUrl, true /* new tab */);
1885 }
1886#endif
1887}
1888
1889void UIHelpBrowserWidget::sltWidgetVisibilityToggle(bool fToggled)
1890{
1891 if (sender() == m_pShowHideSideBarAction)
1892 {
1893 if (m_pTabWidget)
1894 m_pTabWidget->setVisible(fToggled);
1895 }
1896 else if (sender() == m_pShowHideToolBarAction)
1897 {
1898 if (m_pTabManager)
1899 m_pTabManager->setToolBarVisible(fToggled);
1900 }
1901 else if (sender() == m_pShowHideStatusBarAction)
1902 emit sigStatusBarVisible(fToggled);
1903}
1904
1905void UIHelpBrowserWidget::sltCopySelectedText()
1906{
1907 if (m_pTabManager)
1908 m_pTabManager->copySelectedText();
1909}
1910
1911void UIHelpBrowserWidget::sltFindInPage(bool fChecked)
1912{
1913 if (m_pTabManager)
1914 m_pTabManager->toggleFindInPage(fChecked);
1915}
1916
1917void UIHelpBrowserWidget::sltFindNextInPage()
1918{
1919 if (m_pTabManager)
1920 m_pTabManager->findNext();
1921}
1922
1923void UIHelpBrowserWidget::sltFindPreviousInPage()
1924{
1925 if (m_pTabManager)
1926 m_pTabManager->findPrevious();
1927}
1928
1929void UIHelpBrowserWidget::sltHistoryChanged(bool fBackwardAvailable, bool fForwardAvailable)
1930{
1931 if (m_pBackwardAction)
1932 m_pBackwardAction->setEnabled(fBackwardAvailable);
1933 if (m_pForwardAction)
1934 m_pForwardAction->setEnabled(fForwardAvailable);
1935}
1936
1937void UIHelpBrowserWidget::sltLinkHighlighted(const QUrl &url)
1938{
1939 QString strMessage = url.url();
1940 if (url.scheme() != "qthelp")
1941 strMessage = QString("%1: %2").arg(tr("Click to open this link in an external browser")).arg(strMessage);
1942
1943 emit sigStatusBarMessage(strMessage, 0);
1944}
1945
1946void UIHelpBrowserWidget::sltMouseOverImage(const QString &strImageName)
1947{
1948 emit sigStatusBarMessage(QString("%1: %2").arg(tr("Click to enlarge the image")).arg(strImageName), 3000);
1949}
1950
1951void UIHelpBrowserWidget::sltCopyAvailableChanged(bool fAvailable)
1952{
1953 if (m_pCopySelectedTextAction)
1954 m_pCopySelectedTextAction->setEnabled(fAvailable);
1955}
1956
1957void UIHelpBrowserWidget::sltFindInPageWidgetVisibilityChanged(bool fVisible)
1958{
1959 if (m_pFindInPageAction)
1960 {
1961 m_pFindInPageAction->blockSignals(true);
1962 m_pFindInPageAction->setChecked(fVisible);
1963 m_pFindInPageAction->blockSignals(false);
1964 }
1965 if (m_pFindNextInPageAction)
1966 m_pFindNextInPageAction->setEnabled(fVisible);
1967
1968 if (m_pFindPreviousInPageAction)
1969 m_pFindPreviousInPageAction->setEnabled(fVisible);
1970}
1971
1972void UIHelpBrowserWidget::sltShowPrintDialog()
1973{
1974#ifdef VBOX_WS_NIX
1975 if (!m_pTabManager)
1976 return;
1977 QPrinter printer;
1978 QPrintDialog printDialog(&printer, this);
1979 if (printDialog.exec() == QDialog::Accepted)
1980 m_pTabManager->printCurrent(printer);
1981#endif
1982}
1983
1984void UIHelpBrowserWidget::sltHelpEngineSetupFinished()
1985{
1986 AssertReturnVoid(m_pTabManager);
1987 m_fIndexingFinished = true;
1988 m_pTabManager->initializeTabs();
1989}
1990
1991void UIHelpBrowserWidget::sltContentWidgetItemClicked(const QModelIndex & index)
1992{
1993 AssertReturnVoid(m_pTabManager && m_pHelpEngine && m_pContentWidget);
1994 QUrl url = contentWidgetUrl(index);
1995 if (!url.isValid())
1996 return;
1997 m_pTabManager->setSource(url);
1998
1999 m_pContentWidget->scrollTo(index, QAbstractItemView::EnsureVisible);
2000 m_pContentWidget->expand(index);
2001}
2002
2003void UIHelpBrowserWidget::sltViewerSourceChange(const QUrl &source)
2004{
2005 if (m_fModelContentCreated && m_pContentWidget && source.isValid() && m_pContentModel)
2006 {
2007 QModelIndex index = m_pContentWidget->indexOf(source);
2008 QItemSelectionModel *pSelectionModel = m_pContentWidget->selectionModel();
2009 if (pSelectionModel && index.isValid())
2010 {
2011 m_pContentWidget->blockSignals(true);
2012 pSelectionModel->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
2013 m_pContentWidget->scrollTo(index, QAbstractItemView::EnsureVisible);
2014 m_pContentWidget->expand(index);
2015 m_pContentWidget->blockSignals(false);
2016 }
2017 }
2018}
2019
2020void UIHelpBrowserWidget::sltContentsCreated()
2021{
2022 m_fModelContentCreated = true;
2023 if (m_pTabManager)
2024 sltViewerSourceChange(m_pTabManager->currentSource());
2025}
2026
2027void UIHelpBrowserWidget::sltIndexingStarted()
2028{
2029 if (m_pSearchContainerWidget)
2030 m_pSearchContainerWidget->setEnabled(false);
2031}
2032
2033void UIHelpBrowserWidget::sltIndexingFinished()
2034{
2035 AssertReturnVoid(m_pTabManager &&
2036 m_pHelpEngine &&
2037 m_pSearchContainerWidget);
2038
2039 m_pSearchContainerWidget->setEnabled(true);
2040 m_fIndexingFinished = true;
2041 /* Process the keyword queue. */
2042 foreach (const QString strKeyword, m_keywordList)
2043 findAndShowUrlForKeyword(strKeyword);
2044 m_keywordList.clear();
2045
2046}
2047
2048void UIHelpBrowserWidget::sltSearchingStarted()
2049{
2050}
2051
2052void UIHelpBrowserWidget::sltSearchStart()
2053{
2054 AssertReturnVoid(m_pSearchEngine && m_pSearchQueryWidget);
2055 m_pSearchEngine->search(m_pSearchQueryWidget->searchInput());
2056}
2057
2058void UIHelpBrowserWidget::sltShowLinksContextMenu(const QPoint &pos)
2059{
2060 QWidget *pSender = qobject_cast<QWidget*>(sender());
2061 if (!pSender)
2062 return;
2063
2064 QUrl url;
2065 if (pSender == m_pContentWidget)
2066 url = contentWidgetUrl(m_pContentWidget->currentIndex());
2067 else if (pSender == m_pSearchResultWidget)
2068 {
2069 QTextBrowser* browser = m_pSearchResultWidget->findChild<QTextBrowser*>();
2070 if (!browser)
2071 return;
2072 QPoint browserPos = browser->mapFromGlobal(m_pSearchResultWidget->mapToGlobal(pos));
2073 url = browser->anchorAt(browserPos);
2074 }
2075 else if (pSender == m_pBookmarksWidget)
2076 {
2077 /* Assuming that only the UIBookmarksListWidget under the m_pBookmarksWidget sends the context menu request: */
2078 UIBookmarksListWidget *pListWidget = m_pBookmarksWidget->findChild<UIBookmarksListWidget*>();
2079 if (!pListWidget)
2080 return;
2081 url = m_pBookmarksWidget->currentBookmarkUrl();
2082 }
2083 else
2084 return;
2085
2086 bool fURLValid = url.isValid();
2087
2088 QMenu menu;
2089 QAction *pOpen = menu.addAction(tr("Open Link"));
2090 QAction *pOpenInNewTab = menu.addAction(tr("Open Link in New Tab"));
2091 QAction *pCopyLink = menu.addAction(tr("Copy Link"));
2092
2093 pOpen->setData(url);
2094 pOpenInNewTab->setData(url);
2095 pCopyLink->setData(url);
2096
2097 pOpen->setEnabled(fURLValid);
2098 pOpenInNewTab->setEnabled(fURLValid);
2099 pCopyLink->setEnabled(fURLValid);
2100
2101 connect(pOpenInNewTab, &QAction::triggered, this, &UIHelpBrowserWidget::sltOpenLinkInNewTab);
2102 connect(pOpen, &QAction::triggered, this, &UIHelpBrowserWidget::sltOpenLink);
2103 connect(pCopyLink, &QAction::triggered, this, &UIHelpBrowserWidget::sltCopyLink);
2104
2105 if (pSender == m_pBookmarksWidget)
2106 {
2107 menu.addSeparator();
2108 QAction *pDeleteBookmark = menu.addAction(tr("Delete Bookmark"));
2109 QAction *pDeleteAllBookmarks = menu.addAction(tr("Delete All Bookmarks"));
2110 pDeleteBookmark->setEnabled(fURLValid);
2111
2112 connect(pDeleteBookmark, &QAction::triggered, m_pBookmarksWidget, &UIBookmarksListContainer::sltDeleteSelectedBookmark);
2113 connect(pDeleteAllBookmarks, &QAction::triggered, m_pBookmarksWidget, &UIBookmarksListContainer::sltDeleteAllBookmarks);
2114 }
2115
2116 menu.exec(pSender->mapToGlobal(pos));
2117}
2118
2119void UIHelpBrowserWidget::sltOpenLinkInNewTab()
2120{
2121 openLinkSlotHandler(sender(), true);
2122}
2123
2124void UIHelpBrowserWidget::sltOpenLink()
2125{
2126 openLinkSlotHandler(sender(), false);
2127}
2128
2129void UIHelpBrowserWidget::sltCopyLink()
2130{
2131 QAction *pAction = qobject_cast<QAction*>(sender());
2132 if (!pAction)
2133 return;
2134 QUrl url = pAction->data().toUrl();
2135 if (url.isValid())
2136 {
2137 QClipboard *pClipboard = QApplication::clipboard();
2138 if (pClipboard)
2139 pClipboard->setText(url.toString());
2140 }
2141}
2142
2143void UIHelpBrowserWidget::sltAddNewBookmark(const QUrl &url, const QString &strTitle)
2144{
2145 if (m_pBookmarksWidget)
2146 m_pBookmarksWidget->addBookmark(url, strTitle);
2147 Q_UNUSED(url);
2148 emit sigStatusBarMessage(QString("%1 %2").arg(tr("Bookmark added:")).arg(strTitle), 3000);
2149}
2150
2151void UIHelpBrowserWidget::openLinkSlotHandler(QObject *pSenderObject, bool fOpenInNewTab)
2152{
2153 QAction *pAction = qobject_cast<QAction*>(pSenderObject);
2154 if (!pAction)
2155 return;
2156 QUrl url = pAction->data().toUrl();
2157 if (m_pTabManager && url.isValid())
2158 m_pTabManager->setSource(url, fOpenInNewTab);
2159}
2160
2161void UIHelpBrowserWidget::updateTabsMenu(const QStringList &titles)
2162{
2163 if (!m_pTabsMenu)
2164 return;
2165 m_pTabsMenu->clear();
2166
2167 QAction *pCloseTabAction = m_pTabsMenu->addAction(tr("Close T&ab"));
2168 QAction *pCloseOtherTabsAction = m_pTabsMenu->addAction(tr("Close &Other Tabs"));
2169
2170 pCloseTabAction->setShortcut(QString("Ctrl+W"));
2171 pCloseOtherTabsAction->setShortcut(QString("Ctrl+Shift+W"));
2172
2173 pCloseTabAction->setEnabled(titles.size() > 1);
2174 pCloseOtherTabsAction->setEnabled(titles.size() > 1);
2175
2176 connect(pCloseTabAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltCloseCurrentTab);
2177 connect(pCloseOtherTabsAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltCloseOtherTabs);
2178
2179 m_pTabsMenu->addSeparator();
2180
2181 for (int i = 0; i < titles.size(); ++i)
2182 {
2183 QAction *pAction = m_pTabsMenu->addAction(titles[i]);
2184 pAction->setData(i);
2185 connect(pAction, &QAction::triggered, this, &UIHelpBrowserWidget::sltTabChoose);
2186 }
2187 if (m_pTabManager)
2188 sltCurrentTabChanged(m_pTabManager->currentIndex());
2189}
2190
2191void UIHelpBrowserWidget::sltOpenLinkWithUrl(const QUrl &url)
2192{
2193 if (m_pTabManager && url.isValid())
2194 m_pTabManager->setSource(url, false);
2195}
2196
2197void UIHelpBrowserWidget::sltZoomActions(int iZoomOperation)
2198{
2199 if (iZoomOperation >= (int) UIHelpViewer::ZoomOperation_Max)
2200 return;
2201 UIHelpViewer::ZoomOperation enmOperation = (UIHelpViewer::ZoomOperation)(iZoomOperation);
2202 m_pTabManager->sltHandleZoomRequest(enmOperation);
2203}
2204
2205void UIHelpBrowserWidget::sltTabListChanged(const QStringList &titleList)
2206{
2207 updateTabsMenu(titleList);
2208}
2209
2210void UIHelpBrowserWidget::sltTabChoose()
2211{
2212 QAction *pAction = qobject_cast<QAction*>(sender());
2213 if (!pAction)
2214 return;
2215 int iIndex = pAction->data().toInt();
2216 if (m_pTabManager)
2217 m_pTabManager->switchToTab(iIndex);
2218}
2219
2220void UIHelpBrowserWidget::sltCurrentTabChanged(int iIndex)
2221{
2222 Q_UNUSED(iIndex);
2223 if (!m_pTabsMenu)
2224 return;
2225
2226 /** Mark the action with iIndex+3 by assigning an icon to it. it is iIndex+3 and not iIndex since we have
2227 * two additional (close tab, close other tabs and a separator) action on top of the tab selection actions: */
2228 QList<QAction*> list = m_pTabsMenu->actions();
2229 for (int i = 0; i < list.size(); ++i)
2230 list[i]->setIcon(QIcon());
2231 if (iIndex+3 >= list.size())
2232 return;
2233 list[iIndex+3]->setIcon(UIIconPool::iconSet(":/help_browser_star_16px.png"));
2234
2235 if (m_pTabManager)
2236 {
2237 if (m_pCopySelectedTextAction)
2238 m_pCopySelectedTextAction->setEnabled(m_pTabManager->hasCurrentTabSelectedText());
2239 if (m_pFindInPageAction)
2240 m_pFindInPageAction->setChecked(m_pTabManager->isFindInPageWidgetVisible());
2241 if (m_pFindNextInPageAction)
2242 m_pFindNextInPageAction->setEnabled(m_pTabManager->isFindInPageWidgetVisible());
2243 if (m_pFindPreviousInPageAction)
2244 m_pFindPreviousInPageAction->setEnabled(m_pTabManager->isFindInPageWidgetVisible());
2245 }
2246}
2247
2248void UIHelpBrowserWidget::sltZoomPercentageChanged(int iPercentage)
2249{
2250 if (m_pZoomMenuAction)
2251 m_pZoomMenuAction->setZoomPercentage(iPercentage);
2252 emit sigZoomPercentageChanged(iPercentage);
2253}
2254
2255void UIHelpBrowserWidget::addActionToMenu(QMenu *pMenu, QAction *pAction)
2256{
2257 if (!pMenu || !pAction)
2258 return;
2259 pMenu->addAction(pAction);
2260}
2261
2262#include "UIHelpBrowserWidget.moc"
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette