Better type conversion custom event attributes

This commit is contained in:
GriffinR 2022-10-18 19:52:35 -04:00
parent 8e6585bbb2
commit 4c3a508534
7 changed files with 160 additions and 167 deletions

View file

@ -151,8 +151,8 @@ public:
virtual QSet<QString> getExpectedFields() = 0;
void readCustomValues(QJsonObject values);
void addCustomValuesTo(OrderedJson::object *obj);
QMap<QString, QString> getCustomValues() { return this->customValues; }
void setCustomValues(QMap<QString, QString> newCustomValues) { this->customValues = newCustomValues; }
const QMap<QString, QJsonValue> getCustomValues() { return this->customValues; }
void setCustomValues(const QMap<QString, QJsonValue> newCustomValues) { this->customValues = newCustomValues; }
virtual void loadPixmap(Project *project) = 0;
@ -193,7 +193,7 @@ protected:
int spriteHeight = 16;
bool usingSprite = false;
QMap<QString, QString> customValues;
QMap<QString, QJsonValue> customValues;
QPixmap pixmap;
DraggablePixmapItem *pixmapItem = nullptr;

View file

@ -12,11 +12,15 @@ public:
explicit CustomAttributesTable(Event *event, QWidget *parent = nullptr);
~CustomAttributesTable();
static const QMap<QString, QJsonValue> getAttributes(QTableWidget * table);
static QJsonValue pickType(QWidget * parent, bool * ok = nullptr);
static void addAttribute(QTableWidget * table, QString key, QJsonValue value, bool isNew = false);
static bool deleteSelectedAttributes(QTableWidget * table);
private:
Event *event;
QTableWidget *table;
void resizeVertically();
QMap<QString, QString> getTableFields();
};
#endif // CUSTOMATTRIBUTESTABLE_H

View file

@ -38,13 +38,12 @@ void Event::setDefaultValues(Project *) {
this->setElevation(3);
}
// TODO: Don't assume string type
void Event::readCustomValues(QJsonObject values) {
this->customValues.clear();
QSet<QString> expectedFields = this->getExpectedFields();
for (QString key : values.keys()) {
if (!expectedFields.contains(key)) {
this->customValues[key] = values[key].toString();
this->customValues[key] = values[key];
}
}
}
@ -52,7 +51,7 @@ void Event::readCustomValues(QJsonObject values) {
void Event::addCustomValuesTo(OrderedJson::object *obj) {
for (QString key : this->customValues.keys()) {
if (!obj->contains(key)) {
(*obj)[key] = this->customValues[key];
(*obj)[key] = OrderedJson::fromQJsonValue(this->customValues[key]);
}
}
}

View file

@ -10,6 +10,7 @@
#include "editcommands.h"
#include "config.h"
#include "scripting.h"
#include "customattributestable.h"
#include <QCheckBox>
#include <QPainter>
#include <QMouseEvent>
@ -1952,39 +1953,7 @@ void Editor::toggleBorderVisibility(bool visible, bool enableScriptCallback)
void Editor::updateCustomMapHeaderValues(QTableWidget *table)
{
QMap<QString, QJsonValue> 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;
}
map->customHeaders = fields;
map->customHeaders = CustomAttributesTable::getAttributes(table);
emit editedMapData();
}

View file

@ -816,7 +816,7 @@ void MainWindow::displayMapProperties() {
ui->tableWidget_CustomHeaderFields->blockSignals(true);
ui->tableWidget_CustomHeaderFields->setRowCount(0);
for (auto it = map->customHeaders.begin(); it != map->customHeaders.end(); it++)
addCustomHeaderValue(it.key(), it.value());
CustomAttributesTable::addAttribute(ui->tableWidget_CustomHeaderFields, it.key(), it.value());
ui->tableWidget_CustomHeaderFields->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
ui->tableWidget_CustomHeaderFields->blockSignals(false);
}
@ -2756,91 +2756,21 @@ void MainWindow::togglePreferenceSpecificUi() {
ui->actionOpen_Project_in_Text_Editor->setEnabled(true);
}
void MainWindow::addCustomHeaderValue(QString key, QJsonValue value, bool isNew) {
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 = this->ui->tableWidget_CustomHeaderFields->rowCount();
this->ui->tableWidget_CustomHeaderFields->insertRow(rowIndex);
this->ui->tableWidget_CustomHeaderFields->setItem(rowIndex, 0, typeItem);
this->ui->tableWidget_CustomHeaderFields->setItem(rowIndex, 1, new QTableWidgetItem(key));
this->ui->tableWidget_CustomHeaderFields->setItem(rowIndex, 2, valueItem);
if (isNew) {
valueItem->setText(""); // Erase the "0" in new numbers
this->ui->tableWidget_CustomHeaderFields->selectRow(rowIndex);
this->editor->updateCustomMapHeaderValues(this->ui->tableWidget_CustomHeaderFields);
}
}
void MainWindow::on_pushButton_AddCustomHeaderField_clicked()
{
const QMap<QString, QJsonValue> valueTypes = {
{"String", QJsonValue(QString(""))},
{"Number", QJsonValue(0)},
{"Boolean", QJsonValue(false)},
};
bool ok;
QStringList typeNames = valueTypes.keys();
QString selection = QInputDialog::getItem(this, "", "Choose Value Type", typeNames, typeNames.indexOf("String"), false, &ok);
if (ok)
addCustomHeaderValue("", valueTypes[selection], true);
QJsonValue value = CustomAttributesTable::pickType(this, &ok);
if (ok){
CustomAttributesTable::addAttribute(this->ui->tableWidget_CustomHeaderFields, "", value, true);
this->editor->updateCustomMapHeaderValues(this->ui->tableWidget_CustomHeaderFields);
}
}
void MainWindow::on_pushButton_DeleteCustomHeaderField_clicked()
{
int rowCount = this->ui->tableWidget_CustomHeaderFields->rowCount();
if (rowCount > 0) {
QModelIndexList indexList = ui->tableWidget_CustomHeaderFields->selectionModel()->selectedIndexes();
QList<QPersistentModelIndex> persistentIndexes;
for (QModelIndex index : indexList) {
QPersistentModelIndex persistentIndex(index);
persistentIndexes.append(persistentIndex);
}
for (QPersistentModelIndex index : persistentIndexes) {
this->ui->tableWidget_CustomHeaderFields->removeRow(index.row());
}
if (this->ui->tableWidget_CustomHeaderFields->rowCount() > 0) {
this->ui->tableWidget_CustomHeaderFields->selectRow(0);
}
if (CustomAttributesTable::deleteSelectedAttributes(this->ui->tableWidget_CustomHeaderFields))
this->editor->updateCustomMapHeaderValues(this->ui->tableWidget_CustomHeaderFields);
}
}
void MainWindow::on_tableWidget_CustomHeaderFields_cellChanged(int, int)
{

View file

@ -1,10 +1,12 @@
#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)
@ -28,52 +30,34 @@ CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) :
layout->addWidget(buttonsFrame);
this->table = new QTableWidget(this);
this->table->setColumnCount(2);
this->table->setHorizontalHeaderLabels(QStringList({"Key", "Value"}));
this->table->setColumnCount(3);
this->table->setHorizontalHeaderLabels(QStringList({"Type", "Key", "Value"}));
this->table->horizontalHeader()->setStretchLastSection(true);
layout->addWidget(this->table);
QMap<QString, QString> customValues = this->event->getCustomValues();
for (auto it = customValues.begin(); it != customValues.end(); it++) {
int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex);
this->table->setItem(rowIndex, 0, new QTableWidgetItem(it.key()));
this->table->setItem(rowIndex, 1, new QTableWidgetItem(it.value()));
}
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, [=]() {
int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex);
this->table->selectRow(rowIndex);
this->event->setCustomValues(this->getTableFields());
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, [=]() {
int rowCount = this->table->rowCount();
if (rowCount > 0) {
QModelIndexList indexList = this->table->selectionModel()->selectedIndexes();
QList<QPersistentModelIndex> persistentIndexes;
for (QModelIndex index : indexList) {
QPersistentModelIndex persistentIndex(index);
persistentIndexes.append(persistentIndex);
}
for (QPersistentModelIndex index : persistentIndexes) {
this->table->removeRow(index.row());
}
if (this->table->rowCount() > 0) {
this->table->selectRow(0);
}
this->event->setCustomValues(this->getTableFields());
if (CustomAttributesTable::deleteSelectedAttributes(this->table)) {
this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table));
this->resizeVertically();
}
});
connect(this->table, &QTableWidget::cellChanged, [=]() {
this->event->setCustomValues(this->getTableFields());
this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table));
});
this->resizeVertically();
@ -83,20 +67,6 @@ CustomAttributesTable::~CustomAttributesTable()
{
}
QMap<QString, QString> CustomAttributesTable::getTableFields() {
QMap<QString, QString> fields;
for (int row = 0; row < table->rowCount(); row++) {
QString keyStr = "";
QString valueStr = "";
QTableWidgetItem *key = table->item(row, 0);
QTableWidgetItem *value = table->item(row, 1);
if (key) keyStr = key->text();
if (value) valueStr = value->text();
fields[keyStr] = valueStr;
}
return fields;
}
void CustomAttributesTable::resizeVertically() {
int horizontalHeaderHeight = this->table->horizontalHeader()->height();
int rowHeight = 0;
@ -112,3 +82,125 @@ void CustomAttributesTable::resizeVertically() {
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);
}
for (QPersistentModelIndex index : persistentIndexes) {
table->removeRow(index.row());
}
if (table->rowCount() > 0) {
table->selectRow(0);
}
return true;
}

View file

@ -85,9 +85,8 @@ void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
if (eventType == Event::Type::Warp) {
WarpEvent *warp = dynamic_cast<WarpEvent *>(this->event);
QString destMap = warp->getDestinationMap();
bool ok;
int warpId = ParseUtil::gameStringToInt(warp->getDestinationWarpID(), &ok);
if (ok) emit editor->warpEventDoubleClicked(destMap, warpId, Event::Group::Warp);
int warpId = ParseUtil::gameStringToInt(warp->getDestinationWarpID());
emit editor->warpEventDoubleClicked(destMap, warpId, Event::Group::Warp);
}
else if (eventType == Event::Type::CloneObject) {
CloneObjectEvent *clone = dynamic_cast<CloneObjectEvent *>(this->event);