aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJ-P Nurmi <jpnurmi@qt.io>2016-11-03 10:07:50 +0100
committerJ-P Nurmi <jpnurmi@qt.io>2016-11-03 09:56:37 +0000
commit6f95a086b4d396ff62bc2817bcb1545f60973f38 (patch)
tree9aca931fdaefa5a9f6e6349c454b63f17944f3eb /src
parentb552676670b4df7eb0bb2ffd226b4e316c3d2987 (diff)
QQuickComboBox: key search
[ChangeLog][Controls][ComboBox] Added missing keyboard search functionality. Change-Id: If132f2ca0bca8cdb09de03f584c07eec6fb384f6 Task-number: QTBUG-56884 Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/quicktemplates2/qquickcombobox.cpp107
1 files changed, 68 insertions, 39 deletions
diff --git a/src/quicktemplates2/qquickcombobox.cpp b/src/quicktemplates2/qquickcombobox.cpp
index 23ad5bcc..01f0f699 100644
--- a/src/quicktemplates2/qquickcombobox.cpp
+++ b/src/quicktemplates2/qquickcombobox.cpp
@@ -190,6 +190,9 @@ public:
void updateHighlightedIndex();
void setHighlightedIndex(int index, Highlighting highlight);
+ void keySearch(const QString &text);
+ int match(int start, const QString &text, Qt::MatchFlags flags) const;
+
void createDelegateModel();
bool pressed;
@@ -345,6 +348,65 @@ void QQuickComboBoxPrivate::setHighlightedIndex(int index, Highlighting highligh
emit q->highlighted(index);
}
+void QQuickComboBoxPrivate::keySearch(const QString &text)
+{
+ int index = match(currentIndex + 1, text, Qt::MatchStartsWith | Qt::MatchWrap);
+ if (index != -1)
+ setCurrentIndex(index, Activate);
+}
+
+int QQuickComboBoxPrivate::match(int start, const QString &text, Qt::MatchFlags flags) const
+{
+ Q_Q(const QQuickComboBox);
+ uint matchType = flags & 0x0F;
+ bool wrap = flags & Qt::MatchWrap;
+ Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ int from = start;
+ int to = q->count();
+
+ // iterates twice if wrapping
+ for (int i = 0; (wrap && i < 2) || (!wrap && i < 1); ++i) {
+ for (int idx = from; idx < to; ++idx) {
+ QString t = q->textAt(idx);
+ switch (matchType) {
+ case Qt::MatchExactly:
+ if (t == text)
+ return idx;
+ break;
+ case Qt::MatchRegExp:
+ if (QRegExp(text, cs).exactMatch(t))
+ return idx;
+ break;
+ case Qt::MatchWildcard:
+ if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t))
+ return idx;
+ break;
+ case Qt::MatchStartsWith:
+ if (t.startsWith(text, cs))
+ return idx;
+ break;
+ case Qt::MatchEndsWith:
+ if (t.endsWith(text, cs))
+ return idx;
+ break;
+ case Qt::MatchFixedString:
+ if (t.compare(text, cs) == 0)
+ return idx;
+ break;
+ case Qt::MatchContains:
+ default:
+ if (t.contains(text, cs))
+ return idx;
+ break;
+ }
+ }
+ // prepare for the next iteration
+ from = 0;
+ to = start;
+ }
+ return -1;
+}
+
void QQuickComboBoxPrivate::createDelegateModel()
{
Q_Q(QQuickComboBox);
@@ -770,45 +832,8 @@ QString QQuickComboBox::textAt(int index) const
*/
int QQuickComboBox::find(const QString &text, Qt::MatchFlags flags) const
{
- int itemCount = count();
- uint matchType = flags & 0x0F;
- Qt::CaseSensitivity cs = flags & Qt::MatchCaseSensitive ? Qt::CaseSensitive : Qt::CaseInsensitive;
-
- for (int idx = 0; idx < itemCount; ++idx) {
- QString t = textAt(idx);
- switch (matchType) {
- case Qt::MatchExactly:
- if (t == text)
- return idx;
- break;
- case Qt::MatchRegExp:
- if (QRegExp(text, cs).exactMatch(t))
- return idx;
- break;
- case Qt::MatchWildcard:
- if (QRegExp(text, cs, QRegExp::Wildcard).exactMatch(t))
- return idx;
- break;
- case Qt::MatchStartsWith:
- if (t.startsWith(text, cs))
- return idx;
- break;
- case Qt::MatchEndsWith:
- if (t.endsWith(text, cs))
- return idx;
- break;
- case Qt::MatchFixedString:
- if (t.compare(text, cs) == 0)
- return idx;
- break;
- case Qt::MatchContains:
- default:
- if (t.contains(text, cs))
- return idx;
- break;
- }
- }
- return -1;
+ Q_D(const QQuickComboBox);
+ return d->match(0, text, flags);
}
/*!
@@ -892,6 +917,10 @@ void QQuickComboBox::keyPressEvent(QKeyEvent *event)
event->accept();
break;
default:
+ if (!event->text().isEmpty())
+ d->keySearch(event->text());
+ else
+ event->ignore();
break;
}
}