From 367ac8236103f1ec5cdfd69a46fe4bd26e705dbb Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Date: Fri, 24 Apr 2015 14:50:41 +0200
Subject: [PATCH] WIP: Emit QFileDialog::currentChanged() when typing in line
 edit.

Change the logic in QFileDialogPrivate::_q_autoCompleteFileName()
to do QItemSelectionModel::setCurrentIndex() for single selection.

TODO: Breaks tst_QFiledialog::completer_up() since that checks
that currentChanged() does not increase while typing, plus
other sporadic test failures due to tests interfering with each
other due to setLastVisitedDirectory()/settings file
(completer/history).

KEEP AROUND FOR REFERENCE ONLY.

Task-number: QTBUG-45764
Change-Id: I95cbd24189510899869dcfb2a2946b3f7a3d451d
---
 src/widgets/dialogs/qfiledialog.cpp                | 22 +++++++++++++++-------
 .../dialogs/qfiledialog/tst_qfiledialog.cpp        | 22 +++++++++++++++++++++-
 2 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 3f3a6e7..979cbce 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -3446,7 +3446,8 @@ void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text)
 
     QStringList multipleFiles = typedFiles();
     if (multipleFiles.count() > 0) {
-        QModelIndexList oldFiles = qFileDialogUi->listView->selectionModel()->selectedRows();
+        QItemSelectionModel *selectionModel = qFileDialogUi->listView->selectionModel();
+        QModelIndexList oldFiles = selectionModel->selectedRows();
         QModelIndexList newFiles;
         for (int i = 0; i < multipleFiles.count(); ++i) {
             QModelIndex idx = model->index(multipleFiles.at(i));
@@ -3455,12 +3456,19 @@ void QFileDialogPrivate::_q_autoCompleteFileName(const QString &text)
             else
                 newFiles.append(idx);
         }
-        for (int i = 0; i < newFiles.count(); ++i)
-            select(newFiles.at(i));
-        if (lineEdit()->hasFocus())
-            for (int i = 0; i < oldFiles.count(); ++i)
-                qFileDialogUi->listView->selectionModel()->select(oldFiles.at(i),
-                    QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
+        const int newFilesCount = newFiles.count();
+        if (qFileDialogUi->listView->selectionMode() == QAbstractItemView::SingleSelection
+            && newFilesCount == 1 && newFiles.first().isValid()) {
+            selectionModel->setCurrentIndex(mapFromSource(newFiles.first()), QItemSelectionModel::SelectCurrent);
+        } else {
+            for (int i = 0; i < newFilesCount; ++i)
+                select(newFiles.at(i));
+            if (lineEdit()->hasFocus()) {
+                for (int i = 0; i < oldFiles.count(); ++i)
+                    selectionModel->select(oldFiles.at(i),
+                                           QItemSelectionModel::Toggle | QItemSelectionModel::Rows);
+            }
+        }
     }
 }
 
diff --git a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
index 42e2bd0..faa8c56 100644
--- a/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
+++ b/tests/auto/widgets/dialogs/qfiledialog/tst_qfiledialog.cpp
@@ -243,6 +243,12 @@ void tst_QFiledialog::currentChangedSignal()
     listView->setCurrentIndex(folder);
 
     QCOMPARE(spyCurrentChanged.count(), 1);
+
+    QLineEdit *lineEdit = fd.findChild<QLineEdit*>("fileNameEdit");
+    QVERIFY(lineEdit);
+
+    lineEdit->insert(".."); // QTBUG-45764: Also emit when typing.
+    QTRY_COMPARE(spyCurrentChanged.count(), 2);
 }
 
 // only emitted from the views, sidebar, or lookin combo
@@ -743,6 +749,18 @@ void tst_QFiledialog::selectFilter()
     QCOMPARE(spyFilterSelected.count(), 0);
 }
 
+static QString msgModelIndex(const QModelIndex &index)
+{
+    return index.isValid()
+        ? QLatin1Char('"') + index.data().toString() + QLatin1Char('"')
+        : QLatin1String("<invalid>");
+}
+
+static QByteArray msgCompareModelIndexes(const QModelIndex &expected, const QModelIndex &actual)
+{
+    return (msgModelIndex(expected) + QLatin1String(" != ") +  msgModelIndex(actual)).toLocal8Bit();
+}
+
 void tst_QFiledialog::history()
 {
     QNonNativeFileDialog fd;
@@ -753,7 +771,9 @@ void tst_QFiledialog::history()
     QSignalSpy spyDirectoryEntered(&fd, SIGNAL(directoryEntered(QString)));
     QSignalSpy spyFilesSelected(&fd, SIGNAL(filesSelected(QStringList)));
     QSignalSpy spyFilterSelected(&fd, SIGNAL(filterSelected(QString)));
-    QCOMPARE(model->index(fd.history().first()), model->index(QDir::toNativeSeparators(fd.directory().absolutePath())));
+    const QModelIndex expected = model->index(QDir::toNativeSeparators(fd.directory().absolutePath()));
+    const QModelIndex actual = model->index(fd.history().first());
+    QVERIFY2(expected == actual, msgCompareModelIndexes(expected, actual));
     fd.setDirectory(QDir::current().absolutePath());
     QStringList history;
     history << QDir::toNativeSeparators(QDir::current().absolutePath())
-- 
1.9.1

