VirtualBox

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

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

FE/Qt: bugref:9831. Misc. fixes

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