From 8b6d6d4832ea8ed5f9857d5ddf06408ee9d0b4e0 Mon Sep 17 00:00:00 2001 From: Alexey Chernov <4ernov@gmail.com> Date: Tue, 22 Mar 2016 01:01:13 +0300 Subject: Do its best in QComboBox to map completer's index Add additional code paths to map the index passed by QCompleter in its activated() signal in case when QCompleter's model isn't the same as QComboBox's one. Task-number: QTBUG-52027 Change-Id: I1d74037fccbe19962bb7f242aa7b1c2441aa5d54 Reviewed-by: Gabriel de Dietrich --- src/widgets/widgets/qcombobox.cpp | 16 +++++- .../widgets/widgets/qcombobox/tst_qcombobox.cpp | 58 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 0dde839629..4a49542fdd 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -192,7 +192,21 @@ void QComboBoxPrivate::_q_completerActivated(const QModelIndex &index) if (index.isValid() && q->completer()) { QAbstractProxyModel *proxy = qobject_cast(q->completer()->completionModel()); if (proxy) { - q->setCurrentIndex(proxy->mapToSource(index).row()); + const QModelIndex &completerIndex = proxy->mapToSource(index); + int row = -1; + if (completerIndex.model() == model) { + row = completerIndex.row(); + } else { + // if QCompleter uses a proxy model to host widget's one - map again + QAbstractProxyModel *completerProxy = qobject_cast(q->completer()->model()); + if (completerProxy && completerProxy->sourceModel() == model) { + row = completerProxy->mapToSource(completerIndex).row(); + } else { + QString match = q->completer()->model()->data(completerIndex).toString(); + row = q->findText(match, matchFlags()); + } + } + q->setCurrentIndex(row); emitActivated(currentIndex); } } diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index b882055888..75b75ad44c 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -168,6 +168,7 @@ private slots: void task_QTBUG_49831_scrollerNotActivated(); void task_QTBUG_56693_itemFontFromModel(); void inputMethodUpdate(); + void task_QTBUG_52027_mapCompleterIndex(); private: PlatformInputContext m_platformInputContext; @@ -3399,5 +3400,62 @@ void tst_QComboBox::inputMethodUpdate() QVERIFY(m_platformInputContext.m_updateCallCount >= 1); } +void tst_QComboBox::task_QTBUG_52027_mapCompleterIndex() +{ + QStringList words; + words << "" << "foobar1" << "foobar2"; + + QStringList altWords; + altWords << "foobar2" << "hello" << "," << "world" << "" << "foobar0" << "foobar1"; + + QComboBox cbox; + setFrameless(&cbox); + cbox.setEditable(true); + cbox.setInsertPolicy(QComboBox::NoInsert); + cbox.addItems(words); + + QCompleter *completer = new QCompleter(altWords); + completer->setCaseSensitivity(Qt::CaseInsensitive); + cbox.setCompleter(completer); + + QSignalSpy spy(&cbox, SIGNAL(activated(int))); + QCOMPARE(spy.count(), 0); + cbox.move(200, 200); + cbox.show(); + QApplication::setActiveWindow(&cbox); + QVERIFY(QTest::qWaitForWindowActive(&cbox)); + + QTest::keyClicks(&cbox, "foobar2"); + QApplication::processEvents(); + QTRY_VERIFY(completer->popup()); + QTest::keyClick(completer->popup(), Qt::Key_Down); + QApplication::processEvents(); + QTest::keyClick(completer->popup(), Qt::Key_Return); + QApplication::processEvents(); + QList arguments = spy.takeLast(); + QCOMPARE(arguments.at(0).toInt(), 2); + + cbox.lineEdit()->selectAll(); + cbox.lineEdit()->del(); + + QSortFilterProxyModel* model = new QSortFilterProxyModel(); + model->setSourceModel(cbox.model()); + model->setFilterFixedString("foobar1"); + completer->setModel(model); + + QApplication::setActiveWindow(&cbox); + QVERIFY(QTest::qWaitForWindowActive(&cbox)); + + QTest::keyClicks(&cbox, "foobar1"); + QApplication::processEvents(); + QTRY_VERIFY(completer->popup()); + QTest::keyClick(completer->popup(), Qt::Key_Down); + QApplication::processEvents(); + QTest::keyClick(completer->popup(), Qt::Key_Return); + QApplication::processEvents(); + arguments = spy.takeLast(); + QCOMPARE(arguments.at(0).toInt(), 1); +} + QTEST_MAIN(tst_QComboBox) #include "tst_qcombobox.moc" -- cgit v1.2.3