VirtualBox

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

Last change on this file since 100347 was 100344, checked in by vboxsync, 19 months ago

FE/Qt: bugref:10450: Qt6 compatibility bits for QMouseEvent; Replacing QMouseEvent::pos with QSinglePointEvent::position; S.a. r157776.

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

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