diff --git a/bin/app/user/ApplicationSettings_for_package.xml b/bin/app/user/ApplicationSettings_for_package.xml
index 50eeeec9..885046b5 100644
--- a/bin/app/user/ApplicationSettings_for_package.xml
+++ b/bin/app/user/ApplicationSettings_for_package.xml
@@ -1,14 +1,17 @@
-
- 4
- 500
- 500
-
-
-
- ./data/projects/tutorial/tutorial.coatiproject
- ./data/projects/tictactoe/tictactoe.coatiproject
-
-
+
+ 500
+ 500
+
+
+ 4
+
+
+
+ ./data/projects/tutorial/tutorial.coatiproject
+ ./data/projects/tictactoe/tictactoe.coatiproject
+
+
+ 1
diff --git a/bin/app/user/ApplicationSettings_template.xml b/bin/app/user/ApplicationSettings_template.xml
index 8611acb8..3029b232 100644
--- a/bin/app/user/ApplicationSettings_template.xml
+++ b/bin/app/user/ApplicationSettings_template.xml
@@ -7,6 +7,8 @@
+
+
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index 72534d12..42c1d9d8 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -207,6 +207,8 @@ add_files(
settings/ProjectSettings.h
settings/Settings.cpp
settings/Settings.h
+ settings/SettingsMigrator.cpp
+ settings/SettingsMigrator.h
utility/file/FileInfo.cpp
utility/file/FileInfo.h
diff --git a/src/lib/settings/ApplicationSettings.cpp b/src/lib/settings/ApplicationSettings.cpp
index 67686a29..28e67e9a 100644
--- a/src/lib/settings/ApplicationSettings.cpp
+++ b/src/lib/settings/ApplicationSettings.cpp
@@ -3,6 +3,8 @@
#include "utility/ResourcePaths.h"
#include "utility/utility.h"
+const size_t ApplicationSettings::VERSION = 1;
+
std::shared_ptr ApplicationSettings::s_instance;
std::shared_ptr ApplicationSettings::getInstance()
@@ -23,6 +25,36 @@ ApplicationSettings::~ApplicationSettings()
{
}
+bool ApplicationSettings::load(const FilePath& filePath)
+{
+ bool loaded = Settings::load(filePath);
+ if (!loaded)
+ {
+ return false;
+ }
+
+ SettingsMigrator migrator;
+
+ migrator.addMigration(1,
+ "source/header_search_paths/header_search_path",
+ "indexing/cxx/header_search_paths/header_search_path");
+ migrator.addMigration(1,
+ "source/framework_search_paths/framework_search_path",
+ "indexing/cxx/framework_search_paths/framework_search_path");
+ migrator.addMigration(1,
+ "application/indexer_thread_count",
+ "indexing/indexer_thread_count");
+
+ bool migrated = migrator.migrate(this, ApplicationSettings::VERSION);
+
+ if (migrated)
+ {
+ save();
+ }
+
+ return true;
+}
+
bool ApplicationSettings::operator==(const ApplicationSettings& other) const
{
return
diff --git a/src/lib/settings/ApplicationSettings.h b/src/lib/settings/ApplicationSettings.h
index a2b2a769..73eda20f 100644
--- a/src/lib/settings/ApplicationSettings.h
+++ b/src/lib/settings/ApplicationSettings.h
@@ -10,9 +10,14 @@ class ApplicationSettings
{
public:
static std::shared_ptr getInstance();
+
+ static const size_t VERSION;
+
ApplicationSettings();
~ApplicationSettings();
+ bool load(const FilePath& filePath);
+
bool operator==(const ApplicationSettings& other) const;
int getMaxRecentProjectsCount() const;
diff --git a/src/lib/settings/Settings.cpp b/src/lib/settings/Settings.cpp
index 43803967..12a008e6 100644
--- a/src/lib/settings/Settings.cpp
+++ b/src/lib/settings/Settings.cpp
@@ -37,6 +37,7 @@ bool Settings::load(const FilePath& filePath)
else
{
clear();
+ m_filePath = filePath;
LOG_WARNING("File for Settings not found: " + filePath.str());
return false;
}
@@ -44,7 +45,7 @@ bool Settings::load(const FilePath& filePath)
void Settings::save()
{
- if (m_config.get() && m_filePath.exists())
+ if (m_config.get() && !m_filePath.empty())
{
m_config->save(m_filePath.str());
}
@@ -58,14 +59,7 @@ void Settings::save(const FilePath& filePath)
{
setFilePath(filePath);
- if (m_config)
- {
- m_config->save(filePath.str());
- }
- else
- {
- LOG_WARNING("Settings were not saved: " + filePath.str());
- }
+ save();
}
void Settings::clear()
@@ -79,6 +73,33 @@ const FilePath& Settings::getFilePath() const
return m_filePath;
}
+size_t Settings::getVersion() const
+{
+ return getValue("version", 0);
+}
+
+void Settings::setVersion(size_t version)
+{
+ setValue("version", version);
+}
+
+Settings Settings::createFromText(const std::shared_ptr textAccess)
+{
+ Settings settings;
+ settings.m_config = ConfigManager::createAndLoad(textAccess);
+ return settings;
+}
+
+std::string Settings::getAsText() const
+{
+ if (m_config)
+ {
+ return m_config->toString();
+ }
+
+ return "";
+}
+
Settings::Settings()
{
clear();
@@ -126,6 +147,11 @@ bool Settings::isValueDefined(const std::string& key) const
return m_config->isValueDefined(key);
}
+void Settings::removeValues(const std::string& key)
+{
+ m_config->removeValues(key);
+}
+
void Settings::enableWarnings() const
{
m_config->setWarnOnEmptyKey(true);
diff --git a/src/lib/settings/Settings.h b/src/lib/settings/Settings.h
index df05bc8c..1ab55a5a 100644
--- a/src/lib/settings/Settings.h
+++ b/src/lib/settings/Settings.h
@@ -8,6 +8,8 @@
#include "utility/ConfigManager.h"
#include "utility/file/FilePath.h"
+#include "settings/SettingsMigrator.h"
+
class Settings
{
public:
@@ -15,14 +17,20 @@ public:
Settings& operator=(const Settings& other);
virtual ~Settings();
- virtual bool load(const FilePath& filePath);
- virtual void save();
- virtual void save(const FilePath& filePath);
+ bool load(const FilePath& filePath);
+ void save();
+ void save(const FilePath& filePath);
void clear();
virtual const FilePath& getFilePath() const;
+ size_t getVersion() const;
+ void setVersion(size_t version);
+
+ static Settings createFromText(const std::shared_ptr textAccess);
+ std::string getAsText() const;
+
protected:
Settings();
@@ -47,9 +55,13 @@ protected:
bool isValueDefined(const std::string& key) const;
+ void removeValues(const std::string& key);
+
void enableWarnings() const;
void disableWarnings() const;
+ friend bool SettingsMigrator::migrate(Settings* settings, size_t targetVersion) const;
+
private:
FilePath m_filePath;
std::shared_ptr m_config;
diff --git a/src/lib/settings/SettingsMigrator.cpp b/src/lib/settings/SettingsMigrator.cpp
new file mode 100644
index 00000000..e9d86790
--- /dev/null
+++ b/src/lib/settings/SettingsMigrator.cpp
@@ -0,0 +1,55 @@
+#include "settings/SettingsMigrator.h"
+
+#include "settings/Settings.h"
+
+SettingsMigrator::SettingsMigrator()
+{
+}
+
+SettingsMigrator::~SettingsMigrator()
+{
+}
+
+void SettingsMigrator::addMigration(size_t targetVersion, std::string oldKey, std::string newKey)
+{
+ Migration migration;
+ migration.targetVersion = targetVersion;
+ migration.oldKey = oldKey;
+ migration.newKey = newKey;
+
+ m_migrations.emplace(targetVersion, migration);
+}
+
+bool SettingsMigrator::migrate(Settings* settings, size_t targetVersion) const
+{
+ size_t originVersion = settings->getVersion();
+
+ if (originVersion < targetVersion)
+ {
+ for (; originVersion <= targetVersion; originVersion++)
+ {
+ std::pair::const_iterator, std::multimap::const_iterator> ret;
+ ret = m_migrations.equal_range(originVersion);
+
+ for (std::multimap::const_iterator it = ret.first; it != ret.second; it++)
+ {
+ const Migration& migration = it->second;
+
+ if (!settings->isValueDefined(migration.newKey))
+ {
+ settings->setValues(
+ migration.newKey,
+ settings->getValues(migration.oldKey, std::vector())
+ );
+ settings->removeValues(migration.oldKey);
+ }
+ }
+ }
+
+ settings->setVersion(targetVersion);
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/lib/settings/SettingsMigrator.h b/src/lib/settings/SettingsMigrator.h
new file mode 100644
index 00000000..343030b2
--- /dev/null
+++ b/src/lib/settings/SettingsMigrator.h
@@ -0,0 +1,32 @@
+#ifndef SETTNGS_MIGRATOR_H
+#define SETTNGS_MIGRATOR_H
+
+#include