QFileDialog: turn workingDirectory into a QUrl

In order to make this work better with remote URLs.

Change-Id: Ic440735142441150838b05e88940adcc12a90d09
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@digia.com>
This commit is contained in:
David Faure 2014-07-09 11:54:36 +02:00
parent a86f2d4083
commit cd33318025
2 changed files with 68 additions and 48 deletions

View File

@ -80,7 +80,7 @@ extern bool qt_priv_ptr_valid;
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
Q_GLOBAL_STATIC(QString, lastVisitedDir) Q_GLOBAL_STATIC(QUrl, lastVisitedDir)
/*! /*!
\class QFileDialog \class QFileDialog
@ -377,7 +377,7 @@ QFileDialog::QFileDialog(QWidget *parent,
: QDialog(*new QFileDialogPrivate, parent, 0) : QDialog(*new QFileDialogPrivate, parent, 0)
{ {
Q_D(QFileDialog); Q_D(QFileDialog);
d->init(directory, filter, caption); d->init(QUrl::fromLocalFile(directory), filter, caption);
} }
/*! /*!
@ -448,7 +448,7 @@ static const qint32 QFileDialogMagic = 0xbe;
QByteArray QFileDialog::saveState() const QByteArray QFileDialog::saveState() const
{ {
Q_D(const QFileDialog); Q_D(const QFileDialog);
int version = 3; int version = 4;
QByteArray data; QByteArray data;
QDataStream stream(&data, QIODevice::WriteOnly); QDataStream stream(&data, QIODevice::WriteOnly);
@ -483,7 +483,6 @@ QByteArray QFileDialog::saveState() const
bool QFileDialog::restoreState(const QByteArray &state) bool QFileDialog::restoreState(const QByteArray &state)
{ {
Q_D(QFileDialog); Q_D(QFileDialog);
int version = 3;
QByteArray sd = state; QByteArray sd = state;
QDataStream stream(&sd, QIODevice::ReadOnly); QDataStream stream(&sd, QIODevice::ReadOnly);
if (stream.atEnd()) if (stream.atEnd())
@ -492,23 +491,30 @@ bool QFileDialog::restoreState(const QByteArray &state)
QByteArray headerData; QByteArray headerData;
QList<QUrl> bookmarks; QList<QUrl> bookmarks;
QStringList history; QStringList history;
QString currentDirectory; QUrl currentDirectory;
qint32 marker; qint32 marker;
qint32 v; qint32 v;
qint32 viewMode; qint32 viewMode;
stream >> marker; stream >> marker;
stream >> v; 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; return false;
stream >> splitterState stream >> splitterState
>> bookmarks >> bookmarks
>> history >> history;
>> currentDirectory if (v == 3) {
>> headerData QString currentDirectoryString;
stream >> currentDirectoryString;
currentDirectory = QUrl::fromLocalFile(currentDirectoryString);
} else {
stream >> currentDirectory;
}
stream >> headerData
>> viewMode; >> viewMode;
setDirectory(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir()); setDirectoryUrl(lastVisitedDir()->isEmpty() ? currentDirectory : *lastVisitedDir());
setViewMode(static_cast<QFileDialog::ViewMode>(viewMode)); setViewMode(static_cast<QFileDialog::ViewMode>(viewMode));
if (!d->usingWidgets()) if (!d->usingWidgets())
@ -634,7 +640,7 @@ void QFileDialogPrivate::retranslateWindowTitle()
setWindowTitle = q->windowTitle(); setWindowTitle = q->windowTitle();
} }
void QFileDialogPrivate::setLastVisitedDirectory(const QString &dir) void QFileDialogPrivate::setLastVisitedDirectory(const QUrl &dir)
{ {
*lastVisitedDir() = dir; *lastVisitedDir() = dir;
} }
@ -948,11 +954,12 @@ void QFileDialog::setDirectory(const QString &directory)
if (!directory.isEmpty() && newDirectory.isEmpty()) if (!directory.isEmpty() && newDirectory.isEmpty())
return; return;
d->setLastVisitedDirectory(newDirectory); QUrl newDirUrl = QUrl::fromLocalFile(newDirectory);
d->setLastVisitedDirectory(newDirUrl);
d->options->setInitialDirectory(QUrl::fromLocalFile(directory)); d->options->setInitialDirectory(QUrl::fromLocalFile(directory));
if (!d->usingWidgets()) { if (!d->usingWidgets()) {
d->setDirectory_sys(QUrl::fromLocalFile(newDirectory)); d->setDirectory_sys(newDirUrl);
return; return;
} }
if (d->rootPath() == newDirectory) if (d->rootPath() == newDirectory)
@ -999,6 +1006,9 @@ void QFileDialog::setDirectoryUrl(const QUrl &directory)
if (!directory.isValid()) if (!directory.isValid())
return; return;
d->setLastVisitedDirectory(directory);
d->options->setInitialDirectory(directory);
if (d->nativeDialogInUse) if (d->nativeDialogInUse)
d->setDirectory_sys(directory); d->setDirectory_sys(directory);
else if (directory.isLocalFile()) else if (directory.isLocalFile())
@ -2087,8 +2097,8 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
QFileDialogArgs args; QFileDialogArgs args;
args.parent = parent; args.parent = parent;
args.caption = caption; args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir); args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir));
args.selection = QFileDialogPrivate::initialSelection(dir); args.selection = QFileDialogPrivate::initialSelection(QUrl::fromLocalFile(dir));
args.filter = filter; args.filter = filter;
args.mode = ExistingFile; args.mode = ExistingFile;
args.options = options; args.options = options;
@ -2209,8 +2219,8 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
QFileDialogArgs args; QFileDialogArgs args;
args.parent = parent; args.parent = parent;
args.caption = caption; args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir); args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir));
args.selection = QFileDialogPrivate::initialSelection(dir); args.selection = QFileDialogPrivate::initialSelection(QUrl::fromLocalFile(dir));
args.filter = filter; args.filter = filter;
args.mode = ExistingFiles; args.mode = ExistingFiles;
args.options = options; args.options = options;
@ -2334,8 +2344,8 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
QFileDialogArgs args; QFileDialogArgs args;
args.parent = parent; args.parent = parent;
args.caption = caption; args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir); args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir));
args.selection = QFileDialogPrivate::initialSelection(dir); args.selection = QFileDialogPrivate::initialSelection(QUrl::fromLocalFile(dir));
args.filter = filter; args.filter = filter;
args.mode = AnyFile; args.mode = AnyFile;
args.options = options; args.options = options;
@ -2441,7 +2451,7 @@ QString QFileDialog::getExistingDirectory(QWidget *parent,
QFileDialogArgs args; QFileDialogArgs args;
args.parent = parent; args.parent = parent;
args.caption = caption; args.caption = caption;
args.directory = QFileDialogPrivate::workingDirectory(dir); args.directory = QFileDialogPrivate::workingDirectory(QUrl::fromLocalFile(dir));
args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory); args.mode = (options & ShowDirsOnly ? DirectoryOnly : Directory);
args.options = options; args.options = options;
@ -2491,32 +2501,36 @@ QUrl QFileDialog::getExistingDirectoryUrl(QWidget *parent,
return dialogResultToUrl(getExistingDirectory(parent, caption, dir.toLocalFile(), options)); 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 (url.isLocalFile()) {
if (info.exists() && info.isDir()) QFileInfo info = QFileInfo(QDir::current(), url.toLocalFile());
return QDir::cleanPath(info.absoluteFilePath()); if (info.exists() && info.isDir())
info.setFile(info.absolutePath()); return QUrl::fromLocalFile(QDir::cleanPath(info.absoluteFilePath()));
if (info.exists() && info.isDir()) info.setFile(info.absolutePath());
return info.absoluteFilePath(); if (info.exists() && info.isDir())
return QString(); return QUrl::fromLocalFile(info.absoluteFilePath());
return QUrl();
} else {
return url;
}
} }
/* /*
Get the initial directory path Get the initial directory URL
\sa initialSelection() \sa initialSelection()
*/ */
QString QFileDialogPrivate::workingDirectory(const QString &path) QUrl QFileDialogPrivate::workingDirectory(const QUrl &url)
{ {
if (!path.isEmpty()) { if (!url.isEmpty()) {
QString directory = _qt_get_directory(path); QUrl directory = _qt_get_directory(url);
if (!directory.isEmpty()) if (!directory.isEmpty())
return directory; return directory;
} }
QString directory = _qt_get_directory(*lastVisitedDir()); QUrl directory = _qt_get_directory(*lastVisitedDir());
if (!directory.isEmpty()) if (!directory.isEmpty())
return directory; return directory;
return QDir::currentPath(); return QUrl::fromLocalFile(QDir::currentPath());
} }
/* /*
@ -2526,14 +2540,19 @@ QString QFileDialogPrivate::workingDirectory(const QString &path)
\sa workingDirectory() \sa workingDirectory()
*/ */
QString QFileDialogPrivate::initialSelection(const QString &path) QString QFileDialogPrivate::initialSelection(const QUrl &url)
{ {
if (!path.isEmpty()) { if (url.isEmpty())
QFileInfo info(path); return QString();
if (url.isLocalFile()) {
QFileInfo info(url.toLocalFile());
if (!info.isDir()) if (!info.isDir())
return info.fileName(); return info.fileName();
else
return QString();
} }
return QString(); // With remote URLs we can only assume.
return url.fileName();
} }
/*! /*!
@ -2670,7 +2689,7 @@ void QFileDialog::accept()
Create widgets, layout and set default values 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) const QString &caption)
{ {
Q_Q(QFileDialog); Q_Q(QFileDialog);
@ -2687,7 +2706,7 @@ void QFileDialogPrivate::init(const QString &directory, const QString &nameFilte
q->setFileMode(QFileDialog::AnyFile); q->setFileMode(QFileDialog::AnyFile);
if (!nameFilter.isEmpty()) if (!nameFilter.isEmpty())
q->setNameFilter(nameFilter); q->setNameFilter(nameFilter);
q->setDirectory(workingDirectory(directory)); q->setDirectoryUrl(workingDirectory(directory));
q->selectFile(initialSelection(directory)); q->selectFile(initialSelection(directory));
#ifndef QT_NO_SETTINGS #ifndef QT_NO_SETTINGS
@ -3636,9 +3655,10 @@ void QFileDialogPrivate::_q_nativeEnterDirectory(const QUrl &directory)
{ {
Q_Q(QFileDialog); Q_Q(QFileDialog);
emit q->directoryUrlEntered(directory); emit q->directoryUrlEntered(directory);
if (!directory.isEmpty() && directory.isLocalFile()) { // Windows native dialogs occasionally emit signals with empty strings. if (!directory.isEmpty()) { // Windows native dialogs occasionally emit signals with empty strings.
*lastVisitedDir() = directory.toLocalFile(); *lastVisitedDir() = directory;
emit q->directoryEntered(directory.toLocalFile()); if (directory.isLocalFile())
emit q->directoryEntered(directory.toLocalFile());
} }
} }

View File

@ -100,7 +100,7 @@ struct QFileDialogArgs
QWidget *parent; QWidget *parent;
QString caption; QString caption;
QString directory; QUrl directory;
QString selection; QString selection;
QString filter; QString filter;
QFileDialog::FileMode mode; QFileDialog::FileMode mode;
@ -123,12 +123,12 @@ public:
void createMenuActions(); void createMenuActions();
void createWidgets(); 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()); const QString &caption = QString());
bool itemViewKeyboardEvent(QKeyEvent *event); bool itemViewKeyboardEvent(QKeyEvent *event);
QString getEnvironmentVariable(const QString &string); QString getEnvironmentVariable(const QString &string);
static QString workingDirectory(const QString &path); static QUrl workingDirectory(const QUrl &path);
static QString initialSelection(const QString &path); static QString initialSelection(const QUrl &path);
QStringList typedFiles() const; QStringList typedFiles() const;
QList<QUrl> userSelectedFiles() const; QList<QUrl> userSelectedFiles() const;
QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const; QStringList addDefaultSuffixToFiles(const QStringList filesToFix) const;
@ -189,7 +189,7 @@ public:
#endif #endif
} }
void setLastVisitedDirectory(const QString &dir); void setLastVisitedDirectory(const QUrl &dir);
void retranslateWindowTitle(); void retranslateWindowTitle();
void retranslateStrings(); void retranslateStrings();
void emitFilesSelected(const QStringList &files); void emitFilesSelected(const QStringList &files);