VirtualBox

source: vbox/trunk/src/VBox/Frontends/VirtualBox/src/helpbrowser/UIHelpViewer.cpp@ 87208

Last change on this file since 87208 was 87208, checked in by vboxsync, 4 years ago

FE/Qt: bugref:9831. Adding a context menu item for find in page action

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
Line 
1/* $Id: UIHelpViewer.cpp 87208 2021-01-11 09:04:21Z vboxsync $ */
2/** @file
3 * VBox Qt GUI - UIHelpBrowserWidget class implementation.
4 */
5
6/*
7 * Copyright (C) 2010-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18/* Qt includes: */
19#include <QClipboard>
20#include <QtGlobal>
21#if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
22 #include <QtHelp/QHelpEngine>
23 #include <QtHelp/QHelpContentWidget>
24 #include <QtHelp/QHelpIndexWidget>
25 #include <QtHelp/QHelpSearchEngine>
26 #include <QtHelp/QHelpSearchQueryWidget>
27 #include <QtHelp/QHelpSearchResultWidget>
28#endif
29#include <QLabel>
30#include <QMenu>
31#include <QHBoxLayout>
32#include <QScrollBar>
33#include <QWidgetAction>
34#ifdef RT_OS_SOLARIS
35# include <QFontDatabase>
36#endif
37
38/* GUI includes: */
39#include "QIToolButton.h"
40#include "UIHelpViewer.h"
41#include "UIHelpBrowserWidget.h"
42#include "UIIconPool.h"
43#include "UISearchLineEdit.h"
44
45/* COM includes: */
46#include "COMEnums.h"
47#include "CSystemProperties.h"
48
49#if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
50
51
52/*********************************************************************************************************************************
53* UIContextMenuNavigationAction definition. *
54*********************************************************************************************************************************/
55class UIContextMenuNavigationAction : public QWidgetAction
56{
57
58 Q_OBJECT;
59
60signals:
61
62 void sigGoBackward();
63 void sigGoForward();
64 void sigGoHome();
65 void sigAddBookmark();
66
67public:
68
69 UIContextMenuNavigationAction(QObject *pParent = 0);
70 void setBackwardAvailable(bool fAvailable);
71 void setForwardAvailable(bool fAvailable);
72
73protected:
74
75
76private slots:
77
78
79private:
80
81 void prepare();
82 QIToolButton *m_pBackwardButton;
83 QIToolButton *m_pForwardButton;
84 QIToolButton *m_pHomeButton;
85 QIToolButton *m_pAddBookmarkButton;
86};
87
88/*********************************************************************************************************************************
89* UIFindInPageWidget definition. *
90*********************************************************************************************************************************/
91class UIFindInPageWidget : public QIWithRetranslateUI<QWidget>
92{
93
94 Q_OBJECT;
95
96signals:
97
98 void sigDragging(const QPoint &delta);
99 void sigSearchTextChanged(const QString &strSearchText);
100 void sigSelectNextMatch();
101 void sigSelectPreviousMatch();
102 void sigClose();
103
104public:
105
106 UIFindInPageWidget(QWidget *pParent = 0);
107 void setMatchCountAndCurrentIndex(int iTotalMatchCount, int iCurrentlyScrolledIndex);
108 void clearSearchField();
109
110protected:
111
112 virtual bool eventFilter(QObject *pObject, QEvent *pEvent) /* override */;
113 virtual void keyPressEvent(QKeyEvent *pEvent) /* override */;
114
115private:
116
117 void prepare();
118 void retranslateUi();
119 UISearchLineEdit *m_pSearchLineEdit;
120 QIToolButton *m_pNextButton;
121 QIToolButton *m_pPreviousButton;
122 QIToolButton *m_pCloseButton;
123 QLabel *m_pDragMoveLabel;
124 QPoint m_previousMousePosition;
125};
126
127
128/*********************************************************************************************************************************
129* UIContextMenuNavigationAction implementation. *
130*********************************************************************************************************************************/
131UIContextMenuNavigationAction::UIContextMenuNavigationAction(QObject *pParent /* = 0 */)
132 :QWidgetAction(pParent)
133 , m_pBackwardButton(0)
134 , m_pForwardButton(0)
135 , m_pHomeButton(0)
136 , m_pAddBookmarkButton(0)
137{
138 prepare();
139}
140
141void UIContextMenuNavigationAction::setBackwardAvailable(bool fAvailable)
142{
143 if (m_pBackwardButton)
144 m_pBackwardButton->setEnabled(fAvailable);
145}
146
147void UIContextMenuNavigationAction::setForwardAvailable(bool fAvailable)
148{
149 if (m_pForwardButton)
150 m_pForwardButton->setEnabled(fAvailable);
151}
152
153void UIContextMenuNavigationAction::prepare()
154{
155 QWidget *pWidget = new QWidget;
156 setDefaultWidget(pWidget);
157 QHBoxLayout *pMainLayout = new QHBoxLayout(pWidget);
158 AssertReturnVoid(pMainLayout);
159
160 m_pBackwardButton = new QIToolButton;
161 m_pForwardButton = new QIToolButton;
162 m_pHomeButton = new QIToolButton;
163 m_pAddBookmarkButton = new QIToolButton;
164
165 AssertReturnVoid(m_pBackwardButton &&
166 m_pForwardButton &&
167 m_pHomeButton);
168 m_pForwardButton->setEnabled(false);
169 m_pBackwardButton->setEnabled(false);
170 m_pHomeButton->setIcon(UIIconPool::iconSet(":/help_browser_home_32px.png"));
171 m_pForwardButton->setIcon(UIIconPool::iconSet(":/help_browser_forward_32px.png", ":/help_browser_forward_disabled_32px.png"));
172 m_pBackwardButton->setIcon(UIIconPool::iconSet(":/help_browser_backward_32px.png", ":/help_browser_backward_disabled_32px.png"));
173 m_pAddBookmarkButton->setIcon(UIIconPool::iconSet(":/help_browser_add_bookmark.png"));
174
175 pMainLayout->addWidget(m_pBackwardButton);
176 pMainLayout->addWidget(m_pForwardButton);
177 pMainLayout->addWidget(m_pHomeButton);
178 pMainLayout->addWidget(m_pAddBookmarkButton);
179 pMainLayout->setContentsMargins(0, 0, 0, 0);
180 //pMainLayout->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
181
182 connect(m_pBackwardButton, &QIToolButton::pressed,
183 this, &UIContextMenuNavigationAction::sigGoBackward);
184 connect(m_pForwardButton, &QIToolButton::pressed,
185 this, &UIContextMenuNavigationAction::sigGoForward);
186 connect(m_pHomeButton, &QIToolButton::pressed,
187 this, &UIContextMenuNavigationAction::sigGoHome);
188 connect(m_pAddBookmarkButton, &QIToolButton::pressed,
189 this, &UIContextMenuNavigationAction::sigAddBookmark);
190}
191
192
193/*********************************************************************************************************************************
194* UIFindInPageWidget implementation. *
195*********************************************************************************************************************************/
196UIFindInPageWidget::UIFindInPageWidget(QWidget *pParent /* = 0 */)
197 : QIWithRetranslateUI<QWidget>(pParent)
198 , m_pSearchLineEdit(0)
199 , m_pNextButton(0)
200 , m_pPreviousButton(0)
201 , m_pCloseButton(0)
202 , m_previousMousePosition(-1, -1)
203{
204 prepare();
205}
206
207void UIFindInPageWidget::setMatchCountAndCurrentIndex(int iTotalMatchCount, int iCurrentlyScrolledIndex)
208{
209 if (!m_pSearchLineEdit)
210 return;
211 m_pSearchLineEdit->setMatchCount(iTotalMatchCount);
212 m_pSearchLineEdit->setScrollToIndex(iCurrentlyScrolledIndex);
213}
214
215void UIFindInPageWidget::clearSearchField()
216{
217 if (!m_pSearchLineEdit)
218 return;
219 m_pSearchLineEdit->blockSignals(true);
220 m_pSearchLineEdit->reset();
221 m_pSearchLineEdit->blockSignals(false);
222}
223
224bool UIFindInPageWidget::eventFilter(QObject *pObject, QEvent *pEvent)
225{
226 if (pObject == m_pDragMoveLabel)
227 {
228 if (pEvent->type() == QEvent::Enter)
229 m_pDragMoveLabel->setCursor(Qt::CrossCursor);
230 else if (pEvent->type() == QEvent::Leave)
231 {
232 if (parentWidget())
233 m_pDragMoveLabel->setCursor(parentWidget()->cursor());
234 }
235 else if (pEvent->type() == QEvent::MouseMove)
236 {
237 QMouseEvent *pMouseEvent = static_cast<QMouseEvent*>(pEvent);
238 if (pMouseEvent->buttons() == Qt::LeftButton)
239 {
240 if (m_previousMousePosition != QPoint(-1, -1))
241 emit sigDragging(pMouseEvent->globalPos() - m_previousMousePosition);
242 m_previousMousePosition = pMouseEvent->globalPos();
243 m_pDragMoveLabel->setCursor(Qt::ClosedHandCursor);
244 }
245 }
246 else if (pEvent->type() == QEvent::MouseButtonRelease)
247 {
248 m_previousMousePosition = QPoint(-1, -1);
249 m_pDragMoveLabel->setCursor(Qt::CrossCursor);
250 }
251 }
252 return QIWithRetranslateUI<QWidget>::eventFilter(pObject, pEvent);
253}
254
255void UIFindInPageWidget::keyPressEvent(QKeyEvent *pEvent)
256{
257 switch (pEvent->key())
258 {
259 case Qt::Key_Escape:
260 emit sigClose();
261 return;
262 break;
263 case Qt::Key_Down:
264 emit sigSelectNextMatch();
265 return;
266 break;
267 case Qt::Key_Up:
268 emit sigSelectPreviousMatch();
269 return;
270 break;
271 default:
272 QIWithRetranslateUI<QWidget>::keyPressEvent(pEvent);
273 break;
274 }
275}
276
277void UIFindInPageWidget::prepare()
278{
279 setAutoFillBackground(true);
280 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum);
281
282 QHBoxLayout *pLayout = new QHBoxLayout(this);
283 m_pSearchLineEdit = new UISearchLineEdit;
284 AssertReturnVoid(pLayout && m_pSearchLineEdit);
285 setFocusProxy(m_pSearchLineEdit);
286 QFontMetrics fontMetric(m_pSearchLineEdit->font());
287 setMinimumSize(40 * fontMetric.width("x"),
288 fontMetric.height() +
289 qApp->style()->pixelMetric(QStyle::PM_LayoutBottomMargin) +
290 qApp->style()->pixelMetric(QStyle::PM_LayoutTopMargin));
291
292 connect(m_pSearchLineEdit, &UISearchLineEdit::textChanged,
293 this, &UIFindInPageWidget::sigSearchTextChanged);
294
295 m_pDragMoveLabel = new QLabel;
296 AssertReturnVoid(m_pDragMoveLabel);
297 m_pDragMoveLabel->installEventFilter(this);
298 m_pDragMoveLabel->setPixmap(QPixmap(":/drag_move_16px.png"));
299 pLayout->addWidget(m_pDragMoveLabel);
300
301
302 pLayout->setSpacing(0);
303 pLayout->addWidget(m_pSearchLineEdit);
304
305 m_pPreviousButton = new QIToolButton;
306 m_pNextButton = new QIToolButton;
307 m_pCloseButton = new QIToolButton;
308
309 pLayout->addWidget(m_pPreviousButton);
310 pLayout->addWidget(m_pNextButton);
311 pLayout->addWidget(m_pCloseButton);
312
313 m_pPreviousButton->setIcon(UIIconPool::iconSet(":/arrow_up_10px.png"));
314 m_pNextButton->setIcon(UIIconPool::iconSet(":/arrow_down_10px.png"));
315 m_pCloseButton->setIcon(UIIconPool::iconSet(":/close_16px.png"));
316
317 connect(m_pPreviousButton, &QIToolButton::pressed, this, &UIFindInPageWidget::sigSelectPreviousMatch);
318 connect(m_pNextButton, &QIToolButton::pressed, this, &UIFindInPageWidget::sigSelectNextMatch);
319 connect(m_pCloseButton, &QIToolButton::pressed, this, &UIFindInPageWidget::sigClose);
320}
321
322void UIFindInPageWidget::retranslateUi()
323{
324}
325
326
327/*********************************************************************************************************************************
328* UIHelpViewer implementation. *
329*********************************************************************************************************************************/
330
331UIHelpViewer::UIHelpViewer(const QHelpEngine *pHelpEngine, QWidget *pParent /* = 0 */)
332 :QIWithRetranslateUI<QTextBrowser>(pParent)
333 , m_pHelpEngine(pHelpEngine)
334 , m_pFindInPageWidget(new UIFindInPageWidget(this))
335 , m_fFindWidgetDragged(false)
336 , m_iMarginForFindWidget(qApp->style()->pixelMetric(QStyle::PM_LayoutLeftMargin))
337 , m_iSelectedMatchIndex(0)
338 , m_iSearchTermLength(0)
339{
340 m_iInitialFontPointSize = font().pointSize();
341 setUndoRedoEnabled(true);
342 connect(m_pFindInPageWidget, &UIFindInPageWidget::sigDragging,
343 this, &UIHelpViewer::sltHandleFindWidgetDrag);
344 connect(m_pFindInPageWidget, &UIFindInPageWidget::sigSearchTextChanged,
345 this, &UIHelpViewer::sltHandleFindInPageSearchTextChange);
346
347 connect(m_pFindInPageWidget, &UIFindInPageWidget::sigSelectPreviousMatch,
348 this, &UIHelpViewer::sltSelectPreviousMatch);
349 connect(m_pFindInPageWidget, &UIFindInPageWidget::sigSelectNextMatch,
350 this, &UIHelpViewer::sltSelectNextMatch);
351 connect(m_pFindInPageWidget, &UIFindInPageWidget::sigClose,
352 this, &UIHelpViewer::sigCloseFindInPageWidget);
353
354 m_pFindInPageWidget->setVisible(false);
355 retranslateUi();
356}
357
358QVariant UIHelpViewer::loadResource(int type, const QUrl &name)
359{
360 if (name.scheme() == "qthelp" && m_pHelpEngine)
361 return QVariant(m_pHelpEngine->fileData(name));
362 else
363 return QTextBrowser::loadResource(type, name);
364}
365
366void UIHelpViewer::emitHistoryChangedSignal()
367{
368 emit historyChanged();
369 emit backwardAvailable(true);
370}
371
372void UIHelpViewer::setSource(const QUrl &url)
373{
374 QTextBrowser::setSource(url);
375 QTextDocument *pDocument = document();
376 if (!pDocument || pDocument->isEmpty())
377 {
378 setText(tr("<div><p><h3>404. Not found.</h3>The page <b>%1</b> could not be found.</p></div>").arg(url.toString()));
379 }
380 if (m_pFindInPageWidget && m_pFindInPageWidget->isVisible())
381 {
382 document()->undo();
383 m_pFindInPageWidget->clearSearchField();
384 }
385}
386
387void UIHelpViewer::sltToggleFindInPageWidget(bool fVisible)
388{
389 if (!m_pFindInPageWidget)
390 return;
391 /* Closing the find in page widget causes QTextBrowser to jump to the top of the document. This hack puts it back into position: */
392 int iPosition = verticalScrollBar()->value();
393 /* Try to position the widget somewhere meaningful initially: */
394 if (!m_fFindWidgetDragged)
395 m_pFindInPageWidget->move(width() - m_iMarginForFindWidget - m_pFindInPageWidget->width(),
396 m_iMarginForFindWidget);
397
398 m_pFindInPageWidget->setVisible(fVisible);
399
400 if (!fVisible)
401 {
402 document()->undo();
403 m_pFindInPageWidget->clearSearchField();
404 verticalScrollBar()->setValue(iPosition);
405 }
406 else
407 m_pFindInPageWidget->setFocus();
408}
409
410int UIHelpViewer::initialFontPointSize() const
411{
412 return m_iInitialFontPointSize;
413}
414
415void UIHelpViewer::setFont(const QFont &font)
416{
417 QIWithRetranslateUI<QTextBrowser>::setFont(font);
418 /* Make sure the font size of the find in widget stays constant: */
419 if (m_pFindInPageWidget)
420 {
421 QFont wFont(font);
422 wFont.setPointSize(m_iInitialFontPointSize);
423 m_pFindInPageWidget->setFont(wFont);
424 }
425}
426
427bool UIHelpViewer::isFindInPageWidgetVisible() const
428{
429 if (m_pFindInPageWidget)
430 return m_pFindInPageWidget->isVisible();
431 return false;
432}
433
434void UIHelpViewer::contextMenuEvent(QContextMenuEvent *event)
435{
436 QMenu pMenu;
437
438 UIContextMenuNavigationAction *pNavigationActions = new UIContextMenuNavigationAction;
439 pNavigationActions->setBackwardAvailable(isBackwardAvailable());
440 pNavigationActions->setForwardAvailable(isForwardAvailable());
441
442 connect(pNavigationActions, &UIContextMenuNavigationAction::sigGoBackward,
443 this, &UIHelpViewer::sigGoBackward);
444 connect(pNavigationActions, &UIContextMenuNavigationAction::sigGoForward,
445 this, &UIHelpViewer::sigGoForward);
446 connect(pNavigationActions, &UIContextMenuNavigationAction::sigGoHome,
447 this, &UIHelpViewer::sigGoHome);
448 connect(pNavigationActions, &UIContextMenuNavigationAction::sigAddBookmark,
449 this, &UIHelpViewer::sigAddBookmark);
450
451 QAction *pOpenLinkAction = new QAction(UIHelpBrowserWidget::tr("Open Link"));
452 connect(pOpenLinkAction, &QAction::triggered,
453 this, &UIHelpViewer::sltHandleOpenLink);
454
455 QAction *pOpenInNewTabAction = new QAction(UIHelpBrowserWidget::tr("Open Link in New Tab"));
456 connect(pOpenInNewTabAction, &QAction::triggered,
457 this, &UIHelpViewer::sltHandleOpenLinkInNewTab);
458
459 QAction *pCopyLink = new QAction(UIHelpBrowserWidget::tr("Copy Link"));
460 connect(pCopyLink, &QAction::triggered,
461 this, &UIHelpViewer::sltHandleCopyLink);
462
463
464 QAction *pFindInPage = new QAction(UIHelpBrowserWidget::tr("Find in Page"));
465 pFindInPage->setCheckable(true);
466 if (m_pFindInPageWidget)
467 pFindInPage->setChecked(m_pFindInPageWidget->isVisible());
468 connect(pFindInPage, &QAction::toggled, this, &UIHelpViewer::sltToggleFindInPageWidget);
469
470 pMenu.addAction(pNavigationActions);
471 pMenu.addAction(pOpenLinkAction);
472 pMenu.addAction(pOpenInNewTabAction);
473 pMenu.addAction(pCopyLink);
474 pMenu.addAction(pFindInPage);
475
476 QString strAnchor = anchorAt(event->pos());
477 if (!strAnchor.isEmpty())
478 {
479 QString strLink = source().resolved(anchorAt(event->pos())).toString();
480 pOpenLinkAction->setData(strLink);
481 pOpenInNewTabAction->setData(strLink);
482 pCopyLink->setData(strLink);
483 }
484 else
485 {
486 pOpenLinkAction->setEnabled(false);
487 pOpenInNewTabAction->setEnabled(false);
488 pCopyLink->setEnabled(false);
489 }
490 pMenu.exec(event->globalPos());
491}
492
493void UIHelpViewer::resizeEvent(QResizeEvent *pEvent)
494{
495 /* Make sure the widget stays inside the parent during parent resize: */
496 if (m_pFindInPageWidget)
497 {
498 if (!isRectInside(m_pFindInPageWidget->geometry(), m_iMarginForFindWidget))
499 moveFindWidgetIn(m_iMarginForFindWidget);
500 }
501 QIWithRetranslateUI<QTextBrowser>::resizeEvent(pEvent);
502}
503
504void UIHelpViewer::wheelEvent(QWheelEvent *pEvent)
505{
506 int iPreviousSize = font().pointSize();
507 QTextBrowser::wheelEvent(pEvent);
508 /* Don't allow font size to get too large or small: */
509 if (font().pointSize() >= UIHelpBrowserWidget::fontScaleMinMax.second * m_iInitialFontPointSize ||
510 font().pointSize() <= UIHelpBrowserWidget::fontScaleMinMax.first * m_iInitialFontPointSize)
511 {
512 QFont mFont = font();
513 mFont.setPointSize(iPreviousSize);
514 setFont(mFont);
515 }
516 else
517 emit sigFontPointSizeChanged(font().pointSize());
518}
519
520void UIHelpViewer::retranslateUi()
521{
522}
523
524void UIHelpViewer::moveFindWidgetIn(int iMargin)
525{
526 if (!m_pFindInPageWidget)
527 return;
528
529 QRect rect = m_pFindInPageWidget->geometry();
530 if (rect.left() < iMargin)
531 rect.translate(-rect.left() + iMargin, 0);
532 if (rect.right() > width() - iMargin)
533 rect.translate((width() - iMargin - rect.right()), 0);
534 if (rect.top() < iMargin)
535 rect.translate(0, -rect.top() + iMargin);
536
537 if (rect.bottom() > height() - iMargin)
538 rect.translate(0, (height() - iMargin - rect.bottom()));
539 m_pFindInPageWidget->setGeometry(rect);
540 m_pFindInPageWidget->update();
541}
542
543bool UIHelpViewer::isRectInside(const QRect &rect, int iMargin) const
544{
545 if (rect.left() < iMargin || rect.top() < iMargin)
546 return false;
547 if (rect.right() > width() - iMargin || rect.bottom() > height() - iMargin)
548 return false;
549 return true;
550}
551
552void UIHelpViewer::findAllMatches(const QString &searchString)
553{
554 QTextDocument *pDocument = document();
555 AssertReturnVoid(pDocument);
556
557 m_matchedCursorPosition.clear();
558 if (searchString.isEmpty())
559 return;
560 QTextCursor cursor(pDocument);
561 QTextDocument::FindFlags flags;
562 int iMatchCount = 0;
563 while (!cursor.isNull() && !cursor.atEnd())
564 {
565 cursor = pDocument->find(searchString, cursor, flags);
566 if (!cursor.isNull())
567 {
568 m_matchedCursorPosition << cursor.position() - searchString.length();
569 ++iMatchCount;
570 }
571 }
572}
573
574void UIHelpViewer::highlightFinds(int iSearchTermLength)
575{
576 QTextDocument* pDocument = document();
577 AssertReturnVoid(pDocument);
578 /* Clear previous highlight: */
579 pDocument->undo();
580
581 QTextCursor highlightCursor(pDocument);
582 QTextCursor cursor(pDocument);
583 cursor.beginEditBlock();
584 for (int i = 0; i < m_matchedCursorPosition.size(); ++i)
585 {
586 highlightCursor.setPosition(m_matchedCursorPosition[i]);
587
588 QTextCharFormat colorFormat(highlightCursor.charFormat());
589 colorFormat.setBackground(Qt::yellow);
590
591 highlightCursor.setPosition(m_matchedCursorPosition[i] + iSearchTermLength, QTextCursor::KeepAnchor);
592 if (!highlightCursor.isNull())
593 highlightCursor.setCharFormat(colorFormat);
594 }
595 cursor.endEditBlock();
596}
597
598void UIHelpViewer::selectMatch(int iMatchIndex, int iSearchStringLength)
599{
600 QTextCursor cursor = textCursor();
601 /* Move the cursor to the beginning of the matched string: */
602 cursor.setPosition(m_matchedCursorPosition.at(iMatchIndex), QTextCursor::MoveAnchor);
603 /* Move the cursor to the end of the matched string while keeping the anchor at the begining thus selecting the text: */
604 cursor.setPosition(m_matchedCursorPosition.at(iMatchIndex) + iSearchStringLength, QTextCursor::KeepAnchor);
605 ensureCursorVisible();
606 setTextCursor(cursor);
607}
608
609void UIHelpViewer::sltHandleOpenLinkInNewTab()
610{
611 QAction *pSender = qobject_cast<QAction*>(sender());
612 if (!pSender)
613 return;
614 QUrl url = pSender->data().toUrl();
615 if (url.isValid())
616 emit sigOpenLinkInNewTab(url);
617}
618
619void UIHelpViewer::sltHandleOpenLink()
620{
621 QAction *pSender = qobject_cast<QAction*>(sender());
622 if (!pSender)
623 return;
624 QUrl url = pSender->data().toUrl();
625 if (url.isValid())
626 QTextBrowser::setSource(url);
627}
628
629void UIHelpViewer::sltHandleCopyLink()
630{
631 QAction *pSender = qobject_cast<QAction*>(sender());
632 if (!pSender)
633 return;
634 QUrl url = pSender->data().toUrl();
635 if (url.isValid())
636 {
637 QClipboard *pClipboard = QApplication::clipboard();
638 if (pClipboard)
639 pClipboard->setText(url.toString());
640 }
641}
642
643void UIHelpViewer::sltHandleFindWidgetDrag(const QPoint &delta)
644{
645 if (!m_pFindInPageWidget)
646 return;
647 QRect geo = m_pFindInPageWidget->geometry();
648 geo.translate(delta);
649
650 /* Allow the move if m_pFindInPageWidget stays inside after the move: */
651 if (isRectInside(geo, m_iMarginForFindWidget))
652 m_pFindInPageWidget->move(m_pFindInPageWidget->pos() + delta);
653 m_fFindWidgetDragged = true;
654 update();
655}
656
657void UIHelpViewer::sltHandleFindInPageSearchTextChange(const QString &strSearchText)
658{
659 m_iSearchTermLength = strSearchText.length();
660 findAllMatches(strSearchText);
661 highlightFinds(m_iSearchTermLength);
662 //scrollToMatch(int iMatchIndex);
663 selectMatch(0, m_iSearchTermLength);
664 if (m_pFindInPageWidget)
665 m_pFindInPageWidget->setMatchCountAndCurrentIndex(m_matchedCursorPosition.size(), 0);
666}
667
668void UIHelpViewer::sltSelectPreviousMatch()
669{
670 m_iSelectedMatchIndex = m_iSelectedMatchIndex <= 0 ? m_matchedCursorPosition.size() - 1 : (m_iSelectedMatchIndex - 1);
671 selectMatch(m_iSelectedMatchIndex, m_iSearchTermLength);
672 if (m_pFindInPageWidget)
673 m_pFindInPageWidget->setMatchCountAndCurrentIndex(m_matchedCursorPosition.size(), m_iSelectedMatchIndex);
674}
675
676void UIHelpViewer::sltSelectNextMatch()
677{
678 m_iSelectedMatchIndex = m_iSelectedMatchIndex >= m_matchedCursorPosition.size() - 1 ? 0 : (m_iSelectedMatchIndex + 1);
679 selectMatch(m_iSelectedMatchIndex, m_iSearchTermLength);
680 if (m_pFindInPageWidget)
681 m_pFindInPageWidget->setMatchCountAndCurrentIndex(m_matchedCursorPosition.size(), m_iSelectedMatchIndex);
682}
683
684#include "UIHelpViewer.moc"
685
686#endif /*#if defined(RT_OS_LINUX) && defined(VBOX_WITH_DOCS_QHELP) && (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))*/
Note: See TracBrowser for help on using the repository browser.

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