LibreVNA/Software/PC_Application/LibreVNA-GUI/CustomWidgets/jsonpickerdialog.cpp
2022-10-01 17:10:44 +02:00

187 lines
4.4 KiB
C++

#include "jsonpickerdialog.h"
#include "ui_jsonpickerdialog.h"
JSONPickerDialog::JSONPickerDialog(const nlohmann::json &json, QWidget *parent) :
QDialog(parent),
ui(new Ui::JSONPickerDialog),
model(new JSONModel(json))
{
ui->setupUi(this);
ui->treeView->setModel(model);
}
JSONPickerDialog::~JSONPickerDialog()
{
delete ui;
delete model;
}
JSONModel::JSONModel(const nlohmann::json &json, QObject *parent) :
json(json)
{
Q_UNUSED(parent)
setupJsonInfo(json);
}
JSONModel::~JSONModel()
{
}
QModelIndex JSONModel::index(int row, int column, const QModelIndex &parent) const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
nlohmann::json const *parentItem;
if (!parent.isValid())
parentItem = &json;
else
parentItem = static_cast<nlohmann::json*>(parent.internalPointer());
auto it = parentItem->begin();
int rb = row;
while(rb) {
it++;
rb--;
}
nlohmann::json *childItem = const_cast<nlohmann::json*>(&*it);
if (childItem)
return createIndex(row, column, childItem);
return QModelIndex();
}
QModelIndex JSONModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
nlohmann::json *childItem = static_cast<nlohmann::json*>(index.internalPointer());
if (childItem == &json) {
return QModelIndex();
}
// find the parent of this entry and its position in the list
nlohmann::json *parentItem = const_cast<nlohmann::json*>(jsonInfo.at(childItem).parent);
auto it = parentItem->begin();
int row = 0;
while(&*it != childItem) {
it++;
row++;
}
return createIndex(row, 0, parentItem);
}
int JSONModel::rowCount(const QModelIndex &parent) const
{
const nlohmann::json *parentItem;
if (parent.column() > 0) {
return 0;
}
if (!parent.isValid()) {
parentItem = &json;
} else {
parentItem = static_cast<nlohmann::json*>(parent.internalPointer());
}
if (parentItem->is_object() || parentItem->is_array()) {
return parentItem->size();
} else {
return 0;
}
}
int JSONModel::columnCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return 2;
}
QVariant JSONModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
nlohmann::json *item = static_cast<nlohmann::json*>(index.internalPointer());
auto info = jsonInfo.at(item);
switch(role) {
case Qt::DisplayRole:
switch(index.column()) {
case 0:
return info.name;
case 1:
if(!item->is_object() && !item->is_array()) {
return info.data;
}
}
return QVariant();
case Qt::CheckStateRole: {
if(index.column() == 0) {
return info.enabled ? Qt::Checked : Qt::Unchecked;
} else {
return QVariant();
}
}
default:
return QVariant();
}
}
QVariant JSONModel::headerData(int section, Qt::Orientation orientation, int role) const
{
Q_UNUSED(section)
Q_UNUSED(orientation)
Q_UNUSED(role)
return QVariant();
}
bool JSONModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_UNUSED(value)
nlohmann::json *item = static_cast<nlohmann::json*>(index.internalPointer());
auto info = jsonInfo.at(item);
if(role == Qt::CheckStateRole)
{
info.enabled = !info.enabled;
jsonInfo[item] = info;
emit dataChanged(index, index);
return true;
}
if (role != Qt::EditRole)
return false;
return true;
}
Qt::ItemFlags JSONModel::flags(const QModelIndex &index) const
{
if (!index.isValid()) {
return Qt::NoItemFlags;
}
return Qt::ItemIsEditable | QAbstractItemModel::flags(index)|Qt::ItemIsUserCheckable;
}
void JSONModel::setupJsonInfo(const nlohmann::json &j)
{
for(auto it = j.begin();it != j.end(); it++) {
JSONInfo i;
i.parent = &j;
i.enabled = true;
if(j.is_object()) {
i.name = it.key().c_str();
} else if(j.is_array()) {
i.name = QString::number(it - j.begin() + 1);
}
if(it->is_object() || it->is_array()) {
setupJsonInfo(*it);
} else {
i.data = QString::fromStdString(it->dump());
}
jsonInfo[&*it] = i;
}
}