VirtualBox

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

Last change on this file was 104393, checked in by vboxsync, 4 weeks ago

FE/Qt. bugref:10622. Using new UITranslationEventListener in the UIActionPool class.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use