diff options
author | John Thacker <johnthacker@gmail.com> | 2023-02-20 10:18:14 -0500 |
---|---|---|
committer | John Thacker <johnthacker@gmail.com> | 2023-02-23 11:23:41 +0000 |
commit | 0bd4d9b13218ffadd94ba40fc8af052febf293b3 (patch) | |
tree | 321cb4052dbb5ae289a630635359d09cbf76f176 /ui | |
parent | 91366f56f260792650396bf5615e712609653ff9 (diff) |
Qt: Mapping between filter proxy column and displayed column
We need to convert between the column selected for filtering
by the user (which is based on what is currently displayed in the
tab) and the column in the model.
The default mapToSource requires a QModelIndex and needs a row,
and thus doesn't work when all rows are filtered out by the current
filter (that is being replaced.) However, since our filterAcceptsColumn
does not depend on the row, we can determine the mapping just based
on the column number.
We want to convert the filter column to the column used in the model
when it is first selected, so that hiding columns later doesn't
accidentally change what column is used for filtering.
Improved fix #18738
Diffstat (limited to 'ui')
-rw-r--r-- | ui/qt/widgets/traffic_tree.cpp | 54 |
1 files changed, 26 insertions, 28 deletions
diff --git a/ui/qt/widgets/traffic_tree.cpp b/ui/qt/widgets/traffic_tree.cpp index 0bf693f14a..adff561e6d 100644 --- a/ui/qt/widgets/traffic_tree.cpp +++ b/ui/qt/widgets/traffic_tree.cpp @@ -275,7 +275,7 @@ void TrafficDataFilterProxy::filterForColumn(int column, int filterOn, QString f if (filterOn < 0 || filterOn > TrafficDataFilterProxy::TRAFFIC_DATA_EQUAL) column = -1; - _filterColumn = column; + _filterColumn = mapToSourceColumn(column); _filterOn = filterOn; _filterText = filterText; invalidateFilter(); @@ -284,36 +284,32 @@ void TrafficDataFilterProxy::filterForColumn(int column, int filterOn, QString f int TrafficDataFilterProxy::mapToSourceColumn(int proxyColumn) const { ATapDataModel * model = qobject_cast<ATapDataModel *>(sourceModel()); - int column = proxyColumn; - if (model) { + if (!model || proxyColumn == -1) { + return proxyColumn; + } - if (qobject_cast<EndpointDataModel *>(model)) - { - if (model->portsAreHidden() && column > EndpointDataModel::ENDP_COLUMN_ADDR) - column++; - if (! model->showTotalColumn()) { - if (column > EndpointDataModel::ENDP_COLUMN_BYTES) - column+=2; - } - } else if (qobject_cast<ConversationDataModel *>(model)) { - if (model->portsAreHidden()) { - if (column > ConversationDataModel::CONV_COLUMN_SRC_ADDR) - column++; - if (column > ConversationDataModel::CONV_COLUMN_DST_ADDR) - column++; - } - ConversationDataModel * convModel = qobject_cast<ConversationDataModel *>(model); - if (!convModel->showConversationId() && column > ConversationDataModel::CONV_COLUMN_BYTES) { - column++; - } - if (! model->showTotalColumn()) { - if (column > ConversationDataModel::CONV_COLUMN_CONV_ID) - column+=2; + if (rowCount() > 0) { + return mapToSource(index(0, proxyColumn)).column(); + } + + /* mapToSource() requires a valid QModelIndex, and thus does not work when + * all rows are filtered out by the current filter. (E.g., the user has + * accidentally entered an incorrect filter or operator and wants to fix + * it.) Since our filterAcceptsColumn doesn't depend on the row, we can + * determine the mapping between the currently displayed column number and + * the column number in the model this way, even if no rows are displayed. + * It is linear time in the number of columns, though. + */ + int currentProxyColumn = 0; + for (int column=0; column < model->columnCount(); ++column) { + if (filterAcceptsColumn(column, QModelIndex())) { + if (currentProxyColumn++ == proxyColumn) { + return column; } } } - return column; + return -1; } bool TrafficDataFilterProxy::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const @@ -323,9 +319,11 @@ bool TrafficDataFilterProxy::filterAcceptsRow(int source_row, const QModelIndex bool isFiltered = dataModel->data(dataModel->index(source_row, 0), ATapDataModel::ROW_IS_FILTERED).toBool(); if (isFiltered && dataModel->filter().length() > 0) return false; + /* XXX: What if the filter column is now hidden? Should the filter + * still apply or should it be cleared? Right now it is still applied. + */ - int sourceColumn = mapToSourceColumn(_filterColumn); - QModelIndex srcIdx = dataModel->index(source_row, sourceColumn); + QModelIndex srcIdx = dataModel->index(source_row, _filterColumn); if (srcIdx.isValid()) { QVariant data = srcIdx.data(ATapDataModel::UNFORMATTED_DISPLAYDATA); |