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
1088 setCompletionRole(QFileSystemModel::FileNameRole);
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 break;
1312 default:
1313 break;
1314 }
1315 }
1316
1317 if (o != d->popup)
1318 return QObject::eventFilter(o, e);
1319
1320 Q_ASSERT(d->popup);
1321 switch (e->type()) {
1322 case QEvent::KeyPress: {
1323 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
1324
1325 QModelIndex curIndex = d->popup->currentIndex();
1326 QModelIndexList selList = d->popup->selectionModel()->selectedIndexes();
1327
1328 const int key = ke->key();
1329 // In UnFilteredPopup mode, select the current item
1330 if ((key == Qt::Key_Up || key == Qt::Key_Down) && selList.isEmpty() && curIndex.isValid()
1332 d->setCurrentIndex(curIndex);
1333 return true;
1334 }
1335
1336 // Handle popup navigation keys. These are hardcoded because up/down might make the
1337 // widget do something else (lineedit cursor moves to home/end on mac, for instance)
1338 switch (key) {
1339 case Qt::Key_End:
1340 case Qt::Key_Home:
1341 if (ke->modifiers() & Qt::ControlModifier)
1342 return false;
1343 break;
1344
1345 case Qt::Key_Up:
1346 if (!curIndex.isValid()) {
1347 int rowCount = d->proxy->rowCount();
1348 QModelIndex lastIndex = d->proxy->index(rowCount - 1, d->column);
1349 d->setCurrentIndex(lastIndex);
1350 return true;
1351 } else if (curIndex.row() == 0) {
1352 if (d->wrap)
1353 d->setCurrentIndex(QModelIndex());
1354 return true;
1355 }
1356 return false;
1357
1358 case Qt::Key_Down:
1359 if (!curIndex.isValid()) {
1360 QModelIndex firstIndex = d->proxy->index(0, d->column);
1361 d->setCurrentIndex(firstIndex);
1362 return true;
1363 } else if (curIndex.row() == d->proxy->rowCount() - 1) {
1364 if (d->wrap)
1365 d->setCurrentIndex(QModelIndex());
1366 return true;
1367 }
1368 return false;
1369
1370 case Qt::Key_PageUp:
1371 case Qt::Key_PageDown:
1372 return false;
1373 }
1374
1375 // Send the event to the widget. If the widget accepted the event, do nothing
1376 // If the widget did not accept the event, provide a default implementation
1377 d->eatFocusOut = false;
1378 (static_cast<QObject *>(d->widget))->event(ke);
1379 d->eatFocusOut = true;
1380 if (!d->widget || e->isAccepted() || !d->popup->isVisible()) {
1381 // widget lost focus, hide the popup
1382 if (d->widget && (!d->widget->hasFocus()
1383#ifdef QT_KEYPAD_NAVIGATION
1384 || (QApplicationPrivate::keypadNavigationEnabled() && !d->widget->hasEditFocus())
1385#endif
1386 ))
1387 d->popup->hide();
1388 if (e->isAccepted())
1389 return true;
1390 }
1391
1392 // default implementation for keys not handled by the widget when popup is open
1393#if QT_CONFIG(shortcut)
1394 if (ke->matches(QKeySequence::Cancel)) {
1395 d->popup->hide();
1396 return true;
1397 }
1398#endif
1399 switch (key) {
1400#ifdef QT_KEYPAD_NAVIGATION
1401 case Qt::Key_Select:
1402 if (!QApplicationPrivate::keypadNavigationEnabled())
1403 break;
1404#endif
1405 case Qt::Key_Return:
1406 case Qt::Key_Enter:
1407 case Qt::Key_Tab:
1408 d->popup->hide();
1409 if (curIndex.isValid())
1410 d->_q_complete(curIndex);
1411 break;
1412
1413 case Qt::Key_F4:
1414 if (ke->modifiers() & Qt::AltModifier)
1415 d->popup->hide();
1416 break;
1417
1418 case Qt::Key_Backtab:
1419 d->popup->hide();
1420 break;
1421
1422 default:
1423 break;
1424 }
1425
1426 return true;
1427 }
1428
1429#ifdef QT_KEYPAD_NAVIGATION
1430 case QEvent::KeyRelease: {
1431 QKeyEvent *ke = static_cast<QKeyEvent *>(e);
1432 if (QApplicationPrivate::keypadNavigationEnabled() && ke->key() == Qt::Key_Back) {
1433 // Send the event to the 'widget'. This is what we did for KeyPress, so we need
1434 // to do the same for KeyRelease, in case the widget's KeyPress event set
1435 // up something (such as a timer) that is relying on also receiving the
1436 // key release. I see this as a bug in Qt, and should really set it up for all
1437 // the affected keys. However, it is difficult to tell how this will affect
1438 // existing code, and I can't test for every combination!
1439 d->eatFocusOut = false;
1440 static_cast<QObject *>(d->widget)->event(ke);
1441 d->eatFocusOut = true;
1442 }
1443 break;
1444 }
1445#endif
1446
1448#ifdef QT_KEYPAD_NAVIGATION
1449 if (QApplicationPrivate::keypadNavigationEnabled()) {
1450 // if we've clicked in the widget (or its descendant), let it handle the click
1452 if (source) {
1453 QPoint pos = source->mapToGlobal((static_cast<QMouseEvent *>(e))->pos());
1455 if (target && (d->widget->isAncestorOf(target) ||
1456 target == d->widget)) {
1457 d->eatFocusOut = false;
1458 static_cast<QObject *>(target)->event(e);
1459 d->eatFocusOut = true;
1460 return true;
1461 }
1462 }
1463 }
1464#endif
1465 if (!d->popup->underMouse()) {
1466 d->popup->hide();
1467 return true;
1468 }
1469 }
1470 return false;
1471
1474 QCoreApplication::sendEvent(d->widget, e);
1475 break;
1476
1477 default:
1478 return false;
1479 }
1480 return false;
1481}
1482
1494{
1495 Q_D(QCompleter);
1496 QModelIndex idx = d->proxy->currentIndex(false);
1497 d->hiddenBecauseNoMatch = false;
1498 if (d->mode == QCompleter::InlineCompletion) {
1499 if (idx.isValid())
1500 d->_q_complete(idx, true);
1501 return;
1502 }
1503
1504 Q_ASSERT(d->widget);
1505 if ((d->mode == QCompleter::PopupCompletion && !idx.isValid())
1506 || (d->mode == QCompleter::UnfilteredPopupCompletion && d->proxy->rowCount() == 0)) {
1507 if (d->popup)
1508 d->popup->hide(); // no suggestion, hide
1509 d->hiddenBecauseNoMatch = true;
1510 return;
1511 }
1512
1513 popup();
1515 d->setCurrentIndex(idx, false);
1516
1517 d->showPopup(rect);
1518 d->popupRect = rect;
1519}
1520
1531{
1532 Q_D(QCompleter);
1533 return d->proxy->setCurrentRow(row);
1534}
1535
1542{
1543 Q_D(const QCompleter);
1544 return d->proxy->currentRow();
1545}
1546
1553{
1554 Q_D(const QCompleter);
1555 return d->proxy->completionCount();
1556}
1557
1593{
1594 Q_D(QCompleter);
1595 if (d->sorting == sorting)
1596 return;
1597 d->sorting = sorting;
1598 d->proxy->createEngine();
1599 d->proxy->invalidate();
1600}
1601
1603{
1604 Q_D(const QCompleter);
1605 return d->sorting;
1606}
1607
1620{
1621 Q_D(QCompleter);
1622 if (d->column == column)
1623 return;
1624#if QT_CONFIG(listview)
1625 if (QListView *listView = qobject_cast<QListView *>(d->popup))
1627#endif
1628 d->column = column;
1629 d->proxy->invalidate();
1630}
1631
1633{
1634 Q_D(const QCompleter);
1635 return d->column;
1636}
1637
1647{
1648 Q_D(QCompleter);
1649 if (d->role == role)
1650 return;
1651 d->role = role;
1652 d->proxy->invalidate();
1653}
1654
1656{
1657 Q_D(const QCompleter);
1658 return d->role;
1659}
1660
1669{
1670 Q_D(QCompleter);
1671 if (d->wrap == wrap)
1672 return;
1673 d->wrap = wrap;
1674}
1675
1677{
1678 Q_D(const QCompleter);
1679 return d->wrap;
1680}
1681
1690{
1691 Q_D(const QCompleter);
1692 return d->maxVisibleItems;
1693}
1694
1696{
1697 Q_D(QCompleter);
1698 if (Q_UNLIKELY(maxItems < 0)) {
1699 qWarning("QCompleter::setMaxVisibleItems: "
1700 "Invalid max visible items (%d) must be >= 0", maxItems);
1701 return;
1702 }
1703 d->maxVisibleItems = maxItems;
1704}
1705
1715{
1716 Q_D(QCompleter);
1717 if (d->cs == cs)
1718 return;
1719 d->cs = cs;
1720 d->proxy->createEngine();
1721 d->proxy->invalidate();
1722}
1723
1725{
1726 Q_D(const QCompleter);
1727 return d->cs;
1728}
1729
1738{
1739 Q_D(QCompleter);
1740 d->prefix = prefix;
1741 d->proxy->filter(splitPath(prefix));
1742}
1743
1745{
1746 Q_D(const QCompleter);
1747 return d->prefix;
1748}
1749
1756{
1757 Q_D(const QCompleter);
1758 return d->proxy->currentIndex(false);
1759}
1760
1769{
1770 Q_D(const QCompleter);
1771 return pathFromIndex(d->proxy->currentIndex(true));
1772}
1773
1786{
1787 Q_D(const QCompleter);
1788 return d->proxy;
1789}
1790
1803{
1804 Q_D(const QCompleter);
1805 if (!index.isValid())
1806 return QString();
1807
1808 QAbstractItemModel *sourceModel = d->proxy->sourceModel();
1809 if (!sourceModel)
1810 return QString();
1811 bool isFsModel = false;
1812#if QT_CONFIG(filesystemmodel)
1813 isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
1814#endif
1815 if (!isFsModel)
1816 return sourceModel->data(index, d->role).toString();
1817
1818 QModelIndex idx = index;
1820 do {
1821 QString t;
1822#if QT_CONFIG(filesystemmodel)
1823 t = sourceModel->data(idx, QFileSystemModel::FileNameRole).toString();
1824#endif
1825 list.prepend(t);
1826 QModelIndex parent = idx.parent();
1827 idx = parent.sibling(parent.row(), index.column());
1828 } while (idx.isValid());
1829
1830#if !defined(Q_OS_WIN)
1831 if (list.size() == 1) // only the separator or some other text
1832 return list[0];
1833 list[0].clear() ; // the join below will provide the separator
1834#endif
1835
1836 return list.join(QDir::separator());
1837}
1838
1852{
1853 bool isFsModel = false;
1854#if QT_CONFIG(filesystemmodel)
1855 Q_D(const QCompleter);
1856 isFsModel = qobject_cast<QFileSystemModel *>(d->proxy->sourceModel()) != nullptr;
1857#endif
1858
1859 if (!isFsModel || path.isEmpty())
1860 return QStringList(completionPrefix());
1861
1863#if defined(Q_OS_WIN)
1864 if (pathCopy == "\\"_L1 || pathCopy == "\\\\"_L1)
1865 return QStringList(pathCopy);
1866 const bool startsWithDoubleSlash = pathCopy.startsWith("\\\\"_L1);
1867 if (startsWithDoubleSlash)
1868 pathCopy = pathCopy.mid(2);
1869#endif
1870
1871 const QChar sep = QDir::separator();
1872 QStringList parts = pathCopy.split(sep);
1873
1874#if defined(Q_OS_WIN)
1875 if (startsWithDoubleSlash)
1876 parts[0].prepend("\\\\"_L1);
1877#else
1878 if (pathCopy[0] == sep) // readd the "/" at the beginning as the split removed it
1879 parts[0] = u'/';
1880#endif
1881
1882 return parts;
1883}
1884
1920
1921#include "moc_qcompleter.cpp"
1922
1923#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:398
void prepend(rvalue_ref t)
Definition qlist.h:474
void clear()
Definition qlist.h:435
T & value() const
Definition qmap.h:444
iterator erase(const_iterator it)
Definition qmap.h:620
void clear()
Definition qmap.h:290
iterator find(const Key &key)
Definition qmap.h:642
iterator lowerBound(const Key &key)
Definition qmap.h:661
iterator begin()
Definition qmap.h:599
iterator end()
Definition qmap.h:603
const_iterator constBegin() const
Definition qmap.h:601
const_iterator constEnd() const
Definition qmap.h:605
T take(const Key &key)
Definition qmap.h:323
\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:5465
void chop(qsizetype n)
Removes n characters from the end of the string.
Definition qstring.cpp:6351
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:6675
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:2510
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:167
QT_BEGIN_NAMESPACE constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:19
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:21
#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