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