From 4c3a508534a5e2914b5927904aaa272ee0fb1548 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Tue, 18 Oct 2022 19:52:35 -0400 Subject: [PATCH] Better type conversion custom event attributes --- include/core/events.h | 6 +- include/ui/customattributestable.h | 6 +- src/core/events.cpp | 5 +- src/editor.cpp | 35 +----- src/mainwindow.cpp | 84 ++----------- src/ui/customattributestable.cpp | 186 +++++++++++++++++++++-------- src/ui/draggablepixmapitem.cpp | 5 +- 7 files changed, 160 insertions(+), 167 deletions(-) diff --git a/include/core/events.h b/include/core/events.h index a31ca8a5..daadbde0 100644 --- a/include/core/events.h +++ b/include/core/events.h @@ -151,8 +151,8 @@ public: virtual QSet getExpectedFields() = 0; void readCustomValues(QJsonObject values); void addCustomValuesTo(OrderedJson::object *obj); - QMap getCustomValues() { return this->customValues; } - void setCustomValues(QMap newCustomValues) { this->customValues = newCustomValues; } + const QMap getCustomValues() { return this->customValues; } + void setCustomValues(const QMap newCustomValues) { this->customValues = newCustomValues; } virtual void loadPixmap(Project *project) = 0; @@ -193,7 +193,7 @@ protected: int spriteHeight = 16; bool usingSprite = false; - QMap customValues; + QMap customValues; QPixmap pixmap; DraggablePixmapItem *pixmapItem = nullptr; diff --git a/include/ui/customattributestable.h b/include/ui/customattributestable.h index bf9334d0..f17f4877 100644 --- a/include/ui/customattributestable.h +++ b/include/ui/customattributestable.h @@ -12,11 +12,15 @@ public: explicit CustomAttributesTable(Event *event, QWidget *parent = nullptr); ~CustomAttributesTable(); + static const QMap 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 getTableFields(); }; #endif // CUSTOMATTRIBUTESTABLE_H diff --git a/src/core/events.cpp b/src/core/events.cpp index c61c86b6..35b26bd3 100644 --- a/src/core/events.cpp +++ b/src/core/events.cpp @@ -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 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]); } } } diff --git a/src/editor.cpp b/src/editor.cpp index 98000854..77380aab 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -10,6 +10,7 @@ #include "editcommands.h" #include "config.h" #include "scripting.h" +#include "customattributestable.h" #include #include #include @@ -1952,39 +1953,7 @@ void Editor::toggleBorderVisibility(bool visible, bool enableScriptCallback) void Editor::updateCustomMapHeaderValues(QTableWidget *table) { - QMap 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(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(); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index fb4c307e..0da662b6 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -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,90 +2756,20 @@ 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 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 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 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) diff --git a/src/ui/customattributestable.cpp b/src/ui/customattributestable.cpp index 4c41a104..83667483 100644 --- a/src/ui/customattributestable.cpp +++ b/src/ui/customattributestable.cpp @@ -1,10 +1,12 @@ #include "customattributestable.h" +#include "parseutil.h" #include #include #include #include #include #include +#include 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 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 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()); - this->resizeVertically(); + 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 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 CustomAttributesTable::getTableFields() { - QMap 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 CustomAttributesTable::getAttributes(QTableWidget * table) { + QMap 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(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 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 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 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; +} diff --git a/src/ui/draggablepixmapitem.cpp b/src/ui/draggablepixmapitem.cpp index d06c9786..9e7ab855 100644 --- a/src/ui/draggablepixmapitem.cpp +++ b/src/ui/draggablepixmapitem.cpp @@ -85,9 +85,8 @@ void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) { if (eventType == Event::Type::Warp) { WarpEvent *warp = dynamic_cast(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(this->event);