VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 weeks ago

Copyright year updates by scm.

  • 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 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIHelpBrowserWidget class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2024 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 0
911 /* If there is already a tab with a source which is equal to @initialUrl then make it current: */
912 int iExistIndex = findTab(initialUrl);
913 if (iExistIndex != -1)
914 {
915 setCurrentIndex(iExistIndex);
916 setSource(initialUrl);
917 return;
918 }
919#endif
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 QList<QHelpLink> links = m_pHelpEngine->documentsForIdentifier(strKeyword);
1865 if (!links.isEmpty())
1866 {
1867 /* We have to a have a single url per keyword in this case: */
1868 m_pTabManager->setSource(links.first().url, true /* new tab */);
1869 }
1870}
1871
1872void UIHelpBrowserWidget::sltWidgetVisibilityToggle(bool fToggled)
1873{
1874 if (sender() == m_pShowHideSideBarAction)
1875 {
1876 if (m_pTabWidget)
1877 m_pTabWidget->setVisible(fToggled);
1878 }
1879 else if (sender() == m_pShowHideToolBarAction)
1880 {
1881 if (m_pTabManager)
1882 m_pTabManager->setToolBarVisible(fToggled);
1883 }
1884 else if (sender() == m_pShowHideStatusBarAction)
1885 emit sigStatusBarVisible(fToggled);
1886}
1887
1888void UIHelpBrowserWidget::sltCopySelectedText()
1889{
1890 if (m_pTabManager)
1891 m_pTabManager->copySelectedText();
1892}
1893
1894void UIHelpBrowserWidget::sltFindInPage(bool fChecked)
1895{
1896 if (m_pTabManager)
1897 m_pTabManager->toggleFindInPage(fChecked);
1898}
1899
1900void UIHelpBrowserWidget::sltFindNextInPage()
1901{
1902 if (m_pTabManager)
1903 m_pTabManager->findNext();
1904}
1905
1906void UIHelpBrowserWidget::sltFindPreviousInPage()
1907{
1908 if (m_pTabManager)
1909 m_pTabManager->findPrevious();
1910}
1911
1912void UIHelpBrowserWidget::sltHistoryChanged(bool fBackwardAvailable, bool fForwardAvailable)
1913{
1914 if (m_pBackwardAction)
1915 m_pBackwardAction->setEnabled(fBackwardAvailable);
1916 if (m_pForwardAction)
1917 m_pForwardAction->setEnabled(fForwardAvailable);
1918}
1919
1920void UIHelpBrowserWidget::sltLinkHighlighted(const QUrl &url)
1921{
1922 if (url.isEmpty())
1923 {
1924 emit sigStatusBarMessage("", 0);
1925 return;
1926 }
1927
1928 QString strMessage = url.url();
1929 if (url.scheme() == "https" || url.scheme() == "http")
1930 strMessage = QString("%1: %2").arg(tr("Click to open the following URL with an external browser")).arg(strMessage);
1931 else if (url.scheme() == "qthelp")
1932 strMessage = QString("%1: %2").arg(tr("Click to navigate to internal URL")).arg(strMessage);
1933 else
1934 strMessage = "";
1935 emit sigStatusBarMessage(strMessage, 0);
1936}
1937
1938void UIHelpBrowserWidget::sltMouseOverImage(const QString &strImageName)
1939{
1940 emit sigStatusBarMessage(QString("%1: %2").arg(tr("Click to enlarge the image")).arg(strImageName), 3000);
1941}
1942
1943void UIHelpBrowserWidget::sltCopyAvailableChanged(bool fAvailable)
1944{
1945 if (m_pCopySelectedTextAction)
1946 m_pCopySelectedTextAction->setEnabled(fAvailable);
1947}
1948
1949void UIHelpBrowserWidget::sltFindInPageWidgetVisibilityChanged(bool fVisible)
1950{
1951 if (m_pFindInPageAction)
1952 {
1953 m_pFindInPageAction->blockSignals(true);
1954 m_pFindInPageAction->setChecked(fVisible);
1955 m_pFindInPageAction->blockSignals(false);
1956 }
1957 if (m_pFindNextInPageAction)
1958 m_pFindNextInPageAction->setEnabled(fVisible);
1959
1960 if (m_pFindPreviousInPageAction)
1961 m_pFindPreviousInPageAction->setEnabled(fVisible);
1962}
1963
1964void UIHelpBrowserWidget::sltShowPrintDialog()
1965{
1966#ifdef VBOX_WS_NIX
1967 if (!m_pTabManager)
1968 return;
1969 QPrinter printer;
1970 QPrintDialog printDialog(&printer, this);
1971 if (printDialog.exec() == QDialog::Accepted)
1972 m_pTabManager->printCurrent(printer);
1973#endif
1974}
1975
1976void UIHelpBrowserWidget::sltHelpEngineSetupFinished()
1977{
1978 AssertReturnVoid(m_pTabManager);
1979 m_fIndexingFinished = true;
1980 m_pTabManager->initializeTabs();
1981}
1982
1983void UIHelpBrowserWidget::sltContentWidgetItemClicked(const QModelIndex & index)
1984{
1985 AssertReturnVoid(m_pTabManager && m_pHelpEngine && m_pContentWidget);
1986 QUrl url = contentWidgetUrl(index);
1987 if (!url.isValid())
1988 return;
1989 m_pTabManager->setSource(url);
1990
1991 m_pContentWidget->scrollTo(index, QAbstractItemView::EnsureVisible);
1992 m_pContentWidget->expand(index);
1993}
1994
1995void UIHelpBrowserWidget::sltViewerSourceChange(const QUrl &source)
1996{
1997 if (m_fModelContentCreated && m_pContentWidget && source.isValid() && m_pContentModel)
1998 {
1999 QModelIndex index = m_pContentWidget->indexOf(source);
2000 QItemSelectionModel *pSelectionModel = m_pContentWidget->selectionModel();
2001 if (pSelectionModel && index.isValid())
2002 {
2003 m_pContentWidget->blockSignals(true);
2004 pSelectionModel->select(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
2005 m_pContentWidget->scrollTo(index, QAbstractItemView::EnsureVisible);
2006 m_pContentWidget->expand(index);
2007 m_pContentWidget->blockSignals(false);
2008 }
2009 }
2010}
2011
2012void UIHelpBrowserWidget::sltContentsCreated()
2013{
2014 m_fModelContentCreated = true;
2015 if (m_pTabManager)
2016 sltViewerSourceChange(m_pTabManager->currentSource());
2017}
2018
2019void UIHelpBrowserWidget::sltIndexingStarted()
2020{
2021 if (m_pSearchContainerWidget)
2022 m_pSearchContainerWidget->setEnabled(false);
2023}
2024
2025void UIHelpBrowserWidget::sltIndexingFinished()
2026{
2027 AssertReturnVoid(m_pTabManager &&
2028 m_pHelpEngine &&
2029 m_pSearchContainerWidget);
2030
2031 m_pSearchContainerWidget->setEnabled(true);
2032 m_fIndexingFinished = true;
2033 /* Process the keyword queue. */
2034 foreach (const QString strKeyword, m_keywordList)
2035 findAndShowUrlForKeyword(strKeyword);
2036 m_keywordList.clear();
2037
2038}
2039
2040void UIHelpBrowserWidget::sltSearchingStarted()
2041{
2042}
2043
2044void UIHelpBrowserWidget::sltSearchStart()
2045{
2046 AssertReturnVoid(m_pSearchEngine && m_pSearchQueryWidget);
2047 m_pSearchEngine->search(m_pSearchQueryWidget->searchInput());
2048}
2049
2050void UIHelpBrowserWidget::sltShowLinksContextMenu(const QPoint &pos)
2051{
2052 QWidget *pSender = qobject_cast<QWidget*>(sender());
2053 if (!pSender)
2054 return;
2055
2056 QUrl url;
2057 if (pSender == m_pContentWidget)
2058 url = contentWidgetUrl(m_pContentWidget->currentIndex());
2059 else if (pSender == m_pSearchResultWidget)
2060 {
2061 QTextBrowser* browser = m_pSearchResultWidget->findChild<QTextBrowser*>();
2062 if (!browser)
2063 return;
2064 QPoint browserPos = browser->mapFromGlobal(m_pSearchResultWidget->mapToGlobal(pos));
2065 url = browser->anchorAt(browserPos);
2066 }
2067 else if (pSender == m_pBookmarksWidget)
2068 {
2069 /* Assuming that only the UIBookmarksListWidget under the m_pBookmarksWidget sends the context menu request: */
2070 UIBookmarksListWidget *pListWidget = m_pBookmarksWidget->findChild<UIBookmarksListWidget*>();
2071 if (!pListWidget)
2072 return;
2073 url = m_pBookmarksWidget->currentBookmarkUrl();
2074 }
2075 else
2076 return;
2077
2078 bool fURLValid = url.isValid();
2079
2080 QMenu menu;
2081 QAction *pOpen = menu.addAction(tr("Open Link"));
2082 if (url.scheme() == "qthelp")
2083 {
2084 QAction *pOpenInNewTab = menu.addAction(tr("Open Link in New Tab"));
2085 pOpenInNewTab->setData(url);
2086 pOpenInNewTab->setEnabled(fURLValid);
2087 connect(pOpenInNewTab, &QAction::triggered, this, &UIHelpBrowserWidget::sltOpenLinkInNewTab);
2088 }
2089 QAction *pCopyLink = menu.addAction(tr("Copy Link"));
2090
2091 pOpen->setData(url);
2092 pCopyLink->setData(url);
2093
2094 pOpen->setEnabled(fURLValid);
2095 pCopyLink->setEnabled(fURLValid);
2096
2097 connect(pOpen, &QAction::triggered, this, &UIHelpBrowserWidget::sltOpenLink);
2098 connect(pCopyLink, &QAction::triggered, this, &UIHelpBrowserWidget::sltCopyLink);
2099
2100 if (pSender == m_pBookmarksWidget)
2101 {
2102 menu.addSeparator();
2103 QAction *pDeleteBookmark = menu.addAction(tr("Delete Bookmark"));
2104 QAction *pDeleteAllBookmarks = menu.addAction(tr("Delete All Bookmarks"));
2105 pDeleteBookmark->setEnabled(fURLValid);
2106
2107 connect(pDeleteBookmark, &QAction::triggered, m_pBookmarksWidget, &UIBookmarksListContainer::sltDeleteSelectedBookmark);
2108 connect(pDeleteAllBookmarks, &QAction::triggered, m_pBookmarksWidget, &UIBookmarksListContainer::sltDeleteAllBookmarks);
2109 }
2110
2111 menu.exec(pSender->mapToGlobal(pos));
2112}
2113
2114void UIHelpBrowserWidget::sltOpenLinkInNewTab()
2115{
2116 openLinkSlotHandler(sender(), true);
2117}
2118
2119void UIHelpBrowserWidget::sltOpenLink()
2120{
2121 openLinkSlotHandler(sender(), false);
2122}
2123
2124void UIHelpBrowserWidget::sltCopyLink()
2125{
2126 QAction *pAction = qobject_cast<QAction*>(sender());
2127 if (!pAction)
2128 return;
2129 QUrl url = pAction->data().toUrl();
2130 if (url.isValid())
2131 {
2132 QClipboard *pClipboard = QApplication::clipboard();
2133 if (pClipboard)
2134 pClipboard->setText(url.toString());
2135 }
2136}
2137
2138void UIHelpBrowserWidget::sltAddNewBookmark(const QUrl &url, const QString &strTitle)
2139{
2140 if (m_pBookmarksWidget)
2141 m_pBookmarksWidget->addBookmark(url, strTitle);
2142 Q_UNUSED(url);
2143 emit sigStatusBarMessage(QString("%1 %2").arg(tr("Bookmark added:")).arg(strTitle), 3000);
2144}
2145
2146void UIHelpBrowserWidget::openLinkSlotHandler(QObject *pSenderObject, bool fOpenInNewTab)
2147{
2148 QAction *pAction = qobject_cast<QAction*>(pSenderObject);
2149 if (!pAction)
2150 return;
2151 QUrl url = pAction->data().toUrl();
2152 if (m_pTabManager && url.isValid())
2153 m_pTabManager->setSource(url, fOpenInNewTab);
2154}
2155
2156void UIHelpBrowserWidget::updateTabsMenu(const QStringList &titles)
2157{
2158 if (!m_pTabsMenu)
2159 return;
2160 m_pTabsMenu->clear();
2161
2162 QAction *pCloseTabAction = m_pTabsMenu->addAction(tr("Close T&ab"));
2163 QAction *pCloseOtherTabsAction = m_pTabsMenu->addAction(tr("Close &Other Tabs"));
2164
2165 pCloseTabAction->setShortcut(QString("Ctrl+W"));
2166 pCloseOtherTabsAction->setShortcut(QString("Ctrl+Shift+W"));
2167
2168 pCloseTabAction->setEnabled(titles.size() > 1);
2169 pCloseOtherTabsAction->setEnabled(titles.size() > 1);
2170
2171 connect(pCloseTabAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltCloseCurrentTab);
2172 connect(pCloseOtherTabsAction, &QAction::triggered, m_pTabManager, &UIHelpBrowserTabManager::sltCloseOtherTabs);
2173
2174 m_pTabsMenu->addSeparator();
2175
2176 for (int i = 0; i < titles.size(); ++i)
2177 {
2178 QAction *pAction = m_pTabsMenu->addAction(titles[i]);
2179 pAction->setData(i);
2180 connect(pAction, &QAction::triggered, this, &UIHelpBrowserWidget::sltTabChoose);
2181 }
2182 if (m_pTabManager)
2183 sltCurrentTabChanged(m_pTabManager->currentIndex());
2184}
2185
2186void UIHelpBrowserWidget::sltOpenLinkWithUrl(const QUrl &url)
2187{
2188 if (m_pTabManager && url.isValid())
2189 m_pTabManager->setSource(url, false);
2190}
2191
2192void UIHelpBrowserWidget::sltZoomActions(int iZoomOperation)
2193{
2194 if (iZoomOperation >= (int) UIHelpViewer::ZoomOperation_Max)
2195 return;
2196 UIHelpViewer::ZoomOperation enmOperation = (UIHelpViewer::ZoomOperation)(iZoomOperation);
2197 m_pTabManager->sltHandleZoomRequest(enmOperation);
2198}
2199
2200void UIHelpBrowserWidget::sltTabListChanged(const QStringList &titleList)
2201{
2202 updateTabsMenu(titleList);
2203}
2204
2205void UIHelpBrowserWidget::sltTabChoose()
2206{
2207 QAction *pAction = qobject_cast<QAction*>(sender());
2208 if (!pAction)
2209 return;
2210 int iIndex = pAction->data().toInt();
2211 if (m_pTabManager)
2212 m_pTabManager->switchToTab(iIndex);
2213}
2214
2215void UIHelpBrowserWidget::sltCurrentTabChanged(int iIndex)
2216{
2217 Q_UNUSED(iIndex);
2218 if (!m_pTabsMenu)
2219 return;
2220
2221 /** Mark the action with iIndex+3 by assigning an icon to it. it is iIndex+3 and not iIndex since we have
2222 * two additional (close tab, close other tabs and a separator) action on top of the tab selection actions: */
2223 QList<QAction*> list = m_pTabsMenu->actions();
2224 for (int i = 0; i < list.size(); ++i)
2225 list[i]->setIcon(QIcon());
2226 if (iIndex+3 >= list.size())
2227 return;
2228 list[iIndex+3]->setIcon(UIIconPool::iconSet(":/help_browser_star_16px.png"));
2229
2230 if (m_pTabManager)
2231 {
2232 if (m_pCopySelectedTextAction)
2233 m_pCopySelectedTextAction->setEnabled(m_pTabManager->hasCurrentTabSelectedText());
2234 if (m_pFindInPageAction)
2235 m_pFindInPageAction->setChecked(m_pTabManager->isFindInPageWidgetVisible());
2236 if (m_pFindNextInPageAction)
2237 m_pFindNextInPageAction->setEnabled(m_pTabManager->isFindInPageWidgetVisible());
2238 if (m_pFindPreviousInPageAction)
2239 m_pFindPreviousInPageAction->setEnabled(m_pTabManager->isFindInPageWidgetVisible());
2240 }
2241}
2242
2243void UIHelpBrowserWidget::sltZoomPercentageChanged(int iPercentage)
2244{
2245 if (m_pZoomMenuAction)
2246 m_pZoomMenuAction->setZoomPercentage(iPercentage);
2247 emit sigZoomPercentageChanged(iPercentage);
2248}
2249
2250void UIHelpBrowserWidget::addActionToMenu(QMenu *pMenu, QAction *pAction)
2251{
2252 if (!pMenu || !pAction)
2253 return;
2254 pMenu->addAction(pAction);
2255}
2256
2257#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