diff options
author | Oto Magaldadze <omagaldadze@gmail.com> | 2012-12-31 14:11:25 +0400 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-20 23:45:06 +0200 |
commit | 6b95130faa31307579cb3711cab2101d07d20823 (patch) | |
tree | e67c0d181eaf5ea8545417039c049e088b9ba0f6 /src | |
parent | ef5455429f30ec9c8236e5240ed8f96af6ca9271 (diff) |
QCompleter::setFilterMode() add property filterMode.
QCompleter::setFilterMode(Qt::MatchContains) will enable filtering
out entries that contain typed characters in any place, instead of the
default behavior when only those entries that start with typed characters
are displayed. Qt::MatchEndsWith is also possible.
QCompleter::setFilterMode(Qt::MatchStartsWith) will bring the default
behavior back.
Task-number: QTBUG-3414
Change-Id: I3845704c59eb8fc401e9a650c54a9c934ed28c2e
Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/widgets/util/qcompleter.cpp | 105 | ||||
-rw-r--r-- | src/widgets/util/qcompleter.h | 4 | ||||
-rw-r--r-- | src/widgets/util/qcompleter_p.h | 1 |
3 files changed, 94 insertions, 16 deletions
diff --git a/src/widgets/util/qcompleter.cpp b/src/widgets/util/qcompleter.cpp index 18c8ed2bd2..97e6a04992 100644 --- a/src/widgets/util/qcompleter.cpp +++ b/src/widgets/util/qcompleter.cpp @@ -82,7 +82,8 @@ QCompleter::CaseSensitivelySortedModel or QCompleter::CaseInsensitivelySortedModel as the argument. On large models, this can lead to significant performance improvements, because QCompleter - can then use binary search instead of linear search. + can then use binary search instead of linear search. The binary search only + works when the filterMode is Qt::MatchStartsWith. The model can be a \l{QAbstractListModel}{list model}, a \l{QAbstractTableModel}{table model}, or a @@ -199,16 +200,18 @@ void QCompletionModel::setSourceModel(QAbstractItemModel *source) void QCompletionModel::createEngine() { bool sortedEngine = false; - switch (c->sorting) { - case QCompleter::UnsortedModel: - sortedEngine = false; - break; - case QCompleter::CaseSensitivelySortedModel: - sortedEngine = c->cs == Qt::CaseSensitive; - break; - case QCompleter::CaseInsensitivelySortedModel: - sortedEngine = c->cs == Qt::CaseInsensitive; - break; + if (c->filterMode == Qt::MatchStartsWith) { + switch (c->sorting) { + case QCompleter::UnsortedModel: + sortedEngine = false; + break; + case QCompleter::CaseSensitivelySortedModel: + sortedEngine = c->cs == Qt::CaseSensitive; + break; + case QCompleter::CaseInsensitivelySortedModel: + sortedEngine = c->cs == Qt::CaseInsensitive; + break; + } } if (sortedEngine) @@ -522,6 +525,8 @@ bool QCompletionEngine::lookupCache(QString part, const QModelIndex& parent, QMa // When the cache size exceeds 1MB, it clears out about 1/2 of the cache. void QCompletionEngine::saveInCache(QString part, const QModelIndex& parent, const QMatchData& m) { + if (c->filterMode == Qt::MatchEndsWith) + return; QMatchData old = cache[parent].take(part); cost = cost + m.indices.cost() - old.indices.cost(); if (cost * sizeof(int) > 1024 * 1024) { @@ -703,9 +708,35 @@ int QUnsortedModelEngine::buildIndices(const QString& str, const QModelIndex& pa for (i = 0; i < indices.count() && count != n; ++i) { QModelIndex idx = model->index(indices[i], c->column, parent); - QString data = model->data(idx, c->role).toString(); - if (!data.startsWith(str, c->cs) || !(model->flags(idx) & Qt::ItemIsSelectable)) + + if (!(model->flags(idx) & Qt::ItemIsSelectable)) continue; + + QString data = model->data(idx, c->role).toString(); + + switch (c->filterMode) { + case Qt::MatchStartsWith: + if (!data.startsWith(str, c->cs)) + continue; + break; + case Qt::MatchContains: + if (!data.contains(str, c->cs)) + continue; + break; + case Qt::MatchEndsWith: + if (!data.endsWith(str, c->cs)) + continue; + break; + case Qt::MatchExactly: + case Qt::MatchFixedString: + case Qt::MatchCaseSensitive: + case Qt::MatchRegExp: + case Qt::MatchWildcard: + case Qt::MatchWrap: + case Qt::MatchRecursive: + Q_UNREACHABLE(); + break; + } m->indices.append(indices[i]); ++count; if (m->exactMatchIndex == -1 && QString::compare(data, str, c->cs) == 0) { @@ -773,9 +804,9 @@ QMatchData QUnsortedModelEngine::filter(const QString& part, const QModelIndex& /////////////////////////////////////////////////////////////////////////////// QCompleterPrivate::QCompleterPrivate() -: widget(0), proxy(0), popup(0), cs(Qt::CaseSensitive), role(Qt::EditRole), column(0), - maxVisibleItems(7), sorting(QCompleter::UnsortedModel), wrap(true), eatFocusOut(true), - hiddenBecauseNoMatch(false) +: widget(0), proxy(0), popup(0), filterMode(Qt::MatchStartsWith), cs(Qt::CaseSensitive), + role(Qt::EditRole), column(0), maxVisibleItems(7), sorting(QCompleter::UnsortedModel), + wrap(true), eatFocusOut(true), hiddenBecauseNoMatch(false) { } @@ -1098,6 +1129,48 @@ QCompleter::CompletionMode QCompleter::completionMode() const } /*! + \property QCompleter::filterMode + \brief how the filtering is performed + \since 5.2 + + If filterMode is set to Qt::MatchStartsWith, only those entries that start + with the typed characters will be displayed. Qt::MatchContains will display + the entries that contain the typed characters, and Qt::MatchEndsWith the + ones that end with the typed characters. + + Currently, only these three modes are implemented. Setting filterMode to + any other Qt::MatchFlag will issue a warning, and no action will be + performed. + + The default mode is Qt::MatchStartsWith. +*/ + +void QCompleter::setFilterMode(Qt::MatchFlags filterMode) +{ + Q_D(QCompleter); + + if (d->filterMode == filterMode) + return; + + if (filterMode != Qt::MatchStartsWith + && filterMode != Qt::MatchContains + && filterMode != Qt::MatchEndsWith) { + qWarning("Unhandled QCompleter::filterMode flag is used."); + return; + } + + d->filterMode = filterMode; + d->proxy->createEngine(); + d->proxy->invalidate(); +} + +Qt::MatchFlags QCompleter::filterMode() const +{ + Q_D(const QCompleter); + return d->filterMode; +} + +/*! Sets the popup used to display completions to \a popup. QCompleter takes ownership of the view. diff --git a/src/widgets/util/qcompleter.h b/src/widgets/util/qcompleter.h index 737d9f5fba..c9533d5474 100644 --- a/src/widgets/util/qcompleter.h +++ b/src/widgets/util/qcompleter.h @@ -63,6 +63,7 @@ class Q_WIDGETS_EXPORT QCompleter : public QObject Q_OBJECT Q_PROPERTY(QString completionPrefix READ completionPrefix WRITE setCompletionPrefix) Q_PROPERTY(ModelSorting modelSorting READ modelSorting WRITE setModelSorting) + Q_PROPERTY(Qt::MatchFlags filterMode READ filterMode WRITE setFilterMode) Q_PROPERTY(CompletionMode completionMode READ completionMode WRITE setCompletionMode) Q_PROPERTY(int completionColumn READ completionColumn WRITE setCompletionColumn) Q_PROPERTY(int completionRole READ completionRole WRITE setCompletionRole) @@ -99,6 +100,9 @@ public: void setCompletionMode(CompletionMode mode); CompletionMode completionMode() const; + void setFilterMode(Qt::MatchFlags filterMode); + Qt::MatchFlags filterMode() const; + QAbstractItemView *popup() const; void setPopup(QAbstractItemView *popup); diff --git a/src/widgets/util/qcompleter_p.h b/src/widgets/util/qcompleter_p.h index 26d539a57b..1f890e0114 100644 --- a/src/widgets/util/qcompleter_p.h +++ b/src/widgets/util/qcompleter_p.h @@ -82,6 +82,7 @@ public: QCompletionModel *proxy; QAbstractItemView *popup; QCompleter::CompletionMode mode; + Qt::MatchFlags filterMode; QString prefix; Qt::CaseSensitivity cs; |