1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3#include "tracer.h"
4
5#include "mainwindow.h"
6#include "searchwidget.h"
7
8#include <QtCore/QMap>
9#include <QtCore/QMimeData>
10#include <QtCore/QString>
11#include <QtCore/QStringList>
12
13#include <QtWidgets/QMenu>
14#include <QtWidgets/QLayout>
15#include <QtGui/QKeyEvent>
16#if QT_CONFIG(clipboard)
17#include <QtGui/QClipboard>
18#endif
19#include <QtWidgets/QApplication>
20#include <QtWidgets/QTextBrowser>
21
22#include <QtHelp/QHelpSearchEngine>
23#include <QtHelp/QHelpSearchQueryWidget>
24#include <QtHelp/QHelpSearchResultWidget>
25
26QT_BEGIN_NAMESPACE
27
28SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
29 : QWidget(parent)
30 , zoomCount(0)
31 , searchEngine(engine)
32{
33 TRACE_OBJ
34 QVBoxLayout *vLayout = new QVBoxLayout(this);
35
36 resultWidget = searchEngine->resultWidget();
37 QHelpSearchQueryWidget *queryWidget = searchEngine->queryWidget();
38
39 vLayout->addWidget(queryWidget);
40 vLayout->addWidget(resultWidget);
41
42 setFocusProxy(queryWidget);
43
44 connect(sender: queryWidget, signal: &QHelpSearchQueryWidget::search,
45 context: this, slot: &SearchWidget::search);
46 connect(sender: resultWidget, signal: &QHelpSearchResultWidget::requestShowLink,
47 context: this, slot: &SearchWidget::requestShowLink);
48
49 connect(sender: searchEngine, signal: &QHelpSearchEngine::searchingStarted,
50 context: this, slot: &SearchWidget::searchingStarted);
51 connect(sender: searchEngine, signal: &QHelpSearchEngine::searchingFinished,
52 context: this, slot: &SearchWidget::searchingFinished);
53
54 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
55 if (browser)
56 browser->viewport()->installEventFilter(filterObj: this);
57}
58
59SearchWidget::~SearchWidget()
60{
61 TRACE_OBJ
62 // nothing todo
63}
64
65void SearchWidget::zoomIn()
66{
67 TRACE_OBJ
68 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
69 if (browser && zoomCount != 10) {
70 zoomCount++;
71 browser->zoomIn();
72 }
73}
74
75void SearchWidget::zoomOut()
76{
77 TRACE_OBJ
78 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
79 if (browser && zoomCount != -5) {
80 zoomCount--;
81 browser->zoomOut();
82 }
83}
84
85void SearchWidget::resetZoom()
86{
87 TRACE_OBJ
88 if (zoomCount == 0)
89 return;
90
91 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
92 if (browser) {
93 browser->zoomOut(range: zoomCount);
94 zoomCount = 0;
95 }
96}
97
98void SearchWidget::search() const
99{
100 TRACE_OBJ
101 searchEngine->search(searchInput: searchEngine->queryWidget()->searchInput());
102}
103
104void SearchWidget::searchingStarted()
105{
106 TRACE_OBJ
107 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
108}
109
110void SearchWidget::searchingFinished(int searchResultCount)
111{
112 TRACE_OBJ
113 Q_UNUSED(searchResultCount);
114 qApp->restoreOverrideCursor();
115}
116
117bool SearchWidget::eventFilter(QObject* o, QEvent *e)
118{
119 TRACE_OBJ
120 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
121 if (browser && o == browser->viewport()
122 && e->type() == QEvent::MouseButtonRelease){
123 QMouseEvent *me = static_cast<QMouseEvent*>(e);
124 QUrl link = resultWidget->linkAt(point: me->pos());
125 if (!link.isEmpty() || link.isValid()) {
126 bool controlPressed = me->modifiers() & Qt::ControlModifier;
127 if ((me->button() == Qt::LeftButton && controlPressed)
128 || (me->button() == Qt::MiddleButton)) {
129 emit requestShowLinkInNewTab(url: link);
130 }
131 }
132 }
133 return QWidget::eventFilter(watched: o,event: e);
134}
135
136void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
137{
138 TRACE_OBJ
139 if (keyEvent->key() == Qt::Key_Escape)
140 MainWindow::activateCurrentBrowser();
141 else
142 keyEvent->ignore();
143}
144
145void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
146{
147 TRACE_OBJ
148 QMenu menu;
149 QPoint point = contextMenuEvent->globalPos();
150
151 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
152 if (!browser)
153 return;
154
155 point = browser->mapFromGlobal(point);
156 if (!browser->rect().contains(p: point, proper: true))
157 return;
158
159 QUrl link = browser->anchorAt(pos: point);
160
161 QKeySequence keySeq;
162#if QT_CONFIG(clipboard)
163 keySeq = QKeySequence::Copy;
164 QAction *copyAction = menu.addAction(text: tr(s: "&Copy") + QLatin1Char('\t') +
165 keySeq.toString(format: QKeySequence::NativeText));
166 copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection());
167
168 QAction *copyAnchorAction = menu.addAction(text: tr(s: "Copy &Link Location"));
169 copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
170#endif
171
172 keySeq = QKeySequence(Qt::CTRL);
173 QAction *newTabAction = menu.addAction(text: tr(s: "Open Link in New Tab") +
174 QLatin1Char('\t') + keySeq.toString(format: QKeySequence::NativeText) +
175 QLatin1String("LMB"));
176 newTabAction->setEnabled(!link.isEmpty() && link.isValid());
177
178 menu.addSeparator();
179
180 keySeq = QKeySequence::SelectAll;
181 QAction *selectAllAction = menu.addAction(text: tr(s: "Select All") +
182 QLatin1Char('\t') + keySeq.toString(format: QKeySequence::NativeText));
183
184 QAction *usedAction = menu.exec(pos: mapToGlobal(contextMenuEvent->pos()));
185#if QT_CONFIG(clipboard)
186 if (usedAction == copyAction) {
187 QTextCursor cursor = browser->textCursor();
188 if (!cursor.isNull() && cursor.hasSelection()) {
189 QString selectedText = cursor.selectedText();
190 QMimeData *data = new QMimeData();
191 data->setText(selectedText);
192 QApplication::clipboard()->setMimeData(data);
193 }
194 }
195 else if (usedAction == copyAnchorAction) {
196 QApplication::clipboard()->setText(link.toString());
197 }
198 else
199#endif
200 if (usedAction == newTabAction) {
201 emit requestShowLinkInNewTab(url: link);
202 }
203 else if (usedAction == selectAllAction) {
204 browser->selectAll();
205 }
206}
207
208QT_END_NAMESPACE
209

source code of qttools/src/assistant/assistant/searchwidget.cpp