From c738b6f8a3d4b76fcd19be9d046e903eabc3301c Mon Sep 17 00:00:00 2001 From: David Faure Date: Wed, 9 Jul 2014 11:54:36 +0200 Subject: [PATCH 3/4] QFileDialog: turn workingDirectory into a QUrl In order to make this work better with remote URLs. Change-Id: Ic440735142441150838b05e88940adcc12a90d09 Reviewed-by: Friedemann Kleint (cherry picked from commit cd3331802516c012aed1be329e2e889478cbdd3e) --- src/widgets/dialogs/qfiledialog.cpp | 106 +++++++++++++++++++++--------------- src/widgets/dialogs/qfiledialog_p.h | 10 ++-- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp index 82a4a4c..ab0361a 100644 --- a/src/widgets/dialogs/qfiledialog.cpp +++ b/src/widgets/dialogs/qfiledialog.cpp @@ -78,7 +78,7 @@ extern bool qt_priv_ptr_valid; QT_BEGIN_NAMESPACE -Q_GLOBAL_STATIC(QString, lastVisitedDir) +Q_GLOBAL_STATIC(QUrl, lastVisitedDir) /*! \class QFileDialog @@ -373,7 +373,7 @@ QFileDialog::QFileDialog(QWidget *parent, : QDialog(*new QFileDialogPrivate, parent, 0) { Q_D(QFileDialog); - d->init(directory, filter, caption); + d->init(QUrl::fromLocalFile(directory), filter, caption); } /*! @@ -444,7 +444,7 @@ static const qint32 QFileDialogMagic = 0xbe; QByteArray QFileDialog::saveState() const { Q_D(const QFileDialog); - int version = 3; + int version = 4; QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); @@ -479,7 +479,6 @@ QByteArray QFileDialog::saveState() const bool QFileDialog::restoreState(const QByteArray &state) { Q_D(QFileDialog); - int version = 3; QByteArray sd = state; QDataStream stream(&sd, QIODevice::ReadOnly); if (stream.atEnd()) @@ -488,23 +487,30 @@ bool QFileDialog::restoreState(const QByteArray &state) QByteArray headerData; QList bookmarks; QStringList history; - QString currentDirectory; + QUrl currentDirectory; qint32 marker; qint32 v; qint32 viewMode; stream >> marker; stream >> v; - if (marker != QFileDialogMagic || v != version) + // the code below only supports versions 3 and 4 + if (marker != QFileDialogMagic || (v != 3 && v != 4)) return false; stream >> splitterState >> bookmarks - >> history - >> currentDirectory - >> headerData + >> history; + if (v == 3) { + QString currentDirectoryString; + stream >> currentDirectoryString; + currentDirectory = QUrl::fromLocalFile(currentDirectoryString); + } else { + stream >> currentDirectory; + } + stream >> headerData >> viewMode; - setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); + setDirectoryUrl(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); setViewMode(static_cast(viewMode)); if (!d->usingWidgets()) @@ -630,7 +636,7 @@ void QFileDialogPrivate::retranslateWindowTitle() setWindowTitle = q->windowTitle(); } -void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir) +void QFileDialogPrivate::setLastVisitedDirectory(const QUrl &dir) { *lastVisitedDir() = dir; } @@ -944,11 +950,12 @@ void QFileDialog::setDirectory(const QString &directory) if (!directory.isEmpty() && newDirectory.isEmpty()) return; - d->setLastVisitedDirectory(newDirectory); + QUrl newDirUrl = QUrl::fromLocalFile(newDirectory); + d->setLastVisitedDirectory(newDirUrl); d->options->setInitialDirectory(QUrl::fromLocalFile(directory)); if (!d->usingWidgets()) { - d->setDirectory_sys(QUrl::fromLocalFile(newDirectory)); + d->setDirectory_sys(newDirUrl); return; } if (d->rootPath() == newDirectory) @@ -995,6 +1002,9 @@ void QFileDialog::setDirectoryUrl(const QUrl &directory) if (!directory.isValid()) return; + d->setLastVisitedDirectory(directory); + d->options->setInitialDirectory(directory); + if (d->nativeDialogInUse) d->setDirectory_sys(directory); else if (directory.isLocalFile()) @@ -2103,8 +2113,8 @@ QString QFileDialog::getOpenFileName(QWidget *parent, QFileDialogArgs args; args.parent = parent; args.caption = caption; - args.directory = QFileDialogPrivate::workingDirectory(dir); - args.selection = QFileDialogPrivate::initialSelection(dir); + args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir)); + args.selection = QFileDialogPrivate::initialSelection(QUrl::fromLocalFile(dir)); args.filter = filter; args.mode = ExistingFile; args.options = options; @@ -2231,8 +2241,8 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent, QFileDialogArgs args; args.parent = parent; args.caption = caption; - args.directory = QFileDialogPrivate::workingDirectory(dir); - args.selection = QFileDialogPrivate::initialSelection(dir); + args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir)); + args.selection = QFileDialogPrivate::initialSelection(QUrl::fromLocalFile(dir)); args.filter = filter; args.mode = ExistingFiles; args.options = options; @@ -2363,8 +2373,8 @@ QString QFileDialog::getSaveFileName(QWidget *parent, QFileDialogArgs args; args.parent = parent; args.caption = caption; - args.directory = QFileDialogPrivate::workingDirectory(dir); - args.selection = QFileDialogPrivate::initialSelection(dir); + args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir)); + args.selection = QFileDialogPrivate::initialSelection(QUrl::fromLocalFile(dir)); args.filter = filter; args.mode = AnyFile; args.options = options; @@ -2477,7 +2487,7 @@ QString QFileDialog::getExistingDirectory(QWidget *parent, QFileDialogArgs args; args.parent = parent; args.caption = caption; - args.directory = QFileDialogPrivate::workingDirectory(dir); + args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir)); args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory); args.options = options; @@ -2538,32 +2548,36 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent, return dialogResultToUrl(getExistingDirectory(parent, caption, dir.toLocalFile(), options)); } -inline static QString _qt_get_directory(const QString &path) +inline static QUrl _qt_get_directory(const QUrl &url) { - QFileInfo info = QFileInfo(QDir::current(), path); - if (info.exists() && info.isDir()) - return QDir::cleanPath(info.absoluteFilePath()); - info.setFile(info.absolutePath()); - if (info.exists() && info.isDir()) - return info.absoluteFilePath(); - return QString(); + if (url.isLocalFile()) { + QFileInfo info = QFileInfo(QDir::current(), url.toLocalFile()); + if (info.exists() && info.isDir()) + return QUrl::fromLocalFile(QDir::cleanPath(info.absoluteFilePath())); + info.setFile(info.absolutePath()); + if (info.exists() && info.isDir()) + return QUrl::fromLocalFile(info.absoluteFilePath()); + return QUrl(); + } else { + return url; + } } /* - Get the initial directory path + Get the initial directory URL \sa initialSelection() */ -QString QFileDialogPrivate::workingDirectory(const QString &path) +QUrl QFileDialogPrivate::workingDirectory(const QUrl &url) { - if (!path.isEmpty()) { - QString directory = _qt_get_directory(path); + if (!url.isEmpty()) { + QUrl directory = _qt_get_directory(url); if (!directory.isEmpty()) return directory; } - QString directory = _qt_get_directory(*lastVisitedDir()); + QUrl directory = _qt_get_directory(*lastVisitedDir()); if (!directory.isEmpty()) return directory; - return QDir::currentPath(); + return QUrl::fromLocalFile(QDir::currentPath()); } /* @@ -2573,14 +2587,19 @@ QString QFileDialogPrivate::workingDirectory(const QString &path) \sa workingDirectory() */ -QString QFileDialogPrivate::initialSelection(const QString &path) +QString QFileDialogPrivate::initialSelection(const QUrl &url) { - if (!path.isEmpty()) { - QFileInfo info(path); + if (url.isEmpty()) + return QString(); + if (url.isLocalFile()) { + QFileInfo info(url.toLocalFile()); if (!info.isDir()) return info.fileName(); + else + return QString(); } - return QString(); + // With remote URLs we can only assume. + return url.fileName(); } /*! @@ -2717,7 +2736,7 @@ void QFileDialog::accept() Create widgets, layout and set default values */ -void QFileDialogPrivate::init(const QString &directory, const QString &nameFilter, +void QFileDialogPrivate::init(const QUrl &directory, const QString &nameFilter, const QString &caption) { Q_Q(QFileDialog); @@ -2734,7 +2753,7 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte q->setFileMode(QFileDialog::AnyFile); if (!nameFilter.isEmpty()) q->setNameFilter(nameFilter); - q->setDirectory(workingDirectory(directory)); + q->setDirectoryUrl(workingDirectory(directory)); q->selectFile(initialSelection(directory)); #ifndef QT_NO_SETTINGS @@ -3683,9 +3702,10 @@ void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory) { Q_Q(QFileDialog); emit q->directoryUrlEntered(directory); - if (!directory.isEmpty() && directory.isLocalFile()) { // Windows native dialogs occasionally emit signals with empty strings. - *lastVisitedDir() = directory.toLocalFile(); - emit q->directoryEntered(directory.toLocalFile()); + if (!directory.isEmpty()) { // Windows native dialogs occasionally emit signals with empty strings. + *lastVisitedDir() = directory; + if (directory.isLocalFile()) + emit q->directoryEntered(directory.toLocalFile()); } } diff --git a/src/widgets/dialogs/qfiledialog_p.h b/src/widgets/dialogs/qfiledialog_p.h index 9e1c23b..175760c 100644 --- a/src/widgets/dialogs/qfiledialog_p.h +++ b/src/widgets/dialogs/qfiledialog_p.h @@ -100,7 +100,7 @@ struct QFileDialogArgs QWidget *parent; QString caption; - QString directory; + QUrl directory; QString selection; QString filter; QFileDialog::FileMode mode; @@ -123,12 +123,12 @@ public: void createMenuActions(); void createWidgets(); - void init(const QString &directory = QString(), const QString &nameFilter = QString(), + void init(const QUrl &directory = QUrl(), const QString &nameFilter = QString(), const QString &caption = QString()); bool itemViewKeyboardEvent(QKeyEvent *event); QString getEnvironmentVariable(const QString &string); - static QString workingDirectory(const QString &path); - static QString initialSelection(const QString &path); + static QUrl workingDirectory(const QUrl &path); + static QString initialSelection(const QUrl &path); QStringList typedFiles() const; QList userSelectedFiles() const; QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const; @@ -189,7 +189,7 @@ public: #endif } - void setLastVisitedDirectory(const QString &dir); + void setLastVisitedDirectory(const QUrl &dir); void retranslateWindowTitle(); void retranslateStrings(); void emitFilesSelected(const QStringList &files); -- 2.1.1