Fix folder list model when changing drives on Windows.
authorGlenn Watson <glenn.watson@nokia.com>
Thu, 26 Jul 2012 05:00:28 +0000 (15:00 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 31 Jul 2012 05:44:12 +0000 (07:44 +0200)
The folder list model implementation drops drive letters when
changing folder on Windows. Fix this and add a Windows specific
test case.

Task-number: QTBUG-26620
Change-Id: If58551ba01b56343ebf44512620207e49d83ba09
Reviewed-by: Matthew Vogt <matthew.vogt@nokia.com>
src/imports/folderlistmodel/qquickfolderlistmodel.cpp
tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp

index 409c256..1cffa44 100644 (file)
@@ -83,6 +83,8 @@ public:
     void _q_directoryChanged(const QString &directory, const QList<FileProperty> &list);
     void _q_directoryUpdated(const QString &directory, const QList<FileProperty> &list, int fromIndex, int toIndex);
     void _q_sortFinished(const QList<FileProperty> &list);
+
+    static QString resolvePath(const QUrl &path);
 };
 
 
@@ -195,6 +197,15 @@ void QQuickFolderListModelPrivate::_q_sortFinished(const QList<FileProperty> &li
     q->endInsertRows();
 }
 
+QString QQuickFolderListModelPrivate::resolvePath(const QUrl &path)
+{
+    QString localPath = QQmlFile::urlToLocalFileOrQrc(path);
+    QUrl localUrl = QUrl(localPath);
+    QString fullPath = localUrl.path();
+    if (localUrl.scheme().length())
+      fullPath = localUrl.scheme() + ":" + fullPath;
+    return QDir::cleanPath(fullPath);
+}
 
 /*!
     \qmltype FolderListModel
@@ -370,8 +381,7 @@ void QQuickFolderListModel::setFolder(const QUrl &folder)
     if (folder == d->currentDir)
         return;
 
-    QString localPath = QQmlFile::urlToLocalFileOrQrc(folder);
-    QString resolvedPath = QDir::cleanPath(QUrl(localPath).path());
+    QString resolvedPath = QQuickFolderListModelPrivate::resolvePath(folder);
 
     beginResetModel();
 
@@ -413,8 +423,7 @@ void QQuickFolderListModel::setRootFolder(const QUrl &path)
     if (path.isEmpty())
         return;
 
-    QString localPath = QQmlFile::urlToLocalFileOrQrc(path);
-    QString resolvedPath = QDir::cleanPath(QUrl(localPath).path());
+    QString resolvedPath = QQuickFolderListModelPrivate::resolvePath(path);
 
     QFileInfo info(resolvedPath);
     if (!info.exists() || !info.isDir())
index 804bd1a..b574ef7 100644 (file)
 #include <QDebug>
 #include "../../shared/util.h"
 
+#if defined (Q_OS_WIN)
+#include <qt_windows.h>
+#endif
+
 // From qquickfolderlistmodel.h
 const int FileNameRole = Qt::UserRole+1;
 const int FilePathRole = Qt::UserRole+2;
@@ -69,6 +73,9 @@ private slots:
     void basicProperties();
     void resetFiltering();
     void refresh();
+#if defined (Q_OS_WIN)
+    void changeDrive();
+#endif
 
 private:
     void checkNoErrors(const QQmlComponent& component);
@@ -174,6 +181,51 @@ void tst_qquickfolderlistmodel::refresh()
     QTRY_COMPARE(removeEnd, count-1); // wait for refresh
 }
 
+#if defined (Q_OS_WIN)
+void tst_qquickfolderlistmodel::changeDrive()
+{
+    class DriveMapper
+    {
+    public:
+        DriveMapper(const QString &dataDir)
+        {
+            size_t stringLen = dataDir.length();
+            targetPath = new wchar_t[stringLen+1];
+            dataDir.toWCharArray(targetPath);
+            targetPath[stringLen] = 0;
+
+            DefineDosDevice(DDD_NO_BROADCAST_SYSTEM, L"X:", targetPath);
+        }
+
+        ~DriveMapper()
+        {
+            DefineDosDevice(DDD_EXACT_MATCH_ON_REMOVE | DDD_NO_BROADCAST_SYSTEM | DDD_REMOVE_DEFINITION, L"X:", targetPath);
+            delete [] targetPath;
+        }
+
+    private:
+        wchar_t *targetPath;
+    };
+
+    QString dataDir = testFile(0);
+    DriveMapper dm(dataDir);
+    QQmlComponent component(&engine, testFileUrl("basic.qml"));
+
+    QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
+    QVERIFY(flm != 0);
+
+    QSignalSpy folderChangeSpy(flm, SIGNAL(folderChanged()));
+
+    flm->setProperty("folder",QUrl::fromLocalFile(dataDir));
+    QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile(dataDir));
+    QTRY_VERIFY(folderChangeSpy.count() == 1);
+
+    flm->setProperty("folder",QUrl::fromLocalFile("X:/resetfiltering/"));
+    QCOMPARE(flm->property("folder").toUrl(), QUrl::fromLocalFile("X:/resetfiltering/"));
+    QTRY_VERIFY(folderChangeSpy.count() == 2);
+}
+#endif
+
 QTEST_MAIN(tst_qquickfolderlistmodel)
 
 #include "tst_qquickfolderlistmodel.moc"