From 6e65d591c3bd323552af2b09d6367a83a565e30f Mon Sep 17 00:00:00 2001 From: GriffinR Date: Thu, 11 Jan 2024 15:56:01 -0500 Subject: [PATCH] Edit attributes by double-clicking --- include/ui/customattributesdialog.h | 2 + include/ui/customattributestable.h | 1 + src/ui/customattributesdialog.cpp | 31 ++++++++--- src/ui/customattributestable.cpp | 79 ++++++++++++++++------------- 4 files changed, 72 insertions(+), 41 deletions(-) diff --git a/include/ui/customattributesdialog.h b/include/ui/customattributesdialog.h index 33dea972..450a0318 100644 --- a/include/ui/customattributesdialog.h +++ b/include/ui/customattributesdialog.h @@ -18,6 +18,8 @@ public: explicit CustomAttributesDialog(CustomAttributesTable *parent); ~CustomAttributesDialog(); + void setInput(const QString &key, QJsonValue value, bool setDefault); + private: Ui::CustomAttributesDialog *ui; CustomAttributesTable *const table; diff --git a/include/ui/customattributestable.h b/include/ui/customattributestable.h index 629597cc..dfcce05c 100644 --- a/include/ui/customattributestable.h +++ b/include/ui/customattributestable.h @@ -36,6 +36,7 @@ private: QSet m_defaultKeys; // All keys that are in this table by default (whether or not they're present) QSet m_restrictedKeys; // All keys not allowed in the table + QPair getAttribute(int row) const; int addAttribute(const QString &key, QJsonValue value); void removeAttribute(const QString &key); bool deleteSelectedAttributes(); diff --git a/src/ui/customattributesdialog.cpp b/src/ui/customattributesdialog.cpp index 2bc87e56..1a60b2bf 100644 --- a/src/ui/customattributesdialog.cpp +++ b/src/ui/customattributesdialog.cpp @@ -14,12 +14,11 @@ CustomAttributesDialog::CustomAttributesDialog(CustomAttributesTable *parent) : ui->setupUi(this); // Type combo box - static const QStringList types = {"String", "Number", "Boolean"}; - ui->comboBox_Type->addItems(types); + ui->comboBox_Type->addItems({"String", "Number", "Boolean"}); ui->comboBox_Type->setEditable(false); connect(ui->comboBox_Type, QOverload::of(&QComboBox::currentIndexChanged), [this](int index) { // 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); typeIndex = index; } @@ -92,14 +91,32 @@ bool CustomAttributesDialog::verifyInput() { 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 value; - const QString type = ui->comboBox_Type->currentText(); - if (type == "String") { + auto widget = ui->stackedWidget_Value->currentWidget(); + if (widget == ui->page_String) { value = QVariant(ui->lineEdit_Value->text()); - } else if (type == "Number") { + } else if (widget == ui->page_Number) { value = QVariant(ui->spinBox_Value->value()); - } else if (type == "Boolean") { + } else if (widget == ui->page_Boolean) { value = QVariant(ui->checkBox_Value->isChecked()); } return value; diff --git a/src/ui/customattributestable.cpp b/src/ui/customattributestable.cpp index 7f08471e..d5591930 100644 --- a/src/ui/customattributestable.cpp +++ b/src/ui/customattributestable.cpp @@ -38,9 +38,11 @@ CustomAttributesTable::CustomAttributesTable(QWidget *parent) : this->table = new QTableWidget(this); this->table->setColumnCount(Column::Count); + this->table->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); this->table->setHorizontalHeaderLabels(QStringList({"Key", "Value"})); 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->verticalHeader()->setVisible(false); 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 // 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. - // 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) { if (column == Column::Key) { 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) { if (column == Column::Key) { - auto index = this->table->model()->index(row, Column::Value); - this->table->edit(index); + // Get cell data + 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() @@ -110,37 +120,37 @@ void CustomAttributesTable::resizeVertically() { QMap CustomAttributesTable::getAttributes() const { QMap fields; for (int row = 0; row < this->table->rowCount(); row++) { - QString key = ""; - auto keyItem = this->table->item(row, Column::Key); - if (keyItem) key = keyItem->text(); - if (key.isEmpty()) - continue; - - // Read from the table data which JSON type to save the value as - QJsonValue::Type type = static_cast(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(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; + auto keyValuePair = this->getAttribute(row); + if (!keyValuePair.first.isEmpty()) + fields[keyValuePair.first] = keyValuePair.second; } return fields; } +QPair CustomAttributesTable::getAttribute(int row) const { + auto keyItem = this->table->item(row, Column::Key); + if (!keyItem) + return QPair(); + + // Read from the table data which JSON type to save the value as + QJsonValue::Type type = static_cast(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(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(keyItem->text(), value); +} + int CustomAttributesTable::addAttribute(const QString &key, QJsonValue value) { const QSignalBlocker blocker(this->table); @@ -163,6 +173,7 @@ int CustomAttributesTable::addAttribute(const QString &key, QJsonValue value) { keyItem->setFlags(Qt::ItemIsEnabled); keyItem->setData(Qt::UserRole, type); // Record the type for writing to the file 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); // Add value to table @@ -219,12 +230,12 @@ void CustomAttributesTable::setAttributes(const QMap attrib } void CustomAttributesTable::setDefaultAttribute(const QString &key, QJsonValue value) { - m_defaultKeys.insert(key); + this->m_defaultKeys.insert(key); emit this->defaultSet(key, value); } void CustomAttributesTable::unsetDefaultAttribute(const QString &key) { - if (m_defaultKeys.remove(key)) + if (this->m_defaultKeys.remove(key)) emit this->defaultRemoved(key); }