SettingsAccessor: Unify handling of different file locations

Unify the code calculating the different file locations used by the
SettingsAccessor.

Change-Id: I85283f99618143ce1fbdd309bce12529cec442ca
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Tobias Hunger
2018-01-18 11:46:41 +01:00
parent 4f65d9a1fb
commit 79a43b4d86
2 changed files with 51 additions and 32 deletions

View File

@@ -40,15 +40,13 @@ const char SETTINGS_ID_KEY[] = "EnvironmentId";
const char USER_STICKY_KEYS_KEY[] = "UserStickyKeys"; const char USER_STICKY_KEYS_KEY[] = "UserStickyKeys";
const char VERSION_KEY[] = "Version"; const char VERSION_KEY[] = "Version";
static QString generateSuffix(const QString &alt1, const QString &alt2) static QString generateSuffix(const QString &suffix)
{ {
QString suffix = alt1; QString result = suffix;
if (suffix.isEmpty()) result.replace(QRegExp("[^a-zA-Z0-9_.-]"), QString('_')); // replace fishy characters:
suffix = alt2; if (!result.startsWith('.'))
suffix.replace(QRegExp("[^a-zA-Z0-9_.-]"), QString('_')); // replace fishy characters: result.prepend('.');
if (!suffix.startsWith('.')) return result;
suffix.prepend('.');
return suffix;
} }
class Operation { class Operation {
@@ -312,6 +310,8 @@ QVariantMap BasicSettingsAccessor::prepareToWriteSettings(const QVariantMap &dat
class SettingsAccessorPrivate class SettingsAccessorPrivate
{ {
public: public:
SettingsAccessorPrivate(const FileName &projectFilePath) : m_projectFilePath(projectFilePath) { }
// The relevant data from the settings currently in use. // The relevant data from the settings currently in use.
class Settings class Settings
{ {
@@ -338,10 +338,12 @@ public:
QByteArray m_settingsId; QByteArray m_settingsId;
std::unique_ptr<BasicSettingsAccessor> m_sharedFile; std::unique_ptr<BasicSettingsAccessor> m_sharedFile;
const FileName m_projectFilePath;
}; };
// Return path to shared directory for .user files, create if necessary. // Return path to shared directory for .user files, create if necessary.
static inline QString determineSharedUserFileDir() static inline Utils::optional<QString> defineExternalUserFileDir()
{ {
const char userFilePathVariable[] = "QTC_USER_FILE_PATH"; const char userFilePathVariable[] = "QTC_USER_FILE_PATH";
if (!qEnvironmentVariableIsSet(userFilePathVariable)) if (!qEnvironmentVariableIsSet(userFilePathVariable))
@@ -353,22 +355,16 @@ static inline QString determineSharedUserFileDir()
if (fi.exists()) { if (fi.exists()) {
qWarning() << userFilePathVariable << '=' << QDir::toNativeSeparators(path) qWarning() << userFilePathVariable << '=' << QDir::toNativeSeparators(path)
<< " points to an existing file"; << " points to an existing file";
return QString(); return nullopt;
} }
QDir dir; QDir dir;
if (!dir.mkpath(path)) { if (!dir.mkpath(path)) {
qWarning() << "Cannot create: " << QDir::toNativeSeparators(path); qWarning() << "Cannot create: " << QDir::toNativeSeparators(path);
return QString(); return nullopt;
} }
return path; return path;
} }
static QString sharedUserFileDir()
{
static const QString sharedDir = determineSharedUserFileDir();
return sharedDir;
}
// Return a suitable relative path to be created under the shared .user directory. // Return a suitable relative path to be created under the shared .user directory.
static QString makeRelative(QString path) static QString makeRelative(QString path)
{ {
@@ -397,18 +393,18 @@ static QString makeRelative(QString path)
} }
// Return complete file path of the .user file. // Return complete file path of the .user file.
static FileName userFilePath(const Utils::FileName &projectFilePath, const QString &suffix) static FileName externalUserFilePath(const Utils::FileName &projectFilePath, const QString &suffix)
{ {
FileName result; FileName result;
if (sharedUserFileDir().isEmpty()) { static const optional<QString> externalUserFileDir = defineExternalUserFileDir();
result = projectFilePath;
} else { if (!externalUserFileDir) {
// Recreate the relative project file hierarchy under the shared directory. // Recreate the relative project file hierarchy under the shared directory.
// PersistentSettingsWriter::write() takes care of creating the path. // PersistentSettingsWriter::write() takes care of creating the path.
result = FileName::fromString(sharedUserFileDir()); result = FileName::fromString(externalUserFileDir.value());
result.appendString('/' + makeRelative(projectFilePath.toString())); result.appendString('/' + makeRelative(projectFilePath.toString()));
}
result.appendString(suffix); result.appendString(suffix);
}
return result; return result;
} }
@@ -465,15 +461,14 @@ QVariantMap VersionUpgrader::renameKeys(const QList<Change> &changes, QVariantMa
SettingsAccessor::SettingsAccessor(const Utils::FileName &baseFile, const QString &docType, SettingsAccessor::SettingsAccessor(const Utils::FileName &baseFile, const QString &docType,
const QString &displayName, const QString &appDisplayName) : const QString &displayName, const QString &appDisplayName) :
BasicSettingsAccessor(docType, displayName, appDisplayName), BasicSettingsAccessor(docType, displayName, appDisplayName),
d(new SettingsAccessorPrivate) d(new SettingsAccessorPrivate(baseFile))
{ {
Utils::FileName baseFilePath = userFilePath(baseFile, generateSuffix(QString::fromLocal8Bit(qgetenv("QTC_EXTENSION")), ".user")); const FileName externalUser = externalUserFile();
setBaseFilePath(baseFilePath); const FileName projectUser = projectUserFile();
setBaseFilePath(externalUser.isEmpty() ? projectUser : externalUser);
Utils::FileName sharedFilePath = baseFile;
sharedFilePath.appendString(generateSuffix(QString::fromLocal8Bit(qgetenv("QTC_SHARED_EXTENSION")), ".shared"));
d->m_sharedFile = std::make_unique<BasicSettingsAccessor>(docType, displayName, appDisplayName); d->m_sharedFile = std::make_unique<BasicSettingsAccessor>(docType, displayName, appDisplayName);
d->m_sharedFile->setBaseFilePath(sharedFilePath); d->m_sharedFile->setBaseFilePath(sharedFile());
} }
SettingsAccessor::~SettingsAccessor() SettingsAccessor::~SettingsAccessor()
@@ -679,6 +674,25 @@ bool SettingsAccessor::addVersionUpgrader(std::unique_ptr<VersionUpgrader> upgra
return true; return true;
} }
FileName SettingsAccessor::projectUserFile() const
{
FileName projectUserFile = d->m_projectFilePath;
projectUserFile.appendString(generateSuffix(qEnvironmentVariable("QTC_EXTENSION", ".user")));
return projectUserFile;
}
FileName SettingsAccessor::externalUserFile() const
{
return externalUserFilePath(d->m_projectFilePath, generateSuffix(qEnvironmentVariable("QTC_EXTENSION", ".user")));
}
FileName SettingsAccessor::sharedFile() const
{
FileName sharedFile = d->m_projectFilePath;
sharedFile.appendString(generateSuffix(qEnvironmentVariable("QTC_SHARED_EXTENSION", ".shared")));
return sharedFile;
}
BasicSettingsAccessor::RestoreData SettingsAccessor::readData(const FileName &path, BasicSettingsAccessor::RestoreData SettingsAccessor::readData(const FileName &path,
QWidget *parent) const QWidget *parent) const
{ {
@@ -725,9 +739,10 @@ FileNameList SettingsAccessor::settingsFiles() const
const QFileInfo pfi = baseFilePath().toFileInfo(); const QFileInfo pfi = baseFilePath().toFileInfo();
const QStringList filter(pfi.fileName() + '*'); const QStringList filter(pfi.fileName() + '*');
if (!sharedUserFileDir().isEmpty()) { const FileName externalUser = externalUserFile();
const QString sharedPath = sharedUserFileDir() + '/' + makeRelative(pfi.absolutePath()); if (!externalUser.isEmpty()) {
list.append(QDir(sharedPath).entryInfoList(filter, QDir::Files | QDir::Hidden | QDir::System)); const QString externalPath = externalUser.toString() + '/' + makeRelative(pfi.absolutePath());
list.append(QDir(externalPath).entryInfoList(filter, QDir::Files | QDir::Hidden | QDir::System));
} }
list.append(QDir(pfi.dir()).entryInfoList(filter, QDir::Files | QDir::Hidden | QDir::System)); list.append(QDir(pfi.dir()).entryInfoList(filter, QDir::Files | QDir::Hidden | QDir::System));

View File

@@ -149,6 +149,10 @@ public:
bool addVersionUpgrader(std::unique_ptr<VersionUpgrader> upgrader); bool addVersionUpgrader(std::unique_ptr<VersionUpgrader> upgrader);
Utils::FileName projectUserFile() const;
Utils::FileName externalUserFile() const;
Utils::FileName sharedFile() const;
protected: protected:
RestoreData readData(const Utils::FileName &path, QWidget *parent) const final; RestoreData readData(const Utils::FileName &path, QWidget *parent) const final;
Utils::optional<Issue> writeData(const Utils::FileName &path, const QVariantMap &data) const final; Utils::optional<Issue> writeData(const Utils::FileName &path, const QVariantMap &data) const final;