122 lines
3.3 KiB
C++
122 lines
3.3 KiB
C++
|
#include "qtjsonsettings.h"
|
||
|
|
||
|
#include "json.h"
|
||
|
|
||
|
#include <QtDebug>
|
||
|
|
||
|
#include <QtCore/QCoreApplication>
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
void processReadKey(QString& key, QSettings::SettingsMap &map, const QVariant& element)
|
||
|
{
|
||
|
switch (element.type())
|
||
|
{
|
||
|
case QVariant::Map:
|
||
|
{
|
||
|
QVariantMap vMap = element.toMap();
|
||
|
QVariantMap::ConstIterator it = vMap.constBegin();
|
||
|
QVariantMap::ConstIterator end = vMap.constEnd();
|
||
|
|
||
|
for (; it != end; ++it)
|
||
|
{
|
||
|
key.append(it.key());
|
||
|
key.append("/");
|
||
|
processReadKey(key, map, it.value());
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
case QVariant::List:
|
||
|
{
|
||
|
QVariantList list = element.toList();
|
||
|
map.insert(key + "size", list.count());
|
||
|
for (int i = 0; i < list.count(); ++i)
|
||
|
{
|
||
|
key.append(QString::number(i + 1));
|
||
|
key.append("/");
|
||
|
processReadKey(key, map, list.at(i));
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
map.insert(key.left(key.size() - 1), element);
|
||
|
}
|
||
|
key.truncate(key.lastIndexOf("/", -2) + 1);
|
||
|
}
|
||
|
|
||
|
QVariant processWriteKey(QVariant& root, const QString& key, const QVariant& value)
|
||
|
{
|
||
|
int slashPos = key.indexOf('/');
|
||
|
|
||
|
// If it is key
|
||
|
if (slashPos < 0)
|
||
|
{
|
||
|
QVariantMap map = root.toMap();
|
||
|
/** TODO VERY UGLY array detecting method
|
||
|
* Key size always placed after all numeric keys (array indexes)
|
||
|
* Convert root map to list and return it.
|
||
|
* Warning. Index starts with 1
|
||
|
*/
|
||
|
if (key == "size")
|
||
|
{
|
||
|
QVariantList list;
|
||
|
for (int i = 1; i <= value.toInt(); ++i)
|
||
|
{
|
||
|
list.append(map.value(QString::number(i)));
|
||
|
}
|
||
|
return list;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
map.insert(key, value);
|
||
|
return map;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// get group name
|
||
|
QString groupName = key.left(slashPos);
|
||
|
|
||
|
// if name is number then it's row of array, convert to list
|
||
|
QVariantMap map = root.toMap();
|
||
|
QVariant item = map.value(groupName);
|
||
|
map.insert(groupName, processWriteKey(item, key.mid(slashPos + 1), value));
|
||
|
return map;
|
||
|
}
|
||
|
}
|
||
|
const QSettings::Format QtJsonSettings::json_format = QSettings::registerFormat("json", readJsonFile, writeJsonFile);
|
||
|
|
||
|
bool QtJsonSettings::readJsonFile(QIODevice &device, QSettings::SettingsMap &map)
|
||
|
{
|
||
|
QString error;
|
||
|
QVariant parsed = Json::parse(device.readAll(), &error);
|
||
|
if (error.isEmpty())
|
||
|
{
|
||
|
QString str;
|
||
|
processReadKey(str, map, parsed);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
qWarning() << error;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool QtJsonSettings::writeJsonFile(QIODevice &device, const QSettings::SettingsMap &map)
|
||
|
{
|
||
|
QVariant resultMap;
|
||
|
|
||
|
QSettings::SettingsMap::ConstIterator it = map.constBegin();
|
||
|
QSettings::SettingsMap::ConstIterator end = map.constEnd();
|
||
|
|
||
|
for (; it != end; ++it)
|
||
|
{
|
||
|
resultMap = processWriteKey(resultMap, it.key(), it.value());
|
||
|
};
|
||
|
|
||
|
device.write(Json::prettyStringify(resultMap, 4));
|
||
|
return true;
|
||
|
|
||
|
}
|