121 lines
3.2 KiB
C++
121 lines
3.2 KiB
C++
#include "qtjsonsettings.h"
|
|
#include <QtDebug>
|
|
#include <QJsonDocument>
|
|
|
|
namespace {
|
|
|
|
void processReadKey(QString& key, QSettings::SettingsMap &map, const QVariant& element)
|
|
{
|
|
switch (element.type())
|
|
{
|
|
case QVariant::Map:
|
|
{
|
|
auto vMap = element.toMap();
|
|
auto it = vMap.constBegin();
|
|
auto 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)
|
|
{
|
|
QJsonParseError error;
|
|
auto document = QJsonDocument::fromJson(device.readAll(), &error);
|
|
|
|
if (QJsonParseError::NoError == error.error)
|
|
{
|
|
if (!document.isEmpty()){
|
|
QString str;
|
|
processReadKey(str, map, document.toVariant());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
qWarning() << error.errorString();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool QtJsonSettings::writeJsonFile(QIODevice &device, const QSettings::SettingsMap &map)
|
|
{
|
|
QVariant resultMap;
|
|
|
|
auto it = map.constBegin();
|
|
auto end = map.constEnd();
|
|
|
|
for (; it != end; ++it)
|
|
{
|
|
resultMap = processWriteKey(resultMap, it.key(), it.value());
|
|
};
|
|
|
|
device.write(QJsonDocument::fromVariant(resultMap).toJson());
|
|
return true;
|
|
|
|
}
|