aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Knall <rknall@gmail.com>2021-09-08 19:32:39 +0000
committerRoland Knall <rknall@gmail.com>2021-09-08 19:32:39 +0000
commit48cf9d5497361169d5afedf4c699b9aae3f99189 (patch)
tree72c28671758aafc5d204c0ad6d42ac8915de3374
parent03480fd6e1094ac1acc97294fb9076ad17cfd585 (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.
-rw-r--r--ui/qt/io_graph_dialog.cpp55
-rw-r--r--ui/qt/models/uat_model.cpp100
-rw-r--r--ui/qt/models/uat_model.h6
-rw-r--r--ui/qt/uat_dialog.cpp20
-rw-r--r--ui/qt/uat_frame.cpp19
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 &current = 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 &current = 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.