Skip to content

Commit fe4ff35

Browse files
committed
feat: add QSFP to hide empty rows in eventmodel
The favourites and tracepoint patches include some rows in the model that may be empty. To keep the code simple an readable all rows will be shown. Then a proxy model is put ontop to remove empty rows.
1 parent 200d6de commit fe4ff35

File tree

5 files changed

+100
-5
lines changed

5 files changed

+100
-5
lines changed

src/models/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ add_library(
1111
disassemblymodel.cpp
1212
disassemblyoutput.cpp
1313
eventmodel.cpp
14+
eventmodelproxy.cpp
1415
filterandzoomstack.cpp
1516
formattingutils.cpp
1617
frequencymodel.cpp

src/models/eventmodelproxy.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
SPDX-FileCopyrightText: Lieven Hey <[email protected]>
3+
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected]
4+
5+
SPDX-License-Identifier: GPL-2.0-or-later
6+
*/
7+
8+
#include "eventmodelproxy.h"
9+
#include "eventmodel.h"
10+
11+
EventModelProxy::EventModelProxy(QObject* parent)
12+
: QSortFilterProxyModel(parent)
13+
{
14+
setDynamicSortFilter(true);
15+
setRecursiveFilteringEnabled(true);
16+
setSortRole(EventModel::SortRole);
17+
setFilterKeyColumn(EventModel::ThreadColumn);
18+
setFilterRole(Qt::DisplayRole);
19+
}
20+
21+
EventModelProxy::~EventModelProxy() = default;
22+
23+
bool EventModelProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
24+
{
25+
// index is invalid -> we are at the root node
26+
// hide categories that have no children (e.g. favorites, tracepoints)
27+
if (!source_parent.isValid()) {
28+
const auto model = sourceModel();
29+
if (!model->hasChildren(model->index(source_row, 0)))
30+
return false;
31+
}
32+
33+
auto data = sourceModel()
34+
->index(source_row, EventModel::EventsColumn, source_parent)
35+
.data(EventModel::EventsRole)
36+
.value<Data::Events>();
37+
38+
if (data.empty()) {
39+
return false;
40+
}
41+
42+
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
43+
}

src/models/eventmodelproxy.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
SPDX-FileCopyrightText: Lieven Hey <[email protected]>
3+
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, [email protected]
4+
5+
SPDX-License-Identifier: GPL-2.0-or-later
6+
*/
7+
8+
#pragma once
9+
10+
#include <QSortFilterProxyModel>
11+
12+
class EventModelProxy : public QSortFilterProxyModel
13+
{
14+
Q_OBJECT
15+
public:
16+
explicit EventModelProxy(QObject* parent = nullptr);
17+
~EventModelProxy() override;
18+
19+
protected:
20+
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
21+
};

src/timelinewidget.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include "filterandzoomstack.h"
1111
#include "models/eventmodel.h"
12+
#include "models/eventmodelproxy.h"
1213
#include "resultsutil.h"
1314
#include "timelinedelegate.h"
1415

@@ -61,12 +62,8 @@ TimeLineWidget::TimeLineWidget(PerfParser* parser, QMenu* filterMenu, FilterAndZ
6162
ui->setupUi(this);
6263

6364
auto* eventModel = new EventModel(this);
64-
auto* timeLineProxy = new QSortFilterProxyModel(this);
65-
timeLineProxy->setRecursiveFilteringEnabled(true);
65+
auto* timeLineProxy = new EventModelProxy(this);
6666
timeLineProxy->setSourceModel(eventModel);
67-
timeLineProxy->setSortRole(EventModel::SortRole);
68-
timeLineProxy->setFilterKeyColumn(EventModel::ThreadColumn);
69-
timeLineProxy->setFilterRole(Qt::DisplayRole);
7067
ResultsUtil::connectFilter(ui->timeLineSearch, timeLineProxy);
7168
ui->timeLineView->setModel(timeLineProxy);
7269
ui->timeLineView->setSortingEnabled(true);

tests/modeltests/tst_models.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <models/disassemblymodel.h>
2323
#include <models/eventmodel.h>
24+
#include <models/eventmodelproxy.h>
2425
#include <models/sourcecodemodel.h>
2526

2627
namespace {
@@ -672,6 +673,38 @@ private slots:
672673
QCOMPARE(model.rowCount(favoritesIndex), 0);
673674
}
674675

676+
void testEventModelProxy()
677+
{
678+
const auto events = createEventModelTestData();
679+
EventModel model;
680+
QAbstractItemModelTester tester(&model);
681+
model.setData(events);
682+
683+
EventModelProxy proxy;
684+
proxy.setSourceModel(&model);
685+
686+
const auto favoritesIndex = model.index(3, 0);
687+
const auto processesIndex = model.index(1, 0);
688+
689+
QCOMPARE(model.rowCount(), 4);
690+
QCOMPARE(proxy.rowCount(), 2);
691+
692+
proxy.setFilterRegularExpression(QStringLiteral("this does not match"));
693+
QCOMPARE(proxy.rowCount(), 0);
694+
proxy.setFilterRegularExpression(QString());
695+
QCOMPARE(proxy.rowCount(), 2);
696+
697+
// add the first data trace to favourites
698+
// adding the whole process doesn't work currently
699+
auto firstProcess = model.index(0, 0, processesIndex);
700+
model.addToFavorites(model.index(0, 0, firstProcess));
701+
702+
QCOMPARE(proxy.rowCount(), 3);
703+
704+
model.removeFromFavorites(model.index(0, 0, favoritesIndex));
705+
QCOMPARE(proxy.rowCount(), 2);
706+
}
707+
675708
void testPrettySymbol_data()
676709
{
677710
QTest::addColumn<QString>("prettySymbol");

0 commit comments

Comments
 (0)