#if defined(Q_OS_WINCE)
extern bool qt_priv_ptr_valid;
#endif
+#if defined(Q_OS_UNIX)
+#include <pwd.h>
+#endif
#endif
QT_BEGIN_NAMESPACE
d->lineEdit()->setText(file);
}
+#ifdef Q_OS_UNIX
+Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0)
+{
+ if (expanded != 0)
+ *expanded = false;
+ if (!path.startsWith(QLatin1Char('~')))
+ return path;
+ QString ret = path;
+ QStringList tokens = ret.split(QDir::separator());
+ if (tokens.first() == QLatin1String("~")) {
+ ret.replace(0, 1, QDir::homeDirPath());
+ } else {
+ QString userName = tokens.first();
+ userName.remove(0, 1);
+#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD)
+ passwd pw;
+ passwd *tmpPw;
+ char buf[200];
+ const int bufSize = sizeof(buf);
+ int err = getpwnam_r(userName.toLocal8Bit().constData(), &pw, buf, bufSize, &tmpPw);
+ if (err || !tmpPw)
+ return ret;
+ const QString homePath = QString::fromLocal8Bit(pw.pw_dir);
+#else
+ passwd *pw = getpwnam(userName.toLocal8Bit().constData());
+ if (!pw)
+ return ret;
+ const QString homePath = QString::fromLocal8Bit(pw->pw_dir);
+#endif
+ ret.replace(0, tokens.first().length(), homePath);
+ }
+ if (expanded != 0)
+ *expanded = true;
+ return ret;
+}
+#endif
+
/**
Returns the text in the line edit which can be one or more file names
*/
QStringList QFileDialogPrivate::typedFiles() const
{
+ Q_Q(const QFileDialog);
QStringList files;
QString editText = lineEdit()->text();
- if (!editText.contains(QLatin1Char('"')))
+ if (!editText.contains(QLatin1Char('"'))) {
+#ifdef Q_OS_UNIX
+ const QString prefix = q->directory().absolutePath() + QDir::separator();
+ if (QFile::exists(prefix + editText))
+ files << editText;
+ else
+ files << qt_tildeExpansion(editText);
+#else
files << editText;
- else {
+#endif
+ } else {
// " is used to separate files like so: "file1" "file2" "file3" ...
// ### need escape character for filenames with quotes (")
QStringList tokens = editText.split(QLatin1Char('\"'));
for (int i=0; i<tokens.size(); ++i) {
if ((i % 2) == 0)
continue; // Every even token is a separator
+#ifdef Q_OS_UNIX
+ const QString token = tokens.at(i);
+ const QString prefix = q->directory().absolutePath() + QDir::separator();
+ if (QFile::exists(prefix + token))
+ files << token;
+ else
+ files << qt_tildeExpansion(token);
+#else
files << toInternal(tokens.at(i));
+#endif
}
}
return addDefaultSuffixToFiles(files);
pathCopy = pathCopy.mid(2);
else
doubleSlash.clear();
+#elif defined(Q_OS_UNIX)
+ bool expanded;
+ pathCopy = qt_tildeExpansion(pathCopy, &expanded);
+ if (expanded) {
+ QFileSystemModel *dirModel;
+ if (proxyModel)
+ dirModel = qobject_cast<QFileSystemModel *>(proxyModel->sourceModel());
+ else
+ dirModel = sourceModel;
+ dirModel->fetchMore(dirModel->index(pathCopy));
+ }
#endif
QRegExp re(QLatin1Char('[') + QRegExp::escape(sep) + QLatin1Char(']'));
parts.append(QString());
#else
QStringList parts = pathCopy.split(re);
- if (path[0] == sep[0]) // read the "/" at the beginning as the split removed it
+ if (pathCopy[0] == sep[0]) // read the "/" at the beginning as the split removed it
parts[0] = sep[0];
#endif
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
bool startsFromRoot = !parts.isEmpty() && parts[0].endsWith(QLatin1Char(':'));
#else
- bool startsFromRoot = path[0] == sep[0];
+ bool startsFromRoot = pathCopy[0] == sep[0];
#endif
if (parts.count() == 1 || (parts.count() > 1 && !startsFromRoot)) {
const QFileSystemModel *dirModel;
# define STRINGIFY(x) #x
# define TOSTRING(x) STRINGIFY(x)
# define SRCDIR "C:/Private/" TOSTRING(SYMBIAN_SRCDIR_UID) "/"
+#elif defined(Q_OS_UNIX)
+#ifdef QT_BUILD_INTERNAL
+extern Q_GUI_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded = 0);
+#endif
#endif
class QNonNativeFileDialog : public QFileDialog
void clearLineEdit();
void enableChooseButton();
void hooks();
+#ifdef Q_OS_UNIX
+ void tildeExpansion_data();
+ void tildeExpansion();
+#endif
private:
QByteArray userSettings;
QCOMPARE(QFileDialog::getSaveFileName(), QString("saveName"));
}
+#ifdef Q_OS_UNIX
+void tst_QFiledialog::tildeExpansion_data()
+{
+ QTest::addColumn<QString>("tildePath");
+ QTest::addColumn<QString>("expandedPath");
+
+ QTest::newRow("empty path") << QString() << QString();
+ QTest::newRow("~") << QString::fromLatin1("~") << QDir::homePath();
+ QTest::newRow("~/some/sub/dir/") << QString::fromLatin1("~/some/sub/dir") << QDir::homePath()
+ + QString::fromLatin1("/some/sub/dir");
+ QString userHome = QString(qgetenv("USER"));
+ userHome.prepend('~');
+ QTest::newRow("current user (~<user> syntax)") << userHome << QDir::homePath();
+ QString invalid = QString::fromLatin1("~thisIsNotAValidUserName");
+ QTest::newRow("invalid user name") << invalid << invalid;
+}
+
+
+void tst_QFiledialog::tildeExpansion()
+{
+#ifndef QT_BUILD_INTERNAL
+ QSKIP("Test case relies on developer build (AUTOTEST_EXPORT)", SkipAll);
+#else
+ QFETCH(QString, tildePath);
+ QFETCH(QString, expandedPath);
+
+ QCOMPARE(qt_tildeExpansion(tildePath), expandedPath);
+#endif
+}
+#endif
+
QTEST_MAIN(tst_QFiledialog)
#include "tst_qfiledialog.moc"