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 <arichardson.kde@googlemail.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
David Faure 2013-10-31 18:17:44 +01:00 committed by The Qt Project
parent ec12d641fa
commit 44d48862c0
8 changed files with 28 additions and 8 deletions

View File

@ -95,6 +95,9 @@ QT_BEGIN_NAMESPACE
files should be written. For instance unix local sockets. files should be written. For instance unix local sockets.
\value ConfigLocation Returns a directory location where user-specific \value ConfigLocation Returns a directory location where user-specific
configuration files should be written. 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. \value DownloadLocation Returns a directory for user's downloaded files.
@ -335,6 +338,8 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Runtime"); return QCoreApplication::translate("QStandardPaths", "Runtime");
case ConfigLocation: case ConfigLocation:
return QCoreApplication::translate("QStandardPaths", "Configuration"); return QCoreApplication::translate("QStandardPaths", "Configuration");
case GenericConfigLocation:
return QCoreApplication::translate("QStandardPaths", "Shared Configuration");
case GenericCacheLocation: case GenericCacheLocation:
return QCoreApplication::translate("QStandardPaths", "Shared Cache"); return QCoreApplication::translate("QStandardPaths", "Shared Cache");
case DownloadLocation: case DownloadLocation:
@ -358,7 +363,7 @@ QString QStandardPaths::displayName(StandardLocation type)
or writing to the current user's configuration. or writing to the current user's configuration.
This affects the locations into which test programs might write files: This affects the locations into which test programs might write files:
GenericDataLocation, DataLocation, ConfigLocation, GenericDataLocation, DataLocation, ConfigLocation, GenericConfigLocation,
GenericCacheLocation, CacheLocation. GenericCacheLocation, CacheLocation.
Other locations are not affected. Other locations are not affected.

View File

@ -69,7 +69,8 @@ public:
RuntimeLocation, RuntimeLocation,
ConfigLocation, ConfigLocation,
DownloadLocation, DownloadLocation,
GenericCacheLocation GenericCacheLocation,
GenericConfigLocation
}; };
static QString writableLocation(StandardLocation type); static QString writableLocation(StandardLocation type);

View File

@ -75,6 +75,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case GenericCacheLocation: case GenericCacheLocation:
return QDir::homePath() + testModeInsert() + QLatin1String("/Cache"); return QDir::homePath() + testModeInsert() + QLatin1String("/Cache");
case ConfigLocation: case ConfigLocation:
case GenericConfigLocation:
return QDir::homePath() + testModeInsert() + QLatin1String("/Settings"); return QDir::homePath() + testModeInsert() + QLatin1String("/Settings");
case GenericDataLocation: case GenericDataLocation:
return sharedRoot + testModeInsert() + QLatin1String("/misc"); return sharedRoot + testModeInsert() + QLatin1String("/misc");

View File

@ -99,6 +99,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
location = pathForDirectory(NSCachesDirectory); location = pathForDirectory(NSCachesDirectory);
break; break;
case ConfigLocation: case ConfigLocation:
case GenericConfigLocation:
location = pathForDirectory(NSDocumentDirectory); location = pathForDirectory(NSDocumentDirectory);
break; break;
case DownloadLocation: case DownloadLocation:

View File

@ -58,6 +58,7 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
{ {
switch (type) { switch (type) {
case QStandardPaths::ConfigLocation: case QStandardPaths::ConfigLocation:
case QStandardPaths::GenericConfigLocation:
return kPreferencesFolderType; return kPreferencesFolderType;
case QStandardPaths::DesktopLocation: case QStandardPaths::DesktopLocation:
return kDesktopFolderType; return kDesktopFolderType;
@ -149,6 +150,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
if (type == CacheLocation) if (type == CacheLocation)
appendOrganizationAndApp(path); appendOrganizationAndApp(path);
return path; return path;
case GenericConfigLocation:
case ConfigLocation: case ConfigLocation:
return qttestDir + QLatin1String("/Preferences"); return qttestDir + QLatin1String("/Preferences");
default: default:

View File

@ -103,6 +103,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return xdgDataHome; return xdgDataHome;
} }
case ConfigLocation: case ConfigLocation:
case GenericConfigLocation:
{ {
// http://standards.freedesktop.org/basedir-spec/latest/ // http://standards.freedesktop.org/basedir-spec/latest/
QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME")); QString xdgConfigHome = QFile::decodeName(qgetenv("XDG_CONFIG_HOME"));
@ -277,6 +278,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
QStringList dirs; QStringList dirs;
switch (type) { switch (type) {
case ConfigLocation: case ConfigLocation:
case GenericConfigLocation:
{ {
// http://standards.freedesktop.org/basedir-spec/latest/ // http://standards.freedesktop.org/basedir-spec/latest/
const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS")); const QString xdgConfigDirs = QFile::decodeName(qgetenv("XDG_CONFIG_DIRS"));

View File

@ -99,7 +99,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
wchar_t path[MAX_PATH]; wchar_t path[MAX_PATH];
switch (type) { 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 DataLocation:
case GenericDataLocation: case GenericDataLocation:
#if defined Q_OS_WINCE #if defined Q_OS_WINCE
@ -111,7 +112,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
if (isTestModeEnabled()) if (isTestModeEnabled())
result += QLatin1String("/qttest"); result += QLatin1String("/qttest");
#ifndef QT_BOOTSTRAPPED #ifndef QT_BOOTSTRAPPED
if (type != GenericDataLocation) { if (type != GenericDataLocation && type != GenericConfigLocation) {
if (!QCoreApplication::organizationName().isEmpty()) if (!QCoreApplication::organizationName().isEmpty())
result += QLatin1Char('/') + QCoreApplication::organizationName(); result += QLatin1Char('/') + QCoreApplication::organizationName();
if (!QCoreApplication::applicationName().isEmpty()) if (!QCoreApplication::applicationName().isEmpty())
@ -188,12 +189,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
if (SHGetSpecialFolderPath) { if (SHGetSpecialFolderPath) {
wchar_t path[MAX_PATH]; wchar_t path[MAX_PATH];
switch (type) { 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 DataLocation:
case GenericDataLocation: case GenericDataLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) { if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) {
QString result = convertCharArray(path); QString result = convertCharArray(path);
if (type != GenericDataLocation) { if (type != GenericDataLocation && type != GenericConfigLocation) {
#ifndef QT_BOOTSTRAPPED #ifndef QT_BOOTSTRAPPED
if (!QCoreApplication::organizationName().isEmpty()) if (!QCoreApplication::organizationName().isEmpty())
result += QLatin1Char('/') + QCoreApplication::organizationName(); result += QLatin1Char('/') + QCoreApplication::organizationName();

View File

@ -56,7 +56,7 @@
#define Q_XDG_PLATFORM #define Q_XDG_PLATFORM
#endif #endif
const int MaxStandardLocation = QStandardPaths::GenericCacheLocation; static const int MaxStandardLocation = QStandardPaths::GenericConfigLocation;
class tst_qstandardpaths : public QObject class tst_qstandardpaths : public QObject
{ {
@ -127,7 +127,8 @@ static const char * const enumNames[MaxStandardLocation + 1 - int(QStandardPaths
"RuntimeLocation", "RuntimeLocation",
"ConfigLocation", "ConfigLocation",
"DownloadLocation", "DownloadLocation",
"GenericCacheLocation" "GenericCacheLocation",
"GenericConfigLocation"
}; };
void tst_qstandardpaths::dump() void tst_qstandardpaths::dump()
@ -151,9 +152,11 @@ void tst_qstandardpaths::testDefaultLocations()
const QString expectedConfHome = QDir::homePath() + QString::fromLatin1("/.config"); const QString expectedConfHome = QDir::homePath() + QString::fromLatin1("/.config");
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), expectedConfHome); QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), expectedConfHome);
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), expectedConfHome);
const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation);
QCOMPARE(confDirs.count(), 2); QCOMPARE(confDirs.count(), 2);
QVERIFY(confDirs.contains(expectedConfHome)); QVERIFY(confDirs.contains(expectedConfHome));
QCOMPARE(QStandardPaths::standardLocations(QStandardPaths::GenericConfigLocation), confDirs);
const QStringList genericDataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); const QStringList genericDataDirs = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
QCOMPARE(genericDataDirs.count(), 3); QCOMPARE(genericDataDirs.count(), 3);
@ -178,6 +181,7 @@ void tst_qstandardpaths::testCustomLocations()
// test writableLocation() // test writableLocation()
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), m_localConfigDir); QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), m_localConfigDir);
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), m_localConfigDir);
// test locate() // test locate()
const QString thisFileName = QString::fromLatin1("aFile"); const QString thisFileName = QString::fromLatin1("aFile");
@ -212,6 +216,7 @@ void tst_qstandardpaths::enableTestMode()
// ConfigLocation // ConfigLocation
const QString configDir = qttestDir + QLatin1String("/config"); const QString configDir = qttestDir + QLatin1String("/config");
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), configDir); QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::ConfigLocation), configDir);
QCOMPARE(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation), configDir);
const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation); const QStringList confDirs = QStandardPaths::standardLocations(QStandardPaths::ConfigLocation);
QCOMPARE(confDirs, QStringList() << configDir << m_globalConfigDir); 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::DataLocation, QStandardPaths::writableLocation(QStandardPaths::DataLocation));
testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)); testLocations.insert(QStandardPaths::GenericDataLocation, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation));
testLocations.insert(QStandardPaths::ConfigLocation, QStandardPaths::writableLocation(QStandardPaths::ConfigLocation)); 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::CacheLocation, QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
testLocations.insert(QStandardPaths::GenericCacheLocation, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)); testLocations.insert(QStandardPaths::GenericCacheLocation, QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation));
// On Windows, what should "Program Files" become, in test mode? // On Windows, what should "Program Files" become, in test mode?