summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Faure <faure@kde.org>2011-10-21 20:54:35 +0200
committerQt by Nokia <qt-info@nokia.com>2011-10-23 00:56:39 +0200
commit8f3032dfe080c47c6fab7244a356064ce313f050 (patch)
tree714fc893d0286cba3b1b4e714d818d2ce8c3a428 /src
parent86558de34134f67cf3815a29612edc2d730f2ea2 (diff)
QStandardPaths: add Config and GenericData, add methods
New methods: standardLocations, locate, locateAll. Change-Id: I60bc90f8df53727a72c4b1839ea4d1d88a204e29 Reviewed-by: Thiago Macieira (Intel) <thiago.macieira@intel.com>
Diffstat (limited to 'src')
-rw-r--r--src/corelib/io/qstandardpaths.cpp86
-rw-r--r--src/corelib/io/qstandardpaths.h19
-rw-r--r--src/corelib/io/qstandardpaths_mac.cpp64
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp113
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp89
5 files changed, 297 insertions, 74 deletions
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index e441a21c11..58a6ab13eb 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -65,7 +65,8 @@ QT_BEGIN_NAMESPACE
\enum QStandardPaths::StandardLocation
This enum describes the different locations that can be queried using
- methods such as QStandardPaths::storageLocation and QStandardPaths::displayName.
+ methods such as QStandardPaths::storageLocation, QStandardPaths::standardLocations,
+ and QStandardPaths::displayName.
\value DesktopLocation Returns the user's desktop directory.
\value DocumentsLocation Returns the user's document.
@@ -77,19 +78,24 @@ QT_BEGIN_NAMESPACE
\value TempLocation Returns the system's temporary directory.
\value HomeLocation Returns the user's home directory.
\value DataLocation Returns a directory location where persistent
- application data can be stored. QCoreApplication::applicationName
- and QCoreApplication::organizationName should work on all
- platforms.
+ application data can be stored. QCoreApplication::organizationName
+ and QCoreApplication::applicationName are appended to the directory location
+ returned for GenericDataLocation.
\value CacheLocation Returns a directory location where user-specific
non-essential (cached) data should be written.
+ \value GenericDataLocation Returns a directory location where persistent
+ data shared across applications can be stored.
+ \value ConfigLocation Returns a directory location where user-specific
+ configuration files should be written.
- \sa storageLocation() displayName()
+
+ \sa storageLocation() standardLocations() displayName() locate() locateAll()
*/
/*!
\fn QString QStandardPaths::storageLocation(StandardLocation type)
- Returns the default system directory where files of \a type belong, or an empty string
+ Returns the directory where files of \a type should be written to, or an empty string
if the location cannot be determined.
\note The storage location returned can be a directory that does not exist; i.e., it
@@ -102,6 +108,74 @@ QT_BEGIN_NAMESPACE
that if executable is in ROM the folder from C drive is returned.
*/
+
+/*!
+ \fn QStringList QStandardPaths::standardLocations(StandardLocation type)
+
+ Returns all the directories where files of \a type belong.
+
+ Much like the PATH variable, it returns the directories in order of priority,
+ starting with the user-specific storageLocation() for the \a type.
+ */
+
+// TODO add XDG_RUNTIME_DIR?
+
+/*!
+ \enum QStandardPaths::LocateOption
+
+ This enum describes the different flags that can be used for
+ controlling the behavior of QStandardPaths::locate and
+ QStandardPaths::locateAll.
+
+ \value LocateFile return only files
+ \value LocateDirectory return only directories
+*/
+
+static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options)
+{
+ if (options & QStandardPaths::LocateDirectory)
+ return QDir(path).exists();
+ return QFileInfo(path).isFile();
+}
+
+/*!
+ Tries to find a file or directory called \a fileName in the standard locations
+ for \a type.
+
+ The full path to the first file or directory (depending on \a options) found is returned.
+ If no such file or directory can be found, an empty string is returned.
+ */
+QString QStandardPaths::locate(StandardLocation type, const QString &fileName, LocateOptions options)
+{
+ const QStringList &dirs = standardLocations(type);
+ for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
+ const QString path = *dir + QLatin1Char('/') + fileName;
+ if (existsAsSpecified(path, options))
+ return path;
+ }
+ return QString();
+}
+
+/*!
+ Tries to find all files or directories called \a fileName in the standard locations
+ for \a type.
+
+ The \a options flag allows to specify whether to look for files or directories.
+
+ Returns the list of all the files that were found.
+ */
+QStringList QStandardPaths::locateAll(StandardLocation type, const QString &fileName, LocateOptions options)
+{
+ const QStringList &dirs = standardLocations(type);
+ QStringList result;
+ for (QStringList::const_iterator dir = dirs.constBegin(); dir != dirs.constEnd(); ++dir) {
+ const QString path = *dir + QLatin1Char('/') + fileName;
+ if (existsAsSpecified(path, options))
+ result.append(path);
+ }
+ return result;
+}
+
/*!
\fn QString QStandardPaths::displayName(StandardLocation type)
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index 5b1bb826af..1688e16be7 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -69,11 +69,28 @@ public:
TempLocation,
HomeLocation,
DataLocation,
- CacheLocation
+ CacheLocation,
+ GenericDataLocation,
+ ConfigLocation
};
static QString storageLocation(StandardLocation type);
+ static QStringList standardLocations(StandardLocation type);
+
+ enum LocateOption {
+ LocateFile = 0x0,
+ LocateDirectory = 0x1
+ };
+ Q_DECLARE_FLAGS(LocateOptions, LocateOption)
+
+ static QString locate(StandardLocation type, const QString &fileName, LocateOptions options = LocateFile);
+ static QStringList locateAll(StandardLocation type, const QString &fileName, LocateOptions options = LocateFile);
static QString displayName(StandardLocation type);
+
+private:
+ // prevent construction
+ QStandardPaths();
+ ~QStandardPaths();
};
#endif // QT_NO_STANDARDPATHS
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp
index b90cc7c6f2..a13162cc7b 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.cpp
@@ -56,6 +56,8 @@ QT_BEGIN_NAMESPACE
OSType translateLocation(QStandardPaths::StandardLocation type)
{
switch (type) {
+ case QStandardPaths::ConfigLocation:
+ return kPreferencesFolderType;
case QStandardPaths::DesktopLocation:
return kDesktopFolderType;
case QStandardPaths::DocumentsLocation:
@@ -74,6 +76,7 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
return kPictureDocumentsFolderType;
case QStandardPaths::TempLocation:
return kTemporaryFolderType;
+ case QStandardPaths::GenericDataLocation:
case QStandardPaths::DataLocation:
return kApplicationSupportFolderType;
case QStandardPaths::CacheLocation:
@@ -94,35 +97,54 @@ static QString getFullPath(const FSRef &ref)
return QString();
}
-QString QStandardPaths::storageLocation(StandardLocation type)
+static QString macLocation(QStandardPaths::StandardLocation type, short domain)
{
- if (type == HomeLocation)
- return QDir::homePath();
-
- if (type == TempLocation)
- return QDir::tempPath();
+ // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
+ FSRef ref;
+ OSErr err = FSFindFolder(domain, translateLocation(type), false, &ref);
+ if (err)
+ return QString();
- short domain = kOnAppropriateDisk;
+ QString path = getFullPath(ref);
- if (type == DataLocation || type == CacheLocation)
- domain = kUserDomain;
+ if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation) {
+ if (!QCoreApplication::organizationName().isEmpty())
+ path += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (!QCoreApplication::applicationName().isEmpty())
+ path += QLatin1Char('/') + QCoreApplication::applicationName();
+ }
+ return path;
+}
- // http://developer.apple.com/documentation/Carbon/Reference/Folder_Manager/Reference/reference.html
- FSRef ref;
- OSErr err = FSFindFolder(domain, translateLocation(type), false, &ref);
- if (err)
- return QString();
+QString QStandardPaths::storageLocation(StandardLocation type)
+{
+ switch (type) {
+ case HomeLocation:
+ return QDir::homePath();
+ case TempLocation:
+ return QDir::tempPath();
+ case GenericDataLocation:
+ case DataLocation:
+ case CacheLocation:
+ return macLocation(type, kUserDomain);
+ default:
+ return macLocation(type, kOnAppropriateDisk);
+ }
+}
- QString path = getFullPath(ref);
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ QStringList dirs;
- if (type == DataLocation || type == CacheLocation) {
- if (QCoreApplication::organizationName().isEmpty() == false)
- path += QLatin1Char('/') + QCoreApplication::organizationName();
- if (QCoreApplication::applicationName().isEmpty() == false)
- path += QLatin1Char('/') + QCoreApplication::applicationName();
+ if (type == GenericDataLocation || type == DataLocation || type == CacheLocation) {
+ const QString path = macLocation(type, kOnAppropriateDisk);
+ if (!path.isEmpty())
+ dirs.append(path);
}
- return path;
+ const QString localDir = storageLocation(type);
+ dirs.prepend(localDir);
+ return dirs;
}
QString QStandardPaths::displayName(StandardLocation type)
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index f0c50059a9..5a52c2518f 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -54,30 +54,48 @@ QT_BEGIN_NAMESPACE
QString QStandardPaths::storageLocation(StandardLocation type)
{
- if (type == QStandardPaths::HomeLocation)
+ switch (type) {
+ case HomeLocation:
return QDir::homePath();
- if (type == QStandardPaths::TempLocation)
+ case TempLocation:
return QDir::tempPath();
-
- // http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
- if (type == QStandardPaths::CacheLocation) {
- QString xdgCacheHome = QLatin1String(qgetenv("XDG_CACHE_HOME"));
+ case CacheLocation:
+ {
+ // http://standards.freedesktop.org/basedir-spec/basedir-spec-0.6.html
+ QString xdgCacheHome = QFile::decodeName(qgetenv("XDG_CACHE_HOME"));
if (xdgCacheHome.isEmpty())
xdgCacheHome = QDir::homePath() + QLatin1String("/.cache");
- xdgCacheHome += QLatin1Char('/') + QCoreApplication::organizationName()
- + QLatin1Char('/') + QCoreApplication::applicationName();
+ if (!QCoreApplication::organizationName().isEmpty())
+ xdgCacheHome += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (!QCoreApplication::applicationName().isEmpty())
+ xdgCacheHome += QLatin1Char('/') + QCoreApplication::applicationName();
return xdgCacheHome;
}
-
- if (type == QStandardPaths::DataLocation) {
- QString xdgDataHome = QLatin1String(qgetenv("XDG_DATA_HOME"));
+ case DataLocation:
+ case GenericDataLocation:
+ {
+ QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
- xdgDataHome += QLatin1String("/data/")
- + QCoreApplication::organizationName() + QLatin1Char('/')
- + QCoreApplication::applicationName();
+ if (type == QStandardPaths::DataLocation) {
+ if (!QCoreApplication::organizationName().isEmpty())
+ xdgDataHome += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (!QCoreApplication::applicationName().isEmpty())
+ xdgDataHome += QLatin1Char('/') + QCoreApplication::applicationName();
+ }
return xdgDataHome;
}
+ case ConfigLocation:
+ {
+ // http://standards.freedesktop.org/basedir-spec/latest/
+ QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
+ if (xdgConfigHome.isEmpty())
+ xdgConfigHome = QDir::homePath() + QLatin1String("/.config");
+ return xdgConfigHome;
+ }
+ default:
+ break;
+ }
// http://www.freedesktop.org/wiki/Software/xdg-user-dirs
QString xdgConfigHome = QLatin1String(qgetenv("XDG_CONFIG_HOME"));
@@ -90,7 +108,7 @@ QString QStandardPaths::storageLocation(StandardLocation type)
// Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop"
QRegExp exp(QLatin1String("^XDG_(.*)_DIR=(.*)$"));
while (!stream.atEnd()) {
- QString line = stream.readLine();
+ const QString &line = stream.readLine();
if (exp.indexIn(line) != -1) {
const QStringList lst = exp.capturedTexts();
const QString key = lst.at(1);
@@ -106,23 +124,35 @@ QString QStandardPaths::storageLocation(StandardLocation type)
QString key;
switch (type) {
- case DesktopLocation: key = QLatin1String("DESKTOP"); break;
- case DocumentsLocation: key = QLatin1String("DOCUMENTS"); break;
- case PicturesLocation: key = QLatin1String("PICTURES"); break;
- case MusicLocation: key = QLatin1String("MUSIC"); break;
- case MoviesLocation: key = QLatin1String("VIDEOS"); break;
- default: break;
+ case DesktopLocation:
+ key = QLatin1String("DESKTOP");
+ break;
+ case DocumentsLocation:
+ key = QLatin1String("DOCUMENTS");
+ break;
+ case PicturesLocation:
+ key = QLatin1String("PICTURES");
+ break;
+ case MusicLocation:
+ key = QLatin1String("MUSIC");
+ break;
+ case MoviesLocation:
+ key = QLatin1String("VIDEOS");
+ break;
+ default:
+ break;
}
- if (!key.isEmpty() && lines.contains(key)) {
- QString value = lines[key];
- // value can start with $HOME
- if (value.startsWith(QLatin1String("$HOME")))
- value = QDir::homePath() + value.mid(5);
- return value;
+ if (!key.isEmpty()) {
+ QString value = lines.value(key);
+ if (!value.isEmpty()) {
+ // value can start with $HOME
+ if (value.startsWith(QLatin1String("$HOME")))
+ value = QDir::homePath() + value.mid(5);
+ return value;
+ }
}
}
- QDir emptyDir;
QString path;
switch (type) {
case DesktopLocation:
@@ -148,6 +178,9 @@ QString QStandardPaths::storageLocation(StandardLocation type)
break;
case ApplicationsLocation:
+ path = storageLocation(GenericDataLocation) + QLatin1String("/applications");
+ break;
+
default:
break;
}
@@ -155,6 +188,30 @@ QString QStandardPaths::storageLocation(StandardLocation type)
return path;
}
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ QStringList dirs;
+ if (type == ConfigLocation) {
+ // http://standards.freedesktop.org/basedir-spec/latest/
+ QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));
+ if (xdgConfigDirs.isEmpty())
+ dirs.append(QString::fromLatin1("/etc/xdg"));
+ else
+ dirs = xdgConfigDirs.split(QLatin1Char(':'));
+ } else if (type == GenericDataLocation) {
+ // http://standards.freedesktop.org/basedir-spec/latest/
+ QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_DATA_DIRS"));
+ if (xdgConfigDirs.isEmpty()) {
+ dirs.append(QString::fromLatin1("/usr/local/share"));
+ dirs.append(QString::fromLatin1("/usr/share"));
+ } else
+ dirs = xdgConfigDirs.split(QLatin1Char(':'));
+ }
+ const QString localDir = storageLocation(type);
+ dirs.prepend(localDir);
+ return dirs;
+}
+
QString QStandardPaths::displayName(StandardLocation type)
{
Q_UNUSED(type);
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 7d7fbd0857..497e09e0e2 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -70,70 +70,87 @@
QT_BEGIN_NAMESPACE
-QString QStandardPaths::storageLocation(StandardLocation type)
+typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
+static GetSpecialFolderPath resolveGetSpecialFolderPath()
{
- QString result;
-
+ static GetSpecialFolderPath gsfp = 0;
+ if (!gsfp) {
#ifndef Q_OS_WINCE
QSystemLibrary library(QLatin1String("shell32"));
#else
QSystemLibrary library(QLatin1String("coredll"));
#endif // Q_OS_WINCE
- typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
- static GetSpecialFolderPath SHGetSpecialFolderPath =
- (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
+ gsfp = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
+ }
+ return gsfp;
+}
+
+static QString convertCharArray(const wchar_t *path)
+{
+ return QDir::fromNativeSeparators(QString::fromWCharArray(path));
+}
+
+QString QStandardPaths::storageLocation(StandardLocation type)
+{
+ QString result;
+
+ static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath();
if (!SHGetSpecialFolderPath)
return QString();
wchar_t path[MAX_PATH];
switch (type) {
+ case ConfigLocation: // same as DataLocation, on Windows
case DataLocation:
+ case GenericDataLocation:
#if defined Q_OS_WINCE
if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
#else
if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
#endif
- result = QString::fromWCharArray(path);
- if (!QCoreApplication::organizationName().isEmpty())
- result = result + QLatin1String("\\") + QCoreApplication::organizationName();
- if (!QCoreApplication::applicationName().isEmpty())
- result = result + QLatin1String("\\") + QCoreApplication::applicationName();
+ result = convertCharArray(path);
+ if (type != GenericDataLocation) {
+ if (!QCoreApplication::organizationName().isEmpty())
+ result += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (!QCoreApplication::applicationName().isEmpty())
+ result += QLatin1Char('/') + QCoreApplication::applicationName();
+ }
break;
case DesktopLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_DESKTOPDIRECTORY, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case DocumentsLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case FontsLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_FONTS, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case ApplicationsLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_PROGRAMS, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case MusicLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_MYMUSIC, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case MoviesLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_MYVIDEO, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case PicturesLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_MYPICTURES, FALSE))
- result = QString::fromWCharArray(path);
+ result = convertCharArray(path);
break;
case CacheLocation:
@@ -156,6 +173,42 @@ QString QStandardPaths::storageLocation(StandardLocation type)
return result;
}
+QStringList QStandardPaths::standardLocations(StandardLocation type)
+{
+ QStringList dirs;
+
+ // type-specific handling goes here
+
+#ifndef Q_WS_WINCE
+ static GetSpecialFolderPath SHGetSpecialFolderPath = resolveGetSpecialFolderPath();
+ if (SHGetSpecialFolderPath) {
+ wchar_t path[MAX_PATH];
+ switch (type) {
+ case ConfigLocation: // same as DataLocation, on Windows
+ case DataLocation:
+ case GenericDataLocation:
+ if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) {
+ QString result = convertCharArray(path);
+ if (type != GenericDataLocation) {
+ if (!QCoreApplication::organizationName().isEmpty())
+ result += QLatin1Char('/') + QCoreApplication::organizationName();
+ if (!QCoreApplication::applicationName().isEmpty())
+ result += QLatin1Char('/') + QCoreApplication::applicationName();
+ }
+ dirs.append(result);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+#endif
+
+ const QString localDir = storageLocation(type);
+ dirs.prepend(localDir);
+ return dirs;
+}
+
QString QStandardPaths::displayName(StandardLocation type)
{
Q_UNUSED(type);