From dfab8f5fb35f0fb94985bd00c138cbb033c5e141 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sat, 14 Dec 2019 22:33:55 +0000 Subject: [PATCH] QStandardPaths cleanup Signed-off-by: Ivailo Monev --- src/core/io/qstandardpaths.cpp | 232 ++++++++++---------- src/core/io/qstandardpaths.h | 70 +++--- src/core/io/qstandardpaths_unix.cpp | 421 +++++++++++++++++------------------- 3 files changed, 352 insertions(+), 371 deletions(-) diff --git a/src/core/io/qstandardpaths.cpp b/src/core/io/qstandardpaths.cpp index a929331a2..65fc4cf9e 100644 --- a/src/core/io/qstandardpaths.cpp +++ b/src/core/io/qstandardpaths.cpp @@ -222,15 +222,15 @@ QT_BEGIN_NAMESPACE /*! - \fn QStringList QStandardPaths::standardLocations(StandardLocation type) + \fn QStringList QStandardPaths::standardLocations(StandardLocation type) - Returns all the directories where files of \a type belong. + Returns all the directories where files of \a type belong. - The list of directories is sorted from high to low priority, starting with - writableLocation() if it can be determined. This list is empty if no locations - for \a type are defined. + The list of directories is sorted from high to low priority, starting with + writableLocation() if it can be determined. This list is empty if no locations + for \a type are defined. - \sa writableLocation() + \sa writableLocation() */ /*! @@ -246,117 +246,111 @@ QT_BEGIN_NAMESPACE static bool existsAsSpecified(const QString &path, QStandardPaths::LocateOptions options) { - if (options & QStandardPaths::LocateDirectory) { - return QDir(path).exists(); - } - return QFileInfo(path).isFile(); + 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. + 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. + 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(); + foreach (const QString &dir, standardLocations(type)) { + 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. + 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. + The \a options flag allows to specify whether to look for files or directories. - Returns the list of all the files that were found. + 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; + QStringList result; + foreach (const QString &dir, standardLocations(type)) { + const QString path = dir + QLatin1Char('/') + fileName; + if (existsAsSpecified(path, options)) { + result.append(path); + } + } + return result; } static QString checkExecutable(const QString &path) { - const QFileInfo info(path); - if (info.isFile() && info.isExecutable()) { - return QDir::cleanPath(path); - } - return QString(); + const QFileInfo info(path); + if (info.isFile() && info.isExecutable()) { + return QDir::cleanPath(path); + } + return QString(); } static inline QString searchExecutable(const QStringList &searchPaths, const QString &executableName) { - const QDir currentDir = QDir::current(); - foreach (const QString & searchPath, searchPaths) { - const QString candidate = currentDir.absoluteFilePath(searchPath + QLatin1Char('/') + executableName); - const QString absPath = checkExecutable(candidate); - if (!absPath.isEmpty()) { - return absPath; - } - } - return QString(); + const QDir currentDir = QDir::current(); + foreach (const QString &searchPath, searchPaths) { + const QString candidate = currentDir.absoluteFilePath(searchPath + QLatin1Char('/') + executableName); + const QString absPath = checkExecutable(candidate); + if (!absPath.isEmpty()) { + return absPath; + } + } + return QString(); } /*! - Finds the executable named \a executableName in the paths specified by \a paths, - or the system paths if \a paths is empty. - - On most operating systems the system path is determined by the PATH environment variable. + Finds the executable named \a executableName in the paths specified by \a paths, + or the system paths if \a paths is empty. - The directories where to search for the executable can be set in the \a paths argument. - To search in both your own paths and the system paths, call findExecutable twice, once with - \a paths set and once with \a paths empty. + On most operating systems the system path is determined by the PATH environment variable. - Symlinks are not resolved, in order to preserve behavior for the case of executables - whose behavior depends on the name they are invoked with. + The directories where to search for the executable can be set in the \a paths argument. + To search in both your own paths and the system paths, call findExecutable twice, once with + \a paths set and once with \a paths empty. - \note On Windows, the usual executable extensions (from the PATHEXT environment variable) - are automatically appended, so that for instance findExecutable("foo") will find foo.exe - or foo.bat if present. + Symlinks are not resolved, in order to preserve behavior for the case of executables + whose behavior depends on the name they are invoked with. - Returns the absolute file path to the executable, or an empty string if not found. + Returns the absolute file path to the executable, or an empty string if not found. */ QString QStandardPaths::findExecutable(const QString &executableName, const QStringList &paths) { - if (QFileInfo(executableName).isAbsolute()) { - return checkExecutable(executableName); - } - - QStringList searchPaths = paths; - if (paths.isEmpty()) { - const QByteArray pEnv = qgetenv("PATH"); - const QLatin1Char pathSep(':'); - // Remove trailing slashes, which occur on Windows. - const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, QString::SkipEmptyParts); - searchPaths.reserve(rawPaths.size()); - foreach (const QString & rawPath, rawPaths) { - QString cleanPath = QDir::cleanPath(rawPath); - if (cleanPath.size() > 1 && cleanPath.endsWith(QLatin1Char('/'))) { - cleanPath.truncate(cleanPath.size() - 1); - } - searchPaths.push_back(cleanPath); - } - } - - return searchExecutable(searchPaths, executableName); + if (QFileInfo(executableName).isAbsolute()) { + return checkExecutable(executableName); + } + + QStringList searchPaths = paths; + if (paths.isEmpty()) { + const QByteArray pEnv = qgetenv("PATH"); + const QLatin1Char pathSep(':'); + // Remove trailing slashes, which occur on Windows. + const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, QString::SkipEmptyParts); + searchPaths.reserve(rawPaths.size()); + foreach (const QString & rawPath, rawPaths) { + QString cleanPath = QDir::cleanPath(rawPath); + if (cleanPath.size() > 1 && cleanPath.endsWith(QLatin1Char('/'))) { + cleanPath.truncate(cleanPath.size() - 1); + } + searchPaths.push_back(cleanPath); + } + } + + return searchExecutable(searchPaths, executableName); } /*! @@ -368,42 +362,42 @@ QString QStandardPaths::findExecutable(const QString &executableName, const QStr QString QStandardPaths::displayName(StandardLocation type) { - switch (type) { - case DesktopLocation: - return QCoreApplication::translate("QStandardPaths", "Desktop"); - case DocumentsLocation: - return QCoreApplication::translate("QStandardPaths", "Documents"); - case FontsLocation: - return QCoreApplication::translate("QStandardPaths", "Fonts"); - case ApplicationsLocation: - return QCoreApplication::translate("QStandardPaths", "Applications"); - case MusicLocation: - return QCoreApplication::translate("QStandardPaths", "Music"); - case MoviesLocation: - return QCoreApplication::translate("QStandardPaths", "Movies"); - case PicturesLocation: - return QCoreApplication::translate("QStandardPaths", "Pictures"); - case TempLocation: - return QCoreApplication::translate("QStandardPaths", "Temporary Directory"); - case HomeLocation: - return QCoreApplication::translate("QStandardPaths", "Home"); - case DataLocation: - return QCoreApplication::translate("QStandardPaths", "Application Data"); - case CacheLocation: - return QCoreApplication::translate("QStandardPaths", "Cache"); - case GenericDataLocation: - return QCoreApplication::translate("QStandardPaths", "Shared Data"); - case RuntimeLocation: - return QCoreApplication::translate("QStandardPaths", "Runtime"); - case ConfigLocation: - return QCoreApplication::translate("QStandardPaths", "Configuration"); - case GenericConfigLocation: - return QCoreApplication::translate("QStandardPaths", "Shared Configuration"); - case GenericCacheLocation: - return QCoreApplication::translate("QStandardPaths", "Shared Cache"); - case DownloadLocation: - return QCoreApplication::translate("QStandardPaths", "Download"); - } + switch (type) { + case DesktopLocation: + return QCoreApplication::translate("QStandardPaths", "Desktop"); + case DocumentsLocation: + return QCoreApplication::translate("QStandardPaths", "Documents"); + case FontsLocation: + return QCoreApplication::translate("QStandardPaths", "Fonts"); + case ApplicationsLocation: + return QCoreApplication::translate("QStandardPaths", "Applications"); + case MusicLocation: + return QCoreApplication::translate("QStandardPaths", "Music"); + case MoviesLocation: + return QCoreApplication::translate("QStandardPaths", "Movies"); + case PicturesLocation: + return QCoreApplication::translate("QStandardPaths", "Pictures"); + case TempLocation: + return QCoreApplication::translate("QStandardPaths", "Temporary Directory"); + case HomeLocation: + return QCoreApplication::translate("QStandardPaths", "Home"); + case DataLocation: + return QCoreApplication::translate("QStandardPaths", "Application Data"); + case CacheLocation: + return QCoreApplication::translate("QStandardPaths", "Cache"); + case GenericDataLocation: + return QCoreApplication::translate("QStandardPaths", "Shared Data"); + case RuntimeLocation: + return QCoreApplication::translate("QStandardPaths", "Runtime"); + case ConfigLocation: + return QCoreApplication::translate("QStandardPaths", "Configuration"); + case GenericConfigLocation: + return QCoreApplication::translate("QStandardPaths", "Shared Configuration"); + case GenericCacheLocation: + return QCoreApplication::translate("QStandardPaths", "Shared Cache"); + case DownloadLocation: + return QCoreApplication::translate("QStandardPaths", "Download"); + } // not reached return QString(); } diff --git a/src/core/io/qstandardpaths.h b/src/core/io/qstandardpaths.h index 1d595b429..48024102e 100644 --- a/src/core/io/qstandardpaths.h +++ b/src/core/io/qstandardpaths.h @@ -35,46 +35,46 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QStandardPaths { - public: - // Do not re-order, must match QDesktopServices - enum StandardLocation { - DesktopLocation, - DocumentsLocation, - FontsLocation, - ApplicationsLocation, - MusicLocation, - MoviesLocation, - PicturesLocation, - TempLocation, - HomeLocation, - DataLocation, - CacheLocation, - GenericDataLocation, - RuntimeLocation, - ConfigLocation, - DownloadLocation, - GenericCacheLocation, - GenericConfigLocation - }; +public: + // Do not re-order, must match QDesktopServices + enum StandardLocation { + DesktopLocation, + DocumentsLocation, + FontsLocation, + ApplicationsLocation, + MusicLocation, + MoviesLocation, + PicturesLocation, + TempLocation, + HomeLocation, + DataLocation, + CacheLocation, + GenericDataLocation, + RuntimeLocation, + ConfigLocation, + DownloadLocation, + GenericCacheLocation, + GenericConfigLocation + }; - static QString writableLocation(StandardLocation type); - static QStringList standardLocations(StandardLocation type); + static QString writableLocation(StandardLocation type); + static QStringList standardLocations(StandardLocation type); - enum LocateOption { - LocateFile = 0x0, - LocateDirectory = 0x1 - }; - typedef QFlags LocateOptions; + enum LocateOption { + LocateFile = 0x0, + LocateDirectory = 0x1 + }; + typedef QFlags LocateOptions; - 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); + 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); - static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList()); + static QString findExecutable(const QString &executableName, const QStringList &paths = QStringList()); - static void enableTestMode(bool testMode); - static void setTestModeEnabled(bool testMode); - static bool isTestModeEnabled(); + static void enableTestMode(bool testMode); + static void setTestModeEnabled(bool testMode); + static bool isTestModeEnabled(); private: Q_DISABLE_COPY(QStandardPaths) diff --git a/src/core/io/qstandardpaths_unix.cpp b/src/core/io/qstandardpaths_unix.cpp index 81e57f71b..d811eb6dd 100644 --- a/src/core/io/qstandardpaths_unix.cpp +++ b/src/core/io/qstandardpaths_unix.cpp @@ -41,243 +41,230 @@ QT_BEGIN_NAMESPACE static void appendOrganizationAndApp(QString &path) { - const QString org = QCoreApplication::organizationName(); + const QString org = QCoreApplication::organizationName(); - if (!org.isEmpty()) { - path += QLatin1Char('/') + org; - } - const QString appName = QCoreApplication::applicationName(); + if (!org.isEmpty()) { + path += QLatin1Char('/') + org; + } + const QString appName = QCoreApplication::applicationName(); - if (!appName.isEmpty()) { - path += QLatin1Char('/') + appName; - } + if (!appName.isEmpty()) { + path += QLatin1Char('/') + appName; + } } QString QStandardPaths::writableLocation(StandardLocation type) { - switch (type) { - case HomeLocation: - return QDir::homePath(); - case TempLocation: - return QDir::tempPath(); - case CacheLocation: - case GenericCacheLocation: { - // 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"); - } - if (type == QStandardPaths::CacheLocation) { - appendOrganizationAndApp(xdgCacheHome); - } - return xdgCacheHome; - } - case DataLocation: - case GenericDataLocation: { - QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME")); - if (xdgDataHome.isEmpty()) { - xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); - } - if (type == QStandardPaths::DataLocation) { - appendOrganizationAndApp(xdgDataHome); - } - return xdgDataHome; - } - case ConfigLocation: - case GenericConfigLocation: { - // 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; - } - case RuntimeLocation: { - const uid_t myUid = geteuid(); - // http://standards.freedesktop.org/basedir-spec/latest/ - QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR")); - if (xdgRuntimeDir.isEmpty()) { - const QString userName = QFileSystemEngine::resolveUserName(myUid); - xdgRuntimeDir = QDir::tempPath() + QLatin1String("/runtime-") + userName; - QDir dir(xdgRuntimeDir); - if (!dir.exists()) { - if (!QDir().mkdir(xdgRuntimeDir)) { - qWarning("QStandardPaths: error creating runtime directory %s: %s", qPrintable(xdgRuntimeDir), - qPrintable(qt_error_string(errno))); - return QString(); - } + switch (type) { + case DesktopLocation: + return QDir::homePath() + QLatin1String("/Desktop"); + case DocumentsLocation: + return QDir::homePath() + QLatin1String("/Documents"); + case PicturesLocation: + return QDir::homePath() + QLatin1String("/Pictures"); + case FontsLocation: + return QDir::homePath() + QLatin1String("/.fonts"); + case MusicLocation: + return QDir::homePath() + QLatin1String("/Music"); + case MoviesLocation: + return QDir::homePath() + QLatin1String("/Videos"); + case DownloadLocation: + return QDir::homePath() + QLatin1String("/Downloads"); + case ApplicationsLocation: + return writableLocation(GenericDataLocation) + QLatin1String("/applications"); + case HomeLocation: + return QDir::homePath(); + case TempLocation: + return QDir::tempPath(); + case CacheLocation: + case GenericCacheLocation: { + // 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"); } - qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir)); - } - // "The directory MUST be owned by the user" - QFileInfo fileInfo(xdgRuntimeDir); - if (fileInfo.ownerId() != myUid) { - qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir), - fileInfo.ownerId(), myUid); - return QString(); - } - // "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700." - QFile file(xdgRuntimeDir); - const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser; - if (file.permissions() != wantedPerms && !file.setPermissions(wantedPerms)) { - qWarning("QStandardPaths: wrong permissions on runtime directory %s", qPrintable(xdgRuntimeDir)); - return QString(); - } - return xdgRuntimeDir; - } - default: - break; - } - - // http://www.freedesktop.org/wiki/Software/xdg-user-dirs - QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME")); - if (xdgConfigHome.isEmpty()) { - xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); - } - QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs")); - if (file.open(QIODevice::ReadOnly)) { - QHash lines; - QTextStream stream(&file); - // Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop" - QRegExp exp(QLatin1String("^XDG_(.*)_DIR=(.*)$")); - while (!stream.atEnd()) { - const QString &line = stream.readLine(); - if (exp.indexIn(line) != -1) { - const QStringList lst = exp.capturedTexts(); - const QString key = lst.at(1); - QString value = lst.at(2); - if (value.length() > 2 - && value.startsWith(QLatin1Char('\"')) - && value.endsWith(QLatin1Char('\"'))) { - value = value.mid(1, value.length() - 2); + if (type == QStandardPaths::CacheLocation) { + appendOrganizationAndApp(xdgCacheHome); } - // Store the key and value: "DESKTOP", "$HOME/Desktop" - lines[key] = value; - } - } - - 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; - case DownloadLocation: - key = QLatin1String("DOWNLOAD"); - break; - default: - break; - } - 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 xdgCacheHome; + } + case DataLocation: + case GenericDataLocation: { + QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME")); + if (xdgDataHome.isEmpty()) { + xdgDataHome = QDir::homePath() + QLatin1String("/.local/share"); } - return value; - } - } - } - - QString path; - switch (type) { - case DesktopLocation: - path = QDir::homePath() + QLatin1String("/Desktop"); - break; - case DocumentsLocation: - path = QDir::homePath() + QLatin1String("/Documents"); - break; - case PicturesLocation: - path = QDir::homePath() + QLatin1String("/Pictures"); - break; - - case FontsLocation: - path = QDir::homePath() + QLatin1String("/.fonts"); - break; - - case MusicLocation: - path = QDir::homePath() + QLatin1String("/Music"); - break; + if (type == QStandardPaths::DataLocation) { + appendOrganizationAndApp(xdgDataHome); + } + return xdgDataHome; + } + case ConfigLocation: + case GenericConfigLocation: { + // 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; + } + case RuntimeLocation: { + const uid_t myUid = geteuid(); + // http://standards.freedesktop.org/basedir-spec/latest/ + QString xdgRuntimeDir = QFile::decodeName(qgetenv("XDG_RUNTIME_DIR")); + if (xdgRuntimeDir.isEmpty()) { + const QString userName = QFileSystemEngine::resolveUserName(myUid); + xdgRuntimeDir = QDir::tempPath() + QLatin1String("/runtime-") + userName; + QDir dir(xdgRuntimeDir); + if (!dir.exists() && !QDir().mkdir(xdgRuntimeDir)) { + qWarning("QStandardPaths: error creating runtime directory %s: %s", qPrintable(xdgRuntimeDir), + qPrintable(qt_error_string(errno))); + return QString(); + } + qWarning("QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '%s'", qPrintable(xdgRuntimeDir)); + } + // "The directory MUST be owned by the user" + QFileInfo fileInfo(xdgRuntimeDir); + if (fileInfo.ownerId() != myUid) { + qWarning("QStandardPaths: wrong ownership on runtime directory %s, %d instead of %d", qPrintable(xdgRuntimeDir), + fileInfo.ownerId(), myUid); + return QString(); + } + // "and he MUST be the only one having read and write access to it. Its Unix access mode MUST be 0700." + QFile file(xdgRuntimeDir); + const QFile::Permissions wantedPerms = QFile::ReadUser | QFile::WriteUser | QFile::ExeUser; + if (file.permissions() != wantedPerms && !file.setPermissions(wantedPerms)) { + qWarning("QStandardPaths: wrong permissions on runtime directory %s", qPrintable(xdgRuntimeDir)); + return QString(); + } + return xdgRuntimeDir; + } + default: + break; + } - case MoviesLocation: - path = QDir::homePath() + QLatin1String("/Videos"); - break; - case DownloadLocation: - path = QDir::homePath() + QLatin1String("/Downloads"); - break; - case ApplicationsLocation: - path = writableLocation(GenericDataLocation) + QLatin1String("/applications"); - break; + // http://www.freedesktop.org/wiki/Software/xdg-user-dirs + QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME")); + if (xdgConfigHome.isEmpty()) { + xdgConfigHome = QDir::homePath() + QLatin1String("/.config"); + } + QFile file(xdgConfigHome + QLatin1String("/user-dirs.dirs")); + if (file.open(QIODevice::ReadOnly)) { + QHash lines; + QTextStream stream(&file); + // Only look for lines like: XDG_DESKTOP_DIR="$HOME/Desktop" + QRegExp exp(QLatin1String("^XDG_(.*)_DIR=(.*)$")); + while (!stream.atEnd()) { + const QString &line = stream.readLine(); + if (exp.indexIn(line) != -1) { + const QStringList lst = exp.capturedTexts(); + const QString key = lst.at(1); + QString value = lst.at(2); + if (value.length() > 2 + && value.startsWith(QLatin1Char('\"')) + && value.endsWith(QLatin1Char('\"'))) { + value = value.mid(1, value.length() - 2); + } + // Store the key and value: "DESKTOP", "$HOME/Desktop" + lines[key] = value; + } + } - default: - break; - } + 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; + } + case DownloadLocation: { + key = QLatin1String("DOWNLOAD"); + break; + } + default: + break; + } + 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; + } + } + } - return path; + return QString(); } static QStringList xdgDataDirs() { - QStringList dirs; - // http://standards.freedesktop.org/basedir-spec/latest/ - QString xdgDataDirsEnv = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); - if (xdgDataDirsEnv.isEmpty()) { - dirs.append(QString::fromLatin1("/usr/local/share")); - dirs.append(QString::fromLatin1("/usr/share")); - } else { - dirs = xdgDataDirsEnv.split(QLatin1Char(':')); - } - return dirs; + // http://standards.freedesktop.org/basedir-spec/latest/ + QString xdgDataDirsEnv = QFile::decodeName(qgetenv("XDG_DATA_DIRS")); + if (xdgDataDirsEnv.isEmpty()) { + QStringList dirs; + dirs.append(QString::fromLatin1("/usr/local/share")); + dirs.append(QString::fromLatin1("/usr/share")); + return dirs; + } + return xdgDataDirsEnv.split(QLatin1Char(':')); } QStringList QStandardPaths::standardLocations(StandardLocation type) { - QStringList dirs; - switch (type) { - case ConfigLocation: - case GenericConfigLocation: { - // http://standards.freedesktop.org/basedir-spec/latest/ - const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS")); - if (xdgConfigDirs.isEmpty()) { - dirs.append(QString::fromLatin1("/etc/xdg")); - } else { - dirs = xdgConfigDirs.split(QLatin1Char(':')); - } - } - break; - case GenericDataLocation: - dirs = xdgDataDirs(); - break; - case ApplicationsLocation: - dirs = xdgDataDirs(); - for (int i = 0; i < dirs.count(); ++i) { - dirs[i].append(QLatin1String("/applications")); - } - break; - case DataLocation: - dirs = xdgDataDirs(); - for (int i = 0; i < dirs.count(); ++i) { - appendOrganizationAndApp(dirs[i]); - } - break; - default: - break; - } - const QString localDir = writableLocation(type); - dirs.prepend(localDir); - return dirs; + QStringList dirs; + switch (type) { + case ConfigLocation: + case GenericConfigLocation: { + // http://standards.freedesktop.org/basedir-spec/latest/ + const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS")); + if (xdgConfigDirs.isEmpty()) { + dirs.append(QString::fromLatin1("/etc/xdg")); + } else { + dirs = xdgConfigDirs.split(QLatin1Char(':')); + } + break; + } + case GenericDataLocation: { + dirs = xdgDataDirs(); + break; + } + case ApplicationsLocation: { + dirs = xdgDataDirs(); + for (int i = 0; i < dirs.count(); ++i) { + dirs[i].append(QLatin1String("/applications")); + } + break; + } + case DataLocation: { + dirs = xdgDataDirs(); + for (int i = 0; i < dirs.count(); ++i) { + appendOrganizationAndApp(dirs[i]); + } + break; + } + default: + break; + } + dirs.prepend(writableLocation(type)); + return dirs; } QT_END_NAMESPACE -- 2.11.0