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);
|
||||
~CustomAttributesDialog();
|
||||
|
||||
void setInput(const QString &key, QJsonValue value, bool setDefault);
|
||||
|
||||
private:
|
||||
Ui::CustomAttributesDialog *ui;
|
||||
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_restrictedKeys; // All keys not allowed in the table
|
||||
|
||||
QPair<QString, QJsonValue> getAttribute(int row) const;
|
||||
int addAttribute(const QString &key, QJsonValue value);
|
||||
void removeAttribute(const QString &key);
|
||||
bool deleteSelectedAttributes();
|
||||
|
|
|
@ -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<int>::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;
|
||||
|
|
|
@ -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<QString, QJsonValue> CustomAttributesTable::getAttributes() const {
|
||||
QMap<QString, QJsonValue> 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<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;
|
||||
auto keyValuePair = this->getAttribute(row);
|
||||
if (!keyValuePair.first.isEmpty())
|
||||
fields[keyValuePair.first] = keyValuePair.second;
|
||||
}
|
||||
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) {
|
||||
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<QString, QJsonValue> 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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue