Edit attributes by double-clicking
This commit is contained in:
parent
e421a84542
commit
6e65d591c3
4 changed files with 72 additions and 41 deletions
|
@ -18,6 +18,8 @@ public:
|
||||||
explicit CustomAttributesDialog(CustomAttributesTable *parent);
|
explicit CustomAttributesDialog(CustomAttributesTable *parent);
|
||||||
~CustomAttributesDialog();
|
~CustomAttributesDialog();
|
||||||
|
|
||||||
|
void setInput(const QString &key, QJsonValue value, bool setDefault);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::CustomAttributesDialog *ui;
|
Ui::CustomAttributesDialog *ui;
|
||||||
CustomAttributesTable *const table;
|
CustomAttributesTable *const table;
|
||||||
|
|
|
@ -36,6 +36,7 @@ private:
|
||||||
QSet<QString> m_defaultKeys; // All keys that are in this table by default (whether or not they're present)
|
QSet<QString> m_defaultKeys; // All keys that are in this table by default (whether or not they're present)
|
||||||
QSet<QString> m_restrictedKeys; // All keys not allowed in the table
|
QSet<QString> m_restrictedKeys; // All keys not allowed in the table
|
||||||
|
|
||||||
|
QPair<QString, QJsonValue> getAttribute(int row) const;
|
||||||
int addAttribute(const QString &key, QJsonValue value);
|
int addAttribute(const QString &key, QJsonValue value);
|
||||||
void removeAttribute(const QString &key);
|
void removeAttribute(const QString &key);
|
||||||
bool deleteSelectedAttributes();
|
bool deleteSelectedAttributes();
|
||||||
|
|
|
@ -14,12 +14,11 @@ CustomAttributesDialog::CustomAttributesDialog(CustomAttributesTable *parent) :
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
// Type combo box
|
// Type combo box
|
||||||
static const QStringList types = {"String", "Number", "Boolean"};
|
ui->comboBox_Type->addItems({"String", "Number", "Boolean"});
|
||||||
ui->comboBox_Type->addItems(types);
|
|
||||||
ui->comboBox_Type->setEditable(false);
|
ui->comboBox_Type->setEditable(false);
|
||||||
connect(ui->comboBox_Type, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
connect(ui->comboBox_Type, QOverload<int>::of(&QComboBox::currentIndexChanged), [this](int index) {
|
||||||
// When the value type is changed, update the value input widget
|
// When the value type is changed, update the value input widget
|
||||||
if (index >= 0 && index < types.length()){
|
if (index >= 0 && index < ui->stackedWidget_Value->count()){
|
||||||
ui->stackedWidget_Value->setCurrentIndex(index);
|
ui->stackedWidget_Value->setCurrentIndex(index);
|
||||||
typeIndex = index;
|
typeIndex = index;
|
||||||
}
|
}
|
||||||
|
@ -92,14 +91,32 @@ bool CustomAttributesDialog::verifyInput() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For initializing the dialog with a state other than the default
|
||||||
|
void CustomAttributesDialog::setInput(const QString &key, QJsonValue value, bool setDefault) {
|
||||||
|
ui->lineEdit_Name->setText(key);
|
||||||
|
ui->checkBox_Default->setChecked(setDefault);
|
||||||
|
|
||||||
|
auto type = value.type();
|
||||||
|
if (type == QJsonValue::Type::String) {
|
||||||
|
ui->lineEdit_Value->setText(value.toString());
|
||||||
|
ui->stackedWidget_Value->setCurrentWidget(ui->page_String);
|
||||||
|
} else if (type == QJsonValue::Type::Double) {
|
||||||
|
ui->spinBox_Value->setValue(value.toInt());
|
||||||
|
ui->stackedWidget_Value->setCurrentWidget(ui->page_Number);
|
||||||
|
} else if (type == QJsonValue::Type::Bool) {
|
||||||
|
ui->checkBox_Value->setChecked(value.toBool());
|
||||||
|
ui->stackedWidget_Value->setCurrentWidget(ui->page_Boolean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariant CustomAttributesDialog::getValue() const {
|
QVariant CustomAttributesDialog::getValue() const {
|
||||||
QVariant value;
|
QVariant value;
|
||||||
const QString type = ui->comboBox_Type->currentText();
|
auto widget = ui->stackedWidget_Value->currentWidget();
|
||||||
if (type == "String") {
|
if (widget == ui->page_String) {
|
||||||
value = QVariant(ui->lineEdit_Value->text());
|
value = QVariant(ui->lineEdit_Value->text());
|
||||||
} else if (type == "Number") {
|
} else if (widget == ui->page_Number) {
|
||||||
value = QVariant(ui->spinBox_Value->value());
|
value = QVariant(ui->spinBox_Value->value());
|
||||||
} else if (type == "Boolean") {
|
} else if (widget == ui->page_Boolean) {
|
||||||
value = QVariant(ui->checkBox_Value->isChecked());
|
value = QVariant(ui->checkBox_Value->isChecked());
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
|
|
|
@ -38,9 +38,11 @@ CustomAttributesTable::CustomAttributesTable(QWidget *parent) :
|
||||||
|
|
||||||
this->table = new QTableWidget(this);
|
this->table = new QTableWidget(this);
|
||||||
this->table->setColumnCount(Column::Count);
|
this->table->setColumnCount(Column::Count);
|
||||||
|
this->table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
this->table->setHorizontalHeaderLabels(QStringList({"Key", "Value"}));
|
this->table->setHorizontalHeaderLabels(QStringList({"Key", "Value"}));
|
||||||
this->table->horizontalHeader()->setStretchLastSection(true);
|
this->table->horizontalHeader()->setStretchLastSection(true);
|
||||||
this->table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
this->table->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
|
||||||
|
//this->table->horizontalHeader()->setMaximumSectionSize(this->table->horizontalHeader()->length()); // TODO
|
||||||
this->table->horizontalHeader()->setVisible(false);
|
this->table->horizontalHeader()->setVisible(false);
|
||||||
this->table->verticalHeader()->setVisible(false);
|
this->table->verticalHeader()->setVisible(false);
|
||||||
layout->addWidget(this->table);
|
layout->addWidget(this->table);
|
||||||
|
@ -69,19 +71,27 @@ CustomAttributesTable::CustomAttributesTable(QWidget *parent) :
|
||||||
// Adding the "Selectable" flag to the Key cell changes its appearance to match the Value cell, which
|
// Adding the "Selectable" flag to the Key cell changes its appearance to match the Value cell, which
|
||||||
// makes it confusing that you can't edit the Key cell. To keep the uneditable appearance and allow
|
// makes it confusing that you can't edit the Key cell. To keep the uneditable appearance and allow
|
||||||
// deleting rows by selecting Key cells, we select the full row when a Key cell is selected.
|
// deleting rows by selecting Key cells, we select the full row when a Key cell is selected.
|
||||||
// Double clicking the Key cell will begin editing the value cell, as it would for double-clicking the value cell.
|
|
||||||
connect(this->table, &QTableWidget::cellClicked, [this](int row, int column) {
|
connect(this->table, &QTableWidget::cellClicked, [this](int row, int column) {
|
||||||
if (column == Column::Key) {
|
if (column == Column::Key) {
|
||||||
this->table->selectRow(row);
|
this->table->selectRow(row);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Double clicking the Key cell will bring up the dialog window to edit all the attribute's properties
|
||||||
connect(this->table, &QTableWidget::cellDoubleClicked, [this](int row, int column) {
|
connect(this->table, &QTableWidget::cellDoubleClicked, [this](int row, int column) {
|
||||||
if (column == Column::Key) {
|
if (column == Column::Key) {
|
||||||
auto index = this->table->model()->index(row, Column::Value);
|
// Get cell data
|
||||||
this->table->edit(index);
|
auto keyValuePair = this->getAttribute(row);
|
||||||
|
auto key = keyValuePair.first;
|
||||||
|
|
||||||
|
// Create dialog
|
||||||
|
CustomAttributesDialog dialog(this);
|
||||||
|
dialog.setInput(key, keyValuePair.second, this->m_defaultKeys.contains(key));
|
||||||
|
if (dialog.exec() == QDialog::Accepted) {
|
||||||
|
emit this->edited();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// TODO: Right-click for context menu to set a default?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAttributesTable::~CustomAttributesTable()
|
CustomAttributesTable::~CustomAttributesTable()
|
||||||
|
@ -110,37 +120,37 @@ void CustomAttributesTable::resizeVertically() {
|
||||||
QMap<QString, QJsonValue> CustomAttributesTable::getAttributes() const {
|
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 = "";
|
auto keyValuePair = this->getAttribute(row);
|
||||||
auto keyItem = this->table->item(row, Column::Key);
|
if (!keyValuePair.first.isEmpty())
|
||||||
if (keyItem) key = keyItem->text();
|
fields[keyValuePair.first] = keyValuePair.second;
|
||||||
if (key.isEmpty())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Read from the table data which JSON type to save the value as
|
|
||||||
QJsonValue::Type type = static_cast<QJsonValue::Type>(keyItem->data(Qt::UserRole).toInt());
|
|
||||||
|
|
||||||
QJsonValue value;
|
|
||||||
switch (type) {
|
|
||||||
case QJsonValue::String: {
|
|
||||||
value = QJsonValue(this->table->item(row, Column::Value)->text());
|
|
||||||
break;
|
|
||||||
} case QJsonValue::Double: {
|
|
||||||
auto spinBox = static_cast<QSpinBox*>(this->table->cellWidget(row, Column::Value));
|
|
||||||
value = QJsonValue(spinBox->value());
|
|
||||||
break;
|
|
||||||
} case QJsonValue::Bool: {
|
|
||||||
value = QJsonValue(this->table->item(row, Column::Value)->checkState() == Qt::Checked);
|
|
||||||
break;
|
|
||||||
} default: {
|
|
||||||
// All other types will just be preserved
|
|
||||||
value = this->table->item(row, Column::Value)->data(Qt::UserRole).toJsonValue();
|
|
||||||
break;
|
|
||||||
}}
|
|
||||||
fields[key] = value;
|
|
||||||
}
|
}
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPair<QString, QJsonValue> CustomAttributesTable::getAttribute(int row) const {
|
||||||
|
auto keyItem = this->table->item(row, Column::Key);
|
||||||
|
if (!keyItem)
|
||||||
|
return QPair<QString, QJsonValue>();
|
||||||
|
|
||||||
|
// Read from the table data which JSON type to save the value as
|
||||||
|
QJsonValue::Type type = static_cast<QJsonValue::Type>(keyItem->data(Qt::UserRole).toInt());
|
||||||
|
|
||||||
|
QJsonValue value;
|
||||||
|
if (type == QJsonValue::String) {
|
||||||
|
value = QJsonValue(this->table->item(row, Column::Value)->text());
|
||||||
|
} else if (type == QJsonValue::Double) {
|
||||||
|
auto spinBox = static_cast<QSpinBox*>(this->table->cellWidget(row, Column::Value));
|
||||||
|
value = QJsonValue(spinBox->value());
|
||||||
|
} else if (type == QJsonValue::Bool) {
|
||||||
|
value = QJsonValue(this->table->item(row, Column::Value)->checkState() == Qt::Checked);
|
||||||
|
} else {
|
||||||
|
// All other types will just be preserved
|
||||||
|
value = this->table->item(row, Column::Value)->data(Qt::UserRole).toJsonValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QPair<QString, QJsonValue>(keyItem->text(), value);
|
||||||
|
}
|
||||||
|
|
||||||
int CustomAttributesTable::addAttribute(const QString &key, QJsonValue value) {
|
int CustomAttributesTable::addAttribute(const QString &key, QJsonValue value) {
|
||||||
const QSignalBlocker blocker(this->table);
|
const QSignalBlocker blocker(this->table);
|
||||||
|
|
||||||
|
@ -163,6 +173,7 @@ int CustomAttributesTable::addAttribute(const QString &key, QJsonValue value) {
|
||||||
keyItem->setFlags(Qt::ItemIsEnabled);
|
keyItem->setFlags(Qt::ItemIsEnabled);
|
||||||
keyItem->setData(Qt::UserRole, type); // Record the type for writing to the file
|
keyItem->setData(Qt::UserRole, type); // Record the type for writing to the file
|
||||||
keyItem->setTextAlignment(Qt::AlignCenter);
|
keyItem->setTextAlignment(Qt::AlignCenter);
|
||||||
|
keyItem->setToolTip(key); // Display name as tool tip in case it's too long to see in the cell
|
||||||
this->table->setItem(rowIndex, Column::Key, keyItem);
|
this->table->setItem(rowIndex, Column::Key, keyItem);
|
||||||
|
|
||||||
// Add value to table
|
// Add value to table
|
||||||
|
@ -219,12 +230,12 @@ void CustomAttributesTable::setAttributes(const QMap<QString, QJsonValue> attrib
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomAttributesTable::setDefaultAttribute(const QString &key, QJsonValue value) {
|
void CustomAttributesTable::setDefaultAttribute(const QString &key, QJsonValue value) {
|
||||||
m_defaultKeys.insert(key);
|
this->m_defaultKeys.insert(key);
|
||||||
emit this->defaultSet(key, value);
|
emit this->defaultSet(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CustomAttributesTable::unsetDefaultAttribute(const QString &key) {
|
void CustomAttributesTable::unsetDefaultAttribute(const QString &key) {
|
||||||
if (m_defaultKeys.remove(key))
|
if (this->m_defaultKeys.remove(key))
|
||||||
emit this->defaultRemoved(key);
|
emit this->defaultRemoved(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue