porymap/src/ui/customattributestable.cpp
2022-10-24 23:01:26 -04:00

209 lines
7.2 KiB
C++

#include "customattributestable.h"
#include "parseutil.h"
#include <QHBoxLayout>
#include <QHeaderView>
#include <QPushButton>
#include <QTableWidget>
#include <QLabel>
#include <QScrollBar>
#include <QInputDialog>
CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) :
QFrame(parent)
{
this->event = event;
QVBoxLayout *layout = new QVBoxLayout(this);
QLabel *label = new QLabel("Custom Attributes");
layout->addWidget(label);
QFrame *buttonsFrame = new QFrame(this);
buttonsFrame->setLayout(new QHBoxLayout());
QPushButton *addButton = new QPushButton(this);
QPushButton *deleteButton = new QPushButton(this);
addButton->setText("Add");
deleteButton->setText("Delete");
buttonsFrame->layout()->addWidget(addButton);
buttonsFrame->layout()->addWidget(deleteButton);
buttonsFrame->layout()->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed));
buttonsFrame->layout()->setContentsMargins(0, 0, 0, 0);
layout->addWidget(buttonsFrame);
this->table = new QTableWidget(this);
this->table->setColumnCount(3);
this->table->setHorizontalHeaderLabels(QStringList({"Type", "Key", "Value"}));
this->table->horizontalHeader()->setStretchLastSection(true);
layout->addWidget(this->table);
QMap<QString, QJsonValue> customValues = this->event->getCustomValues();
for (auto it = customValues.begin(); it != customValues.end(); it++)
CustomAttributesTable::addAttribute(this->table, it.key(), it.value());
connect(addButton, &QPushButton::clicked, [=]() {
bool ok;
QJsonValue value = CustomAttributesTable::pickType(this, &ok);
if (ok){
CustomAttributesTable::addAttribute(this->table, "", value, true);
this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table));
this->resizeVertically();
}
});
connect(deleteButton, &QPushButton::clicked, [=]() {
if (CustomAttributesTable::deleteSelectedAttributes(this->table)) {
this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table));
this->resizeVertically();
}
});
connect(this->table, &QTableWidget::cellChanged, [=]() {
this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table));
});
this->resizeVertically();
}
CustomAttributesTable::~CustomAttributesTable()
{
}
void CustomAttributesTable::resizeVertically() {
int horizontalHeaderHeight = this->table->horizontalHeader()->height();
int rowHeight = 0;
for (int i = 0; i < this->table->rowCount(); i++) {
rowHeight += this->table->rowHeight(0);
}
int totalHeight = horizontalHeaderHeight + rowHeight;
if (this->table->rowCount() == 0) {
totalHeight += 1;
} else {
totalHeight += 2;
}
this->table->setMinimumHeight(totalHeight);
this->table->setMaximumHeight(totalHeight);
}
const QMap<QString, QJsonValue> CustomAttributesTable::getAttributes(QTableWidget * table) {
QMap<QString, QJsonValue> fields;
if (!table) return fields;
for (int row = 0; row < table->rowCount(); row++) {
QString key = "";
QTableWidgetItem *typeItem = table->item(row, 0);
QTableWidgetItem *keyItem = table->item(row, 1);
QTableWidgetItem *valueItem = table->item(row, 2);
if (keyItem) key = keyItem->text();
if (key.isEmpty() || !typeItem || !valueItem)
continue;
// Read from the table data which JSON type to save the value as
QJsonValue::Type type = static_cast<QJsonValue::Type>(typeItem->data(Qt::UserRole).toInt());
QJsonValue value;
switch (type)
{
case QJsonValue::String:
value = QJsonValue(valueItem->text());
break;
case QJsonValue::Double:
value = QJsonValue(valueItem->text().toInt());
break;
case QJsonValue::Bool:
value = QJsonValue(valueItem->checkState() == Qt::Checked);
break;
default:
// All other types will just be preserved
value = valueItem->data(Qt::UserRole).toJsonValue();
break;
}
fields[key] = value;
}
return fields;
}
QJsonValue CustomAttributesTable::pickType(QWidget * parent, bool * ok) {
const QMap<QString, QJsonValue> valueTypes = {
{"String", QJsonValue(QString(""))},
{"Number", QJsonValue(0)},
{"Boolean", QJsonValue(false)},
};
QStringList typeNames = valueTypes.keys();
QString selection = QInputDialog::getItem(parent, "", "Choose Value Type", typeNames, typeNames.indexOf("String"), false, ok);
return valueTypes.value(selection);
}
void CustomAttributesTable::addAttribute(QTableWidget * table, QString key, QJsonValue value, bool isNew) {
if (!table) return;
QTableWidgetItem * valueItem;
QJsonValue::Type type = value.type();
switch (type)
{
case QJsonValue::String:
case QJsonValue::Double:
valueItem = new QTableWidgetItem(ParseUtil::jsonToQString(value));
break;
case QJsonValue::Bool:
valueItem = new QTableWidgetItem("");
valueItem->setCheckState(value.toBool() ? Qt::Checked : Qt::Unchecked);
valueItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable);
break;
default:
valueItem = new QTableWidgetItem("This value cannot be edited from this table");
valueItem->setFlags(Qt::ItemIsSelectable);
valueItem->setData(Qt::UserRole, value); // Preserve the value for writing to the file
break;
}
const QHash<QJsonValue::Type, QString> typeToName = {
{QJsonValue::Bool, "Bool"},
{QJsonValue::Double, "Number"},
{QJsonValue::String, "String"},
{QJsonValue::Array, "Array"},
{QJsonValue::Object, "Object"},
{QJsonValue::Null, "Null"},
{QJsonValue::Undefined, "Null"},
};
QTableWidgetItem * typeItem = new QTableWidgetItem(typeToName[type]);
typeItem->setFlags(Qt::ItemIsEnabled);
typeItem->setData(Qt::UserRole, type); // Record the type for writing to the file
typeItem->setTextAlignment(Qt::AlignCenter);
int rowIndex = table->rowCount();
table->insertRow(rowIndex);
table->setItem(rowIndex, 0, typeItem);
table->setItem(rowIndex, 1, new QTableWidgetItem(key));
table->setItem(rowIndex, 2, valueItem);
if (isNew) {
valueItem->setText(""); // Erase the "0" in new numbers
table->selectRow(rowIndex);
}
}
bool CustomAttributesTable::deleteSelectedAttributes(QTableWidget * table) {
if (!table)
return false;
int rowCount = table->rowCount();
if (rowCount <= 0)
return false;
QModelIndexList indexList = table->selectionModel()->selectedIndexes();
QList<QPersistentModelIndex> persistentIndexes;
for (QModelIndex index : indexList) {
QPersistentModelIndex persistentIndex(index);
persistentIndexes.append(persistentIndex);
}
if (persistentIndexes.isEmpty())
return false;
for (QPersistentModelIndex index : persistentIndexes) {
table->removeRow(index.row());
}
if (table->rowCount() > 0) {
table->selectRow(0);
}
return true;
}