diff --git a/bin/app/data/ApplicationSettings_template.xml b/bin/app/data/ApplicationSettings_template.xml
index b9144b1a..83c51a4e 100644
--- a/bin/app/data/ApplicationSettings_template.xml
+++ b/bin/app/data/ApplicationSettings_template.xml
@@ -7,7 +7,9 @@
-
+
+
+
diff --git a/bin/app/data/ProjectSettings_template.xml b/bin/app/data/ProjectSettings_template.xml
index ad3a5dcb..fcd103c3 100644
--- a/bin/app/data/ProjectSettings_template.xml
+++ b/bin/app/data/ProjectSettings_template.xml
@@ -8,6 +8,8 @@
-
+
+
+
diff --git a/bin/test/data/SettingsTestSuite/settings.xml b/bin/test/data/SettingsTestSuite/settings.xml
index e9d468d4..462cbcf7 100644
--- a/bin/test/data/SettingsTestSuite/settings.xml
+++ b/bin/test/data/SettingsTestSuite/settings.xml
@@ -7,7 +7,11 @@
data
- data/|src/
+
+ data/
+ src/
+
+
diff --git a/src/lib/ApplicationSettings.cpp b/src/lib/ApplicationSettings.cpp
index 80c14764..90277683 100644
--- a/src/lib/ApplicationSettings.cpp
+++ b/src/lib/ApplicationSettings.cpp
@@ -18,7 +18,9 @@ ApplicationSettings::~ApplicationSettings()
std::vector ApplicationSettings::getHeaderSearchPaths() const
{
- return getValues("source/HeaderSearchPaths", "");
+ //TODO: defaultValues?
+ std::vector defaultValues;
+ return getValues("source/HeaderSearchPaths", defaultValues);
}
int ApplicationSettings::getCodeTabWidth() const
diff --git a/src/lib/ProjectSettings.cpp b/src/lib/ProjectSettings.cpp
index 31710d0c..4f90715d 100644
--- a/src/lib/ProjectSettings.cpp
+++ b/src/lib/ProjectSettings.cpp
@@ -32,5 +32,7 @@ bool ProjectSettings::setSourcePath(const std::string& sourcePath)
std::vector ProjectSettings::getHeaderSearchPaths() const
{
- return getValues("source/HeaderSearchPaths", "");
+ //TODO defaultvalues?
+ std::vector defaultValues;
+ return getValues("source/HeaderSearchPaths/HeaderSearchPath", defaultValues);
}
diff --git a/src/lib/Settings.cpp b/src/lib/Settings.cpp
index a68f1cd9..434719ee 100644
--- a/src/lib/Settings.cpp
+++ b/src/lib/Settings.cpp
@@ -33,7 +33,7 @@ void Settings::save(const std::string& filePath)
{
if (m_config)
{
- m_config->save();
+ m_config->save(filePath);
}
else
{
@@ -45,16 +45,3 @@ void Settings::clear()
{
m_config = ConfigManager::createEmpty();
}
-
-std::vector Settings::getValues(const std::string& key, std::string defaultValue) const
-{
- std::string value = getValue(key, defaultValue);
-
- if (value.size())
- {
- std::deque values = utility::split(value, '|');
- return std::vector(values.begin(), values.end());
- }
-
- return std::vector();
-}
diff --git a/src/lib/Settings.h b/src/lib/Settings.h
index d5ba19a5..a0debe84 100644
--- a/src/lib/Settings.h
+++ b/src/lib/Settings.h
@@ -21,7 +21,8 @@ protected:
template
T getValue(const std::string& key, T defaultValue) const;
- std::vector getValues(const std::string& key, std::string defaultValue) const;
+ template
+ std::vector getValues(const std::string& key, std::vector defaultValues) const;
template
bool setValue(const std::string& key, T value);
@@ -44,6 +45,20 @@ T Settings::getValue(const std::string& key, T defaultValue) const
return defaultValue;
}
+template
+std::vector Settings::getValues(const std::string& key, std::vector defaultValues) const
+{
+ if(m_config)
+ {
+ std::vector values;
+ if(m_config->getValues(key, values))
+ {
+ return values;
+ }
+ }
+ return defaultValues;
+}
+
template
bool Settings::setValue(const std::string& key, T value)
{
diff --git a/src/lib/data/Storage.cpp b/src/lib/data/Storage.cpp
index f54196cd..ca332b93 100644
--- a/src/lib/data/Storage.cpp
+++ b/src/lib/data/Storage.cpp
@@ -24,7 +24,7 @@ Storage::Storage()
{
for (const std::pair& p : QueryCommand::getCommandTypeMap())
{
- m_filterIndex.addNode(std::vector({ p.first }));
+ m_filterIndex.addNode(std::vector(1, p.first));
}
}
diff --git a/src/lib/utility/ConfigManager.cpp b/src/lib/utility/ConfigManager.cpp
index 942a6d59..b039811e 100644
--- a/src/lib/utility/ConfigManager.cpp
+++ b/src/lib/utility/ConfigManager.cpp
@@ -4,6 +4,7 @@
#include "utility/logging/logging.h"
#include "utility/text/TextAccess.h"
+#include "utility/utilityString.h"
std::shared_ptr ConfigManager::createEmpty()
{
@@ -19,7 +20,7 @@ std::shared_ptr ConfigManager::createAndLoad(const std::shared_pt
bool ConfigManager::getValue(const std::string& key, std::string& value) const
{
- std::map::const_iterator it = m_values.find(key);
+ std::multimap::const_iterator it = m_values.find(key);
if (it != m_values.end())
{
@@ -66,9 +67,73 @@ bool ConfigManager::getValue(const std::string& key, bool& value) const
return false;
}
+bool ConfigManager::getValues(const std::string& key, std::vector& values) const
+{
+ std::pair ::const_iterator,
+ std::multimap::const_iterator> ret;
+ ret = m_values.equal_range(key);
+
+ if (ret.first != m_values.end())
+ {
+ std::multimap::const_iterator cit = ret.first;
+ for(;cit!=ret.second;++cit)
+ {
+ values.push_back(cit->second);
+ }
+ return true;
+ }
+ else
+ {
+ LOG_ERROR("value " + key + " is not present in config.");
+ return false;
+ }
+}
+
+bool ConfigManager::getValues(const std::string& key, std::vector& values) const
+{
+ std::vector valuesStringVector;
+ if (getValues(key, valuesStringVector))
+ {
+ for (std::string valueString : valuesStringVector)
+ {
+ values.push_back(atoi(valueString.c_str()));
+ }
+ return true;
+ }
+ return false;
+}
+
+bool ConfigManager::getValues(const std::string& key, std::vector& values) const
+{
+ std::vector valuesStringVector;
+ if (getValues(key, valuesStringVector))
+ {
+ for (std::string valueString : valuesStringVector)
+ {
+ values.push_back(static_cast(atof(valueString.c_str())));
+ }
+ return true;
+ }
+ return false;
+}
+
+bool ConfigManager::getValues(const std::string& key, std::vector& values) const
+{
+ std::vector valuesStringVector;
+ if (getValues(key, valuesStringVector))
+ {
+ for (std::string valueString : valuesStringVector)
+ {
+ values.push_back(atoi(valueString.c_str()) != 0);
+ }
+ return true;
+ }
+ return false;
+}
+
void ConfigManager::setValue(const std::string& key, const std::string& value)
{
- std::map::iterator it = m_values.find(key);
+ std::multimap::iterator it = m_values.find(key);
if (it != m_values.end())
{
@@ -95,6 +160,50 @@ void ConfigManager::setValue(const std::string& key, const bool value)
setValue(key, std::string(value ? "1" : "0"));
}
+void ConfigManager::setValues(const std::string& key, const std::vector& values)
+{
+ std::multimap::iterator it = m_values.find(key);
+
+ if(it != m_values.end())
+ {
+ m_values.erase(key);
+ }
+ for(std::string s : values)
+ {
+ m_values.emplace(key, s);
+ }
+}
+
+void ConfigManager::setValues(const std::string& key, const std::vector& values)
+{
+ std::vector stringValues;
+ for(int i : values)
+ {
+ stringValues.push_back(std::to_string(i));
+ }
+ setValues(key, stringValues);
+}
+
+void ConfigManager::setValues(const std::string& key, const std::vector& values)
+{
+ std::vector stringValues;
+ for(float f : values)
+ {
+ stringValues.push_back(std::to_string(f));
+ }
+ setValues(key, stringValues);
+}
+
+void ConfigManager::setValues(const std::string& key, const std::vector& values)
+{
+ std::vector stringValues;
+ for(bool b : values)
+ {
+ stringValues.push_back(std::string(b ? "1" : "0"));
+ }
+ setValues(key, stringValues);
+}
+
void ConfigManager::load(const std::shared_ptr textAccess)
{
std::string text = textAccess->getText();
@@ -116,21 +225,69 @@ void ConfigManager::load(const std::shared_ptr textAccess)
}
}
-void ConfigManager::save()
+void ConfigManager::save(const std::string filepath)
{
- LOG_ERROR("function: configmanager::save not implemented");
+ std::string output("");
+ createXmlDocument(true, filepath, output);
}
ConfigManager::ConfigManager()
{
}
+bool ConfigManager::createXmlDocument(bool saveAsFile, const std::string filepath, std::string& output)
+{
+ bool success = true;
+ TiXmlDocument doc;
+ TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "utf-8", "" );
+ doc.LinkEndChild(decl);
+ TiXmlElement *root = new TiXmlElement("config");
+ doc.LinkEndChild(root);
+
+ for(std::multimap::iterator it = m_values.begin(); it != m_values.end(); ++it)
+ {
+ std::vector tokens = utility::splitToVector(it->first, "/");
+ TiXmlElement* element = doc.RootElement();
+ TiXmlElement* child;
+ while(tokens.size() > 1)
+ {
+ child = element->FirstChildElement(tokens.front().c_str());
+ if(!child)
+ {
+ child = new TiXmlElement(tokens.front().c_str());
+ element->LinkEndChild(child);
+ }
+ tokens.erase(tokens.begin());
+ element = child;
+ }
+
+ child = new TiXmlElement(tokens.front().c_str());
+ element->LinkEndChild(child);
+ TiXmlText* text = new TiXmlText(it->second.c_str());
+ child->LinkEndChild(text);
+ }
+
+ if(saveAsFile)
+ {
+ success = doc.SaveFile(filepath.c_str());
+ }
+ else
+ {
+ TiXmlPrinter printer;
+ doc.Accept(&printer);
+ output = printer.CStr();
+ }
+ success = doc.SaveFile(filepath.c_str());
+ doc.Clear();
+ return success;
+}
+
void ConfigManager::parseSubtree(TiXmlNode* currentNode, const std::string& currentPath)
{
if (currentNode->Type() == TiXmlNode::TINYXML_TEXT)
{
std::string key = currentPath.substr(0, currentPath.size() - 1);
- m_values[key] = currentNode->ToText()->Value();
+ m_values.insert(std::pair(key,currentNode->ToText()->Value()));
}
else
{
@@ -140,3 +297,10 @@ void ConfigManager::parseSubtree(TiXmlNode* currentNode, const std::string& curr
}
}
}
+
+std::string ConfigManager::toString()
+{
+ std::string output;
+ createXmlDocument(false, "", output);
+ return output;
+}
diff --git a/src/lib/utility/ConfigManager.h b/src/lib/utility/ConfigManager.h
index 33ae8ebe..87f3ed13 100644
--- a/src/lib/utility/ConfigManager.h
+++ b/src/lib/utility/ConfigManager.h
@@ -4,6 +4,7 @@
#include