diff options
author | Roland Knall <rknall@gmail.com> | 2021-09-08 19:32:39 +0000 |
---|---|---|
committer | Roland Knall <rknall@gmail.com> | 2021-09-08 19:32:39 +0000 |
commit | 48cf9d5497361169d5afedf4c699b9aae3f99189 (patch) | |
tree | 72c28671758aafc5d204c0ad6d42ac8915de3374 /ui/qt | |
parent | 03480fd6e1094ac1acc97294fb9076ad17cfd585 (diff) |
Qt: IOGraph - correctly add new graphs
If a graph is added it should be a single operation, not multiple setData operations
leading to a myriad of dataChanged signals to be fired, which in turn can hinder redissection.
Diffstat (limited to 'ui/qt')
-rw-r--r-- | ui/qt/io_graph_dialog.cpp | 55 | ||||
-rw-r--r-- | ui/qt/models/uat_model.cpp | 100 | ||||
-rw-r--r-- | ui/qt/models/uat_model.h | 6 | ||||
-rw-r--r-- | ui/qt/uat_dialog.cpp | 20 | ||||
-rw-r--r-- | ui/qt/uat_frame.cpp | 19 |
5 files changed, 142 insertions, 58 deletions
diff --git a/ui/qt/io_graph_dialog.cpp b/ui/qt/io_graph_dialog.cpp index 8266c1cb2e..53fd0b8925 100644 --- a/ui/qt/io_graph_dialog.cpp +++ b/ui/qt/io_graph_dialog.cpp @@ -480,29 +480,26 @@ void IOGraphDialog::copyFromProfile(QString filename) void IOGraphDialog::addGraph(bool checked, QString name, QString dfilter, QRgb color_idx, IOGraph::PlotStyles style, io_graph_item_unit_t value_units, QString yfield, int moving_average, int y_axis_factor) { - // should not fail, but you never know. - if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) { + + QVariantList newRowData; + newRowData.append(checked ? Qt::Checked : Qt::Unchecked); + newRowData.append(name); + newRowData.append(dfilter); + newRowData.append(QColor(color_idx)); + newRowData.append(val_to_str_const(style, graph_style_vs, "None")); + newRowData.append(val_to_str_const(value_units, y_axis_vs, "Packets")); + newRowData.append(yfield); + newRowData.append(val_to_str_const((guint32) moving_average, moving_avg_vs, "None")); + newRowData.append(y_axis_factor); + + QModelIndex newIndex = uat_model_->appendEntry(newRowData); + if ( !newIndex.isValid() ) + { qDebug() << "Failed to add a new record"; return; } - int currentRow = uat_model_->rowCount() - 1; - const QModelIndex &new_index = uat_model_->index(currentRow, 0); - - //populate model with data - uat_model_->setData(uat_model_->index(currentRow, colEnabled), checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole); - uat_model_->setData(uat_model_->index(currentRow, colName), name); - uat_model_->setData(uat_model_->index(currentRow, colDFilter), dfilter); - uat_model_->setData(uat_model_->index(currentRow, colColor), QColor(color_idx), Qt::DecorationRole); - uat_model_->setData(uat_model_->index(currentRow, colStyle), val_to_str_const(style, graph_style_vs, "None")); - uat_model_->setData(uat_model_->index(currentRow, colYAxis), val_to_str_const(value_units, y_axis_vs, "Packets")); - uat_model_->setData(uat_model_->index(currentRow, colYField), yfield); - uat_model_->setData(uat_model_->index(currentRow, colSMAPeriod), val_to_str_const((guint32) moving_average, moving_avg_vs, "None")); - uat_model_->setData(uat_model_->index(currentRow, colYAxisFactor), (guint32) y_axis_factor); - - // due to an EditTrigger, this will also start editing. - ui->graphUat->setCurrentIndex(new_index); - - createIOGraph(currentRow); + ui->graphUat->setCurrentIndex(newIndex); + createIOGraph(newIndex.row()); } void IOGraphDialog::addGraph(bool copy_from_current) @@ -511,22 +508,24 @@ void IOGraphDialog::addGraph(bool copy_from_current) if (copy_from_current && !current.isValid()) return; + QModelIndex copyIdx; + if (copy_from_current) { - // should not fail, but you never know. - if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) { + copyIdx = uat_model_->copyRow(current); + if (!copyIdx.isValid()) + { qDebug() << "Failed to add a new record"; return; } - const QModelIndex &new_index = uat_model_->index(uat_model_->rowCount() - 1, 0); - uat_model_->copyRow(new_index.row(), current.row()); - createIOGraph(new_index.row()); + createIOGraph(copyIdx.row()); - ui->graphUat->setCurrentIndex(new_index); + ui->graphUat->setCurrentIndex(copyIdx); } else { addDefaultGraph(false); - const QModelIndex &new_index = uat_model_->index(uat_model_->rowCount() - 1, 0); - ui->graphUat->setCurrentIndex(new_index); + copyIdx = uat_model_->index(uat_model_->rowCount() - 1, 0); } + + ui->graphUat->setCurrentIndex(copyIdx); } void IOGraphDialog::createIOGraph(int currentRow) diff --git a/ui/qt/models/uat_model.cpp b/ui/qt/models/uat_model.cpp index 67065cdfb0..bc9d13fe9b 100644 --- a/ui/qt/models/uat_model.cpp +++ b/ui/qt/models/uat_model.cpp @@ -237,6 +237,58 @@ int UatModel::columnCount(const QModelIndex &parent) const return uat_->ncols; } +QModelIndex UatModel::appendEntry(QVariantList rowData) +{ + // A row with less entries could be added, where the remaining entries are empty + if (rowData.count() == 0 || rowData.count() < rowCount()) + return QModelIndex(); + + QModelIndex newIndex; + int row = rowCount(); + emit beginInsertRows(QModelIndex(), row, row); + + // Initialize with given values + void *record = g_malloc0(uat_->record_size); + for (int col = 0; col < columnCount(); col++) { + uat_field_t *field = &uat_->fields[col]; + + QString data; + if (rowData.count() > col) { + if (field->mode != PT_TXTMOD_BOOL) { + data = rowData[col].toString(); + } else { + if (rowData[col] == Qt::Checked) { + data = QString("TRUE"); + } else { + data = QString("FALSE"); + } + } + } + + QByteArray bytes = field->mode == PT_TXTMOD_HEXBYTES ? QByteArray::fromHex(data.toUtf8()) : data.toUtf8(); + field->cb.set(record, bytes.constData(), (unsigned) bytes.size(), field->cbdata.set, field->fld_data); + } + uat_insert_record_idx(uat_, row, record); + if (uat_->free_cb) { + uat_->free_cb(record); + } + g_free(record); + + record_errors.insert(row, QMap<int, QString>()); + // a new row is created. For the moment all fields are empty, so validation + // will likely mark everything as invalid. Ideally validation should be + // postponed until the row (in the view) is not selected anymore + checkRow(row); + dirty_records.insert(row, true); + uat_->changed = TRUE; + + emit endInsertRows(); + + newIndex = index(row, 0, QModelIndex()); + + return newIndex; +} + bool UatModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (!index.isValid()) @@ -367,15 +419,37 @@ void UatModel::clearAll() endResetModel(); } - -bool UatModel::copyRow(int dst_row, int src_row) +QModelIndex UatModel::copyRow(QModelIndex original) { - if (src_row < 0 || src_row >= rowCount() || dst_row < 0 || dst_row >= rowCount()) { - return false; + if (! original.isValid()) + return QModelIndex(); + + int newRow = rowCount(); + + beginInsertRows(QModelIndex(), newRow, newRow); + + // Initialize with empty values, caller should use setData to populate it. + void *record = g_malloc0(uat_->record_size); + for (int col = 0; col < columnCount(); col++) { + uat_field_t *field = &uat_->fields[col]; + field->cb.set(record, "", 0, field->cbdata.set, field->fld_data); + } + uat_insert_record_idx(uat_, newRow, record); + if (uat_->free_cb) { + uat_->free_cb(record); } + g_free(record); - const void *src_record = UAT_INDEX_PTR(uat_, src_row); - void *dst_record = UAT_INDEX_PTR(uat_, dst_row); + record_errors.insert(newRow, QMap<int, QString>()); + // a new row is created. For the moment all fields are empty, so validation + // will likely mark everything as invalid. Ideally validation should be + // postponed until the row (in the view) is not selected anymore + checkRow(newRow); + dirty_records.insert(newRow, true); + + // the UAT record has been created, now it is filled with the infromation + const void *src_record = UAT_INDEX_PTR(uat_, original.row()); + void *dst_record = UAT_INDEX_PTR(uat_, newRow); // insertRows always initializes the record with empty value. Before copying // over the new values, be sure to clear the old fields. if (uat_->free_cb) { @@ -387,16 +461,16 @@ bool UatModel::copyRow(int dst_row, int src_row) /* According to documentation of uat_copy_cb_t memcpy should be used if uat_->copy_cb is NULL */ memcpy(dst_record, src_record, uat_->record_size); } - gboolean src_valid = g_array_index(uat_->valid_data, gboolean, src_row); + gboolean src_valid = g_array_index(uat_->valid_data, gboolean, original.row()); uat_update_record(uat_, dst_record, src_valid); - record_errors[dst_row] = record_errors[src_row]; - dirty_records[dst_row] = true; + record_errors[newRow] = record_errors[original.row()]; + dirty_records[newRow] = true; - QVector<int> roles; - roles << Qt::EditRole << Qt::BackgroundRole; - emit dataChanged(index(dst_row, 0), index(dst_row, columnCount()), roles); + uat_->changed = TRUE; - return true; + endInsertRows(); + + return index(newRow, 0, QModelIndex()); } bool UatModel::moveRow(int src_row, int dst_row) diff --git a/ui/qt/models/uat_model.h b/ui/qt/models/uat_model.h index 36513b1888..7008db8b30 100644 --- a/ui/qt/models/uat_model.h +++ b/ui/qt/models/uat_model.h @@ -41,9 +41,13 @@ public: bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - bool copyRow(int dst_row, int src_row); + QModelIndex appendEntry(QVariantList row); + + QModelIndex copyRow(QModelIndex original); bool moveRow(int src_row, int dst_row); + bool moveRow(const QModelIndex &sourceParent, int sourceRow, const QModelIndex &destinationParent, int destinationChild); + void reloadUat(); bool hasErrors() const; void clearAll(); diff --git a/ui/qt/uat_dialog.cpp b/ui/qt/uat_dialog.cpp index d192b70975..99aa2d568f 100644 --- a/ui/qt/uat_dialog.cpp +++ b/ui/qt/uat_dialog.cpp @@ -260,18 +260,22 @@ void UatDialog::addRecord(bool copy_from_current) { if (!uat_) return; - const QModelIndex ¤t = ui->uatTreeView->currentIndex(); + QModelIndex current = ui->uatTreeView->currentIndex(); if (copy_from_current && !current.isValid()) return; - // should not fail, but you never know. - if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) { - qDebug() << "Failed to add a new record"; - return; - } - const QModelIndex &new_index = uat_model_->index(uat_model_->rowCount() - 1, 0); + QModelIndex new_index; if (copy_from_current) { - uat_model_->copyRow(new_index.row(), current.row()); + new_index = uat_model_->copyRow(current); + } else { + // should not fail, but you never know. + if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) { + qDebug() << "Failed to add a new record"; + return; + } + + new_index = uat_model_->index(uat_model_->rowCount() - 1, 0); } + // due to an EditTrigger, this will also start editing. ui->uatTreeView->setCurrentIndex(new_index); // trigger updating error messages and the OK button state. diff --git a/ui/qt/uat_frame.cpp b/ui/qt/uat_frame.cpp index 8ce4ff03b8..efa813e78b 100644 --- a/ui/qt/uat_frame.cpp +++ b/ui/qt/uat_frame.cpp @@ -184,18 +184,21 @@ void UatFrame::addRecord(bool copy_from_current) { if (!uat_) return; - const QModelIndex ¤t = ui->uatTreeView->currentIndex(); + QModelIndex current = ui->uatTreeView->currentIndex(); if (copy_from_current && !current.isValid()) return; - // should not fail, but you never know. - if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) { - qDebug() << "Failed to add a new record"; - return; - } - const QModelIndex &new_index = uat_model_->index(uat_model_->rowCount() - 1, 0); + QModelIndex new_index; if (copy_from_current) { - uat_model_->copyRow(new_index.row(), current.row()); + new_index = uat_model_->copyRow(current); + } else { + // should not fail, but you never know. + if (!uat_model_->insertRows(uat_model_->rowCount(), 1)) { + qDebug() << "Failed to add a new record"; + return; + } + new_index = uat_model_->index(uat_model_->rowCount() - 1, 0); } + // due to an EditTrigger, this will also start editing. ui->uatTreeView->setCurrentIndex(new_index); // trigger updating error messages and the OK button state. |