VirtualBox

Changeset 87157 in vbox for trunk/src/VBox/Frontends


Ignore:
Timestamp:
Jan 4, 2021 10:59:51 AM (4 years ago)
Author:
vboxsync
Message:

FE/Qt: bugref:9831. Factoring out UIHelpBrowserViewer class.

Location:
trunk/src/VBox/Frontends/VirtualBox
Files:
3 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Frontends/VirtualBox/Makefile.kmk

    r86997 r87157  
    813813        src/globals/VBoxUtils.h \
    814814        src/helpbrowser/UIHelpBrowserDialog.h \
     815        src/helpbrowser/UIHelpBrowserViewer.h \
    815816        src/helpbrowser/UIHelpBrowserWidget.h \
    816817        src/logviewer/UIVMLogPage.h \
     
    993994        src/globals/UIVirtualBoxEventHandler.cpp \
    994995        src/globals/UIVirtualBoxClientEventHandler.cpp \
     996        src/helpbrowser/UIHelpBrowserViewer.cpp \
    995997        src/helpbrowser/UIHelpBrowserWidget.cpp \
    996998        src/logviewer/UIVMLogViewerFilterPanel.cpp \
     
    13351337        src/globals/UIVirtualBoxClientEventHandler.cpp \
    13361338        src/helpbrowser/UIHelpBrowserDialog.cpp \
     1339        src/helpbrowser/UIHelpBrowserViewer.cpp \
    13371340        src/helpbrowser/UIHelpBrowserWidget.cpp \
    13381341        src/logviewer/UIVMLogPage.cpp \
  • trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpBrowserViewer.cpp

    r87156 r87157  
    5858#include "UIActionPool.h"
    5959#include "UIExtraDataManager.h"
     60#include "UIHelpBrowserViewer.h"
    6061#include "UIHelpBrowserWidget.h"
    6162#include "UIIconPool.h"
     
    6869
    6970#if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
    70 
    71 enum HelpBrowserTabs
    72 {
    73     HelpBrowserTabs_TOC = 0,
    74     HelpBrowserTabs_Search,
    75     HelpBrowserTabs_Bookmarks,
    76     HelpBrowserTabs_Index,
    77     HelpBrowserTabs_Max
    78 };
    79 Q_DECLARE_METATYPE(HelpBrowserTabs);
    80 
    81 static const int iBookmarkUrlDataType = 6;
    82 static const QPair<float, float> fontScaleMinMax(0.5f, 3.f);
    83 static int iFontPointSizeChangeStep = 2;
    8471
    8572
     
    118105    QIToolButton *m_pHomeButton;
    119106    QIToolButton *m_pAddBookmarkButton;
    120 };
    121 
    122 /*********************************************************************************************************************************
    123 *   UIFontScaleWidget definition.                                                                                         *
    124 *********************************************************************************************************************************/
    125 class UIFontScaleWidget : public QIWithRetranslateUI<QWidget>
    126 {
    127 
    128     Q_OBJECT;
    129 
    130 signals:
    131 
    132     void sigFontPointSizeChanged(int iNewFontPointSize);
    133 
    134 public:
    135 
    136     UIFontScaleWidget(int iInitialFontPointSize, QWidget *pParent = 0);
    137     void setFontPointSize(int iFontPointSize);
    138     int fontPointSize() const;
    139 
    140 protected:
    141 
    142     void retranslateUi() /* override */;
    143 
    144 private slots:
    145 
    146     void sltSetFontPointSize();
    147 
    148 private:
    149 
    150     void prepare();
    151     int fontPercentage() const;
    152     QHBoxLayout  *m_pMainLayout;
    153     QIToolButton *m_pMinusButton;
    154     QIToolButton *m_pResetButton;
    155     QIToolButton *m_pPlusButton;
    156     QIAdvancedSlider *m_pSlider;
    157     QLabel *m_pValueLabel;
    158     int m_iInitialFontPointSize;
    159     int m_iFontPointSize;
    160 };
    161 
    162 
    163 /*********************************************************************************************************************************
    164 *   UIBookmarksListWidget definition.                                                                                            *
    165 *********************************************************************************************************************************/
    166 class UIBookmarksListWidget : public QListWidget
    167 {
    168 
    169     Q_OBJECT;
    170 
    171 signals:
    172 
    173     void sigBookmarkDoubleClick(const QUrl &url);
    174 
    175 public:
    176 
    177     UIBookmarksListWidget(QWidget *pParent = 0);
    178 
    179 protected:
    180 
    181     void mouseDoubleClickEvent(QMouseEvent *event) /* override */;
    182     void mousePressEvent(QMouseEvent *pEvent) /* override */;
    183 };
    184 
    185 
    186 /*********************************************************************************************************************************
    187 *   UIBookmarksListContainer definition.                                                                                         *
    188 *********************************************************************************************************************************/
    189 class UIBookmarksListContainer : public QIWithRetranslateUI<QWidget>
    190 {
    191 
    192     Q_OBJECT;
    193 
    194 signals:
    195 
    196     void sigBookmarkDoubleClick(const QUrl &url);
    197     void sigListWidgetContextMenuRequest(const QPoint &listWidgetLocalPos);
    198 
    199 public:
    200 
    201     UIBookmarksListContainer(QWidget *pParent = 0);
    202     void addBookmark(const QUrl &url, const QString &strTitle);
    203     /** Return all bookmarks a url, title pair list. */
    204     QStringList bookmarks() const;
    205     QUrl currentBookmarkUrl();
    206 
    207 public:
    208 
    209     void sltDeleteSelectedBookmark();
    210 
    211 protected:
    212 
    213     void retranslateUi() /* override */;
    214 
    215 private slots:
    216 
    217     void sltHandleContextMenuRequest(const QPoint &listWidgetLocalPos);
    218 
    219 private:
    220 
    221     void prepare();
    222     int itemIndex(const QUrl &url);
    223 
    224     QVBoxLayout  *m_pMainLayout;
    225     UIBookmarksListWidget  *m_pListWidget;
    226107};
    227108
     
    264145};
    265146
    266 /*********************************************************************************************************************************
    267 *   UIHelpBrowserViewer definition.                                                                                        *
    268 *********************************************************************************************************************************/
    269 
    270 class UIHelpBrowserViewer : public QIWithRetranslateUI<QTextBrowser>
    271 {
    272     Q_OBJECT;
    273 
    274 signals:
    275 
    276     void sigOpenLinkInNewTab(const QUrl &url);
    277     void sigCloseFindInPageWidget();
    278     void sigFontPointSizeChanged(int iFontPointSize);
    279     void sigGoBackward();
    280     void sigGoForward();
    281     void sigGoHome();
    282     void sigAddBookmark();
    283 
    284 public:
    285 
    286     UIHelpBrowserViewer(const QHelpEngine *pHelpEngine, QWidget *pParent = 0);
    287     virtual QVariant loadResource(int type, const QUrl &name) /* override */;
    288     void emitHistoryChangedSignal();
    289     void setSource(const QUrl &url) /* override */;
    290     void toggleFindInPageWidget(bool fVisible);
    291     int initialFontPointSize() const;
    292     void setFont(const QFont &);
    293 
    294 public slots:
    295 
    296 
    297 protected:
    298 
    299     virtual void contextMenuEvent(QContextMenuEvent *event) /* override */;
    300     virtual void resizeEvent(QResizeEvent *pEvent) /* override */;
    301     virtual void wheelEvent(QWheelEvent *pEvent) /* override */;
    302 
    303 private slots:
    304 
    305     void sltHandleOpenLinkInNewTab();
    306     void sltHandleOpenLink();
    307     void sltHandleCopyLink();
    308     void sltHandleFindWidgetDrag(const QPoint &delta);
    309     void sltHandleFindInPageSearchTextChange(const QString &strSearchText);
    310     void sltSelectPreviousMatch();
    311     void sltSelectNextMatch();
    312 
    313 private:
    314 
    315     void retranslateUi();
    316     bool isRectInside(const QRect &rect, int iMargin) const;
    317     void moveFindWidgetIn(int iMargin);
    318     void findAllMatches(const QString &searchString);
    319     void highlightFinds(int iSearchTermLength);
    320     void selectMatch(int iMatchIndex, int iSearchStringLength);
    321     const QHelpEngine* m_pHelpEngine;
    322     UIFindInPageWidget *m_pFindInPageWidget;
    323     /* Initilized as false and set to true once the user drag moves the find widget. */
    324     bool m_fFindWidgetDragged;
    325     const int m_iMarginForFindWidget;
    326     /** Document positions of the cursors within the document for all matches. */
    327     QVector<int>   m_matchedCursorPosition;
    328     int m_iSelectedMatchIndex;
    329     int m_iSearchTermLength;
    330     int m_iInitialFontPointSize;
    331 };
    332 
    333 /*********************************************************************************************************************************
    334 *   UIHelpBrowserTab definition.                                                                                        *
    335 *********************************************************************************************************************************/
    336 
    337 class UIHelpBrowserTab : public QIWithRetranslateUI<QWidget>
    338 {
    339     Q_OBJECT;
    340 
    341 signals:
    342 
    343     void sigSourceChanged(const QUrl &url);
    344     void sigTitleUpdate(const QString &strTitle);
    345     void sigOpenLinkInNewTab(const QUrl &url);
    346     void sigAddBookmark(const QUrl &url, const QString &strTitle);
    347     void sigFontPointSizeChanged(int iFontPointSize);
    348     void sigLinkHighlighted(const QString &strLink);
    349 
    350 public:
    351 
    352     UIHelpBrowserTab(const QHelpEngine  *pHelpEngine, const QUrl &homeUrl,
    353                      const QUrl &initialUrl, QWidget *pParent = 0);
    354 
    355     QUrl source() const;
    356     void setSource(const QUrl &url);
    357     QString documentTitle() const;
    358     void setToolBarVisible(bool fVisible);
    359     void print(QPrinter &printer);
    360     int initialFontPointSize() const;
    361     void setFontPointSize(int iPointSize);
    362     int fontPointSize() const;
    363 
    364 private slots:
    365 
    366     void sltHandleHomeAction();
    367     void sltHandleForwardAction();
    368     void sltHandleBackwardAction();
    369     void sltHandleFindInPageAction(bool fToggled);
    370     void sltHandleHistoryChanged();
    371     void sltHandleAddressBarIndexChanged(int index);
    372     void sltHandleAddBookmarkAction();
    373     void sltAnchorClicked(const QUrl &link);
    374     void sltCloseFindInPageWidget();
    375 
    376 private:
    377 
    378     void prepare(const QUrl &initialUrl);
    379     void prepareWidgets(const QUrl &initialUrl);
    380     void prepareToolBarAndAddressBar();
    381     virtual void retranslateUi() /* override */;
    382     void setActionTextAndToolTip(QAction *pAction, const QString &strText, const QString &strToolTip);
    383 
    384     QAction     *m_pHomeAction;
    385     QAction     *m_pForwardAction;
    386     QAction     *m_pBackwardAction;
    387     QAction     *m_pAddBookmarkAction;
    388     QAction     *m_pFindInPageAction;
    389 
    390     QVBoxLayout *m_pMainLayout;
    391     QIToolBar   *m_pToolBar;
    392     QComboBox   *m_pAddressBar;
    393     UIHelpBrowserViewer *m_pContentViewer;
    394     const QHelpEngine* m_pHelpEngine;
    395     QUrl m_homeUrl;
    396 };
    397 
    398 
    399 /*********************************************************************************************************************************
    400 *   UIHelpBrowserTabManager definition.                                                                                          *
    401 *********************************************************************************************************************************/
    402 
    403 class UIHelpBrowserTabManager : public QITabWidget
    404 {
    405     Q_OBJECT;
    406 
    407 signals:
    408 
    409     void sigSourceChanged(const QUrl &url);
    410     void sigAddBookmark(const QUrl &url, const QString &strTitle);
    411     /** list.first is tab title and list.second is tab's index. */
    412     void sigTabsListChanged(const QStringList &titleList);
    413     void sigLinkHighlighted(const QString &strLink);
    414 
    415 public:
    416 
    417     UIHelpBrowserTabManager(const QHelpEngine  *pHelpEngine, const QUrl &homeUrl,
    418                             const QStringList &urlList, QWidget *pParent = 0);
    419     /* Return the list of urls of all open tabs as QStringList. */
    420     QStringList tabUrlList() const;
    421     QStringList tabTitleList() const;
    422 
    423     /** Either start with a single tab showin the home url or saved tab(s). Depending on the params. passed to ctor. */
    424     void initializeTabs();
    425     /* Url of the current tab. */
    426     QUrl currentSource() const;
    427     void setSource(const QUrl &url, bool fNewTab = false);
    428     void setToolBarVisible(bool fVisible);
    429     void printCurrent(QPrinter &printer);
    430     int initialFontPointSize() const;
    431     void setFontPointSize(int iPointSize);
    432     int fontPointSize() const;
    433     void setFontScaleWidgetVisible(bool fToggled);
    434     void switchToTab(int iIndex);
    435 
    436 public slots:
    437 
    438     void sltHandleCloseCurrentTab();
    439     void sltHandleCloseOtherTabs();
    440 
    441 protected:
    442 
    443     virtual void paintEvent(QPaintEvent *pEvent) /* override */;
    444 
    445 private slots:
    446 
    447     void sltHandletabTitleChange(const QString &strTitle);
    448     void sltHandleOpenLinkInNewTab(const QUrl &url);
    449     void sltHandleTabClose(int iTabIndex);
    450     void sltHandleContextMenuTabClose();
    451     void sltHandleCurrentChanged(int iTabIndex);
    452     void sltHandleFontSizeChange(int iFontPointSize);
    453     void sltShowTabBarContextMenu(const QPoint &pos);
    454     void sltHandleCloseOtherTabsContextMenuAction();
    455 
    456 private:
    457 
    458     void prepare();
    459     void clearAndDeleteTabs();
    460     void addNewTab(const QUrl &initialUrl);
    461     /** Check if lists of tab url/title has changed. if so emit a signal. */
    462     void updateTabUrlTitleList();
    463     /** Closes all tabs other than the one with index @param iTabIndex. */
    464     void closeAllTabsBut(int iTabIndex);
    465     const QHelpEngine* m_pHelpEngine;
    466     UIFontScaleWidget *m_pFontScaleWidget;
    467     QUrl m_homeUrl;
    468     QStringList m_savedUrlList;
    469     /** Immediately switch the newly created tab. Otherwise open the tab in background. */
    470     bool m_fSwitchToNewTab;
    471     bool m_fToolBarVisible;
    472     QStringList m_tabTitleList;
    473 };
    474 
    475147
    476148/*********************************************************************************************************************************
     
    536208    connect(m_pAddBookmarkButton, &QIToolButton::pressed,
    537209            this, &UIContextMenuNavigationAction::sigAddBookmark);
    538 }
    539 
    540 
    541 /*********************************************************************************************************************************
    542 *   UIFontScaleWidget implementation.                                                                                            *
    543 *********************************************************************************************************************************/
    544 
    545 UIFontScaleWidget::UIFontScaleWidget(int iInitialFontPointSize, QWidget *pParent /* = 0 */)
    546     :QIWithRetranslateUI<QWidget>(pParent)
    547     , m_pMainLayout(0)
    548     , m_pMinusButton(0)
    549     , m_pResetButton(0)
    550     , m_pPlusButton(0)
    551     , m_pSlider(0)
    552     , m_pValueLabel(0)
    553     , m_iInitialFontPointSize(iInitialFontPointSize)
    554     , m_iFontPointSize(iInitialFontPointSize)
    555 {
    556     prepare();
    557 }
    558 
    559 void UIFontScaleWidget::setFontPointSize(int iFontPointSize)
    560 {
    561     if (m_iFontPointSize == iFontPointSize)
    562         return;
    563     m_iFontPointSize = iFontPointSize;
    564     if (m_pValueLabel && m_iInitialFontPointSize != 0)
    565     {
    566         m_pValueLabel->setText(QString("%1\%").arg(QString::number(fontPercentage())));
    567     }
    568 }
    569 
    570 int UIFontScaleWidget::fontPointSize() const
    571 {
    572     return m_iFontPointSize;
    573 }
    574 
    575 void UIFontScaleWidget::retranslateUi()
    576 {
    577 }
    578 
    579 void UIFontScaleWidget::prepare()
    580 {
    581     setAutoFillBackground(true);
    582     m_pMainLayout = new QHBoxLayout(this);
    583     AssertReturnVoid(m_pMainLayout);
    584     m_pMainLayout->setSpacing(0);
    585     m_pMainLayout->setContentsMargins(0, 0, 0, 0);
    586     m_pMinusButton = new QIToolButton;
    587     m_pResetButton = new QIToolButton;
    588     m_pPlusButton = new QIToolButton;
    589     //m_pSlider = new QIAdvancedSlider;
    590     m_pValueLabel = new QLabel;
    591     AssertReturnVoid(m_pMinusButton &&
    592                      m_pResetButton &&
    593                      m_pPlusButton &&
    594                      m_pValueLabel);
    595 
    596     m_pValueLabel->setText(QString("%1\%").arg(QString::number(fontPercentage())));
    597 
    598     m_pMinusButton->setIcon(UIIconPool::iconSet(":/help_browser_minus_32px.png"));
    599     m_pResetButton->setIcon(UIIconPool::iconSet(":/help_browser_reset_32px.png"));
    600     m_pPlusButton->setIcon(UIIconPool::iconSet(":/help_browser_plus_32px.png"));
    601 
    602     connect(m_pPlusButton, &QIToolButton::pressed, this, &UIFontScaleWidget::sltSetFontPointSize);
    603     connect(m_pMinusButton, &QIToolButton::pressed, this, &UIFontScaleWidget::sltSetFontPointSize);
    604     connect(m_pResetButton, &QIToolButton::pressed, this, &UIFontScaleWidget::sltSetFontPointSize);
    605 
    606     m_pMainLayout->addWidget(m_pResetButton);
    607     m_pMainLayout->addWidget(m_pMinusButton);
    608     //m_pMainLayout->addWidget(m_pSlider);
    609     m_pMainLayout->addWidget(m_pValueLabel);
    610     m_pMainLayout->addWidget(m_pPlusButton);
    611 }
    612 
    613 int UIFontScaleWidget::fontPercentage() const
    614 {
    615     if (m_iInitialFontPointSize == 0)
    616         return 0;
    617     return 100 * m_iFontPointSize / m_iInitialFontPointSize;
    618 }
    619 
    620 void UIFontScaleWidget::sltSetFontPointSize()
    621 {
    622     if (!sender())
    623         return;
    624     int iNewSize = m_iFontPointSize;
    625     if (sender() == m_pMinusButton)
    626         iNewSize -= iFontPointSizeChangeStep;
    627     else if (sender() == m_pPlusButton)
    628         iNewSize += iFontPointSizeChangeStep;
    629     else if (sender() == m_pResetButton)
    630         iNewSize = m_iInitialFontPointSize;
    631     if (iNewSize >= fontScaleMinMax.second * m_iInitialFontPointSize ||
    632         iNewSize <= fontScaleMinMax.first * m_iInitialFontPointSize)
    633         iNewSize = m_iFontPointSize;
    634     setFontPointSize(iNewSize);
    635     emit sigFontPointSizeChanged(m_iFontPointSize);
    636 }
    637 
    638 
    639 /*********************************************************************************************************************************
    640 *   UIBookmarksListWidget implementation.                                                                                        *
    641 *********************************************************************************************************************************/
    642 UIBookmarksListWidget::UIBookmarksListWidget(QWidget *pParent /* = 0 */)
    643     :QListWidget(pParent)
    644 {
    645     setSelectionMode(QAbstractItemView::SingleSelection);
    646 }
    647 
    648 void UIBookmarksListWidget::mouseDoubleClickEvent(QMouseEvent *event)
    649 {
    650     QListWidgetItem *pItem = currentItem();
    651     if (!pItem)
    652         return;
    653     emit sigBookmarkDoubleClick(pItem->data(iBookmarkUrlDataType).toUrl());
    654     QListWidget::mouseDoubleClickEvent(event);
    655 }
    656 
    657 void UIBookmarksListWidget::mousePressEvent(QMouseEvent *pEvent)
    658 {
    659     if (!indexAt(pEvent->pos()).isValid())
    660     {
    661         clearSelection();
    662         setCurrentItem(0);
    663     }
    664     QListWidget::mousePressEvent(pEvent);
    665 }
    666 
    667 
    668 /*********************************************************************************************************************************
    669 *   UIBookmarksListContainer implementation.                                                                                     *
    670 *********************************************************************************************************************************/
    671 
    672 UIBookmarksListContainer::UIBookmarksListContainer(QWidget *pParent /* = 0 */)
    673     :QIWithRetranslateUI<QWidget>(pParent)
    674     , m_pMainLayout(0)
    675     , m_pListWidget(0)
    676 {
    677     prepare();
    678 }
    679 
    680 void UIBookmarksListContainer::addBookmark(const QUrl &url, const QString &strTitle)
    681 {
    682     if (!m_pListWidget)
    683         return;
    684     if (itemIndex(url) != -1)
    685         return;
    686     QListWidgetItem *pNewItem = new QListWidgetItem(strTitle, m_pListWidget);
    687     pNewItem->setData(iBookmarkUrlDataType, url);
    688     pNewItem->setToolTip(url.toString());
    689 }
    690 
    691 QStringList UIBookmarksListContainer::bookmarks() const
    692 {
    693     if (!m_pListWidget)
    694         return QStringList();
    695     QStringList bookmarks;
    696     for (int i = 0; i < m_pListWidget->count(); ++i)
    697     {
    698         QListWidgetItem *pItem = m_pListWidget->item(i);
    699         if (!pItem)
    700             continue;
    701         bookmarks << pItem->data(iBookmarkUrlDataType).toUrl().toString() << pItem->text();
    702     }
    703     return bookmarks;
    704 }
    705 
    706 QUrl UIBookmarksListContainer::currentBookmarkUrl()
    707 {
    708     if (!m_pListWidget || !m_pListWidget->currentItem())
    709         return QUrl();
    710     return m_pListWidget->currentItem()->data(iBookmarkUrlDataType).toUrl();
    711 }
    712 
    713 void UIBookmarksListContainer::sltDeleteSelectedBookmark()
    714 {
    715     if (!m_pListWidget || !m_pListWidget->currentItem())
    716         return;
    717     QListWidgetItem *pCurrentItem = m_pListWidget->takeItem(m_pListWidget->currentRow());
    718 
    719     delete pCurrentItem;
    720 
    721 
    722 }
    723 
    724 void UIBookmarksListContainer::retranslateUi()
    725 {
    726 }
    727 
    728 void UIBookmarksListContainer::prepare()
    729 {
    730     m_pMainLayout = new QVBoxLayout(this);
    731     AssertReturnVoid(m_pMainLayout);
    732     m_pMainLayout->setContentsMargins(0, 0, 0, 0);
    733 
    734     m_pListWidget = new UIBookmarksListWidget;
    735     AssertReturnVoid(m_pListWidget);
    736     m_pMainLayout->addWidget(m_pListWidget);
    737     m_pListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    738     connect(m_pListWidget, &UIBookmarksListWidget::sigBookmarkDoubleClick,
    739             this, &UIBookmarksListContainer::sigBookmarkDoubleClick);
    740     connect(m_pListWidget, &UIBookmarksListWidget::customContextMenuRequested,
    741             this, &UIBookmarksListContainer::sltHandleContextMenuRequest);
    742 }
    743 
    744 void UIBookmarksListContainer::sltHandleContextMenuRequest(const QPoint &listWidgetLocalPos)
    745 {
    746     if (!m_pListWidget || !m_pListWidget->currentItem())
    747         return;
    748     emit sigListWidgetContextMenuRequest(listWidgetLocalPos);
    749 }
    750 
    751 int UIBookmarksListContainer::itemIndex(const QUrl &url)
    752 {
    753     if (!m_pListWidget || !url.isValid())
    754         return -1;
    755     for (int i = 0; i < m_pListWidget->count(); ++i)
    756     {
    757         if (m_pListWidget->item(i)->data(iBookmarkUrlDataType).toUrl() == url)
    758             return i;
    759     }
    760     return -1;
    761210}
    762211
     
    873322}
    874323
    875 /*********************************************************************************************************************************
    876 *   UIHelpBrowserTab implementation.                                                                                        *
    877 *********************************************************************************************************************************/
    878 
    879 UIHelpBrowserTab::UIHelpBrowserTab(const QHelpEngine  *pHelpEngine, const QUrl &homeUrl,
    880                                    const QUrl &initialUrl, QWidget *pParent /* = 0 */)
    881     : QIWithRetranslateUI<QWidget>(pParent)
    882     , m_pHomeAction(0)
    883     , m_pForwardAction(0)
    884     , m_pBackwardAction(0)
    885     , m_pAddBookmarkAction(0)
    886     , m_pFindInPageAction(0)
    887     , m_pMainLayout(0)
    888     , m_pToolBar(0)
    889     , m_pAddressBar(0)
    890     , m_pContentViewer(0)
    891     , m_pHelpEngine(pHelpEngine)
    892     , m_homeUrl(homeUrl)
    893 {
    894     if (initialUrl.isValid())
    895         prepare(initialUrl);
    896     else
    897         prepare(m_homeUrl);
    898 }
    899 
    900 QUrl UIHelpBrowserTab::source() const
    901 {
    902     if (!m_pContentViewer)
    903         return QUrl();
    904     return m_pContentViewer->source();
    905 }
    906 
    907 void UIHelpBrowserTab::setSource(const QUrl &url)
    908 {
    909     if (m_pContentViewer)
    910     {
    911         m_pContentViewer->blockSignals(true);
    912         m_pContentViewer->setSource(url);
    913         m_pContentViewer->blockSignals(false);
    914         /* emit historyChanged signal explicitly since we have blocked the signals: */
    915         m_pContentViewer->emitHistoryChangedSignal();
    916     }
    917 }
    918 
    919 QString UIHelpBrowserTab::documentTitle() const
    920 {
    921     if (!m_pContentViewer)
    922         return QString();
    923     return m_pContentViewer->documentTitle();
    924 }
    925 
    926 void UIHelpBrowserTab::setToolBarVisible(bool fVisible)
    927 {
    928     if (m_pToolBar)
    929         m_pToolBar->setVisible(fVisible);
    930     if (m_pAddressBar)
    931         m_pAddressBar->setVisible(fVisible);
    932 }
    933 
    934 void UIHelpBrowserTab::print(QPrinter &printer)
    935 {
    936     if (m_pContentViewer)
    937         m_pContentViewer->print(&printer);
    938 }
    939 
    940 int UIHelpBrowserTab::initialFontPointSize() const
    941 {
    942     if (m_pContentViewer)
    943         return m_pContentViewer->initialFontPointSize();
    944     return 0;
    945 }
    946 
    947 void UIHelpBrowserTab::setFontPointSize(int iPointSize)
    948 {
    949     if (m_pContentViewer)
    950     {
    951         if (m_pContentViewer->font().pointSize() == iPointSize)
    952             return;
    953         QFont mFont = m_pContentViewer->font();
    954         mFont.setPointSize(iPointSize);
    955         m_pContentViewer->setFont(mFont);
    956     }
    957 }
    958 
    959 int UIHelpBrowserTab::fontPointSize() const
    960 {
    961     if (!m_pContentViewer)
    962         return 0;
    963     return m_pContentViewer->font().pointSize();
    964 }
    965 
    966 void UIHelpBrowserTab::prepare(const QUrl &initialUrl)
    967 {
    968     m_pMainLayout = new QVBoxLayout(this);
    969     AssertReturnVoid(m_pMainLayout);
    970     prepareToolBarAndAddressBar();
    971     prepareWidgets(initialUrl);
    972     retranslateUi();
    973 }
    974 
    975 void UIHelpBrowserTab::prepareWidgets(const QUrl &initialUrl)
    976 {
    977     m_pContentViewer = new UIHelpBrowserViewer(m_pHelpEngine);
    978     AssertReturnVoid(m_pContentViewer);
    979     m_pMainLayout->setContentsMargins(0, 0, 0, 0);
    980     m_pMainLayout->setSpacing(0);
    981 
    982     m_pMainLayout->addWidget(m_pContentViewer);
    983     m_pContentViewer->setOpenExternalLinks(false);
    984     connect(m_pContentViewer, &UIHelpBrowserViewer::sourceChanged,
    985         this, &UIHelpBrowserTab::sigSourceChanged);
    986     connect(m_pContentViewer, &UIHelpBrowserViewer::historyChanged,
    987         this, &UIHelpBrowserTab::sltHandleHistoryChanged);
    988     connect(m_pContentViewer, &UIHelpBrowserViewer::anchorClicked,
    989         this, &UIHelpBrowserTab::sltAnchorClicked);
    990     connect(m_pContentViewer, &UIHelpBrowserViewer::sigOpenLinkInNewTab,
    991         this, &UIHelpBrowserTab::sigOpenLinkInNewTab);
    992     connect(m_pContentViewer, &UIHelpBrowserViewer::sigCloseFindInPageWidget,
    993             this, &UIHelpBrowserTab::sltCloseFindInPageWidget);
    994     connect(m_pContentViewer, &UIHelpBrowserViewer::sigFontPointSizeChanged,
    995             this, &UIHelpBrowserTab::sigFontPointSizeChanged);
    996     connect(m_pContentViewer, &UIHelpBrowserViewer::sigGoBackward,
    997             this, &UIHelpBrowserTab::sltHandleBackwardAction);
    998     connect(m_pContentViewer, &UIHelpBrowserViewer::sigGoForward,
    999             this, &UIHelpBrowserTab::sltHandleForwardAction);
    1000     connect(m_pContentViewer, &UIHelpBrowserViewer::sigGoHome,
    1001             this, &UIHelpBrowserTab::sltHandleHomeAction);
    1002     connect(m_pContentViewer, &UIHelpBrowserViewer::sigAddBookmark,
    1003             this, &UIHelpBrowserTab::sltHandleAddBookmarkAction);
    1004     connect(m_pContentViewer, static_cast<void(UIHelpBrowserViewer::*)(const QString&)>(&UIHelpBrowserViewer::highlighted),
    1005             this, &UIHelpBrowserTab::sigLinkHighlighted);
    1006 
    1007     m_pContentViewer->setSource(initialUrl);
    1008 }
    1009 
    1010 void UIHelpBrowserTab::prepareToolBarAndAddressBar()
    1011 {
    1012     m_pHomeAction =
    1013         new QAction(UIIconPool::iconSet(":/help_browser_home_32px.png"), QString(), this);
    1014     m_pForwardAction =
    1015         new QAction(UIIconPool::iconSet(":/help_browser_forward_32px.png", ":/help_browser_forward_disabled_32px.png"), QString(), this);
    1016     m_pBackwardAction =
    1017         new QAction(UIIconPool::iconSet(":/help_browser_backward_32px.png", ":/help_browser_backward_disabled_32px.png"), QString(), this);
    1018     m_pAddBookmarkAction =
    1019         new QAction(UIIconPool::iconSet(":/help_browser_add_bookmark.png"), QString(), this);
    1020     m_pFindInPageAction =
    1021         new QAction(UIIconPool::iconSet(":/help_browser_search.png"), QString(), this);
    1022 
    1023     AssertReturnVoid(m_pHomeAction && m_pForwardAction &&
    1024                      m_pBackwardAction && m_pAddBookmarkAction &&
    1025                      m_pFindInPageAction);
    1026     m_pFindInPageAction->setCheckable(true);
    1027 
    1028     connect(m_pHomeAction, &QAction::triggered, this, &UIHelpBrowserTab::sltHandleHomeAction);
    1029     connect(m_pAddBookmarkAction, &QAction::triggered, this, &UIHelpBrowserTab::sltHandleAddBookmarkAction);
    1030     connect(m_pForwardAction, &QAction::triggered, this, &UIHelpBrowserTab::sltHandleForwardAction);
    1031     connect(m_pBackwardAction, &QAction::triggered, this, &UIHelpBrowserTab::sltHandleBackwardAction);
    1032     connect(m_pFindInPageAction, &QAction::toggled, this, &UIHelpBrowserTab::sltHandleFindInPageAction);
    1033 
    1034     m_pForwardAction->setEnabled(false);
    1035     m_pBackwardAction->setEnabled(false);
    1036 
    1037     m_pToolBar = new QIToolBar;
    1038     AssertReturnVoid(m_pToolBar);
    1039     m_pToolBar->addAction(m_pBackwardAction);
    1040     m_pToolBar->addAction(m_pForwardAction);
    1041     m_pToolBar->addAction(m_pHomeAction);
    1042     m_pToolBar->addAction(m_pAddBookmarkAction);
    1043     m_pToolBar->addAction(m_pFindInPageAction);
    1044 
    1045     m_pAddressBar = new QComboBox();
    1046     m_pAddressBar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    1047     connect(m_pAddressBar, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
    1048             this, &UIHelpBrowserTab::sltHandleAddressBarIndexChanged);
    1049 
    1050 
    1051     QHBoxLayout *pTopLayout = new QHBoxLayout;
    1052     pTopLayout->addWidget(m_pToolBar);
    1053     pTopLayout->addWidget(m_pAddressBar);
    1054     m_pMainLayout->addLayout(pTopLayout);
    1055 }
    1056 
    1057 void UIHelpBrowserTab::setActionTextAndToolTip(QAction *pAction, const QString &strText, const QString &strToolTip)
    1058 {
    1059     if (!pAction)
    1060         return;
    1061     pAction->setText(strText);
    1062     pAction->setToolTip(strToolTip);
    1063 }
    1064 
    1065 void UIHelpBrowserTab::retranslateUi()
    1066 {
    1067     setActionTextAndToolTip(m_pHomeAction, tr("Home"), tr("Return to Start Page"));
    1068     setActionTextAndToolTip(m_pBackwardAction, tr("Backward"), tr("Navigate to Previous Page"));
    1069     setActionTextAndToolTip(m_pForwardAction, tr("Forward"), tr("Navigate to Next Page"));
    1070     setActionTextAndToolTip(m_pAddBookmarkAction, tr("Bookmark"), tr("Add a New Bookmark"));
    1071     setActionTextAndToolTip(m_pFindInPageAction, tr("Find in Page"), tr("Find a String in the Current Page"));
    1072 }
    1073 
    1074 void UIHelpBrowserTab::sltHandleHomeAction()
    1075 {
    1076     if (!m_pContentViewer)
    1077         return;
    1078     m_pContentViewer->setSource(m_homeUrl);
    1079 }
    1080 
    1081 void UIHelpBrowserTab::sltHandleForwardAction()
    1082 {
    1083     if (m_pContentViewer)
    1084         m_pContentViewer->forward();
    1085 }
    1086 
    1087 void UIHelpBrowserTab::sltHandleBackwardAction()
    1088 {
    1089     if (m_pContentViewer)
    1090         m_pContentViewer->backward();
    1091 }
    1092 
    1093 void UIHelpBrowserTab::sltHandleFindInPageAction(bool fToggled)
    1094 {
    1095     if (m_pContentViewer)
    1096         m_pContentViewer->toggleFindInPageWidget(fToggled);
    1097 }
    1098 
    1099 void UIHelpBrowserTab::sltHandleHistoryChanged()
    1100 {
    1101     if (!m_pContentViewer)
    1102         return;
    1103     int iCurrentIndex = 0;
    1104     /* QTextBrower history has negative and positive indices for bacward and forward items, respectively.
    1105      * 0 is the current item: */
    1106     m_pAddressBar->blockSignals(true);
    1107     m_pAddressBar->clear();
    1108     for (int i = -1 * m_pContentViewer->backwardHistoryCount(); i <= m_pContentViewer->forwardHistoryCount(); ++i)
    1109     {
    1110         int iIndex = m_pAddressBar->count();
    1111         m_pAddressBar->addItem(m_pContentViewer->historyUrl(i).toString(), i);
    1112         m_pAddressBar->setItemData(iIndex, m_pContentViewer->historyTitle(i), Qt::ToolTipRole);
    1113         if (i == 0)
    1114             iCurrentIndex = m_pAddressBar->count();
    1115     }
    1116     /* Make sure address bar show the current item: */
    1117     m_pAddressBar->setCurrentIndex(iCurrentIndex - 1);
    1118     m_pAddressBar->blockSignals(false);
    1119 
    1120     if (m_pBackwardAction)
    1121         m_pBackwardAction->setEnabled(m_pContentViewer->isBackwardAvailable());
    1122     if (m_pForwardAction)
    1123         m_pForwardAction->setEnabled(m_pContentViewer->isForwardAvailable());
    1124 
    1125     emit sigTitleUpdate(m_pContentViewer->historyTitle(0));
    1126 }
    1127 
    1128 void UIHelpBrowserTab::sltHandleAddressBarIndexChanged(int iIndex)
    1129 {
    1130     if (!m_pAddressBar && iIndex >= m_pAddressBar->count())
    1131         return;
    1132     int iHistoryIndex = m_pAddressBar->itemData(iIndex).toInt();
    1133     /* There seems to be no way to one-step-jump to a history item: */
    1134     if (iHistoryIndex == 0)
    1135         return;
    1136     else if (iHistoryIndex > 0)
    1137         for (int i = 0; i < iHistoryIndex; ++i)
    1138             m_pContentViewer->forward();
    1139     else
    1140         for (int i = 0; i > iHistoryIndex ; --i)
    1141             m_pContentViewer->backward();
    1142 }
    1143 
    1144 void UIHelpBrowserTab::sltHandleAddBookmarkAction()
    1145 {
    1146     emit sigAddBookmark(source(), documentTitle());
    1147 }
    1148 
    1149 void UIHelpBrowserTab::sltAnchorClicked(const QUrl &link)
    1150 {
    1151     Q_UNUSED(link);
    1152 }
    1153 
    1154 void UIHelpBrowserTab::sltCloseFindInPageWidget()
    1155 {
    1156     if (m_pFindInPageAction)
    1157         m_pFindInPageAction->setChecked(false);
    1158 }
    1159 
    1160324
    1161325/*********************************************************************************************************************************
     
    1323487    QTextBrowser::wheelEvent(pEvent);
    1324488    /* Don't allow font size to get too large or small: */
    1325     if (font().pointSize() >= fontScaleMinMax.second * m_iInitialFontPointSize ||
    1326         font().pointSize() <= fontScaleMinMax.first * m_iInitialFontPointSize)
     489    if (font().pointSize() >= UIHelpBrowserWidget::fontScaleMinMax.second * m_iInitialFontPointSize ||
     490        font().pointSize() <= UIHelpBrowserWidget::fontScaleMinMax.first * m_iInitialFontPointSize)
    1327491    {
    1328492        QFont mFont = font();
     
    1498662}
    1499663
    1500 
    1501 /*********************************************************************************************************************************
    1502 *   UIHelpBrowserTabManager definition.                                                                                          *
    1503 *********************************************************************************************************************************/
    1504 
    1505 UIHelpBrowserTabManager::UIHelpBrowserTabManager(const QHelpEngine  *pHelpEngine, const QUrl &homeUrl,
    1506                                                  const QStringList &urlList, QWidget *pParent /* = 0 */)
    1507     : QITabWidget(pParent)
    1508     , m_pHelpEngine(pHelpEngine)
    1509     , m_pFontScaleWidget(0)
    1510     , m_homeUrl(homeUrl)
    1511     , m_savedUrlList(urlList)
    1512     , m_fSwitchToNewTab(true)
    1513     , m_fToolBarVisible(true)
    1514 {
    1515     prepare();
    1516 }
    1517 
    1518 void UIHelpBrowserTabManager::addNewTab(const QUrl &initialUrl)
    1519 {
    1520    UIHelpBrowserTab *pTabWidget = new  UIHelpBrowserTab(m_pHelpEngine, m_homeUrl, initialUrl);
    1521    AssertReturnVoid(pTabWidget);
    1522    pTabWidget->setToolBarVisible(m_fToolBarVisible);
    1523    int index = addTab(pTabWidget, pTabWidget->documentTitle());
    1524    connect(pTabWidget, &UIHelpBrowserTab::sigSourceChanged,
    1525            this, &UIHelpBrowserTabManager::sigSourceChanged);
    1526    connect(pTabWidget, &UIHelpBrowserTab::sigTitleUpdate,
    1527            this, &UIHelpBrowserTabManager::sltHandletabTitleChange);
    1528    connect(pTabWidget, &UIHelpBrowserTab::sigOpenLinkInNewTab,
    1529            this, &UIHelpBrowserTabManager::sltHandleOpenLinkInNewTab);
    1530    connect(pTabWidget, &UIHelpBrowserTab::sigAddBookmark,
    1531            this, &UIHelpBrowserTabManager::sigAddBookmark);
    1532    connect(pTabWidget, &UIHelpBrowserTab::sigFontPointSizeChanged,
    1533            this, &UIHelpBrowserTabManager::sltHandleFontSizeChange);
    1534    connect(pTabWidget, &UIHelpBrowserTab::sigLinkHighlighted,
    1535            this, &UIHelpBrowserTabManager::sigLinkHighlighted);
    1536 
    1537    if (m_fSwitchToNewTab)
    1538        setCurrentIndex(index);
    1539 
    1540    if (!m_pFontScaleWidget)
    1541    {
    1542        m_pFontScaleWidget = new UIFontScaleWidget(initialFontPointSize(), this);
    1543        connect(m_pFontScaleWidget, &UIFontScaleWidget::sigFontPointSizeChanged,
    1544                this, &UIHelpBrowserTabManager::sltHandleFontSizeChange);
    1545    }
    1546 }
    1547 
    1548 void UIHelpBrowserTabManager::updateTabUrlTitleList()
    1549 {
    1550     QList<QPair<QString, int> > newList;
    1551 
    1552     QStringList titles = tabTitleList();
    1553 
    1554     if (titles == m_tabTitleList)
    1555         return;
    1556 
    1557     m_tabTitleList = titles;
    1558     emit sigTabsListChanged(m_tabTitleList);
    1559 }
    1560 
    1561 void UIHelpBrowserTabManager::closeAllTabsBut(int iTabIndex)
    1562 {
    1563     QString strTitle = tabText(iTabIndex);
    1564     QList<QWidget*> widgetList;
    1565     for (int i = 0; i < count(); ++i)
    1566         widgetList.append(widget(i));
    1567     clear();
    1568     for (int i = 0; i < widgetList.size(); ++i)
    1569     {
    1570         if (i != iTabIndex)
    1571             delete widgetList[i];
    1572     }
    1573     addTab(widgetList[iTabIndex], strTitle);
    1574     updateTabUrlTitleList();
    1575 }
    1576 
    1577 void UIHelpBrowserTabManager::initializeTabs()
    1578 {
    1579     clearAndDeleteTabs();
    1580     /* Start with a single tab showing the home URL: */
    1581     if (m_savedUrlList.isEmpty())
    1582         addNewTab(QUrl());
    1583     /* Start with saved tab(s): */
    1584     else
    1585         for (int i = 0; i < m_savedUrlList.size(); ++i)
    1586             addNewTab(m_savedUrlList[i]);
    1587     updateTabUrlTitleList();
    1588 }
    1589 
    1590 QUrl UIHelpBrowserTabManager::currentSource() const
    1591 {
    1592     UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
    1593     if (!pTab)
    1594         return QUrl();
    1595     return pTab->source();
    1596 }
    1597 
    1598 void UIHelpBrowserTabManager::setSource(const QUrl &url, bool fNewTab /* = false */)
    1599 {
    1600     if (!fNewTab)
    1601     {
    1602         UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
    1603         if (!pTab)
    1604             return;
    1605         pTab->setSource(url);
    1606     }
    1607     else
    1608         addNewTab(url);
    1609 
    1610     updateTabUrlTitleList();
    1611 }
    1612 
    1613 QStringList UIHelpBrowserTabManager::tabUrlList() const
    1614 {
    1615     QStringList list;
    1616     for (int i = 0; i < count(); ++i)
    1617     {
    1618         UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
    1619         if (!pTab || !pTab->source().isValid())
    1620             continue;
    1621         list << pTab->source().toString();
    1622     }
    1623     return list;
    1624 }
    1625 
    1626 QStringList UIHelpBrowserTabManager::tabTitleList() const
    1627 {
    1628     QStringList list;
    1629     for (int i = 0; i < count(); ++i)
    1630     {
    1631         UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
    1632         if (!pTab || !pTab->source().isValid())
    1633             continue;
    1634         list << pTab->documentTitle();
    1635     }
    1636     return list;
    1637 }
    1638 
    1639 
    1640 void UIHelpBrowserTabManager::setToolBarVisible(bool fVisible)
    1641 {
    1642     /* Make sure existing tabs are configured: */
    1643     for (int i = 0; i < count(); ++i)
    1644     {
    1645         UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
    1646         if (!pTab)
    1647             continue;
    1648         pTab->setToolBarVisible(fVisible);
    1649     }
    1650     /* This is for the tabs that will be created later: */
    1651     m_fToolBarVisible = fVisible;
    1652 }
    1653 
    1654 void UIHelpBrowserTabManager::printCurrent(QPrinter &printer)
    1655 {
    1656     UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
    1657     if (!pTab)
    1658         return;
    1659     return pTab->print(printer);
    1660 }
    1661 
    1662 void UIHelpBrowserTabManager::paintEvent(QPaintEvent *pEvent)
    1663 {
    1664     if (m_pFontScaleWidget)
    1665     {
    1666         int iMargin = 20;
    1667         m_pFontScaleWidget->move(width() - m_pFontScaleWidget->width() - iMargin,
    1668                                  height() - m_pFontScaleWidget->height() - iMargin);
    1669     }
    1670     QITabWidget::paintEvent(pEvent);
    1671 }
    1672 
    1673 int UIHelpBrowserTabManager::initialFontPointSize() const
    1674 {
    1675     UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
    1676     if (!pTab)
    1677         return 0;
    1678     return pTab->initialFontPointSize();
    1679 }
    1680 
    1681 void UIHelpBrowserTabManager::setFontPointSize(int iPointSize)
    1682 {
    1683     for (int i = 0; i < count(); ++i)
    1684     {
    1685         UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(widget(i));
    1686         if (!pTab)
    1687             continue;
    1688         pTab->setFontPointSize(iPointSize);
    1689     }
    1690     if (m_pFontScaleWidget)
    1691         m_pFontScaleWidget->setFontPointSize(iPointSize);
    1692 }
    1693 
    1694 int UIHelpBrowserTabManager::fontPointSize() const
    1695 {
    1696     UIHelpBrowserTab *pTab = qobject_cast<UIHelpBrowserTab*>(currentWidget());
    1697     if (!pTab)
    1698         return 0;
    1699     return pTab->fontPointSize();
    1700 }
    1701 
    1702 void UIHelpBrowserTabManager::setFontScaleWidgetVisible(bool fToggled)
    1703 {
    1704     if (m_pFontScaleWidget)
    1705         m_pFontScaleWidget->setVisible(fToggled);
    1706 }
    1707 
    1708 void UIHelpBrowserTabManager::switchToTab(int iIndex)
    1709 {
    1710     if (iIndex == currentIndex())
    1711         return;
    1712     setCurrentIndex(iIndex);
    1713 }
    1714 
    1715 void UIHelpBrowserTabManager::sltHandletabTitleChange(const QString &strTitle)
    1716 {
    1717     for (int i = 0; i < count(); ++i)
    1718     {
    1719         if (sender() == widget(i))
    1720         {
    1721             setTabText(i, strTitle);
    1722             setTabToolTip(i, strTitle);
    1723             continue;
    1724         }
    1725     }
    1726     updateTabUrlTitleList();
    1727 }
    1728 
    1729 void UIHelpBrowserTabManager::sltHandleOpenLinkInNewTab(const QUrl &url)
    1730 {
    1731     if (url.isValid())
    1732         addNewTab(url);
    1733     updateTabUrlTitleList();
    1734 }
    1735 
    1736 void UIHelpBrowserTabManager::sltHandleTabClose(int iTabIndex)
    1737 {
    1738     if (count() <= 1)
    1739         return;
    1740     QWidget *pWidget = widget(iTabIndex);
    1741     if (!pWidget)
    1742         return;
    1743     removeTab(iTabIndex);
    1744     delete pWidget;
    1745     updateTabUrlTitleList();
    1746 }
    1747 
    1748 void UIHelpBrowserTabManager::sltHandleContextMenuTabClose()
    1749 {
    1750     QAction *pAction = qobject_cast<QAction*>(sender());
    1751     if (!pAction)
    1752         return;
    1753     int iTabIndex = pAction->data().toInt();
    1754     if (iTabIndex < 0 || iTabIndex >= count())
    1755         return;
    1756     sltHandleTabClose(iTabIndex);
    1757 }
    1758 
    1759 void UIHelpBrowserTabManager::sltHandleCloseOtherTabsContextMenuAction()
    1760 {
    1761     /* Find the index of the sender tab. we will close all tabs but sender tab: */
    1762     QAction *pAction = qobject_cast<QAction*>(sender());
    1763     if (!pAction)
    1764         return;
    1765     int iTabIndex = pAction->data().toInt();
    1766     if (iTabIndex < 0 || iTabIndex >= count())
    1767         return;
    1768     closeAllTabsBut(iTabIndex);
    1769 }
    1770 
    1771 void UIHelpBrowserTabManager::sltHandleCloseCurrentTab()
    1772 {
    1773     sltHandleTabClose(currentIndex());
    1774 }
    1775 
    1776 void UIHelpBrowserTabManager::sltHandleCloseOtherTabs()
    1777 {
    1778     closeAllTabsBut(currentIndex());
    1779 }
    1780 
    1781 void UIHelpBrowserTabManager::sltHandleCurrentChanged(int iTabIndex)
    1782 {
    1783     Q_UNUSED(iTabIndex);
    1784     emit sigSourceChanged(currentSource());
    1785 }
    1786 
    1787 void UIHelpBrowserTabManager::sltHandleFontSizeChange(int iFontPointSize)
    1788 {
    1789     setFontPointSize(iFontPointSize);
    1790 }
    1791 
    1792 void UIHelpBrowserTabManager::sltShowTabBarContextMenu(const QPoint &pos)
    1793 {
    1794     if (!tabBar())
    1795         return;
    1796     QMenu menu;
    1797     QAction *pCloseAll = menu.addAction(UIHelpBrowserWidget::tr("Close Other Tabs"));
    1798     connect(pCloseAll, &QAction::triggered, this, &UIHelpBrowserTabManager::sltHandleCloseOtherTabsContextMenuAction);
    1799     pCloseAll->setData(tabBar()->tabAt(pos));
    1800 
    1801     QAction *pClose = menu.addAction(UIHelpBrowserWidget::tr("Close Tab"));
    1802     connect(pClose, &QAction::triggered, this, &UIHelpBrowserTabManager::sltHandleContextMenuTabClose);
    1803     pClose->setData(tabBar()->tabAt(pos));
    1804 
    1805     menu.exec(tabBar()->mapToGlobal(pos));
    1806 }
    1807 
    1808 void UIHelpBrowserTabManager::prepare()
    1809 {
    1810     setTabsClosable(true);
    1811     setTabBarAutoHide(true);
    1812     connect(this, &UIHelpBrowserTabManager::tabCloseRequested, this, &UIHelpBrowserTabManager::sltHandleTabClose);
    1813     connect(this, &UIHelpBrowserTabManager::currentChanged, this, &UIHelpBrowserTabManager::sltHandleCurrentChanged);
    1814     if (tabBar())
    1815     {
    1816         tabBar()->setContextMenuPolicy(Qt::CustomContextMenu);
    1817         connect(tabBar(), &QTabBar::customContextMenuRequested, this, &UIHelpBrowserTabManager::sltShowTabBarContextMenu);
    1818     }
    1819 }
    1820 
    1821 void UIHelpBrowserTabManager::clearAndDeleteTabs()
    1822 {
    1823     QList<QWidget*> tabList;
    1824     for (int i = 0; i < count(); ++i)
    1825         tabList << widget(i);
    1826     /* QTabWidget::clear() does not delete tab widgets: */
    1827     clear();
    1828     foreach (QWidget *pWidget, tabList)
    1829         delete pWidget;
    1830 }
    1831 
    1832 
    1833 /*********************************************************************************************************************************
    1834 *   UIHelpBrowserWidget implementation.                                                                                          *
    1835 *********************************************************************************************************************************/
    1836 
    1837 UIHelpBrowserWidget::UIHelpBrowserWidget(EmbedTo enmEmbedding, const QString &strHelpFilePath, QWidget *pParent /* = 0 */)
    1838     : QIWithRetranslateUI<QWidget>(pParent)
    1839     , m_enmEmbedding(enmEmbedding)
    1840     , m_fIsPolished(false)
    1841     , m_pMainLayout(0)
    1842     , m_pTopLayout(0)
    1843     , m_pTabWidget(0)
    1844     , m_pToolBar(0)
    1845     , m_strHelpFilePath(strHelpFilePath)
    1846     , m_pHelpEngine(0)
    1847     , m_pSplitter(0)
    1848     , m_pFileMenu(0)
    1849     , m_pViewMenu(0)
    1850     , m_pTabsMenu(0)
    1851     , m_pContentWidget(0)
    1852     , m_pIndexWidget(0)
    1853     , m_pContentModel(0)
    1854     , m_pSearchEngine(0)
    1855     , m_pSearchQueryWidget(0)
    1856     , m_pSearchResultWidget(0)
    1857     , m_pTabManager(0)
    1858     , m_pBookmarksWidget(0)
    1859     , m_pSearchContainerWidget(0)
    1860     , m_pPrintAction(0)
    1861     , m_pShowHideSideBarAction(0)
    1862     , m_pShowHideToolBarAction(0)
    1863     , m_pShowHideFontScaleWidgetAction(0)
    1864     , m_pShowHideStatusBarAction(0)
    1865     , m_pFontSizeLargerAction(0)
    1866     , m_pFontSizeSmallerAction(0)
    1867     , m_pFontSizeResetAction(0)
    1868     , m_fModelContentCreated(false)
    1869     , m_fIndexingFinished(false)
    1870 {
    1871     qRegisterMetaType<HelpBrowserTabs>("HelpBrowserTabs");
    1872     prepare();
    1873     loadOptions();
    1874 }
    1875 
    1876 UIHelpBrowserWidget::~UIHelpBrowserWidget()
    1877 {
    1878     cleanup();
    1879 }
    1880 
    1881 QList<QMenu*> UIHelpBrowserWidget::menus() const
    1882 {
    1883     QList<QMenu*> menuList;
    1884     menuList
    1885         << m_pFileMenu
    1886         << m_pViewMenu
    1887         << m_pTabsMenu;
    1888     return menuList;
    1889 }
    1890 
    1891 void UIHelpBrowserWidget::showHelpForKeyword(const QString &strKeyword)
    1892 {
    1893     if (m_fIndexingFinished)
    1894         findAndShowUrlForKeyword(strKeyword);
    1895     else
    1896         m_keywordList.append(strKeyword);
    1897 }
    1898 
    1899 bool UIHelpBrowserWidget::shouldBeMaximized() const
    1900 {
    1901     return gEDataManager->logWindowShouldBeMaximized();
    1902 }
    1903 
    1904 void UIHelpBrowserWidget::prepare()
    1905 {
    1906     m_pMainLayout = new QVBoxLayout(this);
    1907     m_pMainLayout->setContentsMargins(0.2 * qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
    1908                                       qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin),
    1909                                       0.2 * qApp->style()->pixelMetric(QStyle::PM_LayoutRightMargin),
    1910                                       0.2 * qApp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin));
    1911 
    1912     AssertReturnVoid(m_pMainLayout);
    1913 
    1914     prepareActions();
    1915     prepareMenu();
    1916     prepareWidgets();
    1917     prepareSearchWidgets();
    1918     loadBookmarks();
    1919     retranslateUi();
    1920 }
    1921 
    1922 void UIHelpBrowserWidget::prepareActions()
    1923 {
    1924     m_pShowHideSideBarAction = new QAction(this);
    1925     m_pShowHideSideBarAction->setCheckable(true);
    1926     m_pShowHideSideBarAction->setChecked(true);
    1927     connect(m_pShowHideSideBarAction, &QAction::toggled,
    1928             this, &UIHelpBrowserWidget::sltHandleWidgetVisibilityToggle);
    1929 
    1930     m_pShowHideToolBarAction = new QAction(this);
    1931     m_pShowHideToolBarAction->setCheckable(true);
    1932     m_pShowHideToolBarAction->setChecked(true);
    1933     connect(m_pShowHideToolBarAction, &QAction::toggled,
    1934             this, &UIHelpBrowserWidget::sltHandleWidgetVisibilityToggle);
    1935 
    1936     m_pShowHideFontScaleWidgetAction = new QAction(this);
    1937     m_pShowHideFontScaleWidgetAction->setCheckable(true);
    1938     m_pShowHideFontScaleWidgetAction->setChecked(true);
    1939     connect(m_pShowHideFontScaleWidgetAction, &QAction::toggled,
    1940             this, &UIHelpBrowserWidget::sltHandleWidgetVisibilityToggle);
    1941 
    1942     m_pShowHideStatusBarAction = new QAction(this);
    1943     m_pShowHideStatusBarAction->setCheckable(true);
    1944     m_pShowHideStatusBarAction->setChecked(true);
    1945     connect(m_pShowHideStatusBarAction, &QAction::toggled,
    1946             this, &UIHelpBrowserWidget::sltHandleWidgetVisibilityToggle);
    1947 
    1948 
    1949     m_pPrintAction = new QAction(this);
    1950     connect(m_pPrintAction, &QAction::triggered,
    1951             this, &UIHelpBrowserWidget::sltShowPrintDialog);
    1952 
    1953     m_pCloseDialogAction = new QAction(this);
    1954     connect(m_pCloseDialogAction, &QAction::triggered,
    1955             this, &UIHelpBrowserWidget::sigCloseDialog);
    1956 
    1957     /* For size control actions: */
    1958     m_pFontSizeLargerAction = new QAction(this);
    1959     m_pFontSizeLargerAction->setIcon(UIIconPool::iconSet(":/help_browser_plus_32px.png"));
    1960 
    1961     m_pFontSizeSmallerAction = new QAction(this);
    1962     m_pFontSizeSmallerAction->setIcon(UIIconPool::iconSet(":/help_browser_minus_32px.png"));
    1963 
    1964     m_pFontSizeResetAction = new QAction(this);
    1965     m_pFontSizeResetAction->setIcon(UIIconPool::iconSet(":/help_browser_reset_32px.png"));
    1966 
    1967     connect(m_pFontSizeLargerAction, &QAction::triggered,
    1968             this, &UIHelpBrowserWidget::sltHandleFontSizeActions);
    1969     connect(m_pFontSizeSmallerAction, &QAction::triggered,
    1970             this, &UIHelpBrowserWidget::sltHandleFontSizeActions);
    1971     connect(m_pFontSizeResetAction, &QAction::triggered,
    1972             this, &UIHelpBrowserWidget::sltHandleFontSizeActions);
    1973 }
    1974 
    1975 void UIHelpBrowserWidget::prepareWidgets()
    1976 {
    1977     m_pSplitter = new QSplitter;
    1978     AssertReturnVoid(m_pSplitter);
    1979 
    1980     m_pMainLayout->addWidget(m_pSplitter);
    1981     m_pHelpEngine = new QHelpEngine(m_strHelpFilePath, this);
    1982     m_pBookmarksWidget = new UIBookmarksListContainer(this);
    1983     m_pTabWidget = new QITabWidget;
    1984     m_pTabManager = new UIHelpBrowserTabManager(m_pHelpEngine, findIndexHtml(), loadSavedUrlList());
    1985 
    1986     AssertReturnVoid(m_pTabWidget &&
    1987                      m_pHelpEngine &&
    1988                      m_pBookmarksWidget &&
    1989                      m_pTabManager);
    1990 
    1991     m_pContentWidget = m_pHelpEngine->contentWidget();
    1992     m_pIndexWidget = m_pHelpEngine->indexWidget();
    1993     m_pContentModel = m_pHelpEngine->contentModel();
    1994 
    1995     AssertReturnVoid(m_pContentWidget && m_pIndexWidget && m_pContentModel);
    1996     m_pSplitter->addWidget(m_pTabWidget);
    1997     m_pContentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    1998 
    1999     m_pTabWidget->insertTab(HelpBrowserTabs_TOC, m_pContentWidget, QString());
    2000     m_pTabWidget->insertTab(HelpBrowserTabs_Bookmarks, m_pBookmarksWidget, QString());
    2001     m_pTabWidget->insertTab(HelpBrowserTabs_Index, m_pIndexWidget, QString());
    2002 
    2003     m_pSplitter->addWidget(m_pTabManager);
    2004     m_pSplitter->setStretchFactor(0,0);
    2005     m_pSplitter->setStretchFactor(1,1);
    2006 
    2007     m_pSplitter->setChildrenCollapsible(false);
    2008 
    2009     connect(m_pTabManager, &UIHelpBrowserTabManager::sigSourceChanged,
    2010             this, &UIHelpBrowserWidget::sltHandleHelpBrowserViewerSourceChange);
    2011     connect(m_pTabManager, &UIHelpBrowserTabManager::sigAddBookmark,
    2012             this, &UIHelpBrowserWidget::sltAddNewBookmark);
    2013     connect(m_pTabManager, &UIHelpBrowserTabManager::sigTabsListChanged,
    2014             this, &UIHelpBrowserWidget::sltHandleTabListChanged);
    2015     connect(m_pTabManager, &UIHelpBrowserTabManager::currentChanged,
    2016             this, &UIHelpBrowserWidget::sltHandleCurrentTabChanged);
    2017     connect(m_pTabManager, &UIHelpBrowserTabManager::sigLinkHighlighted,
    2018             this, &UIHelpBrowserWidget::sigLinkHighlighted);
    2019 
    2020     connect(m_pHelpEngine, &QHelpEngine::setupFinished,
    2021             this, &UIHelpBrowserWidget::sltHandleHelpEngineSetupFinished);
    2022     connect(m_pContentWidget, &QHelpContentWidget::clicked,
    2023             this, &UIHelpBrowserWidget::sltHandleContentWidgetItemClicked);
    2024     connect(m_pContentModel, &QHelpContentModel::contentsCreated,
    2025             this, &UIHelpBrowserWidget::sltHandleContentsCreated);
    2026     connect(m_pContentWidget, &QHelpContentWidget::customContextMenuRequested,
    2027             this, &UIHelpBrowserWidget::sltShowLinksContextMenu);
    2028     connect(m_pBookmarksWidget, &UIBookmarksListContainer::sigBookmarkDoubleClick,
    2029             this, &UIHelpBrowserWidget::sltOpenLinkWithUrl);
    2030     connect(m_pBookmarksWidget, &UIBookmarksListContainer::sigListWidgetContextMenuRequest,
    2031             this, &UIHelpBrowserWidget::sltShowLinksContextMenu);
    2032 
    2033     if (QFile(m_strHelpFilePath).exists() && m_pHelpEngine)
    2034         m_pHelpEngine->setupData();
    2035 }
    2036 
    2037 void UIHelpBrowserWidget::prepareSearchWidgets()
    2038 {
    2039     AssertReturnVoid(m_pTabWidget && m_pHelpEngine);
    2040 
    2041     m_pSearchContainerWidget = new QWidget;
    2042     m_pTabWidget->insertTab(HelpBrowserTabs_Search, m_pSearchContainerWidget, QString());
    2043     m_pTabWidget->setTabPosition(QTabWidget::South);
    2044 
    2045 
    2046     m_pSearchEngine = m_pHelpEngine->searchEngine();
    2047     AssertReturnVoid(m_pSearchEngine);
    2048 
    2049     m_pSearchQueryWidget = m_pSearchEngine->queryWidget();
    2050     m_pSearchResultWidget = m_pSearchEngine->resultWidget();
    2051     AssertReturnVoid(m_pSearchQueryWidget && m_pSearchResultWidget);
    2052     m_pSearchResultWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    2053     m_pSearchQueryWidget->setCompactMode(false);
    2054 
    2055     QVBoxLayout *pSearchLayout = new QVBoxLayout(m_pSearchContainerWidget);
    2056     pSearchLayout->addWidget(m_pSearchQueryWidget);
    2057     pSearchLayout->addWidget(m_pSearchResultWidget);
    2058     m_pSearchQueryWidget->expandExtendedSearch();
    2059 
    2060     connect(m_pSearchQueryWidget, &QHelpSearchQueryWidget::search,
    2061             this, &UIHelpBrowserWidget::sltHandleSearchStart);
    2062     connect(m_pSearchResultWidget, &QHelpSearchResultWidget::requestShowLink,
    2063             this, &UIHelpBrowserWidget::sltOpenLinkWithUrl);
    2064     connect(m_pSearchResultWidget, &QHelpContentWidget::customContextMenuRequested,
    2065             this, &UIHelpBrowserWidget::sltShowLinksContextMenu);
    2066     connect(m_pSearchEngine, &QHelpSearchEngine::indexingStarted,
    2067             this, &UIHelpBrowserWidget::sltHandleIndexingStarted);
    2068     connect(m_pSearchEngine, &QHelpSearchEngine::indexingFinished,
    2069             this, &UIHelpBrowserWidget::sltHandleIndexingFinished);
    2070     connect(m_pSearchEngine, &QHelpSearchEngine::searchingStarted,
    2071             this, &UIHelpBrowserWidget::sltHandleSearchingStarted);
    2072 
    2073     m_pSearchEngine->reindexDocumentation();
    2074 }
    2075 
    2076 void UIHelpBrowserWidget::prepareToolBar()
    2077 {
    2078     m_pTopLayout = new QHBoxLayout;
    2079     m_pToolBar = new QIToolBar(parentWidget());
    2080     if (m_pToolBar)
    2081     {
    2082         m_pToolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
    2083         const int iIconMetric = (int)(QApplication::style()->pixelMetric(QStyle::PM_LargeIconSize));
    2084         m_pToolBar->setIconSize(QSize(iIconMetric, iIconMetric));
    2085 
    2086 #ifdef VBOX_WS_MAC
    2087         /* Check whether we are embedded into a stack: */
    2088         if (m_enmEmbedding == EmbedTo_Stack)
    2089         {
    2090             /* Add into layout: */
    2091             m_pTopLayout->addWidget(m_pToolBar);
    2092             m_pMainLayout->addLayout(m_pTopLayout);
    2093         }
    2094 #else
    2095         /* Add into layout: */
    2096         m_pTopLayout->addWidget(m_pToolBar);
    2097         m_pMainLayout->addLayout(m_pTopLayout);
    2098 #endif
    2099     }
    2100 }
    2101 
    2102 void UIHelpBrowserWidget::prepareMenu()
    2103 {
    2104     m_pFileMenu = new QMenu(tr("File"), this);
    2105     m_pViewMenu = new QMenu(tr("View"), this);
    2106     m_pTabsMenu = new QMenu(tr("Tabs"), this);
    2107 
    2108     AssertReturnVoid(m_pFileMenu && m_pViewMenu && m_pTabsMenu);
    2109 
    2110     if (m_pPrintAction)
    2111         m_pFileMenu->addAction(m_pPrintAction);
    2112     if (m_pCloseDialogAction)
    2113         m_pFileMenu->addAction(m_pCloseDialogAction);
    2114 
    2115     if (m_pFontSizeLargerAction)
    2116         m_pViewMenu->addAction(m_pFontSizeLargerAction);
    2117     if (m_pFontSizeSmallerAction)
    2118         m_pViewMenu->addAction(m_pFontSizeSmallerAction);
    2119     if (m_pFontSizeResetAction)
    2120         m_pViewMenu->addAction(m_pFontSizeResetAction);
    2121     m_pViewMenu->addSeparator();
    2122     if (m_pShowHideSideBarAction)
    2123         m_pViewMenu->addAction(m_pShowHideSideBarAction);
    2124     if (m_pShowHideToolBarAction)
    2125         m_pViewMenu->addAction(m_pShowHideToolBarAction);
    2126     if (m_pShowHideFontScaleWidgetAction)
    2127         m_pViewMenu->addAction(m_pShowHideFontScaleWidgetAction);
    2128     if (m_pShowHideStatusBarAction)
    2129         m_pViewMenu->addAction(m_pShowHideStatusBarAction);
    2130 }
    2131 
    2132 void UIHelpBrowserWidget::loadOptions()
    2133 {
    2134 }
    2135 
    2136 QStringList UIHelpBrowserWidget::loadSavedUrlList()
    2137 {
    2138     return gEDataManager->helpBrowserLastUrlList();
    2139 }
    2140 
    2141 void UIHelpBrowserWidget::loadBookmarks()
    2142 {
    2143     if (!m_pBookmarksWidget)
    2144         return;
    2145 
    2146     QStringList bookmarks = gEDataManager->helpBrowserBookmarks();
    2147     /* bookmarks list is supposed to have url title pair: */
    2148     for (int i = 0; i < bookmarks.size(); ++i)
    2149     {
    2150         const QString &url = bookmarks[i];
    2151         if (i+1 >= bookmarks.size())
    2152             break;
    2153         ++i;
    2154         const QString &strTitle = bookmarks[i];
    2155         m_pBookmarksWidget->addBookmark(url, strTitle);
    2156     }
    2157 }
    2158 
    2159 void UIHelpBrowserWidget::saveBookmarks()
    2160 {
    2161     if (!m_pBookmarksWidget)
    2162         return;
    2163     gEDataManager->setHelpBrowserBookmarks(m_pBookmarksWidget->bookmarks());
    2164 }
    2165 
    2166 void UIHelpBrowserWidget::saveOptions()
    2167 {
    2168     if (m_pTabManager)
    2169         gEDataManager->setHelpBrowserLastUrlList(m_pTabManager->tabUrlList());
    2170 }
    2171 
    2172 QUrl UIHelpBrowserWidget::findIndexHtml() const
    2173 {
    2174     QList<QUrl> files = m_pHelpEngine->files(m_pHelpEngine->namespaceName(m_strHelpFilePath), QStringList());
    2175     int iIndex = -1;
    2176     for (int i = 0; i < files.size(); ++i)
    2177     {
    2178         if (files[i].toString().contains("index.html", Qt::CaseInsensitive))
    2179         {
    2180             iIndex = i;
    2181             break;
    2182         }
    2183     }
    2184     if (iIndex == -1)
    2185     {
    2186         /* If index html/htm could not be found try to find a html file at least: */
    2187         for (int i = 0; i < files.size(); ++i)
    2188         {
    2189             if (files[i].toString().contains(".html", Qt::CaseInsensitive) ||
    2190                 files[i].toString().contains(".htm", Qt::CaseInsensitive))
    2191             {
    2192                 iIndex = i;
    2193                 break;
    2194             }
    2195         }
    2196     }
    2197     if (iIndex != -1 && files.size() > iIndex)
    2198         return files[iIndex];
    2199     else
    2200         return QUrl();
    2201 }
    2202 
    2203 QUrl UIHelpBrowserWidget::contentWidgetUrl(const QModelIndex &itemIndex)
    2204 {
    2205     QHelpContentModel *pContentModel =
    2206         qobject_cast<QHelpContentModel*>(m_pContentWidget->model());
    2207     if (!pContentModel)
    2208         return QUrl();
    2209     QHelpContentItem *pItem = pContentModel->contentItemAt(itemIndex);
    2210     if (!pItem)
    2211         return QUrl();
    2212     return pItem->url();
    2213 }
    2214 
    2215 void UIHelpBrowserWidget::cleanup()
    2216 {
    2217     saveOptions();
    2218     saveBookmarks();
    2219 }
    2220 
    2221 void UIHelpBrowserWidget::retranslateUi()
    2222 {
    2223     /* Translate toolbar: */
    2224 #ifdef VBOX_WS_MAC
    2225     // WORKAROUND:
    2226     // There is a bug in Qt Cocoa which result in showing a "more arrow" when
    2227     // the necessary size of the toolbar is increased. Also for some languages
    2228     // the with doesn't match if the text increase. So manually adjust the size
    2229     // after changing the text. */
    2230     if (m_pToolBar)
    2231         m_pToolBar->updateLayout();
    2232 #endif
    2233     if (m_pTabWidget)
    2234     {
    2235         m_pTabWidget->setTabText(HelpBrowserTabs_TOC, tr("Contents"));
    2236         m_pTabWidget->setTabText(HelpBrowserTabs_Index, tr("Index"));
    2237         m_pTabWidget->setTabText(HelpBrowserTabs_Search, tr("Search"));
    2238         m_pTabWidget->setTabText(HelpBrowserTabs_Bookmarks, tr("Bookmarks"));
    2239     }
    2240 
    2241     if (m_pShowHideSideBarAction)
    2242         m_pShowHideSideBarAction->setText(tr("Show Side Bar"));
    2243     if (m_pShowHideToolBarAction)
    2244         m_pShowHideToolBarAction->setText(tr("Show Tool Bar"));
    2245     if (m_pShowHideFontScaleWidgetAction)
    2246         m_pShowHideFontScaleWidgetAction->setText(tr("Show Font Scale Widget"));
    2247     if (m_pShowHideStatusBarAction)
    2248         m_pShowHideStatusBarAction->setText(tr("Show Status Bar"));
    2249 
    2250 
    2251     if (m_pPrintAction)
    2252         m_pPrintAction->setText(tr("Print..."));
    2253     if (m_pCloseDialogAction)
    2254         m_pCloseDialogAction->setText(tr("Close"));
    2255 
    2256     if (m_pFontSizeLargerAction)
    2257         m_pFontSizeLargerAction->setText(tr("Increase Font Size"));
    2258     if (m_pFontSizeSmallerAction)
    2259         m_pFontSizeSmallerAction->setText(tr("Decrease Font Size"));
    2260     if (m_pFontSizeResetAction)
    2261         m_pFontSizeResetAction->setText(tr("Reset Font Size"));
    2262 }
    2263 
    2264 
    2265 void UIHelpBrowserWidget::showEvent(QShowEvent *pEvent)
    2266 {
    2267     QWidget::showEvent(pEvent);
    2268    if (m_fIsPolished)
    2269         return;
    2270     m_fIsPolished = true;
    2271 }
    2272 
    2273 void UIHelpBrowserWidget::keyPressEvent(QKeyEvent *pEvent)
    2274 {
    2275    QWidget::keyPressEvent(pEvent);
    2276 }
    2277 
    2278 void UIHelpBrowserWidget::findAndShowUrlForKeyword(const QString &strKeyword)
    2279 {
    2280     QMap<QString, QUrl> map = m_pHelpEngine->linksForIdentifier(strKeyword);
    2281     if (!map.isEmpty())
    2282     {
    2283         /* We have to a have a single url per keyword in this case: */
    2284         QUrl keywordUrl = map.first();
    2285         m_pTabManager->setSource(keywordUrl, true /* new tab */);
    2286     }
    2287 }
    2288 
    2289 void UIHelpBrowserWidget::sltHandleWidgetVisibilityToggle(bool fToggled)
    2290 {
    2291     if (sender() == m_pShowHideSideBarAction)
    2292     {
    2293         if (m_pTabWidget)
    2294             m_pTabWidget->setVisible(fToggled);
    2295     }
    2296     else if (sender() == m_pShowHideToolBarAction)
    2297     {
    2298         if (m_pTabManager)
    2299             m_pTabManager->setToolBarVisible(fToggled);
    2300     }
    2301     else if (sender() == m_pShowHideFontScaleWidgetAction)
    2302     {
    2303         if (m_pTabManager)
    2304             m_pTabManager->setFontScaleWidgetVisible(fToggled);
    2305     }
    2306     else if (sender() == m_pShowHideStatusBarAction)
    2307         emit sigStatusBarVisible(fToggled);
    2308 }
    2309 
    2310 void UIHelpBrowserWidget::sltShowPrintDialog()
    2311 {
    2312     if (!m_pTabManager)
    2313         return;
    2314     QPrinter printer;
    2315     QPrintDialog printDialog(&printer, this);
    2316     if (printDialog.exec() == QDialog::Accepted)
    2317         m_pTabManager->printCurrent(printer);
    2318 }
    2319 
    2320 void UIHelpBrowserWidget::sltHandleHelpEngineSetupFinished()
    2321 {
    2322     AssertReturnVoid(m_pTabManager);
    2323     m_fIndexingFinished = true;
    2324     m_pTabManager->initializeTabs();
    2325 }
    2326 
    2327 void UIHelpBrowserWidget::sltHandleContentWidgetItemClicked(const QModelIndex & index)
    2328 {
    2329     AssertReturnVoid(m_pTabManager && m_pHelpEngine && m_pContentWidget);
    2330     QUrl url = contentWidgetUrl(index);
    2331     if (!url.isValid())
    2332         return;
    2333     m_pTabManager->setSource(url);
    2334 
    2335     m_pContentWidget->scrollTo(index, QAbstractItemView::EnsureVisible);
    2336     m_pContentWidget->expand(index);
    2337 }
    2338 
    2339 void UIHelpBrowserWidget::sltHandleHelpBrowserViewerSourceChange(const QUrl &source)
    2340 {
    2341     if (m_fModelContentCreated && m_pContentWidget && source.isValid() && m_pContentModel)
    2342     {
    2343         QModelIndex index = m_pContentWidget->indexOf(source);
    2344         QItemSelectionModel *pSelectionModel = m_pContentWidget->selectionModel();
    2345         if (pSelectionModel && index.isValid())
    2346         {
    2347             m_pContentWidget->blockSignals(true);
    2348             pSelectionModel->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
    2349             m_pContentWidget->scrollTo(index, QAbstractItemView::EnsureVisible);
    2350             m_pContentWidget->expand(index);
    2351             m_pContentWidget->blockSignals(false);
    2352         }
    2353     }
    2354 }
    2355 
    2356 void UIHelpBrowserWidget::sltHandleContentsCreated()
    2357 {
    2358     m_fModelContentCreated = true;
    2359     if (m_pTabManager)
    2360         sltHandleHelpBrowserViewerSourceChange(m_pTabManager->currentSource());
    2361 }
    2362 
    2363 void UIHelpBrowserWidget::sltHandleIndexingStarted()
    2364 {
    2365     if (m_pSearchContainerWidget)
    2366         m_pSearchContainerWidget->setEnabled(false);
    2367 }
    2368 
    2369 void UIHelpBrowserWidget::sltHandleIndexingFinished()
    2370 {
    2371     AssertReturnVoid(m_pTabManager &&
    2372                      m_pHelpEngine &&
    2373                      m_pSearchContainerWidget);
    2374 
    2375     m_pSearchContainerWidget->setEnabled(true);
    2376     m_fIndexingFinished = true;
    2377     /* Process the keyword queue. */
    2378     foreach (const QString strKeyword, m_keywordList)
    2379         findAndShowUrlForKeyword(strKeyword);
    2380     m_keywordList.clear();
    2381 
    2382 }
    2383 
    2384 void UIHelpBrowserWidget::sltHandleSearchingStarted()
    2385 {
    2386 }
    2387 
    2388 void UIHelpBrowserWidget::sltHandleSearchStart()
    2389 {
    2390     AssertReturnVoid(m_pSearchEngine && m_pSearchQueryWidget);
    2391     m_pSearchEngine->search(m_pSearchQueryWidget->searchInput());
    2392 }
    2393 
    2394 void UIHelpBrowserWidget::sltShowLinksContextMenu(const QPoint &pos)
    2395 {
    2396     QWidget *pSender = qobject_cast<QWidget*>(sender());
    2397     if (!pSender)
    2398         return;
    2399 
    2400     QUrl url;
    2401     if (pSender == m_pContentWidget)
    2402         url = contentWidgetUrl(m_pContentWidget->currentIndex());
    2403     else if (pSender == m_pSearchResultWidget)
    2404     {
    2405         QTextBrowser* browser = m_pSearchResultWidget->findChild<QTextBrowser*>();
    2406         if (!browser)
    2407             return;
    2408         QPoint browserPos = browser->mapFromGlobal(m_pSearchResultWidget->mapToGlobal(pos));
    2409         url = browser->anchorAt(browserPos);
    2410     }
    2411     else if (pSender == m_pBookmarksWidget)
    2412     {
    2413         /* Assuming that only the UIBookmarksListWidget under the m_pBookmarksWidget sends the context menu request: */
    2414         UIBookmarksListWidget *pListWidget = m_pBookmarksWidget->findChild<UIBookmarksListWidget*>();
    2415         if (!pListWidget)
    2416             return;
    2417         url = m_pBookmarksWidget->currentBookmarkUrl();
    2418     }
    2419     else
    2420         return;
    2421 
    2422     if (!url.isValid())
    2423         return;
    2424 
    2425     QMenu menu;
    2426     QAction *pOpen = menu.addAction(tr("Open in Link"));
    2427     QAction *pOpenInNewTab = menu.addAction(tr("Open in Link New Tab"));
    2428     QAction *pCopyLink = menu.addAction(tr("Copy Link"));
    2429 
    2430     pOpen->setData(url);
    2431     pOpenInNewTab->setData(url);
    2432     pCopyLink->setData(url);
    2433 
    2434     connect(pOpenInNewTab, &QAction::triggered, this, &UIHelpBrowserWidget::sltOpenLinkInNewTab);
    2435     connect(pOpen, &QAction::triggered, this, &UIHelpBrowserWidget::sltOpenLink);
    2436     connect(pCopyLink, &QAction::triggered, this, &UIHelpBrowserWidget::sltCopyLink);
    2437 
    2438     if (pSender == m_pBookmarksWidget)
    2439     {
    2440         menu.addSeparator();
    2441         QAction *pDeleteBookmark = menu.addAction(tr("Delete Bookmark"));
    2442         connect(pDeleteBookmark, &QAction::triggered, m_pBookmarksWidget, &UIBookmarksListContainer::sltDeleteSelectedBookmark);
    2443     }
    2444 
    2445     menu.exec(pSender->mapToGlobal(pos));
    2446 }
    2447 
    2448 void UIHelpBrowserWidget::sltOpenLinkInNewTab()
    2449 {
    2450     openLinkSlotHandler(sender(), true);
    2451 }
    2452 
    2453 void UIHelpBrowserWidget::sltOpenLink()
    2454 {
    2455     openLinkSlotHandler(sender(), false);
    2456 }
    2457 
    2458 void UIHelpBrowserWidget::sltCopyLink()
    2459 {
    2460     QAction *pAction = qobject_cast<QAction*>(sender());
    2461     if (!pAction)
    2462         return;
    2463     QUrl url = pAction->data().toUrl();
    2464     if (url.isValid())
    2465     {
    2466         QClipboard *pClipboard = QApplication::clipboard();
    2467         if (pClipboard)
    2468             pClipboard->setText(url.toString());
    2469     }
    2470 }
    2471 
    2472 void UIHelpBrowserWidget::sltAddNewBookmark(const QUrl &url, const QString &strTitle)
    2473 {
    2474     if (m_pBookmarksWidget)
    2475         m_pBookmarksWidget->addBookmark(url, strTitle);
    2476 }
    2477 
    2478 void UIHelpBrowserWidget::openLinkSlotHandler(QObject *pSenderObject, bool fOpenInNewTab)
    2479 {
    2480     QAction *pAction = qobject_cast<QAction*>(pSenderObject);
    2481     if (!pAction)
    2482         return;
    2483     QUrl url = pAction->data().toUrl();
    2484     if (m_pTabManager && url.isValid())
    2485         m_pTabManager->setSource(url, fOpenInNewTab);
    2486 }
    2487 
    2488 void UIHelpBrowserWidget::updateTabsMenu(const QStringList &titles)
    2489 {
    2490     if (!m_pTabsMenu)
    2491         return;
    2492     m_pTabsMenu->clear();
    2493 
    2494     QAction *pCloseTabAction = m_pTabsMenu->addAction(tr("Close Tab"));
    2495     QAction *pCloseOtherTabsAction = m_pTabsMenu->addAction(tr("Close Other Tabs"));
    2496 
    2497     pCloseTabAction->setEnabled(titles.size() > 1);
    2498     pCloseOtherTabsAction->setEnabled(titles.size() > 1);
    2499 
    2500     connect(pCloseTabAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltHandleCloseCurrentTab);
    2501     connect(pCloseOtherTabsAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltHandleCloseOtherTabs);
    2502 
    2503     m_pTabsMenu->addSeparator();
    2504 
    2505     for (int i = 0; i < titles.size(); ++i)
    2506     {
    2507         QAction *pAction = m_pTabsMenu->addAction(titles[i]);
    2508         pAction->setData(i);
    2509         connect(pAction, &QAction::triggered, this, &UIHelpBrowserWidget::sltHandleTabChoose);
    2510     }
    2511     if (m_pTabManager)
    2512         sltHandleCurrentTabChanged(m_pTabManager->currentIndex());
    2513 }
    2514 
    2515 void UIHelpBrowserWidget::sltOpenLinkWithUrl(const QUrl &url)
    2516 {
    2517     if (m_pTabManager && url.isValid())
    2518         m_pTabManager->setSource(url, false);
    2519 }
    2520 
    2521 void UIHelpBrowserWidget::sltHandleFontSizeActions()
    2522 {
    2523     if (!sender() || !m_pTabManager)
    2524         return;
    2525     int iFontPointSize = m_pTabManager->fontPointSize();
    2526     if (sender() == m_pFontSizeResetAction)
    2527         iFontPointSize = m_pTabManager->initialFontPointSize();
    2528     else if (sender() == m_pFontSizeLargerAction)
    2529         iFontPointSize += iFontPointSizeChangeStep;
    2530     else if (sender() == m_pFontSizeSmallerAction)
    2531         iFontPointSize -= iFontPointSizeChangeStep;
    2532 
    2533     if (iFontPointSize >= fontScaleMinMax.second * m_pTabManager->initialFontPointSize() ||
    2534         iFontPointSize <= fontScaleMinMax.first * m_pTabManager->initialFontPointSize())
    2535         return;
    2536     m_pTabManager->setFontPointSize(iFontPointSize);
    2537 }
    2538 
    2539 void UIHelpBrowserWidget::sltHandleTabListChanged(const QStringList &titleList)
    2540 {
    2541     updateTabsMenu(titleList);
    2542 }
    2543 
    2544 void UIHelpBrowserWidget::sltHandleTabChoose()
    2545 {
    2546     QAction *pAction = qobject_cast<QAction*>(sender());
    2547     if (!pAction)
    2548         return;
    2549     int iIndex = pAction->data().toInt();
    2550     if (m_pTabManager)
    2551         m_pTabManager->switchToTab(iIndex);
    2552 }
    2553 
    2554 void UIHelpBrowserWidget::sltHandleCurrentTabChanged(int iIndex)
    2555 {
    2556     Q_UNUSED(iIndex);
    2557     if (!m_pTabsMenu)
    2558         return;
    2559 
    2560     /** Mark the action with iIndex+3 by assigning an icon to it. it is iIndex+3 and not iIndex since we have
    2561       * two additional (close tab, close other tabs and a separator) action on top of the tab selection actions: */
    2562     QList<QAction*> list = m_pTabsMenu->actions();
    2563     for (int i = 0; i < list.size(); ++i)
    2564         list[i]->setIcon(QIcon());
    2565     if (iIndex+3 >= list.size())
    2566         return;
    2567     list[iIndex+3]->setIcon(UIIconPool::iconSet(":/help_browser_star_16px.png"));
    2568 }
    2569 
    2570 
    2571 #include "UIHelpBrowserWidget.moc"
     664#include "UIHelpBrowserViewer.moc"
    2572665
    2573666#endif /*#if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))*/
  • trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpBrowserViewer.h

    r87156 r87157  
    1616 */
    1717
    18 #ifndef FEQT_INCLUDED_SRC_helpbrowser_UIHelpBrowserWidget_h
    19 #define FEQT_INCLUDED_SRC_helpbrowser_UIHelpBrowserWidget_h
     18#ifndef FEQT_INCLUDED_SRC_helpbrowser_UIHelpBrowserViewer_h
     19#define FEQT_INCLUDED_SRC_helpbrowser_UIHelpBrowserViewer_h
    2020#ifndef RT_WITHOUT_PRAGMA_ONCE
    2121# pragma once
     
    2626#include <QKeySequence>
    2727#include <QPair>
     28#include <QTextBrowser>
    2829#include <QWidget>
    2930
     
    5556class UIBookmarksListContainer;
    5657class UIDialogPanel;
     58class UIFindInPageWidget;
    5759class UIHelpBrowserTabManager;
    5860
    5961#if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
    60 class SHARED_LIBRARY_STUFF UIHelpBrowserWidget  : public QIWithRetranslateUI<QWidget>
     62class UIHelpBrowserViewer : public QIWithRetranslateUI<QTextBrowser>
    6163{
    6264    Q_OBJECT;
     
    6466signals:
    6567
    66     void sigCloseDialog();
    67     void sigLinkHighlighted(const QString &strLink);
    68     void sigStatusBarVisible(bool fToggled);
     68    void sigOpenLinkInNewTab(const QUrl &url);
     69    void sigCloseFindInPageWidget();
     70    void sigFontPointSizeChanged(int iFontPointSize);
     71    void sigGoBackward();
     72    void sigGoForward();
     73    void sigGoHome();
     74    void sigAddBookmark();
    6975
    7076public:
    7177
    72     UIHelpBrowserWidget(EmbedTo enmEmbedding, const QString &strHelpFilePath, QWidget *pParent = 0);
    73     ~UIHelpBrowserWidget();
    74     QList<QMenu*> menus() const;
    75     void showHelpForKeyword(const QString &strKeyword);
    76 #ifdef VBOX_WS_MAC
    77     QIToolBar *toolbar() const { return m_pToolBar; }
    78 #endif
     78    UIHelpBrowserViewer(const QHelpEngine *pHelpEngine, QWidget *pParent = 0);
     79    virtual QVariant loadResource(int type, const QUrl &name) /* override */;
     80    void emitHistoryChangedSignal();
     81    void setSource(const QUrl &url) /* override */;
     82    void toggleFindInPageWidget(bool fVisible);
     83    int initialFontPointSize() const;
     84    void setFont(const QFont &);
     85
     86public slots:
    7987
    8088
    8189protected:
    8290
    83     /** Returns whether the window should be maximized when geometry being restored. */
    84     virtual bool shouldBeMaximized() const /* override */;
     91    virtual void contextMenuEvent(QContextMenuEvent *event) /* override */;
     92    virtual void resizeEvent(QResizeEvent *pEvent) /* override */;
     93    virtual void wheelEvent(QWheelEvent *pEvent) /* override */;
    8594
    8695private slots:
    8796
    88     void sltHandleHelpEngineSetupFinished();
    89     void sltHandleContentWidgetItemClicked(const QModelIndex &index);
    90     void sltHandleWidgetVisibilityToggle(bool togggled);
    91     void sltShowPrintDialog();
    92     void sltHandleContentsCreated();
    93     void sltHandleIndexingStarted();
    94     void sltHandleIndexingFinished();
    95     void sltHandleSearchingStarted();
    96     void sltHandleSearchStart();
    97     void sltHandleHelpBrowserViewerSourceChange(const QUrl &source);
    98     void sltOpenLinkWithUrl(const QUrl &url);
    99     void sltShowLinksContextMenu(const QPoint &pos);
    100     void sltOpenLinkInNewTab();
    101     void sltOpenLink();
    102     void sltCopyLink();
    103     void sltAddNewBookmark(const QUrl &url, const QString &strTitle);
    104     void sltHandleFontSizeActions();
    105     void sltHandleTabListChanged(const QStringList &titleList);
    106     void sltHandleTabChoose();
    107     void sltHandleCurrentTabChanged(int iIndex);
     97    void sltHandleOpenLinkInNewTab();
     98    void sltHandleOpenLink();
     99    void sltHandleCopyLink();
     100    void sltHandleFindWidgetDrag(const QPoint &delta);
     101    void sltHandleFindInPageSearchTextChange(const QString &strSearchText);
     102    void sltSelectPreviousMatch();
     103    void sltSelectNextMatch();
    108104
    109105private:
    110106
    111     void prepare();
    112     void prepareActions();
    113     void prepareWidgets();
    114     void prepareSearchWidgets();
    115     void prepareToolBar();
    116     void prepareMenu();
    117     void loadOptions();
    118     QStringList loadSavedUrlList();
    119     /** Bookmark list is save as url-title pairs. */
    120     void loadBookmarks();
    121     void saveBookmarks();
    122     void saveOptions();
    123     void cleanup();
    124     QUrl findIndexHtml() const;
    125     /* Returns the url of the item with @p itemIndex. */
    126     QUrl contentWidgetUrl(const QModelIndex &itemIndex);
    127     void openLinkSlotHandler(QObject *pSenderObject, bool fOpenInNewTab);
    128     void updateTabsMenu(const QStringList &titleList);
    129 
    130     /** @name Event handling stuff.
    131      * @{ */
    132     /** Handles translation event. */
    133        virtual void retranslateUi() /* override */;
    134 
    135        /** Handles Qt show @a pEvent. */
    136        virtual void showEvent(QShowEvent *pEvent) /* override */;
    137        /** Handles Qt key-press @a pEvent. */
    138        virtual void keyPressEvent(QKeyEvent *pEvent) /* override */;
    139     /** @} */
    140     /* Looks for Url for the keyword using QHelpEngine API and shows it in a new tab whne successful. */
    141     void findAndShowUrlForKeyword(const QString &strKeyword);
    142 
    143     /** Holds the widget's embedding type. */
    144     const EmbedTo m_enmEmbedding;
    145     UIActionPool *m_pActionPool;
    146     bool m_fIsPolished;
    147 
    148     QVBoxLayout         *m_pMainLayout;
    149     QHBoxLayout         *m_pTopLayout;
    150     /** Container tab widget for content, index, bookmark widgets. Sits on a side bar. */
    151     QITabWidget *m_pTabWidget;
    152 
    153     /** @name Toolbar and menu variables.
    154      * @{ */
    155        QIToolBar *m_pToolBar;
    156     /** @} */
    157 
    158     QString       m_strHelpFilePath;
    159     /** Start the browser with this keyword. When not empty widget is shown `only` with html viewer and single tab.*/
    160     QHelpEngine  *m_pHelpEngine;
    161     QSplitter           *m_pSplitter;
    162     QMenu               *m_pFileMenu;
    163     QMenu               *m_pViewMenu;
    164     QMenu               *m_pTabsMenu;
    165     QHelpContentWidget  *m_pContentWidget;
    166     QHelpIndexWidget    *m_pIndexWidget;
    167     QHelpContentModel   *m_pContentModel;
    168     QHelpSearchEngine   *m_pSearchEngine;
    169     QHelpSearchQueryWidget *m_pSearchQueryWidget;
    170     QHelpSearchResultWidget  *m_pSearchResultWidget;
    171     UIHelpBrowserTabManager  *m_pTabManager;
    172     UIBookmarksListContainer *m_pBookmarksWidget;
    173     QWidget             *m_pSearchContainerWidget;
    174     QAction             *m_pPrintAction;
    175     QAction             *m_pCloseDialogAction;
    176     QAction             *m_pShowHideSideBarAction;
    177     QAction             *m_pShowHideToolBarAction;
    178     QAction             *m_pShowHideFontScaleWidgetAction;
    179     QAction             *m_pShowHideStatusBarAction;
    180     QAction             *m_pFontSizeLargerAction;
    181     QAction             *m_pFontSizeSmallerAction;
    182     QAction             *m_pFontSizeResetAction;
    183 
    184     /* This is set t true when handling QHelpContentModel::contentsCreated signal. */
    185     bool                 m_fModelContentCreated;
    186     bool                 m_fIndexingFinished;
    187     /** This queue is used in unlikely case where possibly several keywords are requested to be shown
    188       *  but indexing is not yet finished. In that case we queue the keywords and process them after
    189       * after indexing is finished. */
    190     QStringList          m_keywordList;
     107    void retranslateUi();
     108    bool isRectInside(const QRect &rect, int iMargin) const;
     109    void moveFindWidgetIn(int iMargin);
     110    void findAllMatches(const QString &searchString);
     111    void highlightFinds(int iSearchTermLength);
     112    void selectMatch(int iMatchIndex, int iSearchStringLength);
     113    const QHelpEngine* m_pHelpEngine;
     114    UIFindInPageWidget *m_pFindInPageWidget;
     115    /* Initilized as false and set to true once the user drag moves the find widget. */
     116    bool m_fFindWidgetDragged;
     117    const int m_iMarginForFindWidget;
     118    /** Document positions of the cursors within the document for all matches. */
     119    QVector<int>   m_matchedCursorPosition;
     120    int m_iSelectedMatchIndex;
     121    int m_iSearchTermLength;
     122    int m_iInitialFontPointSize;
    191123};
    192124
    193125#endif /* #if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)) */
    194 #endif /* !FEQT_INCLUDED_SRC_helpbrowser_UIHelpBrowserWidget_h */
     126#endif /* !FEQT_INCLUDED_SRC_helpbrowser_UIHelpBrowserViewer_h */
  • trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpBrowserWidget.cpp

    r87019 r87157  
    5858#include "UIActionPool.h"
    5959#include "UIExtraDataManager.h"
     60#include "UIHelpBrowserViewer.h"
    6061#include "UIHelpBrowserWidget.h"
    6162#include "UIIconPool.h"
     
    8081
    8182static const int iBookmarkUrlDataType = 6;
    82 static const QPair<float, float> fontScaleMinMax(0.5f, 3.f);
    8383static int iFontPointSizeChangeStep = 2;
    84 
    85 
    86 /*********************************************************************************************************************************
    87 *   UIContextMenuNavigationAction definition.                                                                                    *
    88 *********************************************************************************************************************************/
    89 class UIContextMenuNavigationAction : public QWidgetAction
    90 {
    91 
    92     Q_OBJECT;
    93 
    94 signals:
    95 
    96     void sigGoBackward();
    97     void sigGoForward();
    98     void sigGoHome();
    99     void sigAddBookmark();
    100 
    101 public:
    102 
    103     UIContextMenuNavigationAction(QObject *pParent = 0);
    104     void setBackwardAvailable(bool fAvailable);
    105     void setForwardAvailable(bool fAvailable);
    106 
    107 protected:
    108 
    109 
    110 private slots:
    111 
    112 
    113 private:
    114 
    115     void prepare();
    116     QIToolButton *m_pBackwardButton;
    117     QIToolButton *m_pForwardButton;
    118     QIToolButton *m_pHomeButton;
    119     QIToolButton *m_pAddBookmarkButton;
    120 };
     84const QPair<float, float> UIHelpBrowserWidget::fontScaleMinMax = QPair<float, float>(0.5f, 3.f);
    12185
    12286/*********************************************************************************************************************************
     
    224188    QVBoxLayout  *m_pMainLayout;
    225189    UIBookmarksListWidget  *m_pListWidget;
    226 };
    227 
    228 /*********************************************************************************************************************************
    229 *   UIFindInPageWidget definition.                                                                                        *
    230 *********************************************************************************************************************************/
    231 class UIFindInPageWidget : public QIWithRetranslateUI<QWidget>
    232 {
    233 
    234     Q_OBJECT;
    235 
    236 signals:
    237 
    238     void sigDragging(const QPoint &delta);
    239     void sigSearchTextChanged(const QString &strSearchText);
    240     void sigSelectNextMatch();
    241     void sigSelectPreviousMatch();
    242     void sigClose();
    243 
    244 public:
    245 
    246     UIFindInPageWidget(QWidget *pParent = 0);
    247     void setMatchCountAndCurrentIndex(int iTotalMatchCount, int iCurrentlyScrolledIndex);
    248     void clearSearchField();
    249 
    250 protected:
    251 
    252     virtual bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */;
    253 
    254 private:
    255 
    256     void prepare();
    257     void retranslateUi();
    258     UISearchLineEdit  *m_pSearchLineEdit;
    259     QIToolButton      *m_pNextButton;
    260     QIToolButton      *m_pPreviousButton;
    261     QIToolButton      *m_pCloseButton;
    262     QLabel            *m_pDragMoveLabel;
    263     QPoint m_previousMousePosition;
    264 };
    265 
    266 /*********************************************************************************************************************************
    267 *   UIHelpBrowserViewer definition.                                                                                        *
    268 *********************************************************************************************************************************/
    269 
    270 class UIHelpBrowserViewer : public QIWithRetranslateUI<QTextBrowser>
    271 {
    272     Q_OBJECT;
    273 
    274 signals:
    275 
    276     void sigOpenLinkInNewTab(const QUrl &url);
    277     void sigCloseFindInPageWidget();
    278     void sigFontPointSizeChanged(int iFontPointSize);
    279     void sigGoBackward();
    280     void sigGoForward();
    281     void sigGoHome();
    282     void sigAddBookmark();
    283 
    284 public:
    285 
    286     UIHelpBrowserViewer(const QHelpEngine *pHelpEngine, QWidget *pParent = 0);
    287     virtual QVariant loadResource(int type, const QUrl &name) /* override */;
    288     void emitHistoryChangedSignal();
    289     void setSource(const QUrl &url) /* override */;
    290     void toggleFindInPageWidget(bool fVisible);
    291     int initialFontPointSize() const;
    292     void setFont(const QFont &);
    293 
    294 public slots:
    295 
    296 
    297 protected:
    298 
    299     virtual void contextMenuEvent(QContextMenuEvent *event) /* override */;
    300     virtual void resizeEvent(QResizeEvent *pEvent) /* override */;
    301     virtual void wheelEvent(QWheelEvent *pEvent) /* override */;
    302 
    303 private slots:
    304 
    305     void sltHandleOpenLinkInNewTab();
    306     void sltHandleOpenLink();
    307     void sltHandleCopyLink();
    308     void sltHandleFindWidgetDrag(const QPoint &delta);
    309     void sltHandleFindInPageSearchTextChange(const QString &strSearchText);
    310     void sltSelectPreviousMatch();
    311     void sltSelectNextMatch();
    312 
    313 private:
    314 
    315     void retranslateUi();
    316     bool isRectInside(const QRect &rect, int iMargin) const;
    317     void moveFindWidgetIn(int iMargin);
    318     void findAllMatches(const QString &searchString);
    319     void highlightFinds(int iSearchTermLength);
    320     void selectMatch(int iMatchIndex, int iSearchStringLength);
    321     const QHelpEngine* m_pHelpEngine;
    322     UIFindInPageWidget *m_pFindInPageWidget;
    323     /* Initilized as false and set to true once the user drag moves the find widget. */
    324     bool m_fFindWidgetDragged;
    325     const int m_iMarginForFindWidget;
    326     /** Document positions of the cursors within the document for all matches. */
    327     QVector<int>   m_matchedCursorPosition;
    328     int m_iSelectedMatchIndex;
    329     int m_iSearchTermLength;
    330     int m_iInitialFontPointSize;
    331190};
    332191
     
    475334
    476335/*********************************************************************************************************************************
    477 *   UIContextMenuNavigationAction implementation.                                                                                *
    478 *********************************************************************************************************************************/
    479 UIContextMenuNavigationAction::UIContextMenuNavigationAction(QObject *pParent /* = 0 */)
    480     :QWidgetAction(pParent)
    481     , m_pBackwardButton(0)
    482     , m_pForwardButton(0)
    483     , m_pHomeButton(0)
    484     , m_pAddBookmarkButton(0)
    485 {
    486     prepare();
    487 }
    488 
    489 void UIContextMenuNavigationAction::setBackwardAvailable(bool fAvailable)
    490 {
    491     if (m_pBackwardButton)
    492         m_pBackwardButton->setEnabled(fAvailable);
    493 }
    494 
    495 void UIContextMenuNavigationAction::setForwardAvailable(bool fAvailable)
    496 {
    497     if (m_pForwardButton)
    498         m_pForwardButton->setEnabled(fAvailable);
    499 }
    500 
    501 void UIContextMenuNavigationAction::prepare()
    502 {
    503     QWidget *pWidget = new QWidget;
    504     setDefaultWidget(pWidget);
    505     QHBoxLayout *pMainLayout = new QHBoxLayout(pWidget);
    506     AssertReturnVoid(pMainLayout);
    507 
    508     m_pBackwardButton = new QIToolButton;
    509     m_pForwardButton = new QIToolButton;
    510     m_pHomeButton = new QIToolButton;
    511     m_pAddBookmarkButton = new QIToolButton;
    512 
    513     AssertReturnVoid(m_pBackwardButton &&
    514                      m_pForwardButton &&
    515                      m_pHomeButton);
    516     m_pForwardButton->setEnabled(false);
    517     m_pBackwardButton->setEnabled(false);
    518     m_pHomeButton->setIcon(UIIconPool::iconSet(":/help_browser_home_32px.png"));
    519     m_pForwardButton->setIcon(UIIconPool::iconSet(":/help_browser_forward_32px.png", ":/help_browser_forward_disabled_32px.png"));
    520     m_pBackwardButton->setIcon(UIIconPool::iconSet(":/help_browser_backward_32px.png", ":/help_browser_backward_disabled_32px.png"));
    521     m_pAddBookmarkButton->setIcon(UIIconPool::iconSet(":/help_browser_add_bookmark.png"));
    522 
    523     pMainLayout->addWidget(m_pBackwardButton);
    524     pMainLayout->addWidget(m_pForwardButton);
    525     pMainLayout->addWidget(m_pHomeButton);
    526     pMainLayout->addWidget(m_pAddBookmarkButton);
    527     pMainLayout->setContentsMargins(0, 0, 0, 0);
    528     //pMainLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
    529 
    530     connect(m_pBackwardButton, &QIToolButton::pressed,
    531             this, &UIContextMenuNavigationAction::sigGoBackward);
    532     connect(m_pForwardButton, &QIToolButton::pressed,
    533             this, &UIContextMenuNavigationAction::sigGoForward);
    534     connect(m_pHomeButton, &QIToolButton::pressed,
    535             this, &UIContextMenuNavigationAction::sigGoHome);
    536     connect(m_pAddBookmarkButton, &QIToolButton::pressed,
    537             this, &UIContextMenuNavigationAction::sigAddBookmark);
    538 }
    539 
    540 
    541 /*********************************************************************************************************************************
    542336*   UIFontScaleWidget implementation.                                                                                            *
    543337*********************************************************************************************************************************/
     
    629423    else if (sender() == m_pResetButton)
    630424        iNewSize = m_iInitialFontPointSize;
    631     if (iNewSize >= fontScaleMinMax.second * m_iInitialFontPointSize ||
    632         iNewSize <= fontScaleMinMax.first * m_iInitialFontPointSize)
     425    if (iNewSize >= UIHelpBrowserWidget::fontScaleMinMax.second * m_iInitialFontPointSize ||
     426        iNewSize <= UIHelpBrowserWidget::fontScaleMinMax.first * m_iInitialFontPointSize)
    633427        iNewSize = m_iFontPointSize;
    634428    setFontPointSize(iNewSize);
     
    759553    }
    760554    return -1;
    761 }
    762 
    763 
    764 /*********************************************************************************************************************************
    765 *   UIFindInPageWidget implementation.                                                                                           *
    766 *********************************************************************************************************************************/
    767 UIFindInPageWidget::UIFindInPageWidget(QWidget *pParent /* = 0 */)
    768     : QIWithRetranslateUI<QWidget>(pParent)
    769     , m_pSearchLineEdit(0)
    770     , m_pNextButton(0)
    771     , m_pPreviousButton(0)
    772     , m_pCloseButton(0)
    773     , m_previousMousePosition(-1, -1)
    774 {
    775     prepare();
    776 }
    777 
    778 void UIFindInPageWidget::setMatchCountAndCurrentIndex(int iTotalMatchCount, int iCurrentlyScrolledIndex)
    779 {
    780     if (!m_pSearchLineEdit)
    781         return;
    782     m_pSearchLineEdit->setMatchCount(iTotalMatchCount);
    783     m_pSearchLineEdit->setScrollToIndex(iCurrentlyScrolledIndex);
    784 }
    785 
    786 void UIFindInPageWidget::clearSearchField()
    787 {
    788     if (!m_pSearchLineEdit)
    789         return;
    790     m_pSearchLineEdit->blockSignals(true);
    791     m_pSearchLineEdit->reset();
    792     m_pSearchLineEdit->blockSignals(false);
    793 }
    794 
    795 bool UIFindInPageWidget::eventFilter(QObject *pObject, QEvent *pEvent)
    796 {
    797     if (pObject == m_pDragMoveLabel)
    798     {
    799         if (pEvent->type() == QEvent::Enter)
    800             m_pDragMoveLabel->setCursor(Qt::CrossCursor);
    801         else if (pEvent->type() == QEvent::Leave)
    802         {
    803             if (parentWidget())
    804                 m_pDragMoveLabel->setCursor(parentWidget()->cursor());
    805         }
    806         else if (pEvent->type() == QEvent::MouseMove)
    807         {
    808             QMouseEvent *pMouseEvent = static_cast<QMouseEvent*>(pEvent);
    809             if (pMouseEvent->buttons() == Qt::LeftButton)
    810             {
    811                 if (m_previousMousePosition != QPoint(-1, -1))
    812                     emit sigDragging(pMouseEvent->globalPos() - m_previousMousePosition);
    813                 m_previousMousePosition = pMouseEvent->globalPos();
    814                 m_pDragMoveLabel->setCursor(Qt::ClosedHandCursor);
    815             }
    816         }
    817         else if (pEvent->type() == QEvent::MouseButtonRelease)
    818         {
    819             m_previousMousePosition = QPoint(-1, -1);
    820             m_pDragMoveLabel->setCursor(Qt::CrossCursor);
    821         }
    822     }
    823     return QIWithRetranslateUI<QWidget>::eventFilter(pObject, pEvent);
    824 }
    825 
    826 void UIFindInPageWidget::prepare()
    827 {
    828     setAutoFillBackground(true);
    829     setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
    830 
    831     QHBoxLayout *pLayout = new QHBoxLayout(this);
    832     m_pSearchLineEdit = new UISearchLineEdit;
    833     AssertReturnVoid(pLayout && m_pSearchLineEdit);
    834     setFocusProxy(m_pSearchLineEdit);
    835     QFontMetrics fontMetric(m_pSearchLineEdit->font());
    836     setMinimumSize(40 * fontMetric.width("x"),
    837                    fontMetric.height() +
    838                    qApp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin) +
    839                    qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin));
    840 
    841     connect(m_pSearchLineEdit, &UISearchLineEdit::textChanged,
    842             this, &UIFindInPageWidget::sigSearchTextChanged);
    843 
    844     m_pDragMoveLabel = new QLabel;
    845     AssertReturnVoid(m_pDragMoveLabel);
    846     m_pDragMoveLabel->installEventFilter(this);
    847     m_pDragMoveLabel->setPixmap(QPixmap(":/drag_move_16px.png"));
    848     pLayout->addWidget(m_pDragMoveLabel);
    849 
    850 
    851     pLayout->setSpacing(0);
    852     pLayout->addWidget(m_pSearchLineEdit);
    853 
    854     m_pPreviousButton = new QIToolButton;
    855     m_pNextButton = new QIToolButton;
    856     m_pCloseButton = new QIToolButton;
    857 
    858     pLayout->addWidget(m_pPreviousButton);
    859     pLayout->addWidget(m_pNextButton);
    860     pLayout->addWidget(m_pCloseButton);
    861 
    862     m_pPreviousButton->setIcon(UIIconPool::iconSet(":/arrow_up_10px.png"));
    863     m_pNextButton->setIcon(UIIconPool::iconSet(":/arrow_down_10px.png"));
    864     m_pCloseButton->setIcon(UIIconPool::iconSet(":/close_16px.png"));
    865 
    866     connect(m_pPreviousButton, &QIToolButton::pressed, this, &UIFindInPageWidget::sigSelectPreviousMatch);
    867     connect(m_pNextButton, &QIToolButton::pressed, this, &UIFindInPageWidget::sigSelectNextMatch);
    868     connect(m_pCloseButton, &QIToolButton::pressed, this, &UIFindInPageWidget::sigClose);
    869 }
    870 
    871 void UIFindInPageWidget::retranslateUi()
    872 {
    873555}
    874556
     
    1156838    if (m_pFindInPageAction)
    1157839        m_pFindInPageAction->setChecked(false);
    1158 }
    1159 
    1160 
    1161 /*********************************************************************************************************************************
    1162 *   UIHelpBrowserViewer implementation.                                                                                          *
    1163 *********************************************************************************************************************************/
    1164 
    1165 UIHelpBrowserViewer::UIHelpBrowserViewer(const QHelpEngine *pHelpEngine, QWidget *pParent /* = 0 */)
    1166     :QIWithRetranslateUI<QTextBrowser>(pParent)
    1167     , m_pHelpEngine(pHelpEngine)
    1168     , m_pFindInPageWidget(new UIFindInPageWidget(this))
    1169     , m_fFindWidgetDragged(false)
    1170     , m_iMarginForFindWidget(qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin))
    1171     , m_iSelectedMatchIndex(0)
    1172     , m_iSearchTermLength(0)
    1173 {
    1174     m_iInitialFontPointSize = font().pointSize();
    1175     setUndoRedoEnabled(true);
    1176     connect(m_pFindInPageWidget, &UIFindInPageWidget::sigDragging,
    1177             this, &UIHelpBrowserViewer::sltHandleFindWidgetDrag);
    1178     connect(m_pFindInPageWidget, &UIFindInPageWidget::sigSearchTextChanged,
    1179             this, &UIHelpBrowserViewer::sltHandleFindInPageSearchTextChange);
    1180 
    1181     connect(m_pFindInPageWidget, &UIFindInPageWidget::sigSelectPreviousMatch,
    1182             this, &UIHelpBrowserViewer::sltSelectPreviousMatch);
    1183     connect(m_pFindInPageWidget, &UIFindInPageWidget::sigSelectNextMatch,
    1184             this, &UIHelpBrowserViewer::sltSelectNextMatch);
    1185     connect(m_pFindInPageWidget, &UIFindInPageWidget::sigClose,
    1186             this, &UIHelpBrowserViewer::sigCloseFindInPageWidget);
    1187 
    1188     m_pFindInPageWidget->setVisible(false);
    1189     retranslateUi();
    1190 }
    1191 
    1192 QVariant UIHelpBrowserViewer::loadResource(int type, const QUrl &name)
    1193 {
    1194     if (name.scheme() == "qthelp" && m_pHelpEngine)
    1195         return QVariant(m_pHelpEngine->fileData(name));
    1196     else
    1197         return QTextBrowser::loadResource(type, name);
    1198 }
    1199 
    1200 void UIHelpBrowserViewer::emitHistoryChangedSignal()
    1201 {
    1202     emit historyChanged();
    1203     emit backwardAvailable(true);
    1204 }
    1205 
    1206 void UIHelpBrowserViewer::setSource(const QUrl &url)
    1207 {
    1208     QTextBrowser::setSource(url);
    1209     QTextDocument *pDocument = document();
    1210     if (!pDocument || pDocument->isEmpty())
    1211     {
    1212         setText(tr("<div><p><h3>404. Not found.</h3>The page <b>%1</b> could not be found.</p></div>").arg(url.toString()));
    1213     }
    1214     if (m_pFindInPageWidget && m_pFindInPageWidget->isVisible())
    1215     {
    1216         document()->undo();
    1217         m_pFindInPageWidget->clearSearchField();
    1218     }
    1219 }
    1220 
    1221 void UIHelpBrowserViewer::toggleFindInPageWidget(bool fVisible)
    1222 {
    1223     if (!m_pFindInPageWidget)
    1224         return;
    1225     /* Try to position the widget somewhere meaningful initially: */
    1226     if (!m_fFindWidgetDragged)
    1227         m_pFindInPageWidget->move(width() - m_iMarginForFindWidget - m_pFindInPageWidget->width(),
    1228                                   m_iMarginForFindWidget);
    1229 
    1230     m_pFindInPageWidget->setVisible(fVisible);
    1231 
    1232     if (!fVisible)
    1233     {
    1234         document()->undo();
    1235         m_pFindInPageWidget->clearSearchField();
    1236     }
    1237     else
    1238         m_pFindInPageWidget->setFocus();
    1239 }
    1240 
    1241 int UIHelpBrowserViewer::initialFontPointSize() const
    1242 {
    1243     return m_iInitialFontPointSize;
    1244 }
    1245 
    1246 void UIHelpBrowserViewer::setFont(const QFont &font)
    1247 {
    1248     QIWithRetranslateUI<QTextBrowser>::setFont(font);
    1249     /* Make sure the font size of the find in widget stays constant: */
    1250     if (m_pFindInPageWidget)
    1251     {
    1252         QFont wFont(font);
    1253         wFont.setPointSize(m_iInitialFontPointSize);
    1254         m_pFindInPageWidget->setFont(wFont);
    1255     }
    1256 }
    1257 
    1258 void UIHelpBrowserViewer::contextMenuEvent(QContextMenuEvent *event)
    1259 {
    1260     QMenu pMenu;
    1261 
    1262     UIContextMenuNavigationAction *pNavigationActions = new UIContextMenuNavigationAction;
    1263     pNavigationActions->setBackwardAvailable(isBackwardAvailable());
    1264     pNavigationActions->setForwardAvailable(isForwardAvailable());
    1265 
    1266     connect(pNavigationActions, &UIContextMenuNavigationAction::sigGoBackward,
    1267             this, &UIHelpBrowserViewer::sigGoBackward);
    1268     connect(pNavigationActions, &UIContextMenuNavigationAction::sigGoForward,
    1269             this, &UIHelpBrowserViewer::sigGoForward);
    1270     connect(pNavigationActions, &UIContextMenuNavigationAction::sigGoHome,
    1271             this, &UIHelpBrowserViewer::sigGoHome);
    1272     connect(pNavigationActions, &UIContextMenuNavigationAction::sigAddBookmark,
    1273             this, &UIHelpBrowserViewer::sigAddBookmark);
    1274 
    1275     QAction *pOpenLinkAction = new QAction(UIHelpBrowserWidget::tr("Open Link"));
    1276     connect(pOpenLinkAction, &QAction::triggered,
    1277             this, &UIHelpBrowserViewer::sltHandleOpenLink);
    1278 
    1279     QAction *pOpenInNewTabAction = new QAction(UIHelpBrowserWidget::tr("Open Link in New Tab"));
    1280     connect(pOpenInNewTabAction, &QAction::triggered,
    1281             this, &UIHelpBrowserViewer::sltHandleOpenLinkInNewTab);
    1282 
    1283     QAction *pCopyLink = new QAction(UIHelpBrowserWidget::tr("Copy Link"));
    1284     connect(pCopyLink, &QAction::triggered,
    1285             this, &UIHelpBrowserViewer::sltHandleCopyLink);
    1286 
    1287     pMenu.addAction(pNavigationActions);
    1288     pMenu.addAction(pOpenLinkAction);
    1289     pMenu.addAction(pOpenInNewTabAction);
    1290     pMenu.addAction(pCopyLink);
    1291 
    1292     QString strAnchor = anchorAt(event->pos());
    1293     if (!strAnchor.isEmpty())
    1294     {
    1295         QString strLink = source().resolved(anchorAt(event->pos())).toString();
    1296         pOpenLinkAction->setData(strLink);
    1297         pOpenInNewTabAction->setData(strLink);
    1298         pCopyLink->setData(strLink);
    1299     }
    1300     else
    1301     {
    1302         pOpenLinkAction->setEnabled(false);
    1303         pOpenInNewTabAction->setEnabled(false);
    1304         pCopyLink->setEnabled(false);
    1305     }
    1306     pMenu.exec(event->globalPos());
    1307 }
    1308 
    1309 void UIHelpBrowserViewer::resizeEvent(QResizeEvent *pEvent)
    1310 {
    1311     /* Make sure the widget stays inside the parent during parent resize: */
    1312     if (m_pFindInPageWidget)
    1313     {
    1314         if (!isRectInside(m_pFindInPageWidget->geometry(), m_iMarginForFindWidget))
    1315             moveFindWidgetIn(m_iMarginForFindWidget);
    1316     }
    1317     QIWithRetranslateUI<QTextBrowser>::resizeEvent(pEvent);
    1318 }
    1319 
    1320 void UIHelpBrowserViewer::wheelEvent(QWheelEvent *pEvent)
    1321 {
    1322     int iPreviousSize = font().pointSize();
    1323     QTextBrowser::wheelEvent(pEvent);
    1324     /* Don't allow font size to get too large or small: */
    1325     if (font().pointSize() >= fontScaleMinMax.second * m_iInitialFontPointSize ||
    1326         font().pointSize() <= fontScaleMinMax.first * m_iInitialFontPointSize)
    1327     {
    1328         QFont mFont = font();
    1329         mFont.setPointSize(iPreviousSize);
    1330         setFont(mFont);
    1331     }
    1332     else
    1333         emit sigFontPointSizeChanged(font().pointSize());
    1334 }
    1335 
    1336 void UIHelpBrowserViewer::retranslateUi()
    1337 {
    1338 }
    1339 
    1340 void UIHelpBrowserViewer::moveFindWidgetIn(int iMargin)
    1341 {
    1342     if (!m_pFindInPageWidget)
    1343         return;
    1344 
    1345     QRect  rect = m_pFindInPageWidget->geometry();
    1346     if (rect.left() < iMargin)
    1347         rect.translate(-rect.left() + iMargin, 0);
    1348     if (rect.right() > width() - iMargin)
    1349         rect.translate((width() - iMargin - rect.right()), 0);
    1350     if (rect.top() < iMargin)
    1351         rect.translate(0, -rect.top() + iMargin);
    1352 
    1353     if (rect.bottom() > height() - iMargin)
    1354         rect.translate(0, (height() - iMargin - rect.bottom()));
    1355     m_pFindInPageWidget->setGeometry(rect);
    1356     m_pFindInPageWidget->update();
    1357 }
    1358 
    1359 bool UIHelpBrowserViewer::isRectInside(const QRect &rect, int iMargin) const
    1360 {
    1361     if (rect.left() < iMargin || rect.top() < iMargin)
    1362         return false;
    1363     if (rect.right() > width() - iMargin || rect.bottom() > height() - iMargin)
    1364         return false;
    1365     return true;
    1366 }
    1367 
    1368 void UIHelpBrowserViewer::findAllMatches(const QString &searchString)
    1369 {
    1370     QTextDocument *pDocument = document();
    1371     AssertReturnVoid(pDocument);
    1372 
    1373     m_matchedCursorPosition.clear();
    1374     if (searchString.isEmpty())
    1375         return;
    1376     QTextCursor cursor(pDocument);
    1377     QTextDocument::FindFlags flags;
    1378     int iMatchCount = 0;
    1379     while (!cursor.isNull() && !cursor.atEnd())
    1380     {
    1381         cursor = pDocument->find(searchString, cursor, flags);
    1382         if (!cursor.isNull())
    1383         {
    1384             m_matchedCursorPosition << cursor.position() - searchString.length();
    1385             ++iMatchCount;
    1386         }
    1387     }
    1388 }
    1389 
    1390 void UIHelpBrowserViewer::highlightFinds(int iSearchTermLength)
    1391 {
    1392     QTextDocument* pDocument = document();
    1393     AssertReturnVoid(pDocument);
    1394     /* Clear previous highlight: */
    1395     pDocument->undo();
    1396 
    1397     QTextCursor highlightCursor(pDocument);
    1398     QTextCursor cursor(pDocument);
    1399     cursor.beginEditBlock();
    1400     for (int i = 0; i < m_matchedCursorPosition.size(); ++i)
    1401     {
    1402         highlightCursor.setPosition(m_matchedCursorPosition[i]);
    1403 
    1404         QTextCharFormat colorFormat(highlightCursor.charFormat());
    1405         colorFormat.setBackground(Qt::yellow);
    1406 
    1407         highlightCursor.setPosition(m_matchedCursorPosition[i] + iSearchTermLength, QTextCursor::KeepAnchor);
    1408         if (!highlightCursor.isNull())
    1409             highlightCursor.setCharFormat(colorFormat);
    1410     }
    1411     cursor.endEditBlock();
    1412 }
    1413 
    1414 void UIHelpBrowserViewer::selectMatch(int iMatchIndex, int iSearchStringLength)
    1415 {
    1416     QTextCursor cursor = textCursor();
    1417     /* Move the cursor to the beginning of the matched string: */
    1418     cursor.setPosition(m_matchedCursorPosition.at(iMatchIndex), QTextCursor::MoveAnchor);
    1419     /* Move the cursor to the end of the matched string while keeping the anchor at the begining thus selecting the text: */
    1420     cursor.setPosition(m_matchedCursorPosition.at(iMatchIndex) + iSearchStringLength, QTextCursor::KeepAnchor);
    1421     ensureCursorVisible();
    1422     setTextCursor(cursor);
    1423 }
    1424 
    1425 void UIHelpBrowserViewer::sltHandleOpenLinkInNewTab()
    1426 {
    1427     QAction *pSender = qobject_cast<QAction*>(sender());
    1428     if (!pSender)
    1429         return;
    1430     QUrl url = pSender->data().toUrl();
    1431     if (url.isValid())
    1432         emit sigOpenLinkInNewTab(url);
    1433 }
    1434 
    1435 void UIHelpBrowserViewer::sltHandleOpenLink()
    1436 {
    1437     QAction *pSender = qobject_cast<QAction*>(sender());
    1438     if (!pSender)
    1439         return;
    1440     QUrl url = pSender->data().toUrl();
    1441     if (url.isValid())
    1442         QTextBrowser::setSource(url);
    1443 }
    1444 
    1445 void UIHelpBrowserViewer::sltHandleCopyLink()
    1446 {
    1447     QAction *pSender = qobject_cast<QAction*>(sender());
    1448     if (!pSender)
    1449         return;
    1450     QUrl url = pSender->data().toUrl();
    1451     if (url.isValid())
    1452     {
    1453         QClipboard *pClipboard = QApplication::clipboard();
    1454         if (pClipboard)
    1455             pClipboard->setText(url.toString());
    1456     }
    1457 }
    1458 
    1459 void UIHelpBrowserViewer::sltHandleFindWidgetDrag(const QPoint &delta)
    1460 {
    1461     if (!m_pFindInPageWidget)
    1462         return;
    1463     QRect geo = m_pFindInPageWidget->geometry();
    1464     geo.translate(delta);
    1465 
    1466     /* Allow the move if m_pFindInPageWidget stays inside after the move: */
    1467     if (isRectInside(geo, m_iMarginForFindWidget))
    1468         m_pFindInPageWidget->move(m_pFindInPageWidget->pos() + delta);
    1469     m_fFindWidgetDragged = true;
    1470     update();
    1471 }
    1472 
    1473 void UIHelpBrowserViewer::sltHandleFindInPageSearchTextChange(const QString &strSearchText)
    1474 {
    1475     m_iSearchTermLength = strSearchText.length();
    1476     findAllMatches(strSearchText);
    1477     highlightFinds(m_iSearchTermLength);
    1478     //scrollToMatch(int iMatchIndex);
    1479     selectMatch(0, m_iSearchTermLength);
    1480     if (m_pFindInPageWidget)
    1481         m_pFindInPageWidget->setMatchCountAndCurrentIndex(m_matchedCursorPosition.size(), 0);
    1482 }
    1483 
    1484 void UIHelpBrowserViewer::sltSelectPreviousMatch()
    1485 {
    1486     m_iSelectedMatchIndex = m_iSelectedMatchIndex <= 0 ? m_matchedCursorPosition.size() - 1 : (m_iSelectedMatchIndex - 1);
    1487     selectMatch(m_iSelectedMatchIndex, m_iSearchTermLength);
    1488     if (m_pFindInPageWidget)
    1489         m_pFindInPageWidget->setMatchCountAndCurrentIndex(m_matchedCursorPosition.size(), m_iSelectedMatchIndex);
    1490 }
    1491 
    1492 void UIHelpBrowserViewer::sltSelectNextMatch()
    1493 {
    1494     m_iSelectedMatchIndex = m_iSelectedMatchIndex >= m_matchedCursorPosition.size() - 1 ? 0 : (m_iSelectedMatchIndex + 1);
    1495     selectMatch(m_iSelectedMatchIndex, m_iSearchTermLength);
    1496     if (m_pFindInPageWidget)
    1497         m_pFindInPageWidget->setMatchCountAndCurrentIndex(m_matchedCursorPosition.size(), m_iSelectedMatchIndex);
    1498840}
    1499841
  • trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpBrowserWidget.h

    r87015 r87157  
    7878#endif
    7979
     80    static const QPair<float, float> fontScaleMinMax;
    8081
    8182protected:
Note: See TracChangeset for help on using the changeset viewer.

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