Handle custom key collisions

This commit is contained in:
GriffinR 2024-01-10 13:10:28 -05:00
parent 6c06d1e9d1
commit 6438d332f7
8 changed files with 70 additions and 26 deletions

View file

@ -2383,7 +2383,7 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="CustomAttributesTable" name="customAttributesTable"> <widget class="CustomAttributesTable" name="mapCustomAttributesTable">
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>

View file

@ -132,7 +132,7 @@ public:
bool readSpeciesIconPaths(); bool readSpeciesIconPaths();
QMap<QString, QString> speciesToIconPath; QMap<QString, QString> speciesToIconPath;
QSet<QString> getTopLevelMapFields(); static QSet<QString> getTopLevelMapFields();
bool loadMapData(Map*); bool loadMapData(Map*);
bool readMapLayouts(); bool readMapLayouts();
bool loadLayout(MapLayout *); bool loadLayout(MapLayout *);

View file

@ -16,20 +16,27 @@ public:
QMap<QString, QJsonValue> getAttributes() const; QMap<QString, QJsonValue> getAttributes() const;
void setAttributes(const QMap<QString, QJsonValue> attributes); void setAttributes(const QMap<QString, QJsonValue> attributes);
void addNewAttribute(QString key, QJsonValue value); void addNewAttribute(const QString &key, QJsonValue value);
bool deleteSelectedAttributes();
void setDefaultAttribute(QString key, QJsonValue value); void setDefaultAttribute(const QString &key, QJsonValue value);
void unsetDefaultAttribute(QString key); void unsetDefaultAttribute(const QString &key);
const QStringList restrictedKeyNames; // TODO: Populate QSet<QString> keys() const;
QSet<QString> restrictedKeys() const;
void setRestrictedKeys(const QSet<QString> keys);
signals: signals:
void edited(); void edited();
private: private:
QTableWidget *table; QTableWidget *table;
int addAttribute(QString key, QJsonValue value);
QSet<QString> m_keys;
QSet<QString> m_restrictedKeys;
int addAttribute(const QString &key, QJsonValue value);
void removeAttribute(const QString &key);
bool deleteSelectedAttributes();
void resizeVertically(); void resizeVertically();
}; };

View file

@ -1953,7 +1953,7 @@ void Editor::toggleBorderVisibility(bool visible, bool enableScriptCallback)
void Editor::updateCustomMapHeaderValues() void Editor::updateCustomMapHeaderValues()
{ {
map->customHeaders = ui->customAttributesTable->getAttributes(); map->customHeaders = ui->mapCustomAttributesTable->getAttributes();
emit editedMapData(); emit editedMapData();
} }

View file

@ -256,11 +256,6 @@ void MainWindow::initEditor() {
connect(this->editor, &Editor::tilesetUpdated, this, &Scripting::cb_TilesetUpdated); connect(this->editor, &Editor::tilesetUpdated, this, &Scripting::cb_TilesetUpdated);
connect(ui->toolButton_Open_Scripts, &QToolButton::pressed, this->editor, &Editor::openMapScripts); connect(ui->toolButton_Open_Scripts, &QToolButton::pressed, this->editor, &Editor::openMapScripts);
connect(ui->actionOpen_Project_in_Text_Editor, &QAction::triggered, this->editor, &Editor::openProjectInTextEditor); connect(ui->actionOpen_Project_in_Text_Editor, &QAction::triggered, this->editor, &Editor::openProjectInTextEditor);
connect(ui->customAttributesTable, &CustomAttributesTable::edited, [this]() {
logInfo("TODO");
this->markMapEdited();
this->editor->updateCustomMapHeaderValues();
});
this->loadUserSettings(); this->loadUserSettings();
@ -306,6 +301,11 @@ void MainWindow::initEditor() {
connect(this->ui->spinner_HealID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) { connect(this->ui->spinner_HealID, QOverload<int>::of(&QSpinBox::valueChanged), [this](int value) {
this->editor->selectedEventIndexChanged(value, Event::Group::Heal); this->editor->selectedEventIndexChanged(value, Event::Group::Heal);
}); });
connect(ui->mapCustomAttributesTable, &CustomAttributesTable::edited, [this]() {
this->markMapEdited();
this->editor->updateCustomMapHeaderValues();
});
} }
void MainWindow::initMiscHeapObjects() { void MainWindow::initMiscHeapObjects() {
@ -519,6 +519,7 @@ bool MainWindow::openProject(QString dir) {
this->closeSupplementaryWindows(); this->closeSupplementaryWindows();
this->newMapDefaultsSet = false; this->newMapDefaultsSet = false;
ui->mapCustomAttributesTable->setRestrictedKeys(Project::getTopLevelMapFields());
Scripting::init(this); Scripting::init(this);
bool already_open = isProjectOpen() && (editor->project->root == dir); bool already_open = isProjectOpen() && (editor->project->root == dir);
@ -851,7 +852,7 @@ void MainWindow::displayMapProperties() {
ui->checkBox_AllowEscaping->setChecked(map->allowEscaping); ui->checkBox_AllowEscaping->setChecked(map->allowEscaping);
ui->spinBox_FloorNumber->setValue(map->floorNumber); ui->spinBox_FloorNumber->setValue(map->floorNumber);
ui->customAttributesTable->setAttributes(map->customHeaders); ui->mapCustomAttributesTable->setAttributes(map->customHeaders);
} }
void MainWindow::on_comboBox_Song_currentTextChanged(const QString &song) void MainWindow::on_comboBox_Song_currentTextChanged(const QString &song)

View file

@ -60,7 +60,7 @@ bool CustomAttributesDialog::verifyName() {
} }
// Invalidate name if it would collide with an expected JSON field name // Invalidate name if it would collide with an expected JSON field name
if (this->table->restrictedKeyNames.contains(name)) { if (this->table->restrictedKeys().contains(name)) {
const QString msg = QString("The name '%1' is reserved, please choose a different name.").arg(name); const QString msg = QString("The name '%1' is reserved, please choose a different name.").arg(name);
QMessageBox::critical(this, "Error", msg); QMessageBox::critical(this, "Error", msg);
this->setNameEditHighlight(true); this->setNameEditHighlight(true);
@ -68,7 +68,7 @@ bool CustomAttributesDialog::verifyName() {
} }
// Warn user if key name would overwrite an existing custom attribute // Warn user if key name would overwrite an existing custom attribute
if (this->table->getAttributes().keys().contains(name)) { if (this->table->keys().contains(name)) {
const QString msg = QString("Overwrite value for existing attribute '%1'?").arg(name); const QString msg = QString("Overwrite value for existing attribute '%1'?").arg(name);
if (QMessageBox::warning(this, "Warning", msg, QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Cancel) if (QMessageBox::warning(this, "Warning", msg, QMessageBox::Yes | QMessageBox::Cancel) == QMessageBox::Cancel)
return false; return false;

View file

@ -17,7 +17,7 @@ enum Column {
// TODO: Tooltip-- "Custom fields will be added to the map.json file for the current map."? // TODO: Tooltip-- "Custom fields will be added to the map.json file for the current map."?
// TODO: Fix squishing when first element is added // TODO: Fix squishing when first element is added
// TODO: 'Overwriting' values adds a new attribute // TODO: Fix Header table size on first open
// TODO: Take control of Delete key? // TODO: Take control of Delete key?
// TODO: Edit history? // TODO: Edit history?
CustomAttributesTable::CustomAttributesTable(QWidget *parent) : CustomAttributesTable::CustomAttributesTable(QWidget *parent) :
@ -81,7 +81,6 @@ CustomAttributesTable::~CustomAttributesTable()
{ {
} }
// TODO: Fix Header table size on first open
void CustomAttributesTable::resizeVertically() { void CustomAttributesTable::resizeVertically() {
int height = 0; int height = 0;
for (int i = 0; i < this->table->rowCount(); i++) { for (int i = 0; i < this->table->rowCount(); i++) {
@ -105,7 +104,7 @@ QMap<QString, QJsonValue> CustomAttributesTable::getAttributes() const {
QMap<QString, QJsonValue> fields; QMap<QString, QJsonValue> fields;
for (int row = 0; row < this->table->rowCount(); row++) { for (int row = 0; row < this->table->rowCount(); row++) {
QString key = ""; QString key = "";
QTableWidgetItem *keyItem = this->table->item(row, Column::Key); auto keyItem = this->table->item(row, Column::Key);
if (keyItem) key = keyItem->text(); if (keyItem) key = keyItem->text();
if (key.isEmpty()) if (key.isEmpty())
continue; continue;
@ -135,14 +134,23 @@ QMap<QString, QJsonValue> CustomAttributesTable::getAttributes() const {
return fields; return fields;
} }
int CustomAttributesTable::addAttribute(QString key, QJsonValue value) { int CustomAttributesTable::addAttribute(const QString &key, QJsonValue value) {
const QSignalBlocker blocker(this->table); const QSignalBlocker blocker(this->table);
QJsonValue::Type type = value.type();
// Certain key names cannot be used (if they would overwrite a field used outside this table)
if (this->m_restrictedKeys.contains(key))
return -1;
// Overwrite existing key (if present)
if (this->m_keys.remove(key))
this->removeAttribute(key);
// Add new row // Add new row
int rowIndex = this->table->rowCount(); int rowIndex = this->table->rowCount();
this->table->insertRow(rowIndex); this->table->insertRow(rowIndex);
QJsonValue::Type type = value.type();
// Add key name to table // Add key name to table
auto keyItem = new QTableWidgetItem(key); auto keyItem = new QTableWidgetItem(key);
keyItem->setFlags(Qt::ItemIsEnabled); keyItem->setFlags(Qt::ItemIsEnabled);
@ -159,6 +167,8 @@ int CustomAttributesTable::addAttribute(QString key, QJsonValue value) {
} case QJsonValue::Double: { } case QJsonValue::Double: {
// Add a spin box for editing number values // Add a spin box for editing number values
auto spinBox = new QSpinBox(this->table); auto spinBox = new QSpinBox(this->table);
spinBox->setMinimum(INT_MIN);
spinBox->setMaximum(INT_MAX);
spinBox->setValue(ParseUtil::jsonToInt(value)); spinBox->setValue(ParseUtil::jsonToInt(value));
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), [this]() { emit this->edited(); }); connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), [this]() { emit this->edited(); });
this->table->setCellWidget(rowIndex, Column::Value, spinBox); this->table->setCellWidget(rowIndex, Column::Value, spinBox);
@ -178,13 +188,16 @@ int CustomAttributesTable::addAttribute(QString key, QJsonValue value) {
this->table->setItem(rowIndex, Column::Value, valueItem); this->table->setItem(rowIndex, Column::Value, valueItem);
break; break;
}} }}
this->m_keys.insert(key);
return rowIndex; return rowIndex;
} }
// For the user adding an attribute by interacting with the table // For the user adding an attribute by interacting with the table
void CustomAttributesTable::addNewAttribute(QString key, QJsonValue value) { void CustomAttributesTable::addNewAttribute(const QString &key, QJsonValue value) {
this->table->selectRow(this->addAttribute(key, value)); int row = this->addAttribute(key, value);
if (row < 0) return;
this->table->selectRow(row);
this->resizeVertically(); this->resizeVertically();
} }
@ -196,14 +209,24 @@ void CustomAttributesTable::setAttributes(const QMap<QString, QJsonValue> attrib
this->resizeVertically(); this->resizeVertically();
} }
void CustomAttributesTable::setDefaultAttribute(QString key, QJsonValue value) { void CustomAttributesTable::setDefaultAttribute(const QString &key, QJsonValue value) {
// TODO // TODO
} }
void CustomAttributesTable::unsetDefaultAttribute(QString key) { void CustomAttributesTable::unsetDefaultAttribute(const QString &key) {
// TODO // TODO
} }
void CustomAttributesTable::removeAttribute(const QString &key) {
for (int row = 0; row < this->table->rowCount(); row++) {
auto keyItem = this->table->item(row, Column::Key);
if (keyItem && keyItem->text() == key) {
this->table->removeRow(row);
break;
}
}
}
bool CustomAttributesTable::deleteSelectedAttributes() { bool CustomAttributesTable::deleteSelectedAttributes() {
int rowCount = this->table->rowCount(); int rowCount = this->table->rowCount();
if (rowCount <= 0) if (rowCount <= 0)
@ -229,3 +252,15 @@ bool CustomAttributesTable::deleteSelectedAttributes() {
this->resizeVertically(); this->resizeVertically();
return true; return true;
} }
QSet<QString> CustomAttributesTable::keys() const {
return this->m_keys;
}
QSet<QString> CustomAttributesTable::restrictedKeys() const {
return this->m_restrictedKeys;
}
void CustomAttributesTable::setRestrictedKeys(const QSet<QString> keys) {
this->m_restrictedKeys = keys;
}

View file

@ -103,6 +103,7 @@ void EventFrame::setup() {
void EventFrame::initCustomAttributesTable() { void EventFrame::initCustomAttributesTable() {
this->custom_attributes = new CustomAttributesTable(this); this->custom_attributes = new CustomAttributesTable(this);
this->custom_attributes->setRestrictedKeys(this->event->getExpectedFields());
this->custom_attributes->setAttributes(this->event->getCustomValues()); this->custom_attributes->setAttributes(this->event->getCustomValues());
this->layout_contents->addWidget(this->custom_attributes); this->layout_contents->addWidget(this->custom_attributes);
} }