Handle custom key collisions
This commit is contained in:
parent
6c06d1e9d1
commit
6438d332f7
8 changed files with 70 additions and 26 deletions
|
@ -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>
|
||||||
|
|
|
@ -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 *);
|
||||||
|
|
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue