#include "customattributestable.h" #include "parseutil.h" #include #include #include #include #include #include #include CustomAttributesTable::CustomAttributesTable(Event *event, QWidget *parent) : QFrame(parent) { this->event = event; QVBoxLayout *layout = new QVBoxLayout(this); QLabel *label = new QLabel("Custom Attributes"); layout->addWidget(label); QFrame *buttonsFrame = new QFrame(this); buttonsFrame->setLayout(new QHBoxLayout()); QPushButton *addButton = new QPushButton(this); QPushButton *deleteButton = new QPushButton(this); addButton->setText("Add"); deleteButton->setText("Delete"); buttonsFrame->layout()->addWidget(addButton); buttonsFrame->layout()->addWidget(deleteButton); buttonsFrame->layout()->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Fixed)); buttonsFrame->layout()->setContentsMargins(0, 0, 0, 0); layout->addWidget(buttonsFrame); this->table = new QTableWidget(this); this->table->setColumnCount(3); this->table->setHorizontalHeaderLabels(QStringList({"Type", "Key", "Value"})); this->table->horizontalHeader()->setStretchLastSection(true); layout->addWidget(this->table); QMap customValues = this->event->getCustomValues(); for (auto it = customValues.begin(); it != customValues.end(); it++) CustomAttributesTable::addAttribute(this->table, it.key(), it.value()); connect(addButton, &QPushButton::clicked, [=]() { bool ok; QJsonValue value = CustomAttributesTable::pickType(this, &ok); if (ok){ CustomAttributesTable::addAttribute(this->table, "", value, true); this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table)); this->resizeVertically(); } }); connect(deleteButton, &QPushButton::clicked, [=]() { if (CustomAttributesTable::deleteSelectedAttributes(this->table)) { this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table)); this->resizeVertically(); } }); connect(this->table, &QTableWidget::cellChanged, [=]() { this->event->setCustomValues(CustomAttributesTable::getAttributes(this->table)); }); this->resizeVertically(); } CustomAttributesTable::~CustomAttributesTable() { } void CustomAttributesTable::resizeVertically() { int horizontalHeaderHeight = this->table->horizontalHeader()->height(); int rowHeight = 0; for (int i = 0; i < this->table->rowCount(); i++) { rowHeight += this->table->rowHeight(0); } int totalHeight = horizontalHeaderHeight + rowHeight; if (this->table->rowCount() == 0) { totalHeight += 1; } else { totalHeight += 2; } this->table->setMinimumHeight(totalHeight); this->table->setMaximumHeight(totalHeight); } const QMap CustomAttributesTable::getAttributes(QTableWidget * table) { QMap fields; if (!table) return fields; for (int row = 0; row < table->rowCount(); row++) { QString key = ""; QTableWidgetItem *typeItem = table->item(row, 0); QTableWidgetItem *keyItem = table->item(row, 1); QTableWidgetItem *valueItem = table->item(row, 2); if (keyItem) key = keyItem->text(); if (key.isEmpty() || !typeItem || !valueItem) continue; // Read from the table data which JSON type to save the value as QJsonValue::Type type = static_cast(typeItem->data(Qt::UserRole).toInt()); QJsonValue value; switch (type) { case QJsonValue::String: value = QJsonValue(valueItem->text()); break; case QJsonValue::Double: value = QJsonValue(valueItem->text().toInt()); break; case QJsonValue::Bool: value = QJsonValue(valueItem->checkState() == Qt::Checked); break; default: // All other types will just be preserved value = valueItem->data(Qt::UserRole).toJsonValue(); break; } fields[key] = value; } return fields; } QJsonValue CustomAttributesTable::pickType(QWidget * parent, bool * ok) { const QMap valueTypes = { {"String", QJsonValue(QString(""))}, {"Number", QJsonValue(0)}, {"Boolean", QJsonValue(false)}, }; QStringList typeNames = valueTypes.keys(); QString selection = QInputDialog::getItem(parent, "", "Choose Value Type", typeNames, typeNames.indexOf("String"), false, ok); return valueTypes.value(selection); } void CustomAttributesTable::addAttribute(QTableWidget * table, QString key, QJsonValue value, bool isNew) { if (!table) return; QTableWidgetItem * valueItem; QJsonValue::Type type = value.type(); switch (type) { case QJsonValue::String: case QJsonValue::Double: valueItem = new QTableWidgetItem(ParseUtil::jsonToQString(value)); break; case QJsonValue::Bool: valueItem = new QTableWidgetItem(""); valueItem->setCheckState(value.toBool() ? Qt::Checked : Qt::Unchecked); valueItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); break; default: valueItem = new QTableWidgetItem("This value cannot be edited from this table"); valueItem->setFlags(Qt::ItemIsSelectable); valueItem->setData(Qt::UserRole, value); // Preserve the value for writing to the file break; } const QHash typeToName = { {QJsonValue::Bool, "Bool"}, {QJsonValue::Double, "Number"}, {QJsonValue::String, "String"}, {QJsonValue::Array, "Array"}, {QJsonValue::Object, "Object"}, {QJsonValue::Null, "Null"}, {QJsonValue::Undefined, "Null"}, }; QTableWidgetItem * typeItem = new QTableWidgetItem(typeToName[type]); typeItem->setFlags(Qt::ItemIsEnabled); typeItem->setData(Qt::UserRole, type); // Record the type for writing to the file typeItem->setTextAlignment(Qt::AlignCenter); int rowIndex = table->rowCount(); table->insertRow(rowIndex); table->setItem(rowIndex, 0, typeItem); table->setItem(rowIndex, 1, new QTableWidgetItem(key)); table->setItem(rowIndex, 2, valueItem); if (isNew) { valueItem->setText(""); // Erase the "0" in new numbers table->selectRow(rowIndex); } } bool CustomAttributesTable::deleteSelectedAttributes(QTableWidget * table) { if (!table) return false; int rowCount = table->rowCount(); if (rowCount <= 0) return false; QModelIndexList indexList = table->selectionModel()->selectedIndexes(); QList persistentIndexes; for (QModelIndex index : indexList) { QPersistentModelIndex persistentIndex(index); persistentIndexes.append(persistentIndex); } if (persistentIndexes.isEmpty()) return false; for (QPersistentModelIndex index : persistentIndexes) { table->removeRow(index.row()); } if (table->rowCount() > 0) { table->selectRow(0); } return true; }