Skip to content
270 changes: 74 additions & 196 deletions src/configobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,235 +29,130 @@
ConfigKey::ConfigKey() {
}

ConfigKey::ConfigKey(const QString& g, const QString& i)
: group(g),
item(i) {
ConfigKey::ConfigKey(const ConfigKey& key)
: group(key.group),
item(key.item) {
}

ConfigKey::ConfigKey(const char* g, const char* i)
ConfigKey::ConfigKey(const QString& g, const QString& i)
: group(g),
item(i) {
}

// static
ConfigKey ConfigKey::parseCommaSeparated(QString key) {
ConfigKey configKey;
int comma = key.indexOf(",");
configKey.group = key.left(comma);
configKey.item = key.mid(comma+1);
ConfigKey configKey(key.left(comma), key.mid(comma + 1));
return configKey;
}

ConfigValue::ConfigValue()
{
ConfigValue::ConfigValue() {
}

ConfigValue::ConfigValue(QString _value)
{
value = _value;
ConfigValue::ConfigValue(QString stValue)
: value(stValue) {
}

ConfigValue::ConfigValue(int _value)
{
value = QString::number(_value);
ConfigValue::ConfigValue(int iValue)
: value(QString::number(iValue)) {
}

void ConfigValue::valCopy(const ConfigValue& _value)
{
value = _value.value;
void ConfigValue::valCopy(const ConfigValue& configValue) {
value = configValue.value;
}


ConfigValueKbd::ConfigValueKbd()
{
ConfigValueKbd::ConfigValueKbd() {
}

ConfigValueKbd::ConfigValueKbd(QString _value) : ConfigValue(_value)
{
QString key;

QTextStream(&_value) >> key;
m_qKey = QKeySequence(key);
ConfigValueKbd::ConfigValueKbd(QString value)
: ConfigValue(value) {
m_qKey = QKeySequence(value);
}

ConfigValueKbd::ConfigValueKbd(QKeySequence key)
{
ConfigValueKbd::ConfigValueKbd(QKeySequence key) {
m_qKey = key;
QTextStream(&value) << m_qKey.toString();
// qDebug() << "value" << value;
// qDebug() << "value" << value;
}

void ConfigValueKbd::valCopy(const ConfigValueKbd& v)
{
void ConfigValueKbd::valCopy(const ConfigValueKbd& v) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

technically a change in behavior?

m_qKey = v.m_qKey;
QTextStream(&value) << m_qKey.toString();
}

bool operator==(const ConfigValue& s1, const ConfigValue& s2)
{
bool operator==(const ConfigValue& s1, const ConfigValue& s2) {
return (s1.value.toUpper() == s2.value.toUpper());
}

bool operator==(const ConfigValueKbd& s1, const ConfigValueKbd& s2)
{
return (s1.value.toUpper() == s2.value.toUpper());
bool operator==(const ConfigValueKbd& s1, const ConfigValueKbd& s2) {
//qDebug() << s1.m_qKey << "==" << s2.m_qKey;
return (s1.m_qKey == s2.m_qKey);
}

template <class ValueType> ConfigObject<ValueType>::ConfigObject(QString file)
{
template <class ValueType> ConfigObject<ValueType>::ConfigObject(QString file) {
reopen(file);
}

template <class ValueType> ConfigObject<ValueType>::~ConfigObject()
{
while (m_list.size() > 0) {
ConfigOption<ValueType>* pConfigOption = m_list.takeLast();
delete pConfigOption;
}
}

template <class ValueType>
ConfigOption<ValueType> *ConfigObject<ValueType>::set(ConfigKey k, ValueType v)
{
// Search for key in list, and set value if found
QListIterator<ConfigOption<ValueType>* > iterator(m_list);
ConfigOption<ValueType>* it;
while (iterator.hasNext())
{
it = iterator.next();
// if (QString::compare(it->val->value, v.value, Qt::CaseInsensitive) == 0)
if (it->key->group == k.group && it->key->item == k.item)
{
//qDebug() << "set found." << group << "," << item;
//cout << "1: " << v.value << "\n";
//qDebug() << "configobject " << it->val;
it->val->valCopy(v); // Should be done smarter using object copying
//qDebug() << "configobject " << it->val;
//cout << "2: " << it->val->value << "\n";
return it;
}
}

// If key is not found, insert it into the list of config objects
ConfigKey * key = new ConfigKey(k.group, k.item);
it = new ConfigOption<ValueType>(key, new ValueType(v));
//qDebug() << "new configobject " << it->val;
m_list.append(it);
return it;
template <class ValueType> ConfigObject<ValueType>::~ConfigObject() {
}

template <class ValueType>
ConfigOption<ValueType> *ConfigObject<ValueType>::get(ConfigKey k)
{
QListIterator<ConfigOption<ValueType>* > iterator(m_list);
ConfigOption<ValueType>* it;
while (iterator.hasNext())
{
it = iterator.next();
//qDebug() << it->key->group << k->group << it->key->item << k->item;
if (it->key->group == k.group && it->key->item == k.item)
{
//cout << it->key->group << ":" << it->key->item << ", val: " << it->val->value << "\n";
return it;
}
}
// If key is not found, insert into list with null values
ConfigKey * key = new ConfigKey(k.group, k.item);
it = new ConfigOption<ValueType>(key, new ValueType(""));
m_list.append(it);
return it;
void ConfigObject<ValueType>::set(const ConfigKey& k, ValueType v) {
QWriteLocker lock(&m_valuesLock);
m_values.insert(k, v);
}

template <class ValueType>
bool ConfigObject<ValueType>::exists(ConfigKey k)
{
QListIterator<ConfigOption<ValueType>* > iterator(m_list);
ConfigOption<ValueType>* it;
while (iterator.hasNext())
{
it = iterator.next();
if (it->key->group == k.group && it->key->item == k.item)
{
return true;
}
}
return false;
ValueType ConfigObject<ValueType>::get(const ConfigKey& k) const {
QReadLocker lock(&m_valuesLock);
return m_values.value(k);
}

template <class ValueType>
ConfigKey *ConfigObject<ValueType>::get(ValueType v)
{
QListIterator<ConfigOption<ValueType>* > iterator(m_list);
ConfigOption<ValueType>* it;
while (iterator.hasNext())
{
it = iterator.next();
if (QString::compare(it->val->value, v.value, Qt::CaseInsensitive) == 0) {
//qDebug() << "ConfigObject #534: QString::compare match for " << it->key->group << it->key->item;
return it->key;
}
if (((ValueType)*it->val) == ((ValueType)v))
{
//qDebug() << "ConfigObject: match" << it->val->value.toUpper() << "with" << v.value.toUpper();
return it->key;
}

if (it == m_list.last()) {
//qDebug() << "ConfigObject: last match attempted" << it->val->value.toUpper() << "with" << v.value.toUpper();
}
}
//qDebug() << "No match for ConfigObject:" << v.value;
return 0;
bool ConfigObject<ValueType>::exists(const ConfigKey& k) const {
QReadLocker lock(&m_valuesLock);
return m_values.contains(k);
}

template <class ValueType>
QString ConfigObject<ValueType>::getValueString(ConfigKey k)
{
return get(k)->val->value;
QString ConfigObject<ValueType>::getValueString(const ConfigKey& k) const {
ValueType v = get(k);
return v.value;
}

template <class ValueType>
QString ConfigObject<ValueType>::getValueString(ConfigKey k, const QString& default_string)
{
QString ret = get(k)->val->value;
QString ConfigObject<ValueType>::getValueString(const ConfigKey& k,
const QString& default_string) const {
QString ret = getValueString(k);
if (ret.isEmpty()) {
return default_string;
}
return ret;
}

template <class ValueType> bool ConfigObject<ValueType>::Parse()
{
template <class ValueType> bool ConfigObject<ValueType>::parse() {
// Open file for reading
QFile configfile(m_filename);
if (m_filename.length()<1 || !configfile.open(QIODevice::ReadOnly))
{
if (m_filename.length() < 1 || !configfile.open(QIODevice::ReadOnly)) {
qDebug() << "ConfigObject: Could not read" << m_filename;
return false;
}
else
{
} else {
//qDebug() << "ConfigObject: Parse" << m_filename;
// Parse the file
int group = 0;
QString groupStr, line;
QTextStream text(&configfile);
text.setCodec("UTF-8");

while (!text.atEnd())
{
while (!text.atEnd()) {
line = text.readLine().trimmed();

if (line.length() != 0)
{
if (line.startsWith("[") && line.endsWith("]"))
{
if (line.length() != 0) {
if (line.startsWith("[") && line.endsWith("]")) {
group++;
groupStr = line;
//qDebug() << "Group :" << groupStr;
}
else if (group>0)
{
} else if (group > 0) {
QString key;
QTextStream(&line) >> key;
QString val = line.right(line.length() - key.length()); // finds the value string
Expand All @@ -274,60 +169,39 @@ template <class ValueType> bool ConfigObject<ValueType>::Parse()
return true;
}

template <class ValueType> void ConfigObject<ValueType>::clear()
{
//Delete the pointers, because that's what we did before we
//purged Mixxx of Qt3 code. -- Albert, June 18th 2010 (at 30,000 ft)
for (int i = 0; i < m_list.count(); i++)
delete m_list[i];

// This shouldn't be done, since objects might have references to
// members of list. Instead all member values should be set to some
// null value.
m_list.clear();

}

template <class ValueType> void ConfigObject<ValueType>::reopen(QString file)
{
template <class ValueType> void ConfigObject<ValueType>::reopen(QString file) {
m_filename = file;
Parse();
parse();
}

template <class ValueType> void ConfigObject<ValueType>::Save()
{
template <class ValueType> void ConfigObject<ValueType>::Save() {
QReadLocker lock(&m_valuesLock); // we only read the m_values here.
QFile file(m_filename);
if (!QDir(QFileInfo(file).absolutePath()).exists()) {
QDir().mkpath(QFileInfo(file).absolutePath());
}
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
qDebug() << "Could not write file" << m_filename << ", don't worry.";
return;
}
else
{
} else {
QTextStream stream(&file);
stream.setCodec("UTF-8");

QString grp = "";

QListIterator<ConfigOption<ValueType>* > iterator(m_list);
ConfigOption<ValueType>* it;
while (iterator.hasNext())
{
it = iterator.next();
// qDebug() << "group:" << it->key->group << "item" << it->key->item << "val" << it->val->value;
if (it->key->group != grp)
{
grp = it->key->group;
stream << "\n" << it->key->group << "\n";
typename QMap<ConfigKey, ValueType>::const_iterator i;
for (i = m_values.begin(); i != m_values.end(); ++i) {
//qDebug() << "group:" << it.key().group << "item" << it.key().item << "val" << it.value()->value;
if (i.key().group != grp) {
grp = i.key().group;
stream << "\n" << grp << "\n";
}
stream << it->key->item << " " << it->val->value << "\n";
stream << i.key().item << " " << i.value().value << "\n";
}
file.close();
if (file.error()!=QFile::NoError) //could be better... should actually say what the error was..
qDebug() << "Error while writing configuration file:" << file.errorString();
if (file.error()!=QFile::NoError) { //could be better... should actually say what the error was..
qDebug() << "Error while writing configuration file:" << file.errorString();
}
}
}

Expand Down Expand Up @@ -409,18 +283,22 @@ template <class ValueType> ConfigObject<ValueType>::ConfigObject(QDomNode node)
}
}

template <class ValueType> QString ConfigObject<ValueType>::getSettingsPath() const
{
template <class ValueType>
QString ConfigObject<ValueType>::getSettingsPath() const {
QFileInfo configFileInfo(m_filename);
return configFileInfo.absoluteDir().absolutePath();
}

template <class ValueType> QHash<ConfigKey, ValueType> ConfigObject<ValueType>::toHash() const {
QHash<ConfigKey, ValueType> hash;
foreach (ConfigOption<ValueType>* pOption, m_list) {
hash.insert(*pOption->key, *pOption->val);
template <class ValueType>
QMultiHash<ValueType, ConfigKey> ConfigObject<ValueType>::transpose() const {
QReadLocker lock(&m_valuesLock);

QMultiHash<ValueType, ConfigKey> transposedHash;
for (typename QMap<ConfigKey, ValueType>::const_iterator it =
m_values.begin(); it != m_values.end(); ++it) {
transposedHash.insert(it.value(), it.key());
}
return hash;
return transposedHash;
}

template class ConfigObject<ConfigValue>;
Expand Down
Loading