Skip to content

Commit

Permalink
feat: add QSFP to hide empty rows in eventmodel
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lievenhey committed Nov 19, 2024
1 parent 72b2321 commit f93db35
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 5 deletions.
1 change: 1 addition & 0 deletions src/models/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_library(
disassemblymodel.cpp
disassemblyoutput.cpp
eventmodel.cpp
eventmodelproxy.cpp
filterandzoomstack.cpp
formattingutils.cpp
frequencymodel.cpp
Expand Down
43 changes: 43 additions & 0 deletions src/models/eventmodelproxy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
SPDX-FileCopyrightText: Lieven Hey <lieven.hey@kdab.com>
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
SPDX-License-Identifier: GPL-2.0-or-later
*/

#include "eventmodelproxy.h"
#include "eventmodel.h"

EventModelProxy::EventModelProxy(QObject* parent)
: QSortFilterProxyModel(parent)
{
setDynamicSortFilter(true);
setRecursiveFilteringEnabled(true);
setSortRole(EventModel::SortRole);
setFilterKeyColumn(EventModel::ThreadColumn);
setFilterRole(Qt::DisplayRole);
}

EventModelProxy::~EventModelProxy() = default;

bool EventModelProxy::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
{
// index is invalid -> we are at the root node
// hide categories that have no children (e.g. favorites, tracepoints)
if (!source_parent.isValid()) {
const auto model = sourceModel();
if (!model->hasChildren(model->index(source_row, 0)))
return false;
}

auto data = sourceModel()
->index(source_row, EventModel::EventsColumn, source_parent)
.data(EventModel::EventsRole)
.value<Data::Events>();

if (data.empty()) {
return false;
}

return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
}
21 changes: 21 additions & 0 deletions src/models/eventmodelproxy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
SPDX-FileCopyrightText: Lieven Hey <lieven.hey@kdab.com>
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
SPDX-License-Identifier: GPL-2.0-or-later
*/

#pragma once

#include <QSortFilterProxyModel>

class EventModelProxy : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit EventModelProxy(QObject* parent = nullptr);
~EventModelProxy() override;

protected:
bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
};
7 changes: 2 additions & 5 deletions src/timelinewidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "filterandzoomstack.h"
#include "models/eventmodel.h"
#include "models/eventmodelproxy.h"
#include "resultsutil.h"
#include "timelinedelegate.h"

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

auto* eventModel = new EventModel(this);
auto* timeLineProxy = new QSortFilterProxyModel(this);
timeLineProxy->setRecursiveFilteringEnabled(true);
auto* timeLineProxy = new EventModelProxy(this);
timeLineProxy->setSourceModel(eventModel);
timeLineProxy->setSortRole(EventModel::SortRole);
timeLineProxy->setFilterKeyColumn(EventModel::ThreadColumn);
timeLineProxy->setFilterRole(Qt::DisplayRole);
ResultsUtil::connectFilter(ui->timeLineSearch, timeLineProxy, ui->regexCheckBox);
ui->timeLineView->setModel(timeLineProxy);
ui->timeLineView->setSortingEnabled(true);
Expand Down
33 changes: 33 additions & 0 deletions tests/modeltests/tst_models.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <models/disassemblymodel.h>
#include <models/eventmodel.h>
#include <models/eventmodelproxy.h>
#include <models/sourcecodemodel.h>

namespace {
Expand Down Expand Up @@ -672,6 +673,38 @@ private slots:
QCOMPARE(model.rowCount(favoritesIndex), 0);
}

void testEventModelProxy()
{
const auto events = createEventModelTestData();
EventModel model;
QAbstractItemModelTester tester(&model);
model.setData(events);

EventModelProxy proxy;
proxy.setSourceModel(&model);

const auto favoritesIndex = model.index(3, 0);
const auto processesIndex = model.index(1, 0);

QCOMPARE(model.rowCount(), 4);
QCOMPARE(proxy.rowCount(), 2);

proxy.setFilterRegularExpression(QStringLiteral("this does not match"));
QCOMPARE(proxy.rowCount(), 0);
proxy.setFilterRegularExpression(QString());
QCOMPARE(proxy.rowCount(), 2);

// add the first data trace to favourites
// adding the whole process doesn't work currently
auto firstProcess = model.index(0, 0, processesIndex);
model.addToFavorites(model.index(0, 0, firstProcess));

QCOMPARE(proxy.rowCount(), 3);

model.removeFromFavorites(model.index(0, 0, favoritesIndex));
QCOMPARE(proxy.rowCount(), 2);
}

void testPrettySymbol_data()
{
QTest::addColumn<QString>("prettySymbol");
Expand Down

0 comments on commit f93db35

Please sign in to comment.