Qt: Only save the filtered rows to the Map

Be a little more careful in TrafficTab about whether we
want the Proxy Model or the Source Model, since the tap
filter doesn't exclude rows from the source model (since
the non-displayed rows are used to as part of the percentages
of the total.)

When we want to respect the display filtering or the sorting,
use the proxy model.

In the tap data model, only claim we have GeoIPData (which makes
the map available) if a row that isn't filtered out has data.

Fix #18530
This commit is contained in:
John Thacker 2024-02-04 20:48:22 -05:00 committed by AndersBroman
parent 7fbff7a381
commit 75a64a96b7
3 changed files with 50 additions and 30 deletions

View File

@ -90,10 +90,12 @@ bool ATapDataModel::hasGeoIPData()
while (!coordsFound && row < count) while (!coordsFound && row < count)
{ {
QModelIndex idx = index(row, 0); QModelIndex idx = index(row, 0);
if (_type == ATapDataModel::DATAMODEL_ENDPOINT) if (!data(idx, ATapDataModel::ROW_IS_FILTERED).toBool()) {
coordsFound = qobject_cast<EndpointDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool(); if (_type == ATapDataModel::DATAMODEL_ENDPOINT)
else if (_type == ATapDataModel::DATAMODEL_CONVERSATION) coordsFound = qobject_cast<EndpointDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool();
coordsFound = qobject_cast<ConversationDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool(); else if (_type == ATapDataModel::DATAMODEL_CONVERSATION)
coordsFound = qobject_cast<ConversationDataModel *>(this)->data(idx, ATapDataModel::GEODATA_AVAILABLE).toBool();
}
row++; row++;
} }

View File

@ -159,7 +159,7 @@ void TrafficTab::useAbsoluteTime(bool absolute)
{ {
for(int idx = 0; idx < count(); idx++) for(int idx = 0; idx < count(); idx++)
{ {
ATapDataModel * atdm = modelForTabIndex(idx); ATapDataModel * atdm = dataModelForTabIndex(idx);
if (atdm) if (atdm)
atdm->useAbsoluteTime(absolute); atdm->useAbsoluteTime(absolute);
} }
@ -169,7 +169,7 @@ void TrafficTab::useNanosecondTimestamps(bool nanoseconds)
{ {
for(int idx = 0; idx < count(); idx++) for(int idx = 0; idx < count(); idx++)
{ {
ATapDataModel * atdm = modelForTabIndex(idx); ATapDataModel * atdm = dataModelForTabIndex(idx);
if (atdm) if (atdm)
atdm->useNanosecondTimestamps(nanoseconds); atdm->useNanosecondTimestamps(nanoseconds);
} }
@ -179,7 +179,7 @@ void TrafficTab::disableTap()
{ {
for(int idx = 0; idx < count(); idx++) for(int idx = 0; idx < count(); idx++)
{ {
ATapDataModel * atdm = modelForTabIndex(idx); ATapDataModel * atdm = dataModelForTabIndex(idx);
if (atdm) if (atdm)
atdm->disableTap(); atdm->disableTap();
} }
@ -329,7 +329,7 @@ QVariant TrafficTab::currentItemData(int role)
* to ensure proper handling. Especially ConversationDialog depends on this * to ensure proper handling. Especially ConversationDialog depends on this
* method always returning data */ * method always returning data */
if (!idx.isValid()) { if (!idx.isValid()) {
ATapDataModel * model = modelForTabIndex(currentIndex()); TrafficDataFilterProxy * model = modelForTabIndex(currentIndex());
idx = model->index(0, 0); idx = model->index(0, 0);
} }
return idx.data(role); return idx.data(role);
@ -365,7 +365,7 @@ void TrafficTab::modelReset()
emit tabDataChanged(tabIdx); emit tabDataChanged(tabIdx);
} }
ATapDataModel * TrafficTab::modelForTabIndex(int tabIdx) TrafficDataFilterProxy * TrafficTab::modelForTabIndex(int tabIdx)
{ {
if (tabIdx == -1) if (tabIdx == -1)
tabIdx = currentIndex(); tabIdx = currentIndex();
@ -373,26 +373,40 @@ ATapDataModel * TrafficTab::modelForTabIndex(int tabIdx)
return modelForWidget(widget(tabIdx)); return modelForWidget(widget(tabIdx));
} }
ATapDataModel * TrafficTab::modelForWidget(QWidget * searchWidget) TrafficDataFilterProxy * TrafficTab::modelForWidget(QWidget * searchWidget)
{ {
if (qobject_cast<QTreeView *>(searchWidget)) { if (qobject_cast<QTreeView *>(searchWidget)) {
QTreeView * tree = qobject_cast<QTreeView *>(searchWidget); QTreeView * tree = qobject_cast<QTreeView *>(searchWidget);
if (qobject_cast<TrafficDataFilterProxy *>(tree->model())) { if (qobject_cast<TrafficDataFilterProxy *>(tree->model())) {
TrafficDataFilterProxy * qsfpm = qobject_cast<TrafficDataFilterProxy *>(tree->model()); return qobject_cast<TrafficDataFilterProxy *>(tree->model());
if (qsfpm && qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) {
return qobject_cast<ATapDataModel *>(qsfpm->sourceModel());
}
} }
} }
return nullptr; return nullptr;
} }
ATapDataModel * TrafficTab::dataModelForTabIndex(int tabIdx)
{
if (tabIdx == -1)
tabIdx = currentIndex();
return dataModelForWidget(widget(tabIdx));
}
ATapDataModel * TrafficTab::dataModelForWidget(QWidget * searchWidget)
{
TrafficDataFilterProxy * qsfpm = modelForWidget(searchWidget);
if (qsfpm && qobject_cast<ATapDataModel *>(qsfpm->sourceModel())) {
return qobject_cast<ATapDataModel *>(qsfpm->sourceModel());
}
return nullptr;
}
void TrafficTab::setFilter(QString filter) void TrafficTab::setFilter(QString filter)
{ {
for (int idx = 0; idx < count(); idx++ ) for (int idx = 0; idx < count(); idx++ )
{ {
ATapDataModel * atdm = modelForTabIndex(idx); ATapDataModel * atdm = dataModelForTabIndex(idx);
if (! atdm) if (! atdm)
continue; continue;
atdm->setFilter(filter); atdm->setFilter(filter);
@ -406,7 +420,7 @@ void TrafficTab::setNameResolution(bool checked)
for (int idx = 0; idx < count(); idx++ ) for (int idx = 0; idx < count(); idx++ )
{ {
ATapDataModel * atdm = modelForTabIndex(idx); ATapDataModel * atdm = dataModelForTabIndex(idx);
if (! atdm) if (! atdm)
continue; continue;
atdm->setResolveNames(checked); atdm->setResolveNames(checked);
@ -422,7 +436,7 @@ void TrafficTab::setNameResolution(bool checked)
bool TrafficTab::hasNameResolution(int tabIdx) bool TrafficTab::hasNameResolution(int tabIdx)
{ {
int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx; int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx;
ATapDataModel * dataModel = modelForTabIndex(tab); ATapDataModel * dataModel = dataModelForTabIndex(tab);
if (! dataModel) if (! dataModel)
return false; return false;
@ -443,12 +457,12 @@ bool TrafficTab::hasGeoIPData(int tabIdx)
{ {
int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx; int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx;
ATapDataModel * dataModel = modelForTabIndex(tab); ATapDataModel * dataModel = dataModelForTabIndex(tab);
return dataModel->hasGeoIPData(); return dataModel->hasGeoIPData();
} }
bool bool
TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataModel) TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, TrafficDataFilterProxy * model)
{ {
QTextStream out(fp); QTextStream out(fp);
@ -508,9 +522,10 @@ TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataMo
QJsonArray features; QJsonArray features;
/* Append map data. */ /* Append map data. */
for(int row = 0; row < dataModel->rowCount(QModelIndex()); row++) for(int row = 0; row < model->rowCount(QModelIndex()); row++)
{ {
QModelIndex index = dataModel->index(row, 0); QModelIndex index = model->mapToSource(model->index(row, 0));
ATapDataModel *dataModel = qobject_cast<ATapDataModel *>(model->sourceModel());
const mmdb_lookup_t * result = VariantPointer<const mmdb_lookup_t>::asPtr(dataModel->data(index, ATapDataModel::GEODATA_LOOKUPTABLE)); const mmdb_lookup_t * result = VariantPointer<const mmdb_lookup_t>::asPtr(dataModel->data(index, ATapDataModel::GEODATA_LOOKUPTABLE));
if (!maxmind_db_has_coords(result)) { if (!maxmind_db_has_coords(result)) {
@ -545,8 +560,8 @@ TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataMo
if (qobject_cast<EndpointDataModel *>(dataModel)) { if (qobject_cast<EndpointDataModel *>(dataModel)) {
EndpointDataModel * endpointModel = qobject_cast<EndpointDataModel *>(dataModel); EndpointDataModel * endpointModel = qobject_cast<EndpointDataModel *>(dataModel);
property["packets"] = endpointModel->data(endpointModel->index(row, EndpointDataModel::ENDP_COLUMN_PACKETS)).toString(); property["packets"] = endpointModel->data(index.siblingAtColumn(EndpointDataModel::ENDP_COLUMN_PACKETS)).toString();
property["bytes"] = endpointModel->data(endpointModel->index(row, EndpointDataModel::ENDP_COLUMN_BYTES)).toString(); property["bytes"] = endpointModel->data(index.siblingAtColumn(EndpointDataModel::ENDP_COLUMN_BYTES)).toString();
} }
arrEntry["properties"] = property; arrEntry["properties"] = property;
features.append(arrEntry); features.append(arrEntry);
@ -568,7 +583,7 @@ TrafficTab::writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataMo
QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx) QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx)
{ {
int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx; int tab = tabIdx == -1 || tabIdx >= count() ? currentIndex() : tabIdx;
ATapDataModel * dataModel = modelForTabIndex(tab); ATapDataModel * dataModel = dataModelForTabIndex(tab);
if (! (dataModel && dataModel->hasGeoIPData())) { if (! (dataModel && dataModel->hasGeoIPData())) {
QMessageBox::warning(this, tr("Map file error"), tr("No endpoints available to map")); QMessageBox::warning(this, tr("Map file error"), tr("No endpoints available to map"));
return QUrl(); return QUrl();
@ -581,7 +596,7 @@ QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx)
return QUrl(); return QUrl();
} }
if (!writeGeoIPMapFile(&tf, json_only, dataModel)) { if (!writeGeoIPMapFile(&tf, json_only, modelForTabIndex(tab))) {
tf.close(); tf.close();
return QUrl(); return QUrl();
} }
@ -592,7 +607,7 @@ QUrl TrafficTab::createGeoIPMap(bool json_only, int tabIdx)
#endif #endif
void TrafficTab::detachTab(int tabIdx, QPoint pos) { void TrafficTab::detachTab(int tabIdx, QPoint pos) {
ATapDataModel * model = modelForTabIndex(tabIdx); ATapDataModel * model = dataModelForTabIndex(tabIdx);
if (!model) if (!model)
return; return;
@ -608,7 +623,7 @@ void TrafficTab::detachTab(int tabIdx, QPoint pos) {
void TrafficTab::attachTab(QWidget * content, QString name) void TrafficTab::attachTab(QWidget * content, QString name)
{ {
ATapDataModel * model = modelForWidget(content); ATapDataModel * model = dataModelForWidget(content);
if (!model) { if (!model) {
attachTab(content, name); attachTab(content, name);
return; return;

View File

@ -16,6 +16,7 @@
#include <ui/qt/models/atap_data_model.h> #include <ui/qt/models/atap_data_model.h>
#include <ui/qt/filter_action.h> #include <ui/qt/filter_action.h>
#include <ui/qt/widgets/traffic_tree.h>
#include <ui/qt/widgets/detachable_tabwidget.h> #include <ui/qt/widgets/detachable_tabwidget.h>
#include <ui/qt/widgets/traffic_types_list.h> #include <ui/qt/widgets/traffic_types_list.h>
@ -227,14 +228,16 @@ private:
bool _nameResolution; bool _nameResolution;
QTreeView * createTree(int protoId); QTreeView * createTree(int protoId);
ATapDataModel * modelForTabIndex(int tabIdx = -1); TrafficDataFilterProxy * modelForTabIndex(int tabIdx = -1);
ATapDataModel * modelForWidget(QWidget * widget); TrafficDataFilterProxy * modelForWidget(QWidget * widget);
ATapDataModel * dataModelForTabIndex(int tabIdx = -1);
ATapDataModel * dataModelForWidget(QWidget * widget);
void insertProtoTab(int protoId, bool emitSignals = true); void insertProtoTab(int protoId, bool emitSignals = true);
void removeProtoTab(int protoId, bool emitSignals = true); void removeProtoTab(int protoId, bool emitSignals = true);
#ifdef HAVE_MAXMINDDB #ifdef HAVE_MAXMINDDB
bool writeGeoIPMapFile(QFile * fp, bool json_only, ATapDataModel * dataModel); bool writeGeoIPMapFile(QFile * fp, bool json_only, TrafficDataFilterProxy * model);
#endif #endif
private slots: private slots: