summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp')
-rw-r--r--tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp1519
1 files changed, 1519 insertions, 0 deletions
diff --git a/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
new file mode 100644
index 0000000000..ccf3c449b3
--- /dev/null
+++ b/tests/auto/widgets/util/qcompleter/tst_qcompleter.cpp
@@ -0,0 +1,1519 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include <QtGui>
+#include <QtWidgets>
+#include <QtDebug>
+#include <QPair>
+#include <QList>
+#include <QPointer>
+
+#include "../../../../shared/filesystem.h"
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+class CsvCompleter : public QCompleter
+{
+ Q_OBJECT
+public:
+ CsvCompleter(QObject *parent = 0) : QCompleter(parent), csv(true) { }
+
+ QString pathFromIndex(const QModelIndex& sourceIndex) const;
+
+ void setCsvCompletion(bool set) { csv = set; }
+
+protected:
+ QStringList splitPath(const QString &path) const {
+ return csv ? path.split(",") : QCompleter::splitPath(path);
+ }
+
+private:
+ bool csv;
+};
+
+QString CsvCompleter::pathFromIndex(const QModelIndex& si) const
+{
+ if (!csv)
+ return QCompleter::pathFromIndex(si);
+
+ if (!si.isValid())
+ return QString();
+
+ QModelIndex idx = si;
+ QStringList list;
+ do {
+ QString t = model()->data(idx, completionRole()).toString();
+ list.prepend(t);
+ QModelIndex parent = idx.parent();
+ idx = parent.sibling(parent.row(), si.column());
+ } while (idx.isValid());
+
+ if (list.count() == 1)
+ return list[0];
+ return list.join(",");
+}
+
+class tst_QCompleter : public QObject
+{
+ Q_OBJECT
+public:
+ tst_QCompleter();
+ ~tst_QCompleter();
+
+private slots:
+ void getSetCheck();
+
+ void multipleWidgets();
+ void focusIn();
+
+ void csMatchingOnCsSortedModel_data();
+ void csMatchingOnCsSortedModel();
+ void ciMatchingOnCiSortedModel_data();
+ void ciMatchingOnCiSortedModel();
+
+ void ciMatchingOnCsSortedModel_data();
+ void ciMatchingOnCsSortedModel();
+ void csMatchingOnCiSortedModel_data();
+ void csMatchingOnCiSortedModel();
+
+ void directoryModel_data();
+ void directoryModel();
+ void fileSystemModel_data();
+ void fileSystemModel();
+
+ void changingModel_data();
+ void changingModel();
+
+ void sortedEngineRowCount_data();
+ void sortedEngineRowCount();
+ void unsortedEngineRowCount_data();
+ void unsortedEngineRowCount();
+
+ void currentRow();
+ void sortedEngineMapFromSource();
+ void unsortedEngineMapFromSource();
+
+ void historySearch();
+
+ void modelDeletion();
+ void setters();
+
+ void dynamicSortOrder();
+ void disabledItems();
+
+ // task-specific tests below me
+ void task178797_activatedOnReturn();
+ void task189564_omitNonSelectableItems();
+ void task246056_setCompletionPrefix();
+ void task250064_lostFocus();
+
+ void task253125_lineEditCompletion_data();
+ void task253125_lineEditCompletion();
+ void task247560_keyboardNavigation();
+ void QTBUG_14292_filesystem();
+
+private:
+ void filter(bool assync = false);
+ void testRowCount();
+ enum ModelType {
+ CASE_SENSITIVELY_SORTED_MODEL,
+ CASE_INSENSITIVELY_SORTED_MODEL,
+ DIRECTORY_MODEL,
+ HISTORY_MODEL,
+ FILESYSTEM_MODEL
+ };
+ void setSourceModel(ModelType);
+
+ CsvCompleter *completer;
+ QTreeWidget *treeWidget;
+ const int completionColumn;
+ const int columnCount;
+};
+
+tst_QCompleter::tst_QCompleter() : completer(0), completionColumn(0), columnCount(3)
+{
+ treeWidget = new QTreeWidget;
+ treeWidget->setColumnCount(columnCount);
+}
+
+tst_QCompleter::~tst_QCompleter()
+{
+ delete treeWidget;
+ delete completer;
+}
+
+void tst_QCompleter::setSourceModel(ModelType type)
+{
+ QString text;
+ QTreeWidgetItem *parent, *child;
+ treeWidget->clear();
+ switch(type) {
+ case CASE_SENSITIVELY_SORTED_MODEL:
+ // Creates a tree model with top level items P0, P1, .., p0, p1,..
+ // Each of these items parents have children (for P0 - c0P0, c1P0,...)
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < 5; j++) {
+ parent = new QTreeWidgetItem(treeWidget);
+ text.sprintf("%c%i", i == 0 ? 'P' : 'p', j);
+ parent->setText(completionColumn, text);
+ for (int k = 0; k < 5; k++) {
+ child = new QTreeWidgetItem(parent);
+ QString t = QString().sprintf("c%i", k) + text;
+ child->setText(completionColumn, t);
+ }
+ }
+ }
+ completer->setModel(treeWidget->model());
+ completer->setCompletionColumn(completionColumn);
+ break;
+ case CASE_INSENSITIVELY_SORTED_MODEL:
+ case HISTORY_MODEL:
+ // Creates a tree model with top level items P0, p0, P1, p1,...
+ // Each of these items have children c0p0, c1p0,..
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 2; j++) {
+ parent = new QTreeWidgetItem(treeWidget);
+ text.sprintf("%c%i", j == 0 ? 'P' : 'p', i);
+ parent->setText(completionColumn, text);
+ for (int k = 0; k < 5; k++) {
+ child = new QTreeWidgetItem(parent);
+ QString t = QString().sprintf("c%i", k) + text;
+ child->setText(completionColumn, t);
+ }
+ }
+ }
+ completer->setModel(treeWidget->model());
+ completer->setCompletionColumn(completionColumn);
+ if (type == CASE_INSENSITIVELY_SORTED_MODEL)
+ break;
+ parent = new QTreeWidgetItem(treeWidget);
+ parent->setText(completionColumn, QLatin1String("p3,c3p3"));
+ parent = new QTreeWidgetItem(treeWidget);
+ parent->setText(completionColumn, QLatin1String("p2,c4p2"));
+ break;
+ case DIRECTORY_MODEL:
+ completer->setCsvCompletion(false);
+ completer->setModel(new QDirModel(completer));
+ completer->setCompletionColumn(0);
+ break;
+ case FILESYSTEM_MODEL:
+ completer->setCsvCompletion(false);
+ {
+ QFileSystemModel *m = new QFileSystemModel(completer);
+ m->setRootPath("/");
+ completer->setModel(m);
+ }
+ completer->setCompletionColumn(0);
+ break;
+ default:
+ qDebug() << "Invalid type";
+ }
+}
+
+void tst_QCompleter::filter(bool assync)
+{
+ QFETCH(QString, filterText);
+ QFETCH(QString, step);
+ QFETCH(QString, completion);
+ QFETCH(QString, completionText);
+
+ if (filterText.compare("FILTERING_OFF", Qt::CaseInsensitive) == 0) {
+ completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ return;
+ }
+
+ int times = 0;
+retry:
+
+ completer->setCompletionPrefix(filterText);
+
+ for (int i = 0; i < step.length(); i++) {
+ int row = completer->currentRow();
+ switch (step[i].toUpper().toAscii()) {
+ case 'P': --row; break;
+ case 'N': ++row; break;
+ case 'L': row = completer->completionCount() - 1; break;
+ case 'F': row = 0; break;
+ default:
+ QFAIL(qPrintable(QString(
+ "Problem with 'step' value in test data: %1 (only P, N, L and F are allowed)."
+ ).arg(step[i])));
+ }
+ completer->setCurrentRow(row);
+ }
+
+ int r = QString::compare(completer->currentCompletion(), completionText, completer->caseSensitivity());
+ if (assync && r && times < 10) {
+ times++;
+ QTest::qWait(50*times);
+ goto retry;
+ }
+ QVERIFY(!r);
+}
+
+// Testing get/set functions
+void tst_QCompleter::getSetCheck()
+{
+ QStandardItemModel model(3,3);
+ QCompleter completer(&model);
+
+ // QString QCompleter::completionPrefix()
+ // void QCompleter::setCompletionPrefix(QString)
+ completer.setCompletionPrefix(QString("te"));
+ QCOMPARE(completer.completionPrefix(), QString("te"));
+ completer.setCompletionPrefix(QString());
+ QCOMPARE(completer.completionPrefix(), QString());
+
+ // ModelSorting QCompleter::modelSorting()
+ // void QCompleter::setModelSorting(ModelSorting)
+ completer.setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ QCOMPARE(completer.modelSorting(), QCompleter::CaseSensitivelySortedModel);
+ completer.setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ QCOMPARE(completer.modelSorting(), QCompleter::CaseInsensitivelySortedModel);
+ completer.setModelSorting(QCompleter::UnsortedModel);
+ QCOMPARE(completer.modelSorting(), QCompleter::UnsortedModel);
+
+ // CompletionMode QCompleter::completionMode()
+ // void QCompleter::setCompletionMode(CompletionMode)
+ QCOMPARE(completer.completionMode(), QCompleter::PopupCompletion); // default value
+ completer.setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ QCOMPARE(completer.completionMode(), QCompleter::UnfilteredPopupCompletion);
+ completer.setCompletionMode(QCompleter::InlineCompletion);
+ QCOMPARE(completer.completionMode(), QCompleter::InlineCompletion);
+
+ // int QCompleter::completionColumn()
+ // void QCompleter::setCompletionColumn(int)
+ completer.setCompletionColumn(2);
+ QCOMPARE(completer.completionColumn(), 2);
+ completer.setCompletionColumn(1);
+ QCOMPARE(completer.completionColumn(), 1);
+
+ // int QCompleter::completionRole()
+ // void QCompleter::setCompletionRole(int)
+ QCOMPARE(completer.completionRole(), static_cast<int>(Qt::EditRole)); // default value
+ completer.setCompletionRole(Qt::DisplayRole);
+ QCOMPARE(completer.completionRole(), static_cast<int>(Qt::DisplayRole));
+
+ // int QCompleter::maxVisibleItems()
+ // void QCompleter::setMaxVisibleItems(int)
+ QCOMPARE(completer.maxVisibleItems(), 7); // default value
+ completer.setMaxVisibleItems(10);
+ QCOMPARE(completer.maxVisibleItems(), 10);
+ QTest::ignoreMessage(QtWarningMsg, "QCompleter::setMaxVisibleItems: "
+ "Invalid max visible items (-2147483648) must be >= 0");
+ completer.setMaxVisibleItems(INT_MIN);
+ QCOMPARE(completer.maxVisibleItems(), 10); // Cannot be set to something negative => old value
+
+ // Qt::CaseSensitivity QCompleter::caseSensitivity()
+ // void QCompleter::setCaseSensitivity(Qt::CaseSensitivity)
+ QCOMPARE(completer.caseSensitivity(), Qt::CaseSensitive); // default value
+ completer.setCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(completer.caseSensitivity(), Qt::CaseInsensitive);
+
+ // bool QCompleter::wrapAround()
+ // void QCompleter::setWrapAround(bool)
+ QCOMPARE(completer.wrapAround(), true); // default value
+ completer.setWrapAround(false);
+ QCOMPARE(completer.wrapAround(), false);
+}
+
+void tst_QCompleter::csMatchingOnCsSortedModel_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseSensitive);
+ setSourceModel(CASE_SENSITIVELY_SORTED_MODEL);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<QString>("step");
+ QTest::addColumn<QString>("completion");
+ QTest::addColumn<QString>("completionText");
+
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+
+ // Plain text filter
+ QTest::newRow("()") << "" << "" << "P0" << "P0";
+ QTest::newRow("()F") << "" << "F" << "P0" << "P0";
+ QTest::newRow("()L") << "" << "L" << "p4" << "p4";
+ QTest::newRow("()L") << "" << "L" << "p4" << "p4";
+ QTest::newRow("()N") << "" << "N" << "P1" << "P1";
+ QTest::newRow("(P)") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)F") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)L") << "P" << "L" << "P4" << "P4";
+ QTest::newRow("(p)") << "p" << "" << "p0" << "p0";
+ QTest::newRow("(p)N") << "p" << "N" << "p1" << "p1";
+ QTest::newRow("(p)NN") << "p" << "NN" << "p2" << "p2";
+ QTest::newRow("(p)NNN") << "p" << "NNN" << "p3" << "p3";
+ QTest::newRow("(p)NNNN") << "p" << "NNNN" << "p4" << "p4";
+ QTest::newRow("(p1)") << "p1" << "" << "p1" << "p1";
+ QTest::newRow("(p11)") << "p11" << "" << "" << "";
+
+ // Tree filter
+ QTest::newRow("(P0,)") << "P0," << "" << "c0P0" << "P0,c0P0";
+ QTest::newRow("(P0,c)") << "P0,c" << "" << "c0P0" << "P0,c0P0";
+ QTest::newRow("(P0,c1)") << "P0,c1" << "" << "c1P0" << "P0,c1P0";
+ QTest::newRow("(P0,c3P0)") << "P0,c3P0" << "" << "c3P0" << "P0,c3P0";
+ QTest::newRow("(P3,c)F") << "P3,c" << "F" << "c0P3" << "P3,c0P3";
+ QTest::newRow("(P3,c)L") << "P3,c" << "L" << "c4P3" << "P3,c4P3";
+ QTest::newRow("(P3,c)N") << "P3,c" << "N" << "c1P3" << "P3,c1P3";
+ QTest::newRow("(P3,c)NN") << "P3,c" << "NN" << "c2P3" << "P3,c2P3";
+ QTest::newRow("(P3,,c)") << "P3,,c" << "" << "" << "";
+ QTest::newRow("(P3,c0P3,)") << "P3,c0P3," << "" << "" << "";
+ QTest::newRow("(P,)") << "P," << "" << "" << "";
+ }
+}
+
+void tst_QCompleter::csMatchingOnCsSortedModel()
+{
+ filter();
+}
+
+void tst_QCompleter::ciMatchingOnCiSortedModel_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+ setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<QString>("step");
+ QTest::addColumn<QString>("completion");
+ QTest::addColumn<QString>("completionText");
+
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+
+ // Plain text filter
+ QTest::newRow("()") << "" << "" << "P0" << "P0";
+ QTest::newRow("()F") << "" << "F" << "P0" << "P0";
+ QTest::newRow("()L") << "" << "L" << "p4" << "p4";
+ QTest::newRow("()N") << "" << "N" << "p0" << "p0";
+ QTest::newRow("(P)") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)F") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)L") << "P" << "L" << "p4" << "p4";
+ QTest::newRow("(p)") << "p" << "" << "P0" << "P0";
+ QTest::newRow("(p)N") << "p" << "N" << "p0" << "p0";
+ QTest::newRow("(p)NN") << "p" << "NN" << "P1" << "P1";
+ QTest::newRow("(p)NNN") << "p" << "NNN" << "p1" << "p1";
+ QTest::newRow("(p1)") << "p1" << "" << "P1" << "P1";
+ QTest::newRow("(p1)N") << "p1" << "N" << "p1" << "p1";
+ QTest::newRow("(p11)") << "p11" << "" << "" << "";
+
+ //// Tree filter
+ QTest::newRow("(p0,)") << "p0," << "" << "c0P0" << "P0,c0P0";
+ QTest::newRow("(p0,c)") << "p0,c" << "" << "c0P0" << "P0,c0P0";
+ QTest::newRow("(p0,c1)") << "p0,c1" << "" << "c1P0" << "P0,c1P0";
+ QTest::newRow("(p0,c3P0)") << "p0,c3P0" << "" << "c3P0" << "P0,c3P0";
+ QTest::newRow("(p3,c)F") << "p3,c" << "F" << "c0P3" << "P3,c0P3";
+ QTest::newRow("(p3,c)L") << "p3,c" << "L" << "c4P3" << "P3,c4P3";
+ QTest::newRow("(p3,c)N") << "p3,c" << "N" << "c1P3" << "P3,c1P3";
+ QTest::newRow("(p3,c)NN") << "p3,c" << "NN" << "c2P3" << "P3,c2P3";
+ QTest::newRow("(p3,,c)") << "p3,,c" << "" << "" << "";
+ QTest::newRow("(p3,c0P3,)") << "p3,c0P3," << "" << "" << "";
+ QTest::newRow("(p,)") << "p," << "" << "" << "";
+ }
+}
+
+void tst_QCompleter::ciMatchingOnCiSortedModel()
+{
+ filter();
+}
+
+void tst_QCompleter::ciMatchingOnCsSortedModel_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ setSourceModel(CASE_SENSITIVELY_SORTED_MODEL);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<QString>("step");
+ QTest::addColumn<QString>("completion");
+ QTest::addColumn<QString>("completionText");
+
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+
+ // Plain text filter
+ QTest::newRow("()") << "" << "" << "P0" << "P0";
+ QTest::newRow("()F") << "" << "F" << "P0" << "P0";
+ QTest::newRow("()L") << "" << "L" << "p4" << "p4";
+ QTest::newRow("(P)") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)F") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)L") << "P" << "L" << "p4" << "p4";
+ QTest::newRow("(p)") << "p" << "" << "P0" << "P0";
+ QTest::newRow("(p)N") << "p" << "N" << "P1" << "P1";
+ QTest::newRow("(p)NN") << "p" << "NN" << "P2" << "P2";
+ QTest::newRow("(p)NNN") << "p" << "NNN" << "P3" << "P3";
+ QTest::newRow("(p1)") << "p1" << "" << "P1" << "P1";
+ QTest::newRow("(p1)N") << "p1" << "N" << "p1" << "p1";
+ QTest::newRow("(p11)") << "p11" << "" << "" << "";
+
+ // Tree filter
+ QTest::newRow("(p0,)") << "p0," << "" << "c0P0" << "P0,c0P0";
+ QTest::newRow("(p0,c)") << "p0,c" << "" << "c0P0" << "P0,c0P0";
+ QTest::newRow("(p0,c1)") << "p0,c1" << "" << "c1P0" << "P0,c1P0";
+ QTest::newRow("(p0,c3P0)") << "p0,c3P0" << "" << "c3P0" << "P0,c3P0";
+ QTest::newRow("(p3,c)F") << "p3,c" << "F" << "c0P3" << "P3,c0P3";
+ QTest::newRow("(p3,c)L") << "p3,c" << "L" << "c4P3" << "P3,c4P3";
+ QTest::newRow("(p3,c)N") << "p3,c" << "N" << "c1P3" << "P3,c1P3";
+ QTest::newRow("(p3,c)NN") << "p3,c" << "NN" << "c2P3" << "P3,c2P3";
+ QTest::newRow("(p3,,c)") << "p3,,c" << "" << "" << "";
+ QTest::newRow("(p3,c0P3,)") << "p3,c0P3," << "" << "" << "";
+ QTest::newRow("(p,)") << "p," << "" << "" << "";
+ }
+}
+
+void tst_QCompleter::ciMatchingOnCsSortedModel()
+{
+ filter();
+}
+
+void tst_QCompleter::csMatchingOnCiSortedModel_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL);
+ completer->setCaseSensitivity(Qt::CaseSensitive);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<QString>("step");
+ QTest::addColumn<QString>("completion");
+ QTest::addColumn<QString>("completionText");
+
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+
+ // Plain text filter
+ QTest::newRow("()") << "" << "" << "P0" << "P0";
+ QTest::newRow("()F") << "" << "F" << "P0" << "P0";
+ QTest::newRow("()L") << "" << "L" << "p4" << "p4";
+ QTest::newRow("()N") << "" << "N" << "p0" << "p0";
+ QTest::newRow("(P)") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)F") << "P" << "" << "P0" << "P0";
+ QTest::newRow("(P)L") << "P" << "L" << "P4" << "P4";
+ QTest::newRow("(p)") << "p" << "" << "p0" << "p0";
+ QTest::newRow("(p)N") << "p" << "N" << "p1" << "p1";
+ QTest::newRow("(p)NN") << "p" << "NN" << "p2" << "p2";
+ QTest::newRow("(p)NNN") << "p" << "NNN" << "p3" << "p3";
+ QTest::newRow("(p1)") << "p1" << "" << "p1" << "p1";
+ QTest::newRow("(p11)") << "p11" << "" << "" << "";
+
+ //// Tree filter
+ QTest::newRow("(p0,)") << "p0," << "" << "c0p0" << "p0,c0p0";
+ QTest::newRow("(p0,c)") << "p0,c" << "" << "c0p0" << "p0,c0p0";
+ QTest::newRow("(p0,c1)") << "p0,c1" << "" << "c1p0" << "p0,c1p0";
+ QTest::newRow("(p0,c3P0)") << "p0,c3p0" << "" << "c3p0" << "p0,c3p0";
+ QTest::newRow("(p3,c)F") << "p3,c" << "F" << "c0p3" << "p3,c0p3";
+ QTest::newRow("(p3,c)L") << "p3,c" << "L" << "c4p3" << "p3,c4p3";
+ QTest::newRow("(p3,c)N") << "p3,c" << "N" << "c1p3" << "p3,c1p3";
+ QTest::newRow("(p3,c)NN") << "p3,c" << "NN" << "c2p3" << "p3,c2p3";
+ QTest::newRow("(p3,,c)") << "p3,,c" << "" << "" << "";
+ QTest::newRow("(p3,c0P3,)") << "p3,c0P3," << "" << "" << "";
+ QTest::newRow("(p,)") << "p," << "" << "" << "";
+
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+ }
+}
+
+void tst_QCompleter::csMatchingOnCiSortedModel()
+{
+ filter();
+}
+
+void tst_QCompleter::directoryModel_data()
+{
+ delete completer;
+
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ setSourceModel(DIRECTORY_MODEL);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<QString>("step");
+ QTest::addColumn<QString>("completion");
+ QTest::addColumn<QString>("completionText");
+
+ // NOTE: Add tests carefully, ensurely the paths exist on all systems
+ // Output is the sourceText; currentCompletionText()
+
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+
+#if defined(Q_OS_WINCE)
+ QTest::newRow("()") << "" << "" << "/" << "/";
+ QTest::newRow("()") << "\\Program" << "" << "Program Files" << "\\Program Files";
+#elif defined(Q_OS_WIN)
+ QTest::newRow("()") << "C" << "" << "C:" << "C:";
+ QTest::newRow("()") << "C:\\Program" << "" << "Program Files" << "C:\\Program Files";
+#elif defined (Q_OS_MAC)
+ QTest::newRow("()") << "" << "" << "/" << "/";
+ QTest::newRow("(/a)") << "/a" << "" << "Applications" << "/Applications";
+ QTest::newRow("(/d)") << "/d" << "" << "Developer" << "/Developer";
+#else
+ QTest::newRow("()") << "" << "" << "/" << "/";
+#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX)
+ QTest::newRow("(/h)") << "/h" << "" << "home" << "/home";
+#endif
+ QTest::newRow("(/et)") << "/et" << "" << "etc" << "/etc";
+ QTest::newRow("(/etc/passw)") << "/etc/passw" << "" << "passwd" << "/etc/passwd";
+#endif
+ }
+}
+
+void tst_QCompleter::directoryModel()
+{
+ filter();
+}
+
+void tst_QCompleter::fileSystemModel_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ setSourceModel(FILESYSTEM_MODEL);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<QString>("step");
+ QTest::addColumn<QString>("completion");
+ QTest::addColumn<QString>("completionText");
+
+ // NOTE: Add tests carefully, ensurely the paths exist on all systems
+ // Output is the sourceText; currentCompletionText()
+
+ for (int i = 0; i < 2; i++) {
+ if (i == 1)
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << "" << "" << "";
+
+#if defined(Q_OS_WINCE)
+ QTest::newRow("()") << "" << "" << "/" << "/";
+ QTest::newRow("()") << "\\Program" << "" << "Program Files" << "\\Program Files";
+#elif defined(Q_OS_WIN)
+ QTest::newRow("()") << "C" << "" << "C:" << "C:";
+ QTest::newRow("()") << "C:\\Program" << "" << "Program Files" << "C:\\Program Files";
+#elif defined (Q_OS_MAC)
+ QTest::newRow("()") << "" << "" << "/" << "/";
+ QTest::newRow("(/a)") << "/a" << "" << "Applications" << "/Applications";
+// QTest::newRow("(/d)") << "/d" << "" << "Developer" << "/Developer";
+#else
+ QTest::newRow("()") << "" << "" << "/" << "/";
+#if !defined(Q_OS_IRIX) && !defined(Q_OS_AIX) && !defined(Q_OS_HPUX)
+ QTest::newRow("(/h)") << "/h" << "" << "home" << "/home";
+#endif
+ QTest::newRow("(/et)") << "/et" << "" << "etc" << "/etc";
+ QTest::newRow("(/etc/passw)") << "/etc/passw" << "" << "passwd" << "/etc/passwd";
+#endif
+ }
+}
+
+void tst_QCompleter::fileSystemModel()
+{
+ //QFileSystemModel is assync.
+ filter(true);
+}
+
+
+void tst_QCompleter::changingModel_data()
+{
+}
+
+void tst_QCompleter::changingModel()
+{
+ for (int i = 0; i < 2; i++) {
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseSensitive);
+ setSourceModel(CASE_SENSITIVELY_SORTED_MODEL);
+
+ if (i == 1) {
+ completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ }
+
+ completer->setCompletionPrefix("p");
+ completer->setCurrentRow(completer->completionCount() - 1);
+ QCOMPARE(completer->currentCompletion(), QString("p4"));
+
+ // Test addition of data
+ QTreeWidgetItem p5item;
+ p5item.setText(completionColumn, "p5");
+ treeWidget->addTopLevelItem(&p5item);
+ completer->setCompletionPrefix("p5");
+ QCOMPARE(completer->currentCompletion(), QString("p5"));
+
+ // Test removal of data
+ int p5index = treeWidget->indexOfTopLevelItem(&p5item);
+ treeWidget->takeTopLevelItem(p5index);
+ QCOMPARE(completer->currentCompletion(), QString(""));
+
+ // Test clear
+ treeWidget->clear();
+ QCOMPARE(completer->currentIndex(), QModelIndex());
+ }
+}
+
+void tst_QCompleter::testRowCount()
+{
+ QFETCH(QString, filterText);
+ QFETCH(bool, hasChildren);
+ QFETCH(int, rowCount);
+ QFETCH(int, completionCount);
+
+ if (filterText.compare("FILTERING_OFF", Qt::CaseInsensitive) == 0) {
+ completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ return;
+ }
+
+ completer->setCompletionPrefix(filterText);
+ const QAbstractItemModel *completionModel = completer->completionModel();
+ QCOMPARE(completionModel->rowCount(), rowCount);
+ QCOMPARE(completionCount, completionCount);
+ QCOMPARE(completionModel->hasChildren(), hasChildren);
+ QCOMPARE(completionModel->columnCount(), columnCount);
+}
+
+void tst_QCompleter::sortedEngineRowCount_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+ setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<bool>("hasChildren");
+ QTest::addColumn<int>("rowCount");
+ QTest::addColumn<int>("completionCount");
+
+ QTest::newRow("whatever") << "whatever" << false << 0 << 0;
+ QTest::newRow("p") << "p" << true << 10 << 10;
+ QTest::newRow("p1") << "p1" << true << 2 << 2;
+ QTest::newRow("P1,") << "P1," << true << 5 << 5;
+ QTest::newRow("P1,c") << "P1,c" << true << 5 << 5;
+ QTest::newRow("P1,cc") << "P1,cc" << false << 0 << 0;
+
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << false << 0 << 0;
+
+ QTest::newRow("whatever(filter off)") << "whatever" << true << 10 << 0;
+ QTest::newRow("p1(filter off)") << "p1" << true << 10 << 2;
+ QTest::newRow("p1,(filter off)") << "p1," << true << 5 << 5;
+ QTest::newRow("p1,c(filter off)") << "p1,c" << true << 5 << 5;
+ QTest::newRow("P1,cc(filter off)") << "P1,cc" << true << 5 << 0;
+}
+
+void tst_QCompleter::sortedEngineRowCount()
+{
+ testRowCount();
+}
+
+void tst_QCompleter::unsortedEngineRowCount_data()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseSensitive);
+ setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL);
+
+ QTest::addColumn<QString>("filterText");
+ QTest::addColumn<bool>("hasChildren");
+ QTest::addColumn<int>("rowCount");
+ QTest::addColumn<int>("completionCount");
+
+ QTest::newRow("whatever") << "whatever" << false << 0 << 0;
+ QTest::newRow("p") << "p" << true << 5 << 5;
+ QTest::newRow("p1") << "p1" << true << 1 << 1;
+ QTest::newRow("P1,") << "P1," << true << 5 << 5;
+ QTest::newRow("P1,c") << "P1,c" << true << 5 << 5;
+ QTest::newRow("P1,cc") << "P1,cc" << false << 0 << 0;
+
+ QTest::newRow("FILTERING_OFF") << "FILTERING_OFF" << false << 0 << 0;
+
+ QTest::newRow("whatever(filter off)") << "whatever" << true << 10 << 0;
+ QTest::newRow("p1(filter off)") << "p1" << true << 10 << 1;
+ QTest::newRow("p1,(filter off)") << "p1," << true << 5 << 5;
+ QTest::newRow("p1,c(filter off)") << "p1,c" << true << 5 << 5;
+ QTest::newRow("P1,cc(filter off)") << "P1,cc" << true << 5 << 0;
+}
+
+void tst_QCompleter::unsortedEngineRowCount()
+{
+ testRowCount();
+}
+
+void tst_QCompleter::currentRow()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+ setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL);
+
+ // blank text
+ completer->setCompletionPrefix("");
+ QCOMPARE(completer->currentRow(), 0);
+ QVERIFY(completer->setCurrentRow(4));
+ QCOMPARE(completer->currentRow(), 4);
+ QVERIFY(!completer->setCurrentRow(13));
+ QVERIFY(completer->setCurrentRow(4));
+
+ // some text
+ completer->setCompletionPrefix("p1");
+ QCOMPARE(completer->currentRow(), 0);
+ QVERIFY(completer->setCurrentRow(1));
+ QCOMPARE(completer->currentRow(), 1);
+ QVERIFY(!completer->setCurrentRow(2));
+ QCOMPARE(completer->currentRow(), 1);
+
+ // invalid text
+ completer->setCompletionPrefix("well");
+ QCOMPARE(completer->currentRow(), -1);
+}
+
+void tst_QCompleter::sortedEngineMapFromSource()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+ setSourceModel(CASE_INSENSITIVELY_SORTED_MODEL);
+
+ QModelIndex si1, si2, pi;
+ QAbstractItemModel *sourceModel = completer->model();
+ const QAbstractProxyModel *completionModel =
+ qobject_cast<const QAbstractProxyModel *>(completer->completionModel());
+
+ // Fitering ON
+ // empty
+ si1 = sourceModel->index(4, completionColumn); // "P2"
+ si2 = sourceModel->index(2, 0, si1); // "P2,c0P2"
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+
+ // some text
+ completer->setCompletionPrefix("p");
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+
+ // more text
+ completer->setCompletionPrefix("p2");
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+
+ // invalid text
+ completer->setCompletionPrefix("whatever");
+ pi = completionModel->mapFromSource(si1);
+ QVERIFY(!pi.isValid());
+
+ // Fitering OFF
+ completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ // empty
+ si1 = sourceModel->index(4, completionColumn); // "P2"
+ si2 = sourceModel->index(2, 0, si1); // "P2,c0P2"
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+
+ // some text
+ completer->setCompletionPrefix("p");
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+
+ // more text
+ completer->setCompletionPrefix("p2");
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+
+ // invalid text
+ completer->setCompletionPrefix("whatever");
+ pi = completionModel->mapFromSource(si1);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P2"));
+}
+
+void tst_QCompleter::unsortedEngineMapFromSource()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setCaseSensitivity(Qt::CaseInsensitive);
+ setSourceModel(HISTORY_MODEL); // case insensitively sorted model
+ completer->setModelSorting(QCompleter::UnsortedModel);
+
+ QModelIndex si, si2, si3, pi;
+ QAbstractItemModel *sourceModel = completer->model();
+ const QAbstractProxyModel *completionModel =
+ qobject_cast<const QAbstractProxyModel *>(completer->completionModel());
+
+ si = sourceModel->index(6, completionColumn); // "P3"
+ QCOMPARE(si.data().toString(), QLatin1String("P3"));
+ si2 = sourceModel->index(3, completionColumn, sourceModel->index(0, completionColumn)); // "P0,c3P0"
+ QCOMPARE(si2.data().toString(), QLatin1String("c3P0"));
+ si3 = sourceModel->index(10, completionColumn); // "p3,c3p3" (history)
+ QCOMPARE(si3.data().toString(), QLatin1String("p3,c3p3"));
+
+ // FILTERING ON
+ // empty
+ pi = completionModel->mapFromSource(si);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P3"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+ pi = completionModel->mapFromSource(si3);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("p3,c3p3"));
+
+ // some text
+ completer->setCompletionPrefix("P");
+ pi = completionModel->mapFromSource(si);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P3"));
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(pi.isValid(), false);
+ pi = completionModel->mapFromSource(si3);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("p3,c3p3"));
+
+ // invalid text
+ completer->setCompletionPrefix("whatever");
+ pi = completionModel->mapFromSource(si);
+ QVERIFY(!pi.isValid());
+ pi = completionModel->mapFromSource(si2);
+ QVERIFY(!pi.isValid());
+
+ // tree matching
+ completer->setCompletionPrefix("P0,c");
+ pi = completionModel->mapFromSource(si);
+ QVERIFY(!pi.isValid());
+ pi = completionModel->mapFromSource(si2);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("c3P0"));
+ pi = completionModel->mapFromSource(si3);
+ QCOMPARE(pi.isValid(), false);
+
+ // more tree matching
+ completer->setCompletionPrefix("p3,");
+ pi = completionModel->mapFromSource(si2);
+ QVERIFY(!pi.isValid());
+ pi = completionModel->mapFromSource(si3);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("p3,c3p3"));
+
+ // FILTERING OFF
+ // empty
+ completer->setCompletionPrefix("");
+ completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ pi = completionModel->mapFromSource(si);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P3"));
+
+ // some text
+ completer->setCompletionPrefix("P");
+ pi = completionModel->mapFromSource(si);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P3"));
+
+ // more text
+ completer->setCompletionPrefix("P3");
+ pi = completionModel->mapFromSource(si);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P3"));
+
+ // invalid text
+ completer->setCompletionPrefix("whatever");
+ pi = completionModel->mapFromSource(si);
+ QCOMPARE(completionModel->data(pi).toString(), QLatin1String("P3"));
+}
+
+void tst_QCompleter::historySearch()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
+ completer->setCaseSensitivity(Qt::CaseSensitive);
+ setSourceModel(HISTORY_MODEL);
+
+ const QAbstractProxyModel *completionModel =
+ qobject_cast<const QAbstractProxyModel *>(completer->completionModel());
+
+ // "p3,c3p3" and "p2,c4p2" are added in the tree root
+
+ // FILTERING ON
+ // empty
+ completer->setCurrentRow(10);
+ QCOMPARE(completer->currentCompletion(), QLatin1String("p3,c3p3"));
+
+ // more text
+ completer->setCompletionPrefix("p2");
+ completer->setCurrentRow(1);
+ QCOMPARE(completer->currentCompletion(), QLatin1String("p2,c4p2"));
+
+ // comma separated text
+ completer->setCompletionPrefix("p2,c4");
+ completer->setCurrentRow(1);
+ QCOMPARE(completionModel->rowCount(), 2);
+ QCOMPARE(completer->currentCompletion(), QLatin1String("p2,c4p2"));
+
+ // invalid text
+ completer->setCompletionPrefix("whatever");
+ QCOMPARE(completer->currentCompletion(), QString());
+
+ // FILTERING OFF
+ completer->setCompletionPrefix("");
+ completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
+ completer->setCurrentRow(10);
+ QCOMPARE(completer->currentCompletion(), QLatin1String("p3,c3p3"));
+
+ // more text
+ completer->setCompletionPrefix("p2");
+ completer->setCurrentRow(1);
+ QCOMPARE(completer->currentCompletion(), QLatin1String("p2,c4p2"));
+
+ // comma separated text
+ completer->setCompletionPrefix("p2,c4");
+ QCOMPARE(completionModel->rowCount(), 5);
+
+ // invalid text
+ completer->setCompletionPrefix("whatever");
+ QCOMPARE(completer->currentCompletion(), QString());
+}
+
+void tst_QCompleter::setters()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ QVERIFY(completer->popup() != 0);
+ QPointer<QDirModel> dirModel = new QDirModel(completer);
+ QAbstractItemModel *oldModel = completer->model();
+ completer->setModel(dirModel);
+ QVERIFY(completer->popup()->model() != oldModel);
+ QVERIFY(completer->popup()->model() == completer->completionModel());
+ completer->setPopup(new QListView);
+ QVERIFY(completer->popup()->model() == completer->completionModel());
+ completer->setModel(new QStringListModel(completer));
+ QVERIFY(dirModel == 0); // must have been deleted
+
+ completer->setModel(0);
+ completer->setWidget(0);
+}
+
+void tst_QCompleter::modelDeletion()
+{
+ delete completer;
+ completer = new CsvCompleter;
+ QStringList list;
+ list << "item1" << "item2" << "item3";
+ QStringListModel *listModel = new QStringListModel(list);
+ completer->setCompletionPrefix("i");
+ completer->setModel(listModel);
+ QVERIFY(completer->completionCount() == 3);
+ QListView *view = new QListView;
+ view->setModel(completer->completionModel());
+ delete listModel;
+ view->show();
+ qApp->processEvents();
+ delete view;
+ QVERIFY(completer->completionCount() == 0);
+ QVERIFY(completer->currentRow() == -1);
+}
+
+void tst_QCompleter::multipleWidgets()
+{
+ QStringList list;
+ list << "item1" << "item2" << "item2";
+ QCompleter completer(list);
+ completer.setCompletionMode(QCompleter::InlineCompletion);
+
+ QWidget window;
+ window.show();
+ QApplication::setActiveWindow(&window);
+ QTest::qWaitForWindowShown(&window);
+ QTRY_VERIFY(qApp->activeWindow() == &window);
+
+ QFocusEvent focusIn(QEvent::FocusIn);
+ QFocusEvent focusOut(QEvent::FocusOut);
+
+ QComboBox *comboBox = new QComboBox(&window);
+ comboBox->setEditable(true);
+ comboBox->setCompleter(&completer);
+ comboBox->setFocus();
+ comboBox->show();
+ window.activateWindow();
+ QApplication::setActiveWindow(&window);
+ QTest::qWait(50);
+ QTRY_VERIFY(qApp->focusWidget() == comboBox);
+ comboBox->lineEdit()->setText("it");
+ QCOMPARE(comboBox->currentText(), QString("it")); // should not complete with setText
+ QTest::keyPress(comboBox, 'e');
+ QCOMPARE(comboBox->currentText(), QString("item1"));
+ comboBox->clearEditText();
+ QCOMPARE(comboBox->currentText(), QString("")); // combo box text must not change!
+
+ QLineEdit *lineEdit = new QLineEdit(&window);
+ lineEdit->setCompleter(&completer);
+ lineEdit->show();
+ lineEdit->setFocus();
+ QTest::qWait(50);
+ QTRY_VERIFY(qApp->focusWidget() == lineEdit);
+ lineEdit->setText("it");
+ QCOMPARE(lineEdit->text(), QString("it")); // should not completer with setText
+ QCOMPARE(comboBox->currentText(), QString("")); // combo box text must not change!
+ QTest::keyPress(lineEdit, 'e');
+ QCOMPARE(lineEdit->text(), QString("item1"));
+ QCOMPARE(comboBox->currentText(), QString("")); // combo box text must not change!
+}
+
+void tst_QCompleter::focusIn()
+{
+ QStringList list;
+ list << "item1" << "item2" << "item2";
+ QCompleter completer(list);
+
+ QWidget window;
+ window.show();
+ QTest::qWait(100);
+ window.activateWindow();
+ QApplication::setActiveWindow(&window);
+ QTest::qWait(100);
+
+ QTRY_COMPARE(qApp->activeWindow(), &window);
+
+ QComboBox *comboBox = new QComboBox(&window);
+ comboBox->setEditable(true);
+ comboBox->setCompleter(&completer);
+ comboBox->show();
+ comboBox->lineEdit()->setText("it");
+
+ QLineEdit *lineEdit = new QLineEdit(&window);
+ lineEdit->setCompleter(&completer);
+ lineEdit->setText("it");
+ lineEdit->show();
+
+ QLineEdit *lineEdit2 = new QLineEdit(&window); // has no completer!
+ lineEdit2->show();
+
+ comboBox->setFocus();
+ QTRY_VERIFY(completer.widget() == comboBox);
+ lineEdit->setFocus();
+ QTRY_VERIFY(completer.widget() == lineEdit);
+ comboBox->setFocus();
+ QTRY_VERIFY(completer.widget() == comboBox);
+ lineEdit2->setFocus();
+ QTRY_VERIFY(completer.widget() == comboBox);
+}
+
+void tst_QCompleter::dynamicSortOrder()
+{
+ QStandardItemModel model;
+ QCompleter completer(&model);
+ completer.setModelSorting(QCompleter::CaseSensitivelySortedModel);
+ QStandardItem *root = model.invisibleRootItem();
+ for (int i = 0; i < 20; i++) {
+ root->appendRow(new QStandardItem(QString("%1").arg(i)));
+ }
+ root->appendRow(new QStandardItem("13"));
+ root->sortChildren(0, Qt::AscendingOrder);
+ completer.setCompletionPrefix("1");
+ QCOMPARE(completer.completionCount(), 12);
+ completer.setCompletionPrefix("13");
+ QCOMPARE(completer.completionCount(), 2);
+
+ root->sortChildren(0, Qt::DescendingOrder);
+ completer.setCompletionPrefix("13");
+ QCOMPARE(completer.completionCount(), 2);
+ completer.setCompletionPrefix("1");
+ QCOMPARE(completer.completionCount(), 12);
+}
+
+void tst_QCompleter::disabledItems()
+{
+ QLineEdit lineEdit;
+ QStandardItemModel *model = new QStandardItemModel(&lineEdit);
+ QStandardItem *suggestions = new QStandardItem("suggestions");
+ suggestions->setEnabled(false);
+ model->appendRow(suggestions);
+ model->appendRow(new QStandardItem("suggestions Enabled"));
+ QCompleter *completer = new QCompleter(model, &lineEdit);
+ QSignalSpy spy(completer, SIGNAL(activated(const QString &)));
+ lineEdit.setCompleter(completer);
+ lineEdit.show();
+
+ QTest::keyPress(&lineEdit, Qt::Key_S);
+ QTest::keyPress(&lineEdit, Qt::Key_U);
+ QAbstractItemView *view = lineEdit.completer()->popup();
+ QVERIFY(view->isVisible());
+ QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->visualRect(view->model()->index(0, 0)).center());
+ QCOMPARE(spy.count(), 0);
+ QVERIFY(view->isVisible());
+ QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->visualRect(view->model()->index(1, 0)).center());
+ QCOMPARE(spy.count(), 1);
+ QVERIFY(!view->isVisible());
+}
+
+void tst_QCompleter::task178797_activatedOnReturn()
+{
+ QStringList words;
+ words << "foobar1" << "foobar2";
+ QLineEdit *ledit = new QLineEdit;
+ QCompleter *completer = new QCompleter(words);
+ ledit->setCompleter(completer);
+ QSignalSpy spy(completer, SIGNAL(activated(const QString)));
+ QCOMPARE(spy.count(), 0);
+ ledit->show();
+ QTest::keyClick(ledit, Qt::Key_F);
+ qApp->processEvents();
+ QVERIFY(qApp->activePopupWidget());
+ QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Down);
+ qApp->processEvents();
+ QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Return);
+ qApp->processEvents();
+ QCOMPARE(spy.count(), 1);
+}
+
+class task189564_StringListModel : public QStringListModel
+{
+ const QString omitString;
+ Qt::ItemFlags flags(const QModelIndex &index) const
+ {
+ Qt::ItemFlags flags = Qt::ItemIsEnabled;
+ if (data(index, Qt::DisplayRole).toString() != omitString)
+ flags |= Qt::ItemIsSelectable;
+ return flags;
+ }
+public:
+ task189564_StringListModel(const QString &omitString, QObject *parent = 0)
+ : QStringListModel(parent)
+ , omitString(omitString)
+ {
+ }
+};
+
+void tst_QCompleter::task189564_omitNonSelectableItems()
+{
+ const QString prefix("a");
+ const int n = 5;
+
+ QStringList strings;
+ for (int i = 0; i < n; ++i)
+ strings << QString("%1%2").arg(prefix).arg(i);
+ const QString omitString(strings.at(n / 2));
+ task189564_StringListModel model(omitString);
+ model.setStringList(strings);
+ QCompleter completer_(&model);
+ completer_.setCompletionPrefix(prefix);
+
+ QAbstractItemModel *completionModel = completer_.completionModel();
+ QModelIndexList matches1 =
+ completionModel->match(completionModel->index(0, 0), Qt::DisplayRole, prefix, -1);
+ QCOMPARE(matches1.size(), n - 1);
+ QModelIndexList matches2 =
+ completionModel->match(completionModel->index(0, 0), Qt::DisplayRole, omitString);
+ QVERIFY(matches2.isEmpty());
+}
+
+class task246056_ComboBox : public QComboBox
+{
+ Q_OBJECT
+public:
+ task246056_ComboBox()
+ {
+ setEditable(true);
+ setInsertPolicy(NoInsert);
+ if (completer()) {
+ completer()->setCompletionMode(QCompleter::PopupCompletion);
+ completer()->setCompletionRole(Qt::DisplayRole);
+ connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix()));
+ }
+ }
+private slots:
+ void setCompletionPrefix() { completer()->setCompletionPrefix(lineEdit()->text()); }
+};
+
+void tst_QCompleter::task246056_setCompletionPrefix()
+{
+ task246056_ComboBox *comboBox = new task246056_ComboBox;
+ QVERIFY(comboBox->completer());
+ comboBox->addItem("");
+ comboBox->addItem("a1");
+ comboBox->addItem("a2");
+ comboBox->show();
+ comboBox->setFocus();
+ QTest::qWait(100);
+ QTest::keyPress(comboBox, 'a');
+ QTest::keyPress(comboBox->completer()->popup(), Qt::Key_Down);
+ QTest::keyPress(comboBox->completer()->popup(), Qt::Key_Down);
+ QTest::keyPress(comboBox->completer()->popup(), Qt::Key_Enter); // don't crash!
+}
+
+class task250064_TextEdit : public QTextEdit
+{
+public:
+ QCompleter *completer;
+
+ task250064_TextEdit()
+ {
+ completer = new QCompleter;
+ completer->setWidget(this);
+ }
+
+ void keyPressEvent (QKeyEvent *e)
+ {
+ completer->popup();
+ QTextEdit::keyPressEvent(e);
+ }
+};
+
+class task250064_Widget : public QWidget
+{
+ Q_OBJECT
+public:
+ task250064_TextEdit *textEdit;
+
+ task250064_Widget(task250064_TextEdit *textEdit)
+ : textEdit(textEdit)
+ {
+ QTabWidget *tabWidget = new QTabWidget;
+ tabWidget->setFocusPolicy(Qt::ClickFocus);
+ tabWidget->addTab(textEdit, "untitled");
+
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ layout->addWidget(tabWidget);
+
+ textEdit->setPlainText("bla bla bla");
+ textEdit->setFocus();
+ }
+
+ void setCompletionModel()
+ {
+ textEdit->completer->setModel(0);
+ }
+};
+
+void tst_QCompleter::task250064_lostFocus()
+{
+ task250064_TextEdit *textEdit = new task250064_TextEdit;
+ task250064_Widget *widget = new task250064_Widget(textEdit);
+ widget->show();
+ QTest::qWait(100);
+ QTest::keyPress(textEdit, 'a');
+ Qt::FocusPolicy origPolicy = textEdit->focusPolicy();
+ QVERIFY(origPolicy != Qt::NoFocus);
+ widget->setCompletionModel();
+ QCOMPARE(textEdit->focusPolicy(), origPolicy);
+}
+
+void tst_QCompleter::task253125_lineEditCompletion_data()
+{
+ QTest::addColumn<QStringList>("list");
+ QTest::addColumn<int>("completionMode");
+
+ QStringList list = QStringList()
+ << "alpha" << "beta" << "gamma" << "delta" << "epsilon" << "zeta"
+ << "eta" << "theta" << "iota" << "kappa" << "lambda" << "mu"
+ << "nu" << "xi" << "omicron" << "pi" << "rho" << "sigma"
+ << "tau" << "upsilon" << "phi" << "chi" << "psi" << "omega";
+
+ QTest::newRow("Inline") << list << (int)QCompleter::InlineCompletion;
+ QTest::newRow("Filtered") << list << (int)QCompleter::PopupCompletion;
+ QTest::newRow("Unfiltered") << list << (int)QCompleter::UnfilteredPopupCompletion;
+}
+
+void tst_QCompleter::task253125_lineEditCompletion()
+{
+ QFETCH(QStringList, list);
+ QFETCH(int, completionMode);
+
+ QStringListModel *model = new QStringListModel;
+ model->setStringList(list);
+
+ QCompleter *completer = new QCompleter(list);
+ completer->setModel(model);
+ completer->setCompletionMode((QCompleter::CompletionMode)completionMode);
+
+ QLineEdit edit;
+ edit.setCompleter(completer);
+ edit.show();
+ edit.setFocus();
+
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&edit);
+#endif
+ QTest::qWait(10);
+ QApplication::setActiveWindow(&edit);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&edit));
+
+ QTest::keyClick(&edit, 'i');
+ QCOMPARE(edit.completer()->currentCompletion(), QString("iota"));
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Down);
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Enter);
+
+ QCOMPARE(edit.text(), QString("iota"));
+
+ delete completer;
+ delete model;
+}
+
+void tst_QCompleter::task247560_keyboardNavigation()
+{
+ QStandardItemModel model;
+
+ for (int i = 0; i < 5; i++) {
+ for (int j = 0; j < 5; j++) {
+ model.setItem(i, j, new QStandardItem(QString("row %1 column %2").arg(i).arg(j)));
+ }
+ }
+
+
+ QCompleter completer(&model);
+ completer.setCompletionColumn(1);
+
+ QLineEdit edit;
+ edit.setCompleter(&completer);
+ edit.show();
+ edit.setFocus();
+
+#ifdef Q_WS_X11
+ qt_x11_wait_for_window_manager(&edit);
+#endif
+
+ QTest::qWait(10);
+ QApplication::setActiveWindow(&edit);
+ QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(&edit));
+
+ QTest::keyClick(&edit, 'r');
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Down);
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Down);
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Enter);
+
+ QCOMPARE(edit.text(), QString("row 1 column 1"));
+
+ edit.clear();
+
+ QTest::keyClick(&edit, 'r');
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Up);
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Up);
+ QTest::keyClick(edit.completer()->popup(), Qt::Key_Enter);
+
+ QCOMPARE(edit.text(), QString("row 3 column 1"));
+}
+
+void tst_QCompleter::QTBUG_14292_filesystem()
+{
+ FileSystem fs;
+ QDir tmpDir = QDir::currentPath();
+
+ qsrand(QTime::currentTime().msec());
+ QString d = "tst_QCompleter_" + QString::number(qrand());
+ QVERIFY(fs.createDirectory(tmpDir.filePath(d)));
+
+ QVERIFY(tmpDir.cd(d));
+ QVERIFY(fs.createDirectory(tmpDir.filePath("hello")));
+ QVERIFY(fs.createDirectory(tmpDir.filePath("holla")));
+
+ QLineEdit edit;
+ QCompleter comp;
+ QFileSystemModel model;
+ model.setRootPath(tmpDir.path());
+ comp.setModel(&model);
+ edit.setCompleter(&comp);
+
+ edit.show();
+ QApplication::setActiveWindow(&edit);
+ QTest::qWaitForWindowShown(&edit);
+ QTRY_VERIFY(QApplication::activeWindow() == &edit);
+ edit.setFocus();
+ QTRY_VERIFY(edit.hasFocus());
+
+ QVERIFY(!comp.popup()->isVisible());
+ edit.setText(tmpDir.path());
+ QTest::keyClick(&edit, '/');
+ QTRY_VERIFY(comp.popup()->isVisible());
+ QCOMPARE(comp.popup()->model()->rowCount(), 2);
+ QApplication::processEvents();
+ QTest::keyClick(&edit, 'h');
+ QCOMPARE(comp.popup()->model()->rowCount(), 2);
+ QTest::keyClick(&edit, 'e');
+ QCOMPARE(comp.popup()->model()->rowCount(), 1);
+ QTest::keyClick(&edit, 'r');
+ QTRY_VERIFY(!comp.popup()->isVisible());
+ QVERIFY(fs.createDirectory(tmpDir.filePath("hero")));
+ QTRY_VERIFY(comp.popup()->isVisible());
+ QCOMPARE(comp.popup()->model()->rowCount(), 1);
+ QTest::keyClick(comp.popup(), Qt::Key_Escape);
+ QTRY_VERIFY(!comp.popup()->isVisible());
+ QVERIFY(fs.createDirectory(tmpDir.filePath("nothingThere")));
+ //there is no reason creating a file should open a popup, it did in Qt 4.7.0
+ QTest::qWait(60);
+ QVERIFY(!comp.popup()->isVisible());
+
+ QTest::keyClick(&edit, Qt::Key_Backspace);
+ QTRY_VERIFY(comp.popup()->isVisible());
+ QCOMPARE(comp.popup()->model()->rowCount(), 2);
+ QTest::keyClick(&edit, 'm');
+ QTRY_VERIFY(!comp.popup()->isVisible());
+
+ QWidget w;
+ w.show();
+ QApplication::setActiveWindow(&w);
+ QTest::qWaitForWindowShown(&w);
+ QTRY_VERIFY(!edit.hasFocus() && !comp.popup()->hasFocus());
+
+ QVERIFY(fs.createDirectory(tmpDir.filePath("hemo")));
+ //there is no reason creating a file should open a popup, it did in Qt 4.7.0
+ QTest::qWait(60);
+ QVERIFY(!comp.popup()->isVisible());
+}
+
+QTEST_MAIN(tst_QCompleter)
+#include "tst_qcompleter.moc"