Add custom attributes dialog
This commit is contained in:
parent
84d3b4c55e
commit
2bf221c729
6 changed files with 326 additions and 22 deletions
173
forms/customattributesdialog.ui
Normal file
173
forms/customattributesdialog.ui
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>CustomAttributesDialog</class>
|
||||||
|
<widget class="QDialog" name="CustomAttributesDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>410</width>
|
||||||
|
<height>192</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Add New Custom Attribute</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QFrame" name="centralwidget">
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label_Name">
|
||||||
|
<property name="text">
|
||||||
|
<string>Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_Name">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The key name for the new JSON field</string>
|
||||||
|
</property>
|
||||||
|
<property name="clearButtonEnabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_Type">
|
||||||
|
<property name="text">
|
||||||
|
<string>Type</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="NoScrollComboBox" name="comboBox_Type">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The data type for the new JSON field</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_Value">
|
||||||
|
<property name="text">
|
||||||
|
<string>Value</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QStackedWidget" name="stackedWidget_Value">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>The value for the new JSON field</string>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="page_String">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit_Value"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_Number">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QSpinBox" name="spinBox_Value"/>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_Boolean">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkBox_Value">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_Default">
|
||||||
|
<property name="text">
|
||||||
|
<string>Add to Defaults</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="checkBox_Default">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>If checked, this JSON field will be added to any new maps/events of this type, with the current value as its default</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<customwidgets>
|
||||||
|
<customwidget>
|
||||||
|
<class>NoScrollComboBox</class>
|
||||||
|
<extends>QComboBox</extends>
|
||||||
|
<header>noscrollcombobox.h</header>
|
||||||
|
</customwidget>
|
||||||
|
</customwidgets>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
31
include/ui/customattributesdialog.h
Normal file
31
include/ui/customattributesdialog.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef CUSTOMATTRIBUTESDIALOG_H
|
||||||
|
#define CUSTOMATTRIBUTESDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QAbstractButton>
|
||||||
|
|
||||||
|
#include "customattributestable.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class CustomAttributesDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomAttributesDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit CustomAttributesDialog(CustomAttributesTable *parent);
|
||||||
|
~CustomAttributesDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::CustomAttributesDialog *ui;
|
||||||
|
CustomAttributesTable *const table;
|
||||||
|
|
||||||
|
void addNewAttribute();
|
||||||
|
bool verifyName();
|
||||||
|
void setNameEditHighlight(bool highlight);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // CUSTOMATTRIBUTESDIALOG_H
|
|
@ -16,14 +16,19 @@ 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 addAttribute(QString key, QJsonValue value);
|
||||||
bool deleteSelectedAttributes();
|
bool deleteSelectedAttributes();
|
||||||
|
|
||||||
|
void setDefaultAttribute(QString key, QJsonValue value);
|
||||||
|
void unsetDefaultAttribute(QString key);
|
||||||
|
|
||||||
|
const QStringList restrictedKeyNames; // TODO: Populate
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void edited();
|
void edited();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTableWidget *table;
|
QTableWidget *table;
|
||||||
QJsonValue pickType(bool * ok = nullptr);
|
|
||||||
void addAttribute(QString key, QJsonValue value, bool init);
|
void addAttribute(QString key, QJsonValue value, bool init);
|
||||||
void resizeVertically();
|
void resizeVertically();
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,6 +43,7 @@ SOURCES += src/core/block.cpp \
|
||||||
src/scriptapi/apiutility.cpp \
|
src/scriptapi/apiutility.cpp \
|
||||||
src/scriptapi/scripting.cpp \
|
src/scriptapi/scripting.cpp \
|
||||||
src/ui/aboutporymap.cpp \
|
src/ui/aboutporymap.cpp \
|
||||||
|
src/ui/customattributesdialog.cpp \
|
||||||
src/ui/customscriptseditor.cpp \
|
src/ui/customscriptseditor.cpp \
|
||||||
src/ui/customscriptslistitem.cpp \
|
src/ui/customscriptslistitem.cpp \
|
||||||
src/ui/draggablepixmapitem.cpp \
|
src/ui/draggablepixmapitem.cpp \
|
||||||
|
@ -134,6 +135,7 @@ HEADERS += include/core/block.h \
|
||||||
include/lib/orderedmap.h \
|
include/lib/orderedmap.h \
|
||||||
include/lib/orderedjson.h \
|
include/lib/orderedjson.h \
|
||||||
include/ui/aboutporymap.h \
|
include/ui/aboutporymap.h \
|
||||||
|
include/ui/customattributesdialog.h \
|
||||||
include/ui/customscriptseditor.h \
|
include/ui/customscriptseditor.h \
|
||||||
include/ui/customscriptslistitem.h \
|
include/ui/customscriptslistitem.h \
|
||||||
include/ui/draggablepixmapitem.h \
|
include/ui/draggablepixmapitem.h \
|
||||||
|
@ -214,7 +216,8 @@ FORMS += forms/mainwindow.ui \
|
||||||
forms/colorpicker.ui \
|
forms/colorpicker.ui \
|
||||||
forms/projectsettingseditor.ui \
|
forms/projectsettingseditor.ui \
|
||||||
forms/customscriptseditor.ui \
|
forms/customscriptseditor.ui \
|
||||||
forms/customscriptslistitem.ui
|
forms/customscriptslistitem.ui \
|
||||||
|
forms/customattributesdialog.ui
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
resources/images.qrc \
|
resources/images.qrc \
|
||||||
|
|
96
src/ui/customattributesdialog.cpp
Normal file
96
src/ui/customattributesdialog.cpp
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
#include "customattributesdialog.h"
|
||||||
|
#include "ui_customattributesdialog.h"
|
||||||
|
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
// Preserve type selection for later dialogs
|
||||||
|
static int typeIndex = 0;
|
||||||
|
|
||||||
|
CustomAttributesDialog::CustomAttributesDialog(CustomAttributesTable *parent) :
|
||||||
|
QDialog(parent),
|
||||||
|
ui(new Ui::CustomAttributesDialog),
|
||||||
|
table(parent)
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
// Type combo box
|
||||||
|
static const QStringList types = {"String", "Number", "Boolean"};
|
||||||
|
ui->comboBox_Type->addItems(types);
|
||||||
|
ui->comboBox_Type->setEditable(false);
|
||||||
|
connect(ui->comboBox_Type, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
|
// When the value type is changed, update the value input widget
|
||||||
|
if (index >= 0 && index < types.length()){
|
||||||
|
ui->stackedWidget_Value->setCurrentIndex(index);
|
||||||
|
typeIndex = index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui->comboBox_Type->setCurrentIndex(typeIndex);
|
||||||
|
|
||||||
|
// Clear the red highlight that may be set if user tries to finish with an invalid key name
|
||||||
|
connect(ui->lineEdit_Name, &QLineEdit::textChanged, [this](QString) {
|
||||||
|
this->setNameEditHighlight(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Button box
|
||||||
|
connect(ui->buttonBox, &QDialogButtonBox::clicked, [this](QAbstractButton *button) {
|
||||||
|
auto buttonRole = ui->buttonBox->buttonRole(button);
|
||||||
|
if (buttonRole == QDialogButtonBox::AcceptRole && this->verifyName()) {
|
||||||
|
this->addNewAttribute();
|
||||||
|
this->done(QDialog::Accepted);
|
||||||
|
} else if (buttonRole == QDialogButtonBox::RejectRole) {
|
||||||
|
this->done(QDialog::Rejected);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomAttributesDialog::~CustomAttributesDialog() {
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomAttributesDialog::setNameEditHighlight(bool highlight) {
|
||||||
|
ui->lineEdit_Name->setStyleSheet(highlight ? "QLineEdit { background-color: rgba(255, 0, 0, 25%) }" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CustomAttributesDialog::verifyName() {
|
||||||
|
const QString name = ui->lineEdit_Name->text();
|
||||||
|
|
||||||
|
if (name.isEmpty()) {
|
||||||
|
this->setNameEditHighlight(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalidate name if it would collide with an expected JSON field name
|
||||||
|
if (this->table->restrictedKeyNames.contains(name)) {
|
||||||
|
const QString msg = QString("The name '%1' is reserved, please choose a different name.").arg(name);
|
||||||
|
QMessageBox::critical(this, "Error", msg);
|
||||||
|
this->setNameEditHighlight(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Warn user if key name would overwrite an existing custom attribute
|
||||||
|
if (this->table->getAttributes().keys().contains(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)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomAttributesDialog::addNewAttribute() {
|
||||||
|
QJsonValue value;
|
||||||
|
const QString type = ui->comboBox_Type->currentText();
|
||||||
|
if (type == "String") {
|
||||||
|
value = QJsonValue(ui->lineEdit_Value->text());
|
||||||
|
} else if (type == "Number") {
|
||||||
|
value = QJsonValue(ui->spinBox_Value->value());
|
||||||
|
} else if (type == "Boolean") {
|
||||||
|
value = QJsonValue(ui->checkBox_Value->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString key = ui->lineEdit_Name->text();
|
||||||
|
this->table->addAttribute(key, value);
|
||||||
|
|
||||||
|
if (ui->checkBox_Default->isChecked())
|
||||||
|
this->table->setDefaultAttribute(key, value);
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
#include "customattributestable.h"
|
#include "customattributestable.h"
|
||||||
|
#include "customattributesdialog.h"
|
||||||
#include "parseutil.h"
|
#include "parseutil.h"
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
@ -41,9 +42,8 @@ CustomAttributesTable::CustomAttributesTable(QWidget *parent) :
|
||||||
|
|
||||||
connect(addButton, &QPushButton::clicked, [this]() {
|
connect(addButton, &QPushButton::clicked, [this]() {
|
||||||
bool ok;
|
bool ok;
|
||||||
QJsonValue value = this->pickType(&ok);
|
CustomAttributesDialog dialog(this);
|
||||||
if (ok) {
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
this->addAttribute("", value, false);
|
|
||||||
emit this->edited();
|
emit this->edited();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -63,6 +63,7 @@ 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++) {
|
||||||
|
@ -118,23 +119,6 @@ QMap<QString, QJsonValue> CustomAttributesTable::getAttributes() const {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonValue CustomAttributesTable::pickType(bool * ok) {
|
|
||||||
static const QMap<QString, QJsonValue> valueTypes = {
|
|
||||||
{"String", QJsonValue(QString(""))},
|
|
||||||
{"Number", QJsonValue(0)},
|
|
||||||
{"Boolean", QJsonValue(false)},
|
|
||||||
};
|
|
||||||
static const QStringList typeNames = valueTypes.keys();
|
|
||||||
static int defaultIndex = typeNames.indexOf("String");
|
|
||||||
QString selection = QInputDialog::getItem(this, "", "Choose Value Type", typeNames, defaultIndex, false, ok);
|
|
||||||
|
|
||||||
// Preserve selection for next time
|
|
||||||
int index = typeNames.indexOf(selection);
|
|
||||||
if (index >= 0) defaultIndex = index;
|
|
||||||
|
|
||||||
return valueTypes.value(selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CustomAttributesTable::setAttributes(const QMap<QString, QJsonValue> attributes) {
|
void CustomAttributesTable::setAttributes(const QMap<QString, QJsonValue> attributes) {
|
||||||
this->table->setRowCount(0);
|
this->table->setRowCount(0);
|
||||||
for (auto it = attributes.cbegin(); it != attributes.cend(); it++)
|
for (auto it = attributes.cbegin(); it != attributes.cend(); it++)
|
||||||
|
@ -142,6 +126,10 @@ void CustomAttributesTable::setAttributes(const QMap<QString, QJsonValue> attrib
|
||||||
this->resizeVertically();
|
this->resizeVertically();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CustomAttributesTable::addAttribute(QString key, QJsonValue value) {
|
||||||
|
this->addAttribute(key, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
void CustomAttributesTable::addAttribute(QString key, QJsonValue value, bool init) {
|
void CustomAttributesTable::addAttribute(QString key, QJsonValue value, bool init) {
|
||||||
const QSignalBlocker blocker(this->table);
|
const QSignalBlocker blocker(this->table);
|
||||||
QTableWidgetItem * valueItem;
|
QTableWidgetItem * valueItem;
|
||||||
|
@ -191,6 +179,14 @@ void CustomAttributesTable::addAttribute(QString key, QJsonValue value, bool ini
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CustomAttributesTable::setDefaultAttribute(QString key, QJsonValue value) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
void CustomAttributesTable::unsetDefaultAttribute(QString key) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
bool CustomAttributesTable::deleteSelectedAttributes() {
|
bool CustomAttributesTable::deleteSelectedAttributes() {
|
||||||
int rowCount = this->table->rowCount();
|
int rowCount = this->table->rowCount();
|
||||||
if (rowCount <= 0)
|
if (rowCount <= 0)
|
||||||
|
|
Loading…
Reference in a new issue