VirtualBox

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

Last change on this file since 104596 was 104596, checked in by vboxsync, 5 months ago

FE/Qt: bugref:10450: UIHelpBrowserWidget: Get rid of pre-5.15 code related to QHelpEngine.

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

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