Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qhelpsearchquerywidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
6
7#include <QtCore/qabstractitemmodel.h>
8#include <QtCore/qstringlist.h>
9#include <QtGui/qevent.h>
10#include <QtWidgets/qcompleter.h>
11#include <QtWidgets/qlabel.h>
12#include <QtWidgets/qlayout.h>
13#include <QtWidgets/qlineedit.h>
14#include <QtWidgets/qpushbutton.h>
15#include <QtWidgets/qtoolbutton.h>
16
18
20{
21public:
22 struct QueryHistory {
23 explicit QueryHistory() : curQuery(-1) {}
25 int curQuery = 0;
26 };
27
29 {
30 public:
31 explicit CompleterModel(QObject *parent) : QAbstractListModel(parent) { }
32
33 int rowCount(const QModelIndex &parent = QModelIndex()) const override
34 {
35 return parent.isValid() ? 0 : termList.size();
36 }
37
38 QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
39 {
40 if (!index.isValid() || index.row() >= termList.size()||
41 (role != Qt::EditRole && role != Qt::DisplayRole))
42 return {};
43 return termList.at(index.row());
44 }
45
46 void addTerm(const QString &term)
47 {
48 if (!termList.contains(term)) {
49 beginResetModel();
50 termList.append(term);
51 endResetModel();
52 }
53 }
54
55 private:
56 QStringList termList;
57 };
58
60
62 {
63 m_searchLabel->setText(QHelpSearchQueryWidget::tr("Search for:"));
64 m_searchButton->setText(QHelpSearchQueryWidget::tr("Search"));
65#if QT_CONFIG(tooltip)
66 m_prevQueryButton->setToolTip(QHelpSearchQueryWidget::tr("Previous search"));
67 m_nextQueryButton->setToolTip(QHelpSearchQueryWidget::tr("Next search"));
68#endif
69 }
70
71 void saveQuery(const QString &query)
72 {
73 // We only add the query to the list if it is different from the last one.
74 if (!m_queries.queries.isEmpty() && m_queries.queries.last() == query)
75 return;
76
77 m_queries.queries.append(query);
78 static_cast<CompleterModel *>(m_searchCompleter.model())->addTerm(query);
79 }
80
81 void nextOrPrevQuery(int maxOrMinIndex, int addend, QToolButton *thisButton,
82 QToolButton *otherButton)
83 {
84 m_lineEdit->clear();
85
86 // Otherwise, the respective button would be disabled.
87 Q_ASSERT(m_queries.curQuery != maxOrMinIndex);
88
89 m_queries.curQuery = qBound(0, m_queries.curQuery + addend, m_queries.queries.size() - 1);
90 const QString &query = m_queries.queries.at(m_queries.curQuery);
91 m_lineEdit->setText(query);
92
93 if (m_queries.curQuery == maxOrMinIndex)
94 thisButton->setEnabled(false);
95 otherButton->setEnabled(true);
96 }
97
99 {
100 m_prevQueryButton->setEnabled(m_queries.curQuery > 0);
101 m_nextQueryButton->setEnabled(m_queries.curQuery < m_queries.queries.size() - 1);
102 }
103
104 bool eventFilter(QObject *ob, QEvent *event) override
105 {
106 if (event->type() == QEvent::KeyPress) {
107 QKeyEvent *const keyEvent = static_cast<QKeyEvent *>(event);
108 if (keyEvent->key() == Qt::Key_Down) {
109 if (m_queries.curQuery + 1 < m_queries.queries.size())
111 return true;
112 }
113 if (keyEvent->key() == Qt::Key_Up) {
114 if (m_queries.curQuery > 0)
116 return true;
117 }
118 }
119 return QObject::eventFilter(ob, event);
120 }
121
123 {
124 saveQuery(m_lineEdit->text());
125 m_queries.curQuery = m_queries.queries.size() - 1;
126 if (m_queries.curQuery > 0)
127 m_prevQueryButton->setEnabled(true);
128 m_nextQueryButton->setEnabled(false);
129 }
130
132 {
133 nextOrPrevQuery(m_queries.queries.size() - 1, 1, m_nextQueryButton, m_prevQueryButton);
134 }
135
136 void prevQuery() { nextOrPrevQuery(0, -1, m_prevQueryButton, m_nextQueryButton); }
137
145 bool m_compactMode = false;
146};
147
148/*!
149 \class QHelpSearchQueryWidget
150 \since 4.4
151 \inmodule QtHelp
152 \brief The QHelpSearchQueryWidget class provides a simple line edit or
153 an advanced widget to enable the user to input a search term in a
154 standardized input mask.
155*/
156
157/*!
158 \fn void QHelpSearchQueryWidget::search()
159
160 This signal is emitted when a the user has the search button invoked.
161 After receiving the signal you can ask the QHelpSearchQueryWidget for the
162 search input that you may pass to the QHelpSearchEngine::search() function.
163*/
164
165/*!
166 Constructs a new search query widget with the given \a parent.
167*/
168QHelpSearchQueryWidget::QHelpSearchQueryWidget(QWidget *parent)
169 : QWidget(parent)
170 , d(new QHelpSearchQueryWidgetPrivate)
171{
172 QVBoxLayout *vLayout = new QVBoxLayout(this);
173 vLayout->setContentsMargins({});
174
175 QHBoxLayout* hBoxLayout = new QHBoxLayout;
176 d->m_searchLabel = new QLabel(this);
177 d->m_lineEdit = new QLineEdit(this);
178 d->m_lineEdit->setClearButtonEnabled(true);
179 d->m_lineEdit->setCompleter(&d->m_searchCompleter);
180 d->m_lineEdit->installEventFilter(d);
181 d->m_prevQueryButton = new QToolButton(this);
182 d->m_prevQueryButton->setArrowType(Qt::LeftArrow);
183 d->m_prevQueryButton->setEnabled(false);
184 d->m_nextQueryButton = new QToolButton(this);
185 d->m_nextQueryButton->setArrowType(Qt::RightArrow);
186 d->m_nextQueryButton->setEnabled(false);
187 d->m_searchButton = new QPushButton(this);
188 hBoxLayout->addWidget(d->m_searchLabel);
189 hBoxLayout->addWidget(d->m_lineEdit);
190 hBoxLayout->addWidget(d->m_prevQueryButton);
191 hBoxLayout->addWidget(d->m_nextQueryButton);
192 hBoxLayout->addWidget(d->m_searchButton);
193
194 vLayout->addLayout(hBoxLayout);
195
196 connect(d->m_prevQueryButton, &QAbstractButton::clicked, this, [this] { d->prevQuery(); });
197 connect(d->m_nextQueryButton, &QAbstractButton::clicked, this, [this] { d->nextQuery(); });
198 connect(d->m_searchButton, &QAbstractButton::clicked, this, &QHelpSearchQueryWidget::search);
199 connect(d->m_lineEdit, &QLineEdit::returnPressed, this, &QHelpSearchQueryWidget::search);
200
201 d->retranslate();
202 connect(this, &QHelpSearchQueryWidget::search, this, [this] { d->searchRequested(); });
203 setCompactMode(true);
204}
205
206/*!
207 Destroys the search query widget.
208*/
209QHelpSearchQueryWidget::~QHelpSearchQueryWidget()
210{
211 delete d;
212}
213
214/*!
215 Expands the search query widget so that the extended search fields are shown.
216*/
217void QHelpSearchQueryWidget::expandExtendedSearch()
218{
219 // TODO: no extended search anymore, deprecate it?
220}
221
222/*!
223 Collapses the search query widget so that only the default search field is
224 shown.
225*/
226void QHelpSearchQueryWidget::collapseExtendedSearch()
227{
228 // TODO: no extended search anymore, deprecate it?
229}
230
231#if QT_DEPRECATED_SINCE(5, 9)
232QT_WARNING_PUSH
233QT_WARNING_DISABLE_DEPRECATED
234/*!
235 \deprecated
236
237 Use searchInput() instead.
238*/
239QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
240{
241 return {{QHelpSearchQuery::DEFAULT, searchInput().split(QChar::Space, Qt::SkipEmptyParts)}};
242}
243
244/*!
245 \deprecated
246
247 Use setSearchInput() instead.
248*/
249void QHelpSearchQueryWidget::setQuery(const QList<QHelpSearchQuery> &queryList)
250{
251 if (queryList.isEmpty())
252 return;
253
254 setSearchInput(queryList.first().wordList.join(QChar::Space));
255}
256QT_WARNING_POP
257#endif // QT_DEPRECATED_SINCE(5, 9)
258
259/*!
260 \since 5.9
261
262 Returns a search phrase to use in combination with the
263 QHelpSearchEngine::search(const QString &searchInput) function.
264*/
265QString QHelpSearchQueryWidget::searchInput() const
266{
267 if (d->m_queries.queries.isEmpty())
268 return {};
269 return d->m_queries.queries.last();
270}
271
272/*!
273 \since 5.9
274
275 Sets the QHelpSearchQueryWidget input field to the value specified by
276 \a searchInput.
277
278 \note The QHelpSearchEngine::search(const QString &searchInput) function has
279 to be called to perform the actual search.
280*/
281void QHelpSearchQueryWidget::setSearchInput(const QString &searchInput)
282{
283 d->m_lineEdit->clear();
284 d->m_lineEdit->setText(searchInput);
285 d->searchRequested();
286}
287
288bool QHelpSearchQueryWidget::isCompactMode() const
289{
290 return d->m_compactMode;
291}
292
293void QHelpSearchQueryWidget::setCompactMode(bool on)
294{
295 if (d->m_compactMode != on) {
296 d->m_compactMode = on;
297 d->m_prevQueryButton->setVisible(!on);
298 d->m_nextQueryButton->setVisible(!on);
299 d->m_searchLabel->setVisible(!on);
300 }
301}
302
303/*!
304 \reimp
305*/
306void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent)
307{
308 if (focusEvent->reason() != Qt::MouseFocusReason) {
309 d->m_lineEdit->selectAll();
310 d->m_lineEdit->setFocus();
311 }
312}
313
314/*!
315 \reimp
316*/
317void QHelpSearchQueryWidget::changeEvent(QEvent *event)
318{
319 if (event->type() == QEvent::LanguageChange)
320 d->retranslate();
321 else
322 QWidget::changeEvent(event);
323}
324
325QT_END_NAMESPACE
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Returns the data stored under the given role for the item referred to by the index.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Returns the number of rows under the given parent.
bool eventFilter(QObject *ob, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void nextOrPrevQuery(int maxOrMinIndex, int addend, QToolButton *thisButton, QToolButton *otherButton)
void saveQuery(const QString &query)
Combined button and popup list for selecting options.