Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qcompleter.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
108#include "qcompleter_p.h"
109
110#include "QtWidgets/qscrollbar.h"
111#include "QtCore/qdir.h"
112#if QT_CONFIG(stringlistmodel)
113#include "QtCore/qstringlistmodel.h"
114#endif
115#if QT_CONFIG(filesystemmodel)
116#include "QtGui/qfilesystemmodel.h"
117#endif
118#include "QtWidgets/qheaderview.h"
119#if QT_CONFIG(listview)
120#include "QtWidgets/qlistview.h"
121#endif
122#include "QtWidgets/qapplication.h"
123#include "QtGui/qevent.h"
124#include <private/qapplication_p.h>
125#include <private/qwidget_p.h>
126#if QT_CONFIG(lineedit)
127#include "QtWidgets/qlineedit.h"
128#endif
129#include "QtCore/qdir.h"
130
132
133using namespace Qt::StringLiterals;
134
137 c(c), showAll(false)
138{
139 createEngine();
140}
141
143{
144 Q_D(const QCompletionModel);
145 return d->model->columnCount();
146}
147
149{
150 bool hadModel = (sourceModel() != nullptr);
151
152 if (hadModel)
153 QObject::disconnect(sourceModel(), nullptr, this, nullptr);
154
156
157 if (source) {
158 // TODO: Optimize updates in the source model
167 }
168
169 invalidate();
170}
171
173{
174 bool sortedEngine = false;
175 if (c->filterMode == Qt::MatchStartsWith) {
176 switch (c->sorting) {
178 sortedEngine = false;
179 break;
181 sortedEngine = c->cs == Qt::CaseSensitive;
182 break;
184 sortedEngine = c->cs == Qt::CaseInsensitive;
185 break;
186 }
187 }
188
189 if (sortedEngine)
191 else
193}
194
196{
197 Q_D(const QCompletionModel);
198 if (!index.isValid())
199 return engine->curParent;
200
201 int row;
203 if (!showAll) {
204 if (!engine->matchCount())
205 return QModelIndex();
206 Q_ASSERT(index.row() < engine->matchCount());
207 QIndexMapper& rootIndices = engine->historyMatch.indices;
208 if (index.row() < rootIndices.count()) {
209 row = rootIndices[index.row()];
211 } else {
212 row = engine->curMatch.indices[index.row() - rootIndices.count()];
213 }
214 } else {
215 row = index.row();
216 }
217
218 return d->model->index(row, index.column(), parent);
219}
220
222{
223 if (!idx.isValid())
224 return QModelIndex();
225
226 int row = -1;
227 if (!showAll) {
228 if (!engine->matchCount())
229 return QModelIndex();
230
231 QIndexMapper& rootIndices = engine->historyMatch.indices;
232 if (idx.parent().isValid()) {
233 if (idx.parent() != engine->curParent)
234 return QModelIndex();
235 } else {
236 row = rootIndices.indexOf(idx.row());
237 if (row == -1 && engine->curParent.isValid())
238 return QModelIndex(); // source parent and our parent don't match
239 }
240
241 if (row == -1) {
243 engine->filterOnDemand(idx.row() - indices.last());
244 row = indices.indexOf(idx.row()) + rootIndices.count();
245 }
246
247 if (row == -1)
248 return QModelIndex();
249 } else {
250 if (idx.parent() != engine->curParent)
251 return QModelIndex();
252 row = idx.row();
253 }
254
255 return createIndex(row, idx.column());
256}
257
259{
260 if (row < 0 || !engine->matchCount())
261 return false;
262
263 if (row >= engine->matchCount())
265
266 if (row >= engine->matchCount()) // invalid row
267 return false;
268
269 engine->curRow = row;
270 return true;
271}
272
274{
275 if (!engine->matchCount())
276 return QModelIndex();
277
278 int row = engine->curRow;
279 if (showAll)
281
282 QModelIndex idx = createIndex(row, c->column);
283 if (!sourceIndex)
284 return idx;
285 return mapToSource(idx);
286}
287
289{
290 Q_D(const QCompletionModel);
291 if (row < 0 || column < 0 || column >= columnCount(parent) || parent.isValid())
292 return QModelIndex();
293
294 if (!showAll) {
295 if (!engine->matchCount())
296 return QModelIndex();
297 if (row >= engine->historyMatch.indices.count()) {
298 int want = row + 1 - engine->matchCount();
299 if (want > 0)
300 engine->filterOnDemand(want);
301 if (row >= engine->matchCount())
302 return QModelIndex();
303 }
304 } else {
305 if (row >= d->model->rowCount(engine->curParent))
306 return QModelIndex();
307 }
308
309 return createIndex(row, column);
310}
311
313{
314 if (!engine->matchCount())
315 return 0;
316
317 engine->filterOnDemand(INT_MAX);
318 return engine->matchCount();
319}
320
322{
323 Q_D(const QCompletionModel);
324 if (parent.isValid())
325 return 0;
326
327 if (showAll) {
328 // Show all items below current parent, even if we have no valid matches
329 if (engine->curParts.size() != 1 && !engine->matchCount()
330 && !engine->curParent.isValid())
331 return 0;
332 return d->model->rowCount(engine->curParent);
333 }
334
335 return completionCount();
336}
337
339{
340 if (showAll == !filtered)
341 return;
343 showAll = !filtered;
345}
346
348{
349 Q_D(const QCompletionModel);
350 if (parent.isValid())
351 return false;
352
353 if (showAll)
354 return d->model->hasChildren(mapToSource(parent));
355
356 if (!engine->matchCount())
357 return false;
358
359 return true;
360}
361
363{
364 Q_D(const QCompletionModel);
365 return d->model->data(mapToSource(index), role);
366}
367
369{
370 QAbstractProxyModel::setSourceModel(nullptr); // switch to static empty model
371 invalidate();
372}
373
375{
376 invalidate();
377 emit rowsAdded();
378}
379
381{
382 engine->cache.clear();
384}
385
387{
388 Q_D(QCompletionModel);
390 engine->filter(parts);
392
393 if (d->model->canFetchMore(engine->curParent))
394 d->model->fetchMore(engine->curParent);
395}
396
399{
400 const QAbstractItemModel *model = c->proxy->sourceModel();
401 curParts = parts;
402 if (curParts.isEmpty())
403 curParts.append(QString());
404
405 curRow = -1;
409
410 if (!model)
411 return;
412
414 for (int i = 0; i < curParts.size() - 1; i++) {
415 QString part = curParts.at(i);
416 int emi = filter(part, parent, -1).exactMatchIndex;
417 if (emi == -1)
418 return;
419 parent = model->index(emi, c->column, parent);
420 }
421
422 // Note that we set the curParent to a valid parent, even if we have no matches
423 // When filtering is disabled, we show all the items under this parent
425 if (curParts.constLast().isEmpty())
426 curMatch = QMatchData(QIndexMapper(0, model->rowCount(curParent) - 1), -1, false);
427 else
428 curMatch = filter(curParts.constLast(), curParent, 1); // build at least one
429 curRow = curMatch.isValid() ? 0 : -1;
430}
431
433{
434 QAbstractItemModel *source = c->proxy->sourceModel();
435 if (curParts.size() <= 1 || c->proxy->showAll || !source)
436 return QMatchData();
437
438#if QT_CONFIG(filesystemmodel)
439 const bool isFsModel = (qobject_cast<QFileSystemModel *>(source) != nullptr);
440#else
441 const bool isFsModel = false;
442#endif
443 Q_UNUSED(isFsModel);
445 QIndexMapper im(v);
446 QMatchData m(im, -1, true);
447
448 for (int i = 0; i < source->rowCount(); i++) {
449 QString str = source->index(i, c->column).data().toString();
450 if (str.startsWith(c->prefix, c->cs)
451#if !defined(Q_OS_WIN)
452 && (!isFsModel || QDir::toNativeSeparators(str) != QDir::separator())
453#endif
454 )
455 m.indices.append(i);
456 }
457 return m;
458}
459
460// Returns a match hint from the cache by chopping the search string
462{
463 if (part.isEmpty())
464 return false; // early out to avoid cache[parent] lookup costs
465
466 const auto cit = cache.find(parent);
467 if (cit == cache.end())
468 return false;
469
470 const CacheItem& map = *cit;
471 const auto mapEnd = map.end();
472
473 QString key = c->cs == Qt::CaseInsensitive ? part.toLower() : part;
474
475 while (!key.isEmpty()) {
476 key.chop(1);
477 const auto it = map.find(key);
478 if (it != mapEnd) {
479 *hint = *it;
480 return true;
481 }
482 }
483
484 return false;
485}
486
488{
489 if (part.isEmpty())
490 return false; // early out to avoid cache[parent] lookup costs
491
492 const auto cit = cache.find(parent);
493 if (cit == cache.end())
494 return false;
495
496 const CacheItem& map = *cit;
497
498 const QString key = c->cs == Qt::CaseInsensitive ? part.toLower() : part;
499
500 const auto it = map.find(key);
501 if (it == map.end())
502 return false;
503
504 *m = it.value();
505 return true;
506}
507
508// When the cache size exceeds 1MB, it clears out about 1/2 of the cache.
510{
511 if (c->filterMode == Qt::MatchEndsWith)
512 return;
513 QMatchData old = cache[parent].take(part);
514 cost = cost + m.indices.cost() - old.indices.cost();
515 if (cost * sizeof(int) > 1024 * 1024) {
517 while (it1 != cache.end()) {
518 CacheItem& ci = it1.value();
519 int sz = ci.size()/2;
521 int i = 0;
522 while (it2 != ci.end() && i < sz) {
523 cost -= it2.value().indices.cost();
524 it2 = ci.erase(it2);
525 i++;
526 }
527 if (ci.size() == 0) {
528 it1 = cache.erase(it1);
529 } else {
530 ++it1;
531 }
532 }
533 }
534
535 if (c->cs == Qt::CaseInsensitive)
536 part = std::move(part).toLower();
537 cache[parent][part] = m;
538}
539
542{
543 const QAbstractItemModel *model = c->proxy->sourceModel();
544
545 if (c->cs == Qt::CaseInsensitive)
546 part = std::move(part).toLower();
547
548 const CacheItem& map = cache[parent];
549
550 // Try to find a lower and upper bound for the search from previous results
551 int to = model->rowCount(parent) - 1;
552 int from = 0;
554
555 // look backward for first valid hint
556 for (CacheItem::const_iterator it1 = it; it1 != map.constBegin();) {
557 --it1;
558 const QMatchData& value = it1.value();
559 if (value.isValid()) {
560 if (order == Qt::AscendingOrder) {
561 from = value.indices.last() + 1;
562 } else {
563 to = value.indices.first() - 1;
564 }
565 break;
566 }
567 }
568
569 // look forward for first valid hint
570 for(CacheItem::const_iterator it2 = it; it2 != map.constEnd(); ++it2) {
571 const QMatchData& value = it2.value();
572 if (value.isValid() && !it2.key().startsWith(part)) {
573 if (order == Qt::AscendingOrder) {
574 to = value.indices.first() - 1;
575 } else {
576 from = value.indices.first() + 1;
577 }
578 break;
579 }
580 }
581
582 return QIndexMapper(from, to);
583}
584
586{
587 const QAbstractItemModel *model = c->proxy->sourceModel();
588
589 int rowCount = model->rowCount(parent);
590 if (rowCount < 2)
591 return Qt::AscendingOrder;
592 QString first = model->data(model->index(0, c->column, parent), c->role).toString();
593 QString last = model->data(model->index(rowCount - 1, c->column, parent), c->role).toString();
595}
596
598{
599 const QAbstractItemModel *model = c->proxy->sourceModel();
600
602 if (lookupCache(part, parent, &hint))
603 return hint;
604
607
608 if (matchHint(part, parent, &hint)) {
609 if (!hint.isValid())
610 return QMatchData();
611 indices = hint.indices;
612 } else {
613 indices = indexHint(part, parent, order);
614 }
615
616 // binary search the model within 'indices' for 'part' under 'parent'
617 int high = indices.to() + 1;
618 int low = indices.from() - 1;
619 int probe;
620 QModelIndex probeIndex;
621 QString probeData;
622
623 while (high - low > 1)
624 {
625 probe = (high + low) / 2;
626 probeIndex = model->index(probe, c->column, parent);
627 probeData = model->data(probeIndex, c->role).toString();
628 const int cmp = QString::compare(probeData, part, c->cs);
629 if ((order == Qt::AscendingOrder && cmp >= 0)
630 || (order == Qt::DescendingOrder && cmp < 0)) {
631 high = probe;
632 } else {
633 low = probe;
634 }
635 }
636
637 if ((order == Qt::AscendingOrder && low == indices.to())
638 || (order == Qt::DescendingOrder && high == indices.from())) { // not found
639 saveInCache(part, parent, QMatchData());
640 return QMatchData();
641 }
642
643 probeIndex = model->index(order == Qt::AscendingOrder ? low+1 : high-1, c->column, parent);
644 probeData = model->data(probeIndex, c->role).toString();
645 if (!probeData.startsWith(part, c->cs)) {
646 saveInCache(part, parent, QMatchData());
647 return QMatchData();
648 }
649
650 const bool exactMatch = QString::compare(probeData, part, c->cs) == 0;
651 int emi = exactMatch ? (order == Qt::AscendingOrder ? low+1 : high-1) : -1;
652
653 int from = 0;
654 int to = 0;
655 if (order == Qt::AscendingOrder) {
656 from = low + 1;
657 high = indices.to() + 1;
658 low = from;
659 } else {
660 to = high - 1;
661 low = indices.from() - 1;
662 high = to;
663 }
664
665 while (high - low > 1)
666 {
667 probe = (high + low) / 2;
668 probeIndex = model->index(probe, c->column, parent);
669 probeData = model->data(probeIndex, c->role).toString();
670 const bool startsWith = probeData.startsWith(part, c->cs);
671 if ((order == Qt::AscendingOrder && startsWith)
672 || (order == Qt::DescendingOrder && !startsWith)) {
673 low = probe;
674 } else {
675 high = probe;
676 }
677 }
678
679 QMatchData m(order == Qt::AscendingOrder ? QIndexMapper(from, high - 1) : QIndexMapper(low+1, to), emi, false);
680 saveInCache(part, parent, m);
681 return m;
682}
683
685int QUnsortedModelEngine::buildIndices(const QString& str, const QModelIndex& parent, int n,
687{
688 Q_ASSERT(m->partial);
689 Q_ASSERT(n != -1 || m->exactMatchIndex == -1);
690 const QAbstractItemModel *model = c->proxy->sourceModel();
691 int i, count = 0;
692
693 for (i = 0; i < indices.count() && count != n; ++i) {
694 QModelIndex idx = model->index(indices[i], c->column, parent);
695
696 if (!(model->flags(idx) & Qt::ItemIsSelectable))
697 continue;
698
699 QString data = model->data(idx, c->role).toString();
700
701 switch (c->filterMode) {
703 if (!data.startsWith(str, c->cs))
704 continue;
705 break;
707 if (!data.contains(str, c->cs))
708 continue;
709 break;
711 if (!data.endsWith(str, c->cs))
712 continue;
713 break;
714 case Qt::MatchExactly:
719 case Qt::MatchWrap:
721 Q_UNREACHABLE();
722 break;
723 }
724 m->indices.append(indices[i]);
725 ++count;
726 if (m->exactMatchIndex == -1 && QString::compare(data, str, c->cs) == 0) {
727 m->exactMatchIndex = indices[i];
728 if (n == -1)
729 return indices[i];
730 }
731 }
732 return indices[i-1];
733}
734
736{
738 if (!curMatch.partial)
739 return;
740 Q_ASSERT(n >= -1);
741 const QAbstractItemModel *model = c->proxy->sourceModel();
742 int lastRow = model->rowCount(curParent) - 1;
743 QIndexMapper im(curMatch.indices.last() + 1, lastRow);
744 int lastIndex = buildIndices(curParts.constLast(), curParent, n, im, &curMatch);
745 curMatch.partial = (lastRow != lastIndex);
746 saveInCache(curParts.constLast(), curParent, curMatch);
747}
748
750{
752
754 QIndexMapper im(v);
755 QMatchData m(im, -1, true);
756
757 const QAbstractItemModel *model = c->proxy->sourceModel();
758 bool foundInCache = lookupCache(part, parent, &m);
759
760 if (!foundInCache) {
761 if (matchHint(part, parent, &hint) && !hint.isValid())
762 return QMatchData();
763 }
764
765 if (!foundInCache && !hint.isValid()) {
766 const int lastRow = model->rowCount(parent) - 1;
767 QIndexMapper all(0, lastRow);
768 int lastIndex = buildIndices(part, parent, n, all, &m);
769 m.partial = (lastIndex != lastRow);
770 } else {
771 if (!foundInCache) { // build from hint as much as we can
772 buildIndices(part, parent, INT_MAX, hint.indices, &m);
773 m.partial = hint.partial;
774 }
775 if (m.partial && ((n == -1 && m.exactMatchIndex == -1) || (m.indices.count() < n))) {
776 // need more and have more
777 const int lastRow = model->rowCount(parent) - 1;
778 QIndexMapper rest(hint.indices.last() + 1, lastRow);
779 int want = n == -1 ? -1 : n - m.indices.count();
780 int lastIndex = buildIndices(part, parent, want, rest, &m);
781 m.partial = (lastRow != lastIndex);
782 }
783 }
784
785 saveInCache(part, parent, m);
786 return m;
787}
788
791 : widget(nullptr),
792 proxy(nullptr),
793 popup(nullptr),
794 filterMode(Qt::MatchStartsWith),
795 cs(Qt::CaseSensitive),
796 role(Qt::EditRole),
797 column(0),
798 maxVisibleItems(7),
799 sorting(QCompleter::UnsortedModel),
800 wrap(true),
801 eatFocusOut(true),
802 hiddenBecauseNoMatch(false)
803{
804}
805
807{
808 Q_Q(QCompleter);
809 proxy = new QCompletionModel(this, q);
811 q->setModel(m);
812#if !QT_CONFIG(listview)
813 q->setCompletionMode(QCompleter::InlineCompletion);
814#else
815 q->setCompletionMode(QCompleter::PopupCompletion);
816#endif // QT_CONFIG(listview)
817}
818
820{
821 Q_Q(QCompleter);
822 if (!q->popup())
823 return;
824 if (!select) {
826 } else {
827 if (!index.isValid())
829 else
832 }
834 if (!index.isValid())
836 else
838}
839
841{
843 if (!selection.indexes().isEmpty())
845
846 _q_complete(index, true);
847}
848
850{
851 Q_Q(QCompleter);
852 QString completion;
853
854 if (!index.isValid() || (!proxy->showAll && (index.row() >= proxy->engine->matchCount()))) {
855 completion = prefix;
856 index = QModelIndex();
857 } else {
858 if (!(index.flags() & Qt::ItemIsEnabled))
859 return;
861 si = si.sibling(si.row(), column); // for clicked()
862 completion = q->pathFromIndex(si);
863#if QT_CONFIG(filesystemmodel)
864 // add a trailing separator in inline
866 if (qobject_cast<QFileSystemModel *>(proxy->sourceModel()) && QFileInfo(completion).isDir())
867 completion += QDir::separator();
868 }
869#endif
870 }
871
872 if (highlighted) {
873 emit q->highlighted(index);
874 emit q->highlighted(completion);
875 } else {
876 emit q->activated(index);
877 emit q->activated(completion);
878 }
879}
880
882{
883 if (!popup || !popup->isVisible())
884 return;
886}
887
889{
892 QPoint pos;
893 int rh, w;
894 int h = (popup->sizeHintForRow(0) * qMin(maxVisibleItems, popup->model()->rowCount()) + 3) + 3;
895 QScrollBar *hsb = popup->horizontalScrollBar();
896 if (hsb && hsb->isVisible())
897 h += popup->horizontalScrollBar()->sizeHint().height();
898
899 if (rect.isValid()) {
900 rh = rect.height();
901 w = rect.width();
902 pos = widget->mapToGlobal(dir == Qt::RightToLeft ? rect.bottomRight() : rect.bottomLeft());
903 } else {
904 rh = widget->height();
905 pos = widget->mapToGlobal(QPoint(0, widget->height() - 2));
906 w = widget->width();
907 }
908
909 if (w > screen.width())
910 w = screen.width();
911 if ((pos.x() + w) > (screen.x() + screen.width()))
912 pos.setX(screen.x() + screen.width() - w);
913 if (pos.x() < screen.x())
914 pos.setX(screen.x());
915
916 int top = pos.y() - rh - screen.top() + 2;
917 int bottom = screen.bottom() - pos.y();
918 h = qMax(h, popup->minimumHeight());
919 if (h > bottom) {
920 h = qMin(qMax(top, bottom), h);
921
922 if (top > bottom)
923 pos.setY(pos.y() - h - rh + 2);
924 }
925
926 popup->setGeometry(pos.x(), pos.y(), w, h);
927
928 if (!popup->isVisible())
929 popup->show();
930}
931
932#if QT_CONFIG(filesystemmodel)
933static bool isRoot(const QFileSystemModel *model, const QString &path)
934{
935 const auto index = model->index(path);
936 return index.isValid() && model->fileInfo(index).isRoot();
937}
938
939static bool completeOnLoaded(const QFileSystemModel *model,
940 const QString &nativePrefix,
941 const QString &path,
942 Qt::CaseSensitivity caseSensitivity)
943{
944 const auto pathSize = path.size();
945 const auto prefixSize = nativePrefix.size();
946 if (prefixSize < pathSize)
947 return false;
948 const QString prefix = QDir::fromNativeSeparators(nativePrefix);
949 if (prefixSize == pathSize)
950 return path.compare(prefix, caseSensitivity) == 0 && isRoot(model, path);
951 // The user is typing something within that directory and is not in a subdirectory yet.
952 const auto separator = u'/';
953 return prefix.startsWith(path, caseSensitivity) && prefix.at(pathSize) == separator
954 && !QStringView{prefix}.right(prefixSize - pathSize - 1).contains(separator);
955}
956
958{
959 Q_Q(QCompleter);
960 // Slot called when QFileSystemModel has finished loading.
961 // If we hide the popup because there was no match because the model was not loaded yet,
962 // we re-start the completion when we get the results (unless triggered by
963 // something else, see QTBUG-14292).
965 if (auto model = qobject_cast<const QFileSystemModel *>(proxy->sourceModel())) {
966 if (completeOnLoaded(model, prefix, path, cs))
967 q->complete();
968 }
969 }
970}
971#else // QT_CONFIG(filesystemmodel)
973#endif
974
980{
981 Q_D(QCompleter);
982 d->init();
983}
984
991{
992 Q_D(QCompleter);
993 d->init(model);
994}
995
996#if QT_CONFIG(stringlistmodel)
1003{
1004 Q_D(QCompleter);
1005 d->init(new QStringListModel(list, this));
1006}
1007#endif // QT_CONFIG(stringlistmodel)
1008
1013{
1014}
1015
1026{
1027 Q_D(QCompleter);
1028 if (widget == d->widget)
1029 return;
1030
1031 if (d->widget)
1032 d->widget->removeEventFilter(this);
1033 d->widget = widget;
1034 if (d->widget)
1035 d->widget->installEventFilter(this);
1036
1037 if (d->popup) {
1038 d->popup->hide();
1039 d->popup->setFocusProxy(d->widget);
1040 }
1041}
1042
1049{
1050 Q_D(const QCompleter);
1051 return d->widget;
1052}
1053
1066{
1067 Q_D(QCompleter);
1068 QAbstractItemModel *oldModel = d->proxy->sourceModel();
1069 if (oldModel == model)
1070 return;
1071#if QT_CONFIG(filesystemmodel)
1072 if (qobject_cast<const QFileSystemModel *>(oldModel))
1073 setCompletionRole(Qt::EditRole); // QTBUG-54642, clear FileNameRole set by QFileSystemModel
1074#endif
1075 d->proxy->setSourceModel(model);
1076 if (d->popup)
1077 setPopup(d->popup); // set the model and make new connections
1078 if (oldModel && oldModel->QObject::parent() == this)
1079 delete oldModel;
1080#if QT_CONFIG(filesystemmodel)
1081 QFileSystemModel *fsModel = qobject_cast<QFileSystemModel *>(model);
1082 if (fsModel) {
1083#if defined(Q_OS_WIN)
1085#else
1087#endif
1089 connect(fsModel, SIGNAL(directoryLoaded(QString)), this, SLOT(_q_fileSystemModelDirectoryLoaded(QString)));
1090 }
1091#endif // QT_CONFIG(filesystemmodel)
1092}
1093
1100{
1101 Q_D(const QCompleter);
1102 return d->proxy->sourceModel();
1103}
1104
1124{
1125 Q_D(QCompleter);
1126 d->mode = mode;
1127 d->proxy->setFiltered(mode != QCompleter::UnfilteredPopupCompletion);
1128
1130 if (d->widget)
1131 d->widget->removeEventFilter(this);
1132 if (d->popup) {
1133 d->popup->deleteLater();
1134 d->popup = nullptr;
1135 }
1136 } else {
1137 if (d->widget)
1138 d->widget->installEventFilter(this);
1139 }
1140}
1141
1143{
1144 Q_D(const QCompleter);
1145 return d->mode;
1146}
1147
1168void QCompleter::setFilterMode(Qt::MatchFlags filterMode)
1169{
1170 Q_D(QCompleter);
1171
1172 if (d->filterMode == filterMode)
1173 return;
1174
1178 qWarning("Unhandled QCompleter::filterMode flag is used.");
1179 return;
1180 }
1181
1182 d->filterMode = filterMode;
1183 d->proxy->createEngine();
1184 d->proxy->invalidate();
1185}
1186
1187Qt::MatchFlags QCompleter::filterMode() const
1188{
1189 Q_D(const QCompleter);
1190 return d->filterMode;
1191}
1192
1209{
1210 Q_ASSERT(popup);
1211 Q_D(QCompleter);
1212 if (popup == d->popup)
1213 return;
1214
1215 // Remember existing widget's focus policy, default to NoFocus
1216 const Qt::FocusPolicy origPolicy = d->widget ? d->widget->focusPolicy()
1217 : Qt::NoFocus;
1218
1219 // If popup existed already, disconnect signals and delete object
1220 if (d->popup) {
1221 QObject::disconnect(d->popup->selectionModel(), nullptr, this, nullptr);
1222 QObject::disconnect(d->popup, nullptr, this, nullptr);
1223 delete d->popup;
1224 }
1225
1226 // Assign new object, set model and hide
1227 d->popup = popup;
1228 if (d->popup->model() != d->proxy)
1229 d->popup->setModel(d->proxy);
1230 d->popup->hide();
1231
1232 // Mark the widget window as a popup, so that if the last non-popup window is closed by the
1233 // user, the application should not be prevented from exiting. It needs to be set explicitly via
1234 // setWindowFlag(), because passing the flag via setParent(parent, windowFlags) does not call
1235 // QWidgetPrivate::adjustQuitOnCloseAttribute(), and causes an application not to exit if the
1236 // popup ends up being the last window.
1237 d->popup->setParent(nullptr);
1238 d->popup->setWindowFlag(Qt::Popup);
1239 d->popup->setFocusPolicy(Qt::NoFocus);
1240 if (d->widget)
1241 d->widget->setFocusPolicy(origPolicy);
1242
1243 d->popup->setFocusProxy(d->widget);
1244 d->popup->installEventFilter(this);
1245 d->popup->setItemDelegate(new QCompleterItemDelegate(d->popup));
1246#if QT_CONFIG(listview)
1247 if (QListView *listView = qobject_cast<QListView *>(d->popup)) {
1248 listView->setModelColumn(d->column);
1249 }
1250#endif
1251
1252 QObject::connect(d->popup, SIGNAL(clicked(QModelIndex)),
1253 this, SLOT(_q_complete(QModelIndex)));
1255 d->popup, SLOT(hide()));
1256
1257 QObject::connect(d->popup->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
1258 this, SLOT(_q_completionSelected(QItemSelection)));
1259}
1260
1267{
1268 Q_D(const QCompleter);
1269#if QT_CONFIG(listview)
1270 if (!d->popup && completionMode() != QCompleter::InlineCompletion) {
1273 listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
1276 listView->setModelColumn(d->column);
1277 QCompleter *that = const_cast<QCompleter*>(this);
1278 that->setPopup(listView);
1279 }
1280#endif // QT_CONFIG(listview)
1281 return d->popup;
1282}
1283
1288{
1289 return QObject::event(ev);
1290}
1291
1296{
1297 Q_D(QCompleter);
1298
1299 if (d->eatFocusOut && o == d->widget && e->type() == QEvent::FocusOut) {
1300 d->hiddenBecauseNoMatch = false;
1301 if (d->popup && d->popup->isVisible())
1302 return true;
1303 }
1304
1305 if (o != d->popup)
1306 return QObject::eventFilter(o, e);
1307
1308 Q_ASSERT(d->popup);
1309 switch (e->type()) {
1310 case QEvent::KeyPress: {
1311 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
1312
1313 QModelIndex curIndex = d->popup->currentIndex();
1314 QModelIndexList selList = d->popup->selectionModel()->selectedIndexes();
1315
1316 const int key = ke->key();
1317 // In UnFilteredPopup mode, select the current item
1318 if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid()
1320 d->setCurrentIndex(curIndex);
1321 return true;
1322 }
1323
1324 // Handle popup navigation keys. These are hardcoded because up/down might make the
1325 // widget do something else (lineedit cursor moves to home/end on mac, for instance)
1326 switch (key) {
1327 case Qt::Key_End:
1328 case Qt::Key_Home:
1329 if (ke->modifiers() & Qt::ControlModifier)
1330 return false;
1331 break;
1332
1333 case Qt::Key_Up:
1334 if (!curIndex.isValid()) {
1335 int rowCount = d->proxy->rowCount();
1336 QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column);
1337 d->setCurrentIndex(lastIndex);
1338 return true;
1339 } else if (curIndex.row() == 0) {
1340 if (d->wrap)
1341 d->setCurrentIndex(QModelIndex());
1342 return true;
1343 }
1344 return false;
1345
1346 case Qt::Key_Down:
1347 if (!curIndex.isValid()) {
1348 QModelIndex firstIndex = d->proxy->index(0, d->column);
1349 d->setCurrentIndex(firstIndex);
1350 return true;
1351 } else if (curIndex.row() == d->proxy->rowCount() - 1) {
1352 if (d->wrap)
1353 d->setCurrentIndex(QModelIndex());
1354 return true;
1355 }
1356 return false;
1357
1358 case Qt::Key_PageUp:
1359 case Qt::Key_PageDown:
1360 return false;
1361 }
1362
1363 // Send the event to the widget. If the widget accepted the event, do nothing
1364 // If the widget did not accept the event, provide a default implementation
1365 d->eatFocusOut = false;
1366 (static_cast<QObject *>(d->widget))->event(ke);
1367 d->eatFocusOut = true;
1368 if (!d->widget || e->isAccepted() || !d->popup->isVisible()) {
1369 // widget lost focus, hide the popup
1370 if (d->widget && (!d->widget->hasFocus()
1371#ifdef QT_KEYPAD_NAVIGATION
1372 || (QApplicationPrivate::keypadNavigationEnabled() && !d->widget->hasEditFocus())
1373#endif
1374 ))
1375 d->popup->hide();
1376 if (e->isAccepted())
1377 return true;
1378 }
1379
1380 // default implementation for keys not handled by the widget when popup is open
1381#if QT_CONFIG(shortcut)
1382 if (ke->matches(QKeySequence::Cancel)) {
1383 d->popup->hide();
1384 return true;
1385 }
1386#endif
1387 switch (key) {
1388#ifdef QT_KEYPAD_NAVIGATION
1389 case Qt::Key_Select:
1390 if (!QApplicationPrivate::keypadNavigationEnabled())
1391 break;
1392#endif
1393 case Qt::Key_Return:
1394 case Qt::Key_Enter:
1395 case Qt::Key_Tab:
1396 d->popup->hide();
1397 if (curIndex.isValid())
1398 d->_q_complete(curIndex);
1399 break;
1400
1401 case Qt::Key_F4:
1402 if (ke->modifiers() & Qt::AltModifier)
1403 d->popup->hide();
1404 break;
1405
1406 case Qt::Key_Backtab:
1407 d->popup->hide();
1408 break;
1409
1410 default:
1411 break;
1412 }
1413
1414 return true;
1415 }
1416
1417#ifdef QT_KEYPAD_NAVIGATION
1418 case QEvent::KeyRelease: {
1419 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
1420 if (QApplicationPrivate::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) {
1421 // Send the event to the 'widget'. This is what we did for KeyPress, so we need
1422 // to do the same for KeyRelease, in case the widget's KeyPress event set
1423 // up something (such as a timer) that is relying on also receiving the
1424 // key release. I see this as a bug in Qt, and should really set it up for all
1425 // the affected keys. However, it is difficult to tell how this will affect
1426 // existing code, and I can't test for every combination!
1427 d->eatFocusOut = false;
1428 static_cast<QObject *>(d->widget)->event(ke);
1429 d->eatFocusOut = true;
1430 }
1431 break;
1432 }
1433#endif
1434
1436#ifdef QT_KEYPAD_NAVIGATION
1437 if (QApplicationPrivate::keypadNavigationEnabled()) {
1438 // if we've clicked in the widget (or its descendant), let it handle the click
1440 if (source) {
1441 QPoint pos = source->mapToGlobal((static_cast<QMouseEvent *>(e))->pos());
1443 if (target && (d->widget->isAncestorOf(target) ||
1444 target == d->widget)) {
1445 d->eatFocusOut = false;
1446 static_cast<QObject *>(target)->event(e);
1447 d->eatFocusOut = true;
1448 return true;
1449 }
1450 }
1451 }
1452#endif
1453 if (!d->popup->underMouse()) {
1454 d->popup->hide();
1455 return true;
1456 }
1457 }
1458 return false;
1459
1463 break;
1464
1465 default:
1466 return false;
1467 }
1468 return false;
1469}
1470
1482{
1483 Q_D(QCompleter);
1484 QModelIndex idx = d->proxy->currentIndex(false);
1485 d->hiddenBecauseNoMatch = false;
1486 if (d->mode == QCompleter::InlineCompletion) {
1487 if (idx.isValid())
1488 d->_q_complete(idx, true);
1489 return;
1490 }
1491
1492 Q_ASSERT(d->widget);
1493 if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
1494 || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
1495 if (d->popup)
1496 d->popup->hide(); // no suggestion, hide
1497 d->hiddenBecauseNoMatch = true;
1498 return;
1499 }
1500
1501 popup();
1503 d->setCurrentIndex(idx, false);
1504
1505 d->showPopup(rect);
1506 d->popupRect = rect;
1507}
1508
1519{
1520 Q_D(QCompleter);
1521 return d->proxy->setCurrentRow(row);
1522}
1523
1530{
1531 Q_D(const QCompleter);
1532 return d->proxy->currentRow();
1533}
1534
1541{
1542 Q_D(const QCompleter);
1543 return d->proxy->completionCount();
1544}
1545
1581{
1582 Q_D(QCompleter);
1583 if (d->sorting == sorting)
1584 return;
1585 d->sorting = sorting;
1586 d->proxy->createEngine();
1587 d->proxy->invalidate();
1588}
1589
1591{
1592 Q_D(const QCompleter);
1593 return d->sorting;
1594}
1595
1608{
1609 Q_D(QCompleter);
1610 if (d->column == column)
1611 return;
1612#if QT_CONFIG(listview)
1613 if (QListView *listView = qobject_cast<QListView *>(d->popup))
1615#endif
1616 d->column = column;
1617 d->proxy->invalidate();
1618}
1619
1621{
1622 Q_D(const QCompleter);
1623 return d->column;
1624}
1625
1635{
1636 Q_D(QCompleter);
1637 if (d->role == role)
1638 return;
1639 d->role = role;
1640 d->proxy->invalidate();
1641}
1642
1644{
1645 Q_D(const QCompleter);
1646 return d->role;
1647}
1648
1657{
1658 Q_D(QCompleter);
1659 if (d->wrap == wrap)
1660 return;
1661 d->wrap = wrap;
1662}
1663
1665{
1666 Q_D(const QCompleter);
1667 return d->wrap;
1668}
1669
1678{
1679 Q_D(const QCompleter);
1680 return d->maxVisibleItems;
1681}
1682
1684{
1685 Q_D(QCompleter);
1686 if (Q_UNLIKELY(maxItems < 0)) {
1687 qWarning("QCompleter::setMaxVisibleItems: "
1688 "Invalid max visible items (%d) must be >= 0", maxItems);
1689 return;
1690 }
1691 d->maxVisibleItems = maxItems;
1692}
1693
1703{
1704 Q_D(QCompleter);
1705 if (d->cs == cs)
1706 return;
1707 d->cs = cs;
1708 d->proxy->createEngine();
1709 d->proxy->invalidate();
1710}
1711
1713{
1714 Q_D(const QCompleter);
1715 return d->cs;
1716}
1717
1726{
1727 Q_D(QCompleter);
1728 d->prefix = prefix;
1729 d->proxy->filter(splitPath(prefix));
1730}
1731
1733{
1734 Q_D(const QCompleter);
1735 return d->prefix;
1736}
1737
1744{
1745 Q_D(const QCompleter);
1746 return d->proxy->currentIndex(false);
1747}
1748
1757{
1758 Q_D(const QCompleter);
1759 return pathFromIndex(d->proxy->currentIndex(true));
1760}
1761
1774{
1775 Q_D(const QCompleter);
1776 return d->proxy;
1777}
1778
1791{
1792 Q_D(const QCompleter);
1793 if (!index.isValid())
1794 return QString();
1795
1796 QAbstractItemModel *sourceModel = d->proxy->sourceModel();
1797 if (!sourceModel)
1798 return QString();
1799 bool isFsModel = false;
1800#if QT_CONFIG(filesystemmodel)
1801 isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
1802#endif
1803 if (!isFsModel)
1804 return sourceModel->data(index, d->role).toString();
1805
1806 QModelIndex idx = index;
1808 do {
1809 QString t;
1810#if QT_CONFIG(filesystemmodel)
1811 t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
1812#endif
1813 list.prepend(t);
1814 QModelIndex parent = idx.parent();
1815 idx = parent.sibling(parent.row(), index.column());
1816 } while (idx.isValid());
1817
1818#if !defined(Q_OS_WIN)
1819 if (list.size() == 1) // only the separator or some other text
1820 return list[0];
1821 list[0].clear() ; // the join below will provide the separator
1822#endif
1823
1824 return list.join(QDir::separator());
1825}
1826
1840{
1841 bool isFsModel = false;
1842#if QT_CONFIG(filesystemmodel)
1843 Q_D(const QCompleter);
1844 isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
1845#endif
1846
1847 if (!isFsModel || path.isEmpty())
1848 return QStringList(completionPrefix());
1849
1851#if defined(Q_OS_WIN)
1852 if (pathCopy == "\\"_L1 || pathCopy == "\\\\"_L1)
1853 return QStringList(pathCopy);
1854 const bool startsWithDoubleSlash = pathCopy.startsWith("\\\\"_L1);
1855 if (startsWithDoubleSlash)
1856 pathCopy = pathCopy.mid(2);
1857#endif
1858
1859 const QChar sep = QDir::separator();
1860 QStringList parts = pathCopy.split(sep);
1861
1862#if defined(Q_OS_WIN)
1863 if (startsWithDoubleSlash)
1864 parts[0].prepend("\\\\"_L1);
1865#else
1866 if (pathCopy[0] == sep) // readd the "/" at the beginning as the split removed it
1867 parts[0] = u'/';
1868#endif
1869
1870 return parts;
1871}
1872
1908
1909#include "moc_qcompleter.cpp"
1910
1911#include "moc_qcompleter_p.cpp"
Q_INVOKABLE int const QModelIndex & parent
Returns the parent of the model item with the given index.
void endResetModel()
Completes a model reset operation.
void columnsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after columns have been removed from the model.
void modelReset(QPrivateSignal)
void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QList< int > &roles=QList< int >())
This signal is emitted whenever the data in an existing item changes.
virtual Q_INVOKABLE int rowCount(const QModelIndex &parent=QModelIndex()) const =0
Returns the number of rows under the given parent.
void layoutChanged(const QList< QPersistentModelIndex > &parents=QList< QPersistentModelIndex >(), QAbstractItemModel::LayoutChangeHint hint=QAbstractItemModel::NoLayoutChangeHint)
void beginResetModel()
Begins a model reset operation.
QModelIndex createIndex(int row, int column, const void *data=nullptr) const
Creates a model index for the given row and column with the internal pointer ptr.
void columnsInserted(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after columns have been inserted into the model.
virtual Q_INVOKABLE QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const =0
Returns the data stored under the given role for the item referred to by the index.
void rowsRemoved(const QModelIndex &parent, int first, int last, QPrivateSignal)
This signal is emitted after rows have been removed from the model.
The QAbstractItemView class provides the basic functionality for item view classes.
void setEditTriggers(EditTriggers triggers)
QAbstractItemModel * model() const
Returns the model that this view is presenting.
void setSelectionBehavior(QAbstractItemView::SelectionBehavior behavior)
virtual void scrollTo(const QModelIndex &index, ScrollHint hint=EnsureVisible)=0
Scrolls the view if necessary to ensure that the item at index is visible.
QItemSelectionModel * selectionModel() const
Returns the current selection model.
void setSelectionMode(QAbstractItemView::SelectionMode mode)
virtual int sizeHintForRow(int row) const
Returns the height size hint for the specified row or -1 if there is no model.
The QAbstractProxyModel class provides a base class for proxy item models that can do sorting,...
QAbstractItemModel * sourceModel
the source model of this proxy model.
virtual void setSourceModel(QAbstractItemModel *sourceModel)
Sets the given sourceModel to be processed by the proxy model.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Returns the index of the data in row and column with parent.
Qt::ItemFlags flags(const QModelIndex &index) const override
\reimp
static QWidget * widgetAt(const QPoint &p)
Returns the widget at global screen position point, or \nullptr if there is no Qt widget there.
\inmodule QtCore
Definition qchar.h:48
Qt::CaseSensitivity cs
void setCurrentIndex(QModelIndex, bool=true)
void _q_fileSystemModelDirectoryLoaded(const QString &path)
void _q_completionSelected(const QItemSelection &)
QPointer< QWidget > widget
void init(QAbstractItemModel *model=nullptr)
QAbstractItemView * popup
void _q_complete(QModelIndex, bool=false)
QCompletionModel * proxy
void showPopup(const QRect &)
The QCompleter class provides completions based on an item model.
Definition qcompleter.h:24
void setCompletionColumn(int column)
QAbstractItemModel * model() const
Returns the model that provides completion strings.
void setModelSorting(ModelSorting sorting)
QWidget * widget() const
Returns the widget for which the completer object is providing completions.
~QCompleter() override
Destroys the completer object.
int completionCount() const
Returns the number of completions for the current prefix.
int completionColumn
the column in the model in which completions are searched for.
Definition qcompleter.h:30
void setFilterMode(Qt::MatchFlags filterMode)
CompletionMode
This enum specifies how completions are provided to the user.
Definition qcompleter.h:37
@ PopupCompletion
Definition qcompleter.h:38
@ InlineCompletion
Definition qcompleter.h:40
@ UnfilteredPopupCompletion
Definition qcompleter.h:39
int maxVisibleItems
the maximum allowed size on screen of the completer, measured in items
Definition qcompleter.h:32
void setCompletionMode(CompletionMode mode)
bool wrapAround
the completions wrap around when navigating through items
Definition qcompleter.h:34
QCompleter(QObject *parent=nullptr)
Constructs a completer object with the given parent.
Qt::MatchFlags filterMode
This property controls how filtering is performed.
Definition qcompleter.h:28
virtual QStringList splitPath(const QString &path) const
Splits the given path into strings that are used to match at each level in the model().
QString completionPrefix
the completion prefix used to provide completions.
Definition qcompleter.h:26
QAbstractItemView * popup() const
Returns the popup used to display completions.
virtual QString pathFromIndex(const QModelIndex &index) const
Returns the path for the given index.
void setCompletionRole(int role)
bool setCurrentRow(int row)
Sets the current row to the row specified.
Qt::CaseSensitivity caseSensitivity
the case sensitivity of the matching
Definition qcompleter.h:33
void setPopup(QAbstractItemView *popup)
Sets the popup used to display completions to popup.
void complete(const QRect &rect=QRect())
For QCompleter::PopupCompletion and QCompletion::UnfilteredPopupCompletion modes, calling this functi...
ModelSorting
This enum specifies how the items in the model are sorted.
Definition qcompleter.h:44
@ CaseSensitivelySortedModel
Definition qcompleter.h:46
@ CaseInsensitivelySortedModel
Definition qcompleter.h:47
ModelSorting modelSorting
the way the model is sorted
Definition qcompleter.h:27
void setModel(QAbstractItemModel *c)
Sets the model which provides completions to model.
QModelIndex currentIndex() const
Returns the model index of the current completion in the completionModel().
bool event(QEvent *) override
\reimp
void setWidget(QWidget *widget)
Sets the widget for which completion are provided for to widget.
bool eventFilter(QObject *o, QEvent *e) override
\reimp
QString currentCompletion() const
Returns the current completion string.
void setCaseSensitivity(Qt::CaseSensitivity caseSensitivity)
CompletionMode completionMode
how the completions are provided to the user
Definition qcompleter.h:29
void setCompletionPrefix(const QString &prefix)
QAbstractItemModel * completionModel() const
Returns the completion model.
int currentRow() const
Returns the current row.
void setWrapAround(bool wrap)
void setMaxVisibleItems(int maxItems)
void activated(const QString &text)
This signal is sent when an item in the popup() is activated by the user (by clicking or pressing ret...
int completionRole
the item role to be used to query the contents of items for matching.
Definition qcompleter.h:31
QMatchData historyMatch
QMatchData curMatch
void saveInCache(QString, const QModelIndex &, const QMatchData &)
QModelIndex curParent
void filter(const QStringList &parts)
virtual void filterOnDemand(int)
int matchCount() const
bool matchHint(const QString &part, const QModelIndex &parent, QMatchData *m) const
bool lookupCache(const QString &part, const QModelIndex &parent, QMatchData *m) const
QStringList curParts
QMatchData filterHistory()
QModelIndex index(int row, int column, const QModelIndex &=QModelIndex()) const override
Returns the index of the item in the model specified by the given row, column and parent index.
int rowCount(const QModelIndex &index=QModelIndex()) const override
Returns the number of rows under the given parent.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
\reimp
void setFiltered(bool)
int completionCount() const
int columnCount(const QModelIndex &index=QModelIndex()) const override
Returns the number of columns for the children of the given parent.
QScopedPointer< QCompletionEngine > engine
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override
Reimplement this function to return the model index in the proxy model that corresponds to the source...
bool hasChildren(const QModelIndex &parent=QModelIndex()) const override
\reimp
QModelIndex currentIndex(bool) const
void filter(const QStringList &parts)
QModelIndex mapToSource(const QModelIndex &proxyIndex) const override
Reimplement this function to return the model index in the source model that corresponds to the proxy...
QCompletionModel(QCompleterPrivate *c, QObject *parent)
void setSourceModel(QAbstractItemModel *sourceModel) override
Sets the given sourceModel to be processed by the proxy model.
bool setCurrentRow(int row)
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static QString fromNativeSeparators(const QString &pathName)
Definition qdir.cpp:962
static QChar separator()
Returns the native directory separator: "/" under Unix and "\\" under Windows.
Definition qdir.h:206
static QString toNativeSeparators(const QString &pathName)
Definition qdir.cpp:929
\inmodule QtCore
Definition qcoreevent.h:45
@ ShortcutOverride
Definition qcoreevent.h:158
@ FocusOut
Definition qcoreevent.h:67
@ InputMethod
Definition qcoreevent.h:120
@ KeyRelease
Definition qcoreevent.h:65
@ KeyPress
Definition qcoreevent.h:64
@ MouseButtonPress
Definition qcoreevent.h:60
\inmodule QtCore \reentrant
Definition qfileinfo.h:22
The QFileSystemModel class provides a data model for the local filesystem.
int cost() const
int indexOf(int x) const
int first() const
int count() const
int last() const
virtual void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command)
Sets the model item index to be the current item, and emits currentChanged().
virtual void clear()
Clears the selection model.
\inmodule QtCore
Q_CORE_EXPORT QModelIndexList indexes() const
Returns a list of model indexes that correspond to the selected items.
The QKeyEvent class describes a key event.
Definition qevent.h:423
Qt::KeyboardModifiers modifiers() const
Returns the keyboard modifier flags that existed immediately after the event occurred.
Definition qevent.cpp:1465
int key() const
Returns the code of the key that was pressed or released.
Definition qevent.h:433
The QListView class provides a list or icon view onto a model.
Definition qlistview.h:17
void setModelColumn(int column)
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
T & first()
Definition qlist.h:628
void prepend(rvalue_ref t)
Definition qlist.h:456
void clear()
Definition qlist.h:417
T & value() const
Definition qmap.h:442
Definition qmap.h:186
iterator erase(const_iterator it)
Definition qmap.h:618
void clear()
Definition qmap.h:288
iterator find(const Key &key)
Definition qmap.h:640
iterator lowerBound(const Key &key)
Definition qmap.h:659
iterator begin()
Definition qmap.h:597
iterator end()
Definition qmap.h:601
const_iterator constBegin() const
Definition qmap.h:599
size_type size() const
Definition qmap.h:266
const_iterator constEnd() const
Definition qmap.h:603
T take(const Key &key)
Definition qmap.h:321
\inmodule QtCore
constexpr int row() const noexcept
Returns the row this model index refers to.
QModelIndex parent() const
Returns the parent of the model index, or QModelIndex() if it has no parent.
constexpr int column() const noexcept
Returns the column this model index refers to.
constexpr bool isValid() const noexcept
Returns {true} if this model index is valid; otherwise returns {false}.
QModelIndex sibling(int row, int column) const
Returns the sibling at row and column.
\inmodule QtGui
Definition qevent.h:195
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1363
virtual bool eventFilter(QObject *watched, QEvent *event)
Filters events if this object has been installed as an event filter for the watched object.
Definition qobject.cpp:1518
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3099
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
\inmodule QtCore\reentrant
Definition qpoint.h:23
\inmodule QtCore\reentrant
Definition qrect.h:30
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
QRect availableGeometry
the screen's available geometry in pixels
Definition qscreen.h:46
The QScrollBar widget provides a vertical or horizontal scroll bar.
Definition qscrollbar.h:20
QMatchData filter(const QString &, const QModelIndex &, int) override
Qt::SortOrder sortOrder(const QModelIndex &) const
QIndexMapper indexHint(QString, const QModelIndex &, Qt::SortOrder)
QVariant data(const QModelIndex &item, int role=Qt::DisplayRole) const override
Returns the value for the specified item and role.
int rowCount(const QModelIndex &parent=QModelIndex()) const override
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:76
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
QString right(qsizetype n) const
Returns a substring that contains the n rightmost characters of the string.
Definition qstring.cpp:5180
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition qstring.cpp:5299
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6180
QStringList split(const QString &sep, Qt::SplitBehavior behavior=Qt::KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Splits the string into substrings wherever sep occurs, and returns the list of those strings.
Definition qstring.cpp:7956
qsizetype size() const
Returns the number of characters in this string.
Definition qstring.h:182
QString mid(qsizetype position, qsizetype n=-1) const
Returns a string that contains n characters of this string, starting at the specified position index.
Definition qstring.cpp:5204
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1079
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6498
QString toLower() const &
Definition qstring.h:368
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1095
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1217
void filterOnDemand(int) override
QMatchData filter(const QString &, const QModelIndex &, int) override
\inmodule QtCore
Definition qvariant.h:64
bool isValid() const
Returns true if the storage type of this variant is not QMetaType::UnknownType; otherwise returns fal...
Definition qvariant.h:707
QString toString() const
Returns the variant as a QString if the variant has a userType() including, but not limited to:
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
Qt::LayoutDirection layoutDirection
the layout direction for this widget.
Definition qwidget.h:170
QPointF mapToGlobal(const QPointF &) const
Translates the widget coordinate pos to global screen coordinates.
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
int height
the height of the widget excluding any window frame
Definition qwidget.h:115
QScreen * screen() const
Returns the screen the widget is on.
Definition qwidget.cpp:2503
bool isVisible() const
Definition qwidget.h:874
QOpenGLWidget * widget
[1]
QString str
[2]
QMap< QString, QString > map
[6]
double e
QSet< QString >::iterator it
rect
[4]
Combined button and popup list for selecting options.
LayoutDirection
@ RightToLeft
FocusPolicy
Definition qnamespace.h:105
@ NoFocus
Definition qnamespace.h:106
@ EditRole
@ Key_Tab
Definition qnamespace.h:659
@ Key_Select
@ Key_Return
Definition qnamespace.h:662
@ Key_Enter
Definition qnamespace.h:663
@ Key_PageUp
Definition qnamespace.h:676
@ Key_Backtab
Definition qnamespace.h:660
@ Key_Up
Definition qnamespace.h:673
@ Key_Down
Definition qnamespace.h:675
@ Key_F4
Definition qnamespace.h:688
@ Key_PageDown
Definition qnamespace.h:677
@ Key_Back
Definition qnamespace.h:841
@ Key_Home
Definition qnamespace.h:670
@ Key_End
Definition qnamespace.h:671
@ ScrollBarAlwaysOff
SortOrder
Definition qnamespace.h:120
@ DescendingOrder
Definition qnamespace.h:122
@ AscendingOrder
Definition qnamespace.h:121
@ ControlModifier
@ AltModifier
CaseSensitivity
@ CaseInsensitive
@ CaseSensitive
@ Popup
Definition qnamespace.h:210
@ ItemIsSelectable
@ ItemIsEnabled
@ MatchWildcard
@ MatchRecursive
@ MatchCaseSensitive
@ MatchExactly
@ MatchFixedString
@ MatchRegularExpression
@ MatchEndsWith
@ MatchWrap
@ MatchContains
@ MatchStartsWith
static const int prefixSize
#define Q_UNLIKELY(x)
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLsizei const GLfloat * v
[13]
GLenum mode
const GLfloat * m
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLdouble GLdouble GLdouble GLdouble top
GLenum GLenum GLsizei count
GLint GLint bottom
GLenum target
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint first
GLfloat n
GLsizei GLenum const void * indices
GLfloat GLfloat GLfloat GLfloat h
GLsizei GLsizei GLchar * source
GLenum GLenum GLsizei void GLsizei void * column
struct _cl_event * event
const GLubyte * c
GLdouble GLdouble t
Definition qopenglext.h:243
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLsizei const GLchar *const * path
GLenum GLenum GLsizei void * row
GLfixed GLfixed GLint GLint order
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
static constexpr QChar sep
static QT_BEGIN_NAMESPACE QAsn1Element wrap(quint8 type, const QAsn1Element &child)
static QT_BEGIN_NAMESPACE QVariant hint(QPlatformIntegration::StyleHint h)
QScreen * screen
[1]
Definition main.cpp:29
#define emit
#define Q_UNUSED(x)
QWidget * qobject_cast< QWidget * >(QObject *o)
Definition qwidget.h:786
QSqlQueryModel * model
[16]
QList< int > list
[14]
QObject::connect nullptr
QListView * listView
QString dir
[11]
edit hide()
QItemSelection * selection
[0]
selection select(topLeft, bottomRight)
QNetworkProxy proxy
[0]
bool isValid() const
QIndexMapper indices
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent