1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Assistant of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include "tracer.h"
29
30#include "mainwindow.h"
31#include "searchwidget.h"
32
33#include <QtCore/QMap>
34#include <QtCore/QMimeData>
35#include <QtCore/QString>
36#include <QtCore/QStringList>
37
38#include <QtWidgets/QMenu>
39#include <QtWidgets/QLayout>
40#include <QtGui/QKeyEvent>
41#if QT_CONFIG(clipboard)
42#include <QtGui/QClipboard>
43#endif
44#include <QtWidgets/QApplication>
45#include <QtWidgets/QTextBrowser>
46
47#include <QtHelp/QHelpSearchEngine>
48#include <QtHelp/QHelpSearchQueryWidget>
49#include <QtHelp/QHelpSearchResultWidget>
50
51QT_BEGIN_NAMESPACE
52
53SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
54 : QWidget(parent)
55 , zoomCount(0)
56 , searchEngine(engine)
57{
58 TRACE_OBJ
59 QVBoxLayout *vLayout = new QVBoxLayout(this);
60
61 resultWidget = searchEngine->resultWidget();
62 QHelpSearchQueryWidget *queryWidget = searchEngine->queryWidget();
63
64 vLayout->addWidget(queryWidget);
65 vLayout->addWidget(resultWidget);
66
67 setFocusProxy(queryWidget);
68
69 connect(sender: queryWidget, signal: &QHelpSearchQueryWidget::search,
70 receiver: this, slot: &SearchWidget::search);
71 connect(sender: resultWidget, signal: &QHelpSearchResultWidget::requestShowLink,
72 receiver: this, slot: &SearchWidget::requestShowLink);
73
74 connect(sender: searchEngine, signal: &QHelpSearchEngine::searchingStarted,
75 receiver: this, slot: &SearchWidget::searchingStarted);
76 connect(sender: searchEngine, signal: &QHelpSearchEngine::searchingFinished,
77 receiver: this, slot: &SearchWidget::searchingFinished);
78
79 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
80 if (browser)
81 browser->viewport()->installEventFilter(filterObj: this);
82}
83
84SearchWidget::~SearchWidget()
85{
86 TRACE_OBJ
87 // nothing todo
88}
89
90void SearchWidget::zoomIn()
91{
92 TRACE_OBJ
93 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
94 if (browser && zoomCount != 10) {
95 zoomCount++;
96 browser->zoomIn();
97 }
98}
99
100void SearchWidget::zoomOut()
101{
102 TRACE_OBJ
103 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
104 if (browser && zoomCount != -5) {
105 zoomCount--;
106 browser->zoomOut();
107 }
108}
109
110void SearchWidget::resetZoom()
111{
112 TRACE_OBJ
113 if (zoomCount == 0)
114 return;
115
116 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
117 if (browser) {
118 browser->zoomOut(range: zoomCount);
119 zoomCount = 0;
120 }
121}
122
123void SearchWidget::search() const
124{
125 TRACE_OBJ
126 searchEngine->search(searchInput: searchEngine->queryWidget()->searchInput());
127}
128
129void SearchWidget::searchingStarted()
130{
131 TRACE_OBJ
132 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
133}
134
135void SearchWidget::searchingFinished(int searchResultCount)
136{
137 TRACE_OBJ
138 Q_UNUSED(searchResultCount);
139 qApp->restoreOverrideCursor();
140}
141
142bool SearchWidget::eventFilter(QObject* o, QEvent *e)
143{
144 TRACE_OBJ
145 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
146 if (browser && o == browser->viewport()
147 && e->type() == QEvent::MouseButtonRelease){
148 QMouseEvent *me = static_cast<QMouseEvent*>(e);
149 QUrl link = resultWidget->linkAt(point: me->pos());
150 if (!link.isEmpty() || link.isValid()) {
151 bool controlPressed = me->modifiers() & Qt::ControlModifier;
152 if ((me->button() == Qt::LeftButton && controlPressed)
153 || (me->button() == Qt::MiddleButton)) {
154 emit requestShowLinkInNewTab(url: link);
155 }
156 }
157 }
158 return QWidget::eventFilter(watched: o,event: e);
159}
160
161void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
162{
163 TRACE_OBJ
164 if (keyEvent->key() == Qt::Key_Escape)
165 MainWindow::activateCurrentBrowser();
166 else
167 keyEvent->ignore();
168}
169
170void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
171{
172 TRACE_OBJ
173 QMenu menu;
174 QPoint point = contextMenuEvent->globalPos();
175
176 QTextBrowser* browser = resultWidget->findChild<QTextBrowser*>();
177 if (!browser)
178 return;
179
180 point = browser->mapFromGlobal(point);
181 if (!browser->rect().contains(p: point, proper: true))
182 return;
183
184 QUrl link = browser->anchorAt(pos: point);
185
186 QKeySequence keySeq;
187#if QT_CONFIG(clipboard)
188 keySeq = QKeySequence::Copy;
189 QAction *copyAction = menu.addAction(text: tr(s: "&Copy") + QLatin1Char('\t') +
190 keySeq.toString(format: QKeySequence::NativeText));
191 copyAction->setEnabled(QTextCursor(browser->textCursor()).hasSelection());
192
193 QAction *copyAnchorAction = menu.addAction(text: tr(s: "Copy &Link Location"));
194 copyAnchorAction->setEnabled(!link.isEmpty() && link.isValid());
195#endif
196
197 keySeq = QKeySequence(Qt::CTRL);
198 QAction *newTabAction = menu.addAction(text: tr(s: "Open Link in New Tab") +
199 QLatin1Char('\t') + keySeq.toString(format: QKeySequence::NativeText) +
200 QLatin1String("LMB"));
201 newTabAction->setEnabled(!link.isEmpty() && link.isValid());
202
203 menu.addSeparator();
204
205 keySeq = QKeySequence::SelectAll;
206 QAction *selectAllAction = menu.addAction(text: tr(s: "Select All") +
207 QLatin1Char('\t') + keySeq.toString(format: QKeySequence::NativeText));
208
209 QAction *usedAction = menu.exec(pos: mapToGlobal(contextMenuEvent->pos()));
210#if QT_CONFIG(clipboard)
211 if (usedAction == copyAction) {
212 QTextCursor cursor = browser->textCursor();
213 if (!cursor.isNull() && cursor.hasSelection()) {
214 QString selectedText = cursor.selectedText();
215 QMimeData *data = new QMimeData();
216 data->setText(selectedText);
217 QApplication::clipboard()->setMimeData(data);
218 }
219 }
220 else if (usedAction == copyAnchorAction) {
221 QApplication::clipboard()->setText(link.toString());
222 }
223 else
224#endif
225 if (usedAction == newTabAction) {
226 emit requestShowLinkInNewTab(url: link);
227 }
228 else if (usedAction == selectAllAction) {
229 browser->selectAll();
230 }
231}
232
233QT_END_NAMESPACE
234

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