Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
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
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
379
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
413 QModelIndex parent;
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
424 curParent = 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);
444 QList<int> v;
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
461bool QCompletionEngine::matchHint(const QString &part, const QModelIndex &parent, QMatchData *hint) const
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
487bool QCompletionEngine::lookupCache(const QString &part, const QModelIndex &parent, QMatchData *m) const
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;
553 const CacheItem::const_iterator it = map.lowerBound(part);
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
606 Qt::SortOrder order = sortOrder(parent);
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
753 QList<int> v;
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 (const auto indexes = selection.indexes(); !indexes.isEmpty())
844 index = indexes.first();
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
979: QObject(*new QCompleterPrivate(), parent)
980{
981 Q_D(QCompleter);
982 d->init();
983}
984
990 : QObject(*new QCompleterPrivate(), parent)
991{
992 Q_D(QCompleter);
993 d->init(model);
994}
995
996#if QT_CONFIG(stringlistmodel)
1002: QObject(*new QCompleterPrivate(), parent)
1003{
1004 Q_D(QCompleter);
1005 d->init(new QStringListModel(list, this));
1006}
1007#endif // QT_CONFIG(stringlistmodel)
1008
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 (o == d->widget) {
1300 switch (e->type()) {
1301 case QEvent::FocusOut:
1302 if (d->eatFocusOut) {
1303 d->hiddenBecauseNoMatch = false;
1304 if (d->popup && d->popup->isVisible())
1305 return true;
1306 }
1307 break;
1308 case QEvent::Hide:
1309 if (d->popup)
1310 d->popup->hide();
1311 default:
1312 break;
1313 }
1314 }
1315
1316 if (o != d->popup)
1317 return QObject::eventFilter(o, e);
1318
1319 Q_ASSERT(d->popup);
1320 switch (e->type()) {
1321 case QEvent::KeyPress: {
1322 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
1323
1324 QModelIndex curIndex = d->popup->currentIndex();
1325 QModelIndexList selList = d->popup->selectionModel()->selectedIndexes();
1326
1327 const int key = ke->key();
1328 // In UnFilteredPopup mode, select the current item
1329 if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid()
1331 d->setCurrentIndex(curIndex);
1332 return true;
1333 }
1334
1335 // Handle popup navigation keys. These are hardcoded because up/down might make the
1336 // widget do something else (lineedit cursor moves to home/end on mac, for instance)
1337 switch (key) {
1338 case Qt::Key_End:
1339 case Qt::Key_Home:
1340 if (ke->modifiers() & Qt::ControlModifier)
1341 return false;
1342 break;
1343
1344 case Qt::Key_Up:
1345 if (!curIndex.isValid()) {
1346 int rowCount = d->proxy->rowCount();
1347 QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column);
1348 d->setCurrentIndex(lastIndex);
1349 return true;
1350 } else if (curIndex.row() == 0) {
1351 if (d->wrap)
1352 d->setCurrentIndex(QModelIndex());
1353 return true;
1354 }
1355 return false;
1356
1357 case Qt::Key_Down:
1358 if (!curIndex.isValid()) {
1359 QModelIndex firstIndex = d->proxy->index(0, d->column);
1360 d->setCurrentIndex(firstIndex);
1361 return true;
1362 } else if (curIndex.row() == d->proxy->rowCount() - 1) {
1363 if (d->wrap)
1364 d->setCurrentIndex(QModelIndex());
1365 return true;
1366 }
1367 return false;
1368
1369 case Qt::Key_PageUp:
1370 case Qt::Key_PageDown:
1371 return false;
1372 }
1373
1374 // Send the event to the widget. If the widget accepted the event, do nothing
1375 // If the widget did not accept the event, provide a default implementation
1376 d->eatFocusOut = false;
1377 (static_cast<QObject *>(d->widget))->event(ke);
1378 d->eatFocusOut = true;
1379 if (!d->widget || e->isAccepted() || !d->popup->isVisible()) {
1380 // widget lost focus, hide the popup
1381 if (d->widget && (!d->widget->hasFocus()
1382#ifdef QT_KEYPAD_NAVIGATION
1383 || (QApplicationPrivate::keypadNavigationEnabled() && !d->widget->hasEditFocus())
1384#endif
1385 ))
1386 d->popup->hide();
1387 if (e->isAccepted())
1388 return true;
1389 }
1390
1391 // default implementation for keys not handled by the widget when popup is open
1392#if QT_CONFIG(shortcut)
1393 if (ke->matches(QKeySequence::Cancel)) {
1394 d->popup->hide();
1395 return true;
1396 }
1397#endif
1398 switch (key) {
1399#ifdef QT_KEYPAD_NAVIGATION
1400 case Qt::Key_Select:
1401 if (!QApplicationPrivate::keypadNavigationEnabled())
1402 break;
1403#endif
1404 case Qt::Key_Return:
1405 case Qt::Key_Enter:
1406 case Qt::Key_Tab:
1407 d->popup->hide();
1408 if (curIndex.isValid())
1409 d->_q_complete(curIndex);
1410 break;
1411
1412 case Qt::Key_F4:
1413 if (ke->modifiers() & Qt::AltModifier)
1414 d->popup->hide();
1415 break;
1416
1417 case Qt::Key_Backtab:
1418 d->popup->hide();
1419 break;
1420
1421 default:
1422 break;
1423 }
1424
1425 return true;
1426 }
1427
1428#ifdef QT_KEYPAD_NAVIGATION
1429 case QEvent::KeyRelease: {
1430 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
1431 if (QApplicationPrivate::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) {
1432 // Send the event to the 'widget'. This is what we did for KeyPress, so we need
1433 // to do the same for KeyRelease, in case the widget's KeyPress event set
1434 // up something (such as a timer) that is relying on also receiving the
1435 // key release. I see this as a bug in Qt, and should really set it up for all
1436 // the affected keys. However, it is difficult to tell how this will affect
1437 // existing code, and I can't test for every combination!
1438 d->eatFocusOut = false;
1439 static_cast<QObject *>(d->widget)->event(ke);
1440 d->eatFocusOut = true;
1441 }
1442 break;
1443 }
1444#endif
1445
1447#ifdef QT_KEYPAD_NAVIGATION
1448 if (QApplicationPrivate::keypadNavigationEnabled()) {
1449 // if we've clicked in the widget (or its descendant), let it handle the click
1451 if (source) {
1452 QPoint pos = source->mapToGlobal((static_cast<QMouseEvent *>(e))->pos());
1454 if (target && (d->widget->isAncestorOf(target) ||
1455 target == d->widget)) {
1456 d->eatFocusOut = false;
1457 static_cast<QObject *>(target)->event(e);
1458 d->eatFocusOut = true;
1459 return true;
1460 }
1461 }
1462 }
1463#endif
1464 if (!d->popup->underMouse()) {
1465 d->popup->hide();
1466 return true;
1467 }
1468 }
1469 return false;
1470
1473 QCoreApplication::sendEvent(d->widget, e);
1474 break;
1475
1476 default:
1477 return false;
1478 }
1479 return false;
1480}
1481
1493{
1494 Q_D(QCompleter);
1495 QModelIndex idx = d->proxy->currentIndex(false);
1496 d->hiddenBecauseNoMatch = false;
1497 if (d->mode == QCompleter::InlineCompletion) {
1498 if (idx.isValid())
1499 d->_q_complete(idx, true);
1500 return;
1501 }
1502
1503 Q_ASSERT(d->widget);
1504 if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
1505 || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
1506 if (d->popup)
1507 d->popup->hide(); // no suggestion, hide
1508 d->hiddenBecauseNoMatch = true;
1509 return;
1510 }
1511
1512 popup();
1514 d->setCurrentIndex(idx, false);
1515
1516 d->showPopup(rect);
1517 d->popupRect = rect;
1518}
1519
1530{
1531 Q_D(QCompleter);
1532 return d->proxy->setCurrentRow(row);
1533}
1534
1541{
1542 Q_D(const QCompleter);
1543 return d->proxy->currentRow();
1544}
1545
1552{
1553 Q_D(const QCompleter);
1554 return d->proxy->completionCount();
1555}
1556
1592{
1593 Q_D(QCompleter);
1594 if (d->sorting == sorting)
1595 return;
1596 d->sorting = sorting;
1597 d->proxy->createEngine();
1598 d->proxy->invalidate();
1599}
1600
1602{
1603 Q_D(const QCompleter);
1604 return d->sorting;
1605}
1606
1619{
1620 Q_D(QCompleter);
1621 if (d->column == column)
1622 return;
1623#if QT_CONFIG(listview)
1624 if (QListView *listView = qobject_cast<QListView *>(d->popup))
1626#endif
1627 d->column = column;
1628 d->proxy->invalidate();
1629}
1630
1632{
1633 Q_D(const QCompleter);
1634 return d->column;
1635}
1636
1646{
1647 Q_D(QCompleter);
1648 if (d->role == role)
1649 return;
1650 d->role = role;
1651 d->proxy->invalidate();
1652}
1653
1655{
1656 Q_D(const QCompleter);
1657 return d->role;
1658}
1659
1668{
1669 Q_D(QCompleter);
1670 if (d->wrap == wrap)
1671 return;
1672 d->wrap = wrap;
1673}
1674
1676{
1677 Q_D(const QCompleter);
1678 return d->wrap;
1679}
1680
1689{
1690 Q_D(const QCompleter);
1691 return d->maxVisibleItems;
1692}
1693
1695{
1696 Q_D(QCompleter);
1697 if (Q_UNLIKELY(maxItems < 0)) {
1698 qWarning("QCompleter::setMaxVisibleItems: "
1699 "Invalid max visible items (%d) must be >= 0", maxItems);
1700 return;
1701 }
1702 d->maxVisibleItems = maxItems;
1703}
1704
1714{
1715 Q_D(QCompleter);
1716 if (d->cs == cs)
1717 return;
1718 d->cs = cs;
1719 d->proxy->createEngine();
1720 d->proxy->invalidate();
1721}
1722
1724{
1725 Q_D(const QCompleter);
1726 return d->cs;
1727}
1728
1737{
1738 Q_D(QCompleter);
1739 d->prefix = prefix;
1740 d->proxy->filter(splitPath(prefix));
1741}
1742
1744{
1745 Q_D(const QCompleter);
1746 return d->prefix;
1747}
1748
1755{
1756 Q_D(const QCompleter);
1757 return d->proxy->currentIndex(false);
1758}
1759
1768{
1769 Q_D(const QCompleter);
1770 return pathFromIndex(d->proxy->currentIndex(true));
1771}
1772
1785{
1786 Q_D(const QCompleter);
1787 return d->proxy;
1788}
1789
1802{
1803 Q_D(const QCompleter);
1804 if (!index.isValid())
1805 return QString();
1806
1807 QAbstractItemModel *sourceModel = d->proxy->sourceModel();
1808 if (!sourceModel)
1809 return QString();
1810 bool isFsModel = false;
1811#if QT_CONFIG(filesystemmodel)
1812 isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
1813#endif
1814 if (!isFsModel)
1815 return sourceModel->data(index, d->role).toString();
1816
1817 QModelIndex idx = index;
1819 do {
1820 QString t;
1821#if QT_CONFIG(filesystemmodel)
1822 t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
1823#endif
1824 list.prepend(t);
1825 QModelIndex parent = idx.parent();
1826 idx = parent.sibling(parent.row(), index.column());
1827 } while (idx.isValid());
1828
1829#if !defined(Q_OS_WIN)
1830 if (list.size() == 1) // only the separator or some other text
1831 return list[0];
1832 list[0].clear() ; // the join below will provide the separator
1833#endif
1834
1835 return list.join(QDir::separator());
1836}
1837
1851{
1852 bool isFsModel = false;
1853#if QT_CONFIG(filesystemmodel)
1854 Q_D(const QCompleter);
1855 isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
1856#endif
1857
1858 if (!isFsModel || path.isEmpty())
1859 return QStringList(completionPrefix());
1860
1862#if defined(Q_OS_WIN)
1863 if (pathCopy == "\\"_L1 || pathCopy == "\\\\"_L1)
1864 return QStringList(pathCopy);
1865 const bool startsWithDoubleSlash = pathCopy.startsWith("\\\\"_L1);
1866 if (startsWithDoubleSlash)
1867 pathCopy = pathCopy.mid(2);
1868#endif
1869
1870 const QChar sep = QDir::separator();
1871 QStringList parts = pathCopy.split(sep);
1872
1873#if defined(Q_OS_WIN)
1874 if (startsWithDoubleSlash)
1875 parts[0].prepend("\\\\"_L1);
1876#else
1877 if (pathCopy[0] == sep) // readd the "/" at the beginning as the split removed it
1878 parts[0] = u'/';
1879#endif
1880
1881 return parts;
1882}
1883
1919
1920#include "moc_qcompleter.cpp"
1921
1922#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 setModel(QAbstractItemModel *model)
Sets the model for the view to present.
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
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)
QMap< QString, QMatchData > CacheItem
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:209
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
Type type() const
Returns the event type.
Definition qcoreevent.h:304
bool isAccepted() const
Definition qcoreevent.h:308
The QFileSystemModel class provides a data model for the local filesystem.
int cost() 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:424
The QListView class provides a list or icon view onto a model.
Definition qlistview.h:17
void setModelColumn(int column)
qsizetype size() const noexcept
Definition qlist.h:397
void prepend(rvalue_ref t)
Definition qlist.h:473
void clear()
Definition qlist.h:434
T & value() const
Definition qmap.h:443
iterator erase(const_iterator it)
Definition qmap.h:619
void clear()
Definition qmap.h:289
iterator find(const Key &key)
Definition qmap.h:641
iterator lowerBound(const Key &key)
Definition qmap.h:660
iterator begin()
Definition qmap.h:598
iterator end()
Definition qmap.h:602
const_iterator constBegin() const
Definition qmap.h:600
const_iterator constEnd() const
Definition qmap.h:604
T take(const Key &key)
Definition qmap.h:322
\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:196
\inmodule QtCore
Definition qobject.h:103
void installEventFilter(QObject *filterObj)
Installs an event filter filterObj on this object.
Definition qobject.cpp:2339
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:346
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
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:1389
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:1555
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
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:25
\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
If the database supports returning the size of a query (see QSqlDriver::hasFeature()),...
\inmodule QtCore
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
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:5455
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6340
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
QString right(qsizetype n) const &
Definition qstring.h:375
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
Definition qstring.h:1226
int compare(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.cpp:6664
static QString static QString qsizetype Qt::CaseSensitivity cs
Definition qstring.h:291
QString toLower() const &
Definition qstring.h:435
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1240
bool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition qstring.h:1369
void filterOnDemand(int) override
QMatchData filter(const QString &, const QModelIndex &, int) override
\inmodule QtCore
Definition qvariant.h:65
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:2496
QOpenGLWidget * widget
[1]
QString str
[2]
QMap< QString, QString > map
[6]
QSet< QString >::iterator it
rect
[4]
Combined button and popup list for selecting options.
Definition qcompare.h:63
LayoutDirection
@ RightToLeft
FocusPolicy
Definition qnamespace.h:106
@ NoFocus
Definition qnamespace.h:107
@ EditRole
@ Key_Tab
Definition qnamespace.h:664
@ Key_Select
@ Key_Return
Definition qnamespace.h:667
@ Key_Enter
Definition qnamespace.h:668
@ Key_PageUp
Definition qnamespace.h:681
@ Key_Backtab
Definition qnamespace.h:665
@ Key_Up
Definition qnamespace.h:678
@ Key_Down
Definition qnamespace.h:680
@ Key_F4
Definition qnamespace.h:693
@ Key_PageDown
Definition qnamespace.h:682
@ Key_Back
Definition qnamespace.h:846
@ Key_Home
Definition qnamespace.h:675
@ Key_End
Definition qnamespace.h:676
@ ScrollBarAlwaysOff
SortOrder
Definition qnamespace.h:121
@ DescendingOrder
Definition qnamespace.h:123
@ AscendingOrder
Definition qnamespace.h:122
@ ControlModifier
@ AltModifier
CaseSensitivity
@ CaseInsensitive
@ CaseSensitive
@ Popup
Definition qnamespace.h:211
@ ItemIsSelectable
@ ItemIsEnabled
@ MatchWildcard
@ MatchRecursive
@ MatchCaseSensitive
@ MatchExactly
@ MatchFixedString
@ MatchRegularExpression
@ MatchEndsWith
@ MatchWrap
@ MatchContains
@ MatchStartsWith
static const int prefixSize
#define Q_UNLIKELY(x)
QList< QString > QStringList
Constructs a string list that contains the given string, str.
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define qWarning
Definition qlogging.h:166
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:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
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 GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLint bottom
GLenum target
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
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