From 44d48862c0ff4b67a76734deae5e76f926a77bce Mon Sep 17 00:00:00 2001 From: David Faure Date: Thu, 31 Oct 2013 18:17:44 +0100 Subject: [PATCH] QStandardPaths: add GenericConfigLocation This is what ConfigLocation was meant to be. A directory shared by all applications. Unfortunately when I wrote the fallback on Windows, I picked DataLocation (which is app-specific) instead of GenericDataLocation (which is shared between apps). This makes it impossible to have config files shared between apps, e.g. for libraries. It also makes ConfigLocation quite inconsistent (on Windows one cannot use it to load another app's config file, while it works everywhere else). All this is fixed by GenericConfigLocation, which is shared between apps. Change-Id: I23a755131061d4fea01e13dd1038fbd8ef333a5d Reviewed-by: Alex Richardson Reviewed-by: Thiago Macieira --- src/corelib/io/qstandardpaths.cpp | 7 ++++++- src/corelib/io/qstandardpaths.h | 3 ++- src/corelib/io/qstandardpaths_blackberry.cpp | 1 + src/corelib/io/qstandardpaths_ios.mm | 1 + src/corelib/io/qstandardpaths_mac.cpp | 2 ++ src/corelib/io/qstandardpaths_unix.cpp | 2 ++ src/corelib/io/qstandardpaths_win.cpp | 10 ++++++---- .../corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 10 ++++++++-- 8 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp index 186321db6e..2207b8c43e 100644 --- a/src/corelib/io/qstandardpaths.cpp +++ b/src/corelib/io/qstandardpaths.cpp @@ -95,6 +95,9 @@ QT_BEGIN_NAMESPACE files should be written. For instance unix local sockets. \value ConfigLocation Returns a directory location where user-specific configuration files should be written. + \value GenericConfigLocation Returns a directory location where user-specific + configuration files shared between multiple applications should be written. + This is a generic value and the returned path is never empty. \value DownloadLocation Returns a directory for user's downloaded files. @@ -335,6 +338,8 @@ QString QStandardPaths::displayName(StandardLocation type) 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: @@ -358,7 +363,7 @@ QString QStandardPaths::displayName(StandardLocation type) or writing to the current user's configuration. This affects the locations into which test programs might write files: - GenericDataLocation, DataLocation, ConfigLocation, + GenericDataLocation, DataLocation, ConfigLocation, GenericConfigLocation, GenericCacheLocation, CacheLocation. Other locations are not affected. diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h index df9089ace7..08d6d7b50c 100644 --- a/src/corelib/io/qstandardpaths.h +++ b/src/corelib/io/qstandardpaths.h @@ -69,7 +69,8 @@ public: RuntimeLocation, ConfigLocation, DownloadLocation, - GenericCacheLocation + GenericCacheLocation, + GenericConfigLocation }; static QString writableLocation(StandardLocation type); diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp index a801c2fba3..815756ff9a 100644 --- a/src/corelib/io/qstandardpaths_blackberry.cpp +++ b/src/corelib/io/qstandardpaths_blackberry.cpp @@ -75,6 +75,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) case GenericCacheLocation: return QDir::homePath() + testModeInsert() + QLatin1String("/Cache"); case ConfigLocation: + case GenericConfigLocation: return QDir::homePath() + testModeInsert() + QLatin1String("/Settings"); case GenericDataLocation: return sharedRoot + testModeInsert() + QLatin1String("/misc"); diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm index 332400eaf2..e2100045a6 100644 --- a/src/corelib/io/qstandardpaths_ios.mm +++ b/src/corelib/io/qstandardpaths_ios.mm @@ -99,6 +99,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) location = pathForDirectory(NSCachesDirectory); break; case ConfigLocation: + case GenericConfigLocation: location = pathForDirectory(NSDocumentDirectory); break; case DownloadLocation: diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp index 6744bfeab4..0efdfae253 100644 --- a/src/corelib/io/qstandardpaths_mac.cpp +++ b/src/corelib/io/qstandardpaths_mac.cpp @@ -58,6 +58,7 @@ OSType translateLocation(QStandardPaths::StandardLocation type) { switch (type) { case QStandardPaths::ConfigLocation: + case QStandardPaths::GenericConfigLocation: return kPreferencesFolderType; case QStandardPaths::DesktopLocation: return kDesktopFolderType; @@ -149,6 +150,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (type == CacheLocation) appendOrganizationAndApp(path); return path; + case GenericConfigLocation: case ConfigLocation: return qttestDir + QLatin1String("/Preferences"); default: diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp index 61e2e03a3d..1b9078f712 100644 --- a/src/corelib/io/qstandardpaths_unix.cpp +++ b/src/corelib/io/qstandardpaths_unix.cpp @@ -103,6 +103,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) return xdgDataHome; } case ConfigLocation: + case GenericConfigLocation: { // http://standards.freedesktop.org/basedir-spec/latest/ QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME")); @@ -277,6 +278,7 @@ 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")); diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index d4e0779381..6a79c7c00b 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -99,7 +99,8 @@ QString QStandardPaths::writableLocation(StandardLocation type) wchar_t path[MAX_PATH]; switch (type) { - case ConfigLocation: // same as DataLocation, on Windows + case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it) + case GenericConfigLocation: // same as GenericDataLocation, on Windows case DataLocation: case GenericDataLocation: #if defined Q_OS_WINCE @@ -111,7 +112,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) if (isTestModeEnabled()) result += QLatin1String("/qttest"); #ifndef QT_BOOTSTRAPPED - if (type != GenericDataLocation) { + if (type != GenericDataLocation && type != GenericConfigLocation) { if (!QCoreApplication::organizationName().isEmpty()) result += QLatin1Char('/') + QCoreApplication::organizationName(); if (!QCoreApplication::applicationName().isEmpty()) @@ -188,12 +189,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) if (SHGetSpecialFolderPath) { wchar_t path[MAX_PATH]; switch (type) { - case ConfigLocation: // same as DataLocation, on Windows + case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it) + case GenericConfigLocation: // same as GenericDataLocation, on Windows case DataLocation: case GenericDataLocation: if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) { QString result = convertCharArray(path); - if (type != GenericDataLocation) { + if (type != GenericDataLocation && type != GenericConfigLocation) { #ifndef QT_BOOTSTRAPPED if (!QCoreApplication::organizationName().isEmpty()) result += QLatin1Char('/') + QCoreApplication::organizationName(); diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index 9ac1526f07..35a59401b7 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -56,7 +56,7 @@ #define Q_XDG_PLATFORM #endif -const int MaxStandardLocation = QStandardPaths::GenericCacheLocation; +static const int MaxStandardLocation = QStandardPaths::GenericConfigLocation; class tst_qstandardpaths : public QObject { @@ -127,7 +127,8 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths "RuntimeLocation", "ConfigLocation", "DownloadLocation", - "GenericCacheLocation" + "GenericCacheLocation", + "GenericConfigLocation" }; void tst_qstandardpaths::dump() @@ -151,9 +152,11 @@ void tst_qstandardpaths::testDefaultLocations() const QString expectedConfHome = QDir::homePath() + QString::fromLatin1("/.config"); QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), expectedConfHome); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), expectedConfHome); const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); QCOMPARE(confDirs.count(), 2); QVERIFY(confDirs.contains(expectedConfHome)); + QCOMPARE(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation), confDirs); const QStringList genericDataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); QCOMPARE(genericDataDirs.count(), 3); @@ -178,6 +181,7 @@ void tst_qstandardpaths::testCustomLocations() // test writableLocation() QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), m_localConfigDir); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), m_localConfigDir); // test locate() const QString thisFileName = QString::fromLatin1("aFile"); @@ -212,6 +216,7 @@ void tst_qstandardpaths::enableTestMode() // ConfigLocation const QString configDir = qttestDir + QLatin1String("/config"); QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), configDir); + QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), configDir); const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); QCOMPARE(confDirs, QStringList() << configDir << m_globalConfigDir); @@ -235,6 +240,7 @@ void tst_qstandardpaths::enableTestMode() testLocations.insert(QStandardPaths::DataLocation, QStandardPaths::writableLocation(QStandardPaths::DataLocation)); testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); testLocations.insert(QStandardPaths::ConfigLocation, QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); + testLocations.insert(QStandardPaths::GenericConfigLocation, QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)); testLocations.insert(QStandardPaths::CacheLocation, QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); testLocations.insert(QStandardPaths::GenericCacheLocation, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); // On Windows, what should "Program Files" become, in test mode?