From 04a154605413c5d4ef22cc93785f8c680cdeebae Mon Sep 17 00:00:00 2001 From: Lieven Hey Date: Wed, 6 Oct 2021 15:17:32 +0200 Subject: [PATCH] add filtering to diff view --- src/diffviewwidget.cpp | 56 +++++++++++++++++++++++++++++++++++-- src/diffviewwidget.h | 4 +++ src/models/CMakeLists.txt | 1 + src/models/costdelegate.cpp | 1 + src/models/diffviewproxy.h | 45 +++++++++++++++++++++++++++++ 5 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/models/diffviewproxy.h diff --git a/src/diffviewwidget.cpp b/src/diffviewwidget.cpp index 009fb23d2..94b2ad839 100644 --- a/src/diffviewwidget.cpp +++ b/src/diffviewwidget.cpp @@ -27,9 +27,16 @@ #include "diffviewwidget.h" +#include +#include #include +#include #include +#include +#include + +#include "diffviewproxy.h" #include "dockwidgetsetup.h" #include "filterandzoomstack.h" #include "models/treemodel.h" @@ -45,14 +52,50 @@ DiffViewWidget::DiffViewWidget(QWidget* parent) , ui(new Ui::ResultsDiffPage) , m_parserA(new PerfParser(this)) , m_parserB(new PerfParser(this)) + , m_filterAndZoomStackA(new FilterAndZoomStack(this)) + , m_filterAndZoomStackB(new FilterAndZoomStack(this)) + , m_filterMenu(new QMenu(this)) , m_model(new DiffViewModel(this)) + , m_contents(createDockingArea(QStringLiteral("diffview"), this)) + , m_timelineA(new TimeLineWidget(m_parserA, m_filterMenu, m_filterAndZoomStackA, this)) + , m_timelineB(new TimeLineWidget(m_parserB, m_filterMenu, m_filterAndZoomStackB, this)) { ui->setupUi(this); - ; - ui->diffTreeView->setModel(m_model); + auto diffProxy = new DiffViewProxy(this); + diffProxy->setSourceModel(m_model); + + ResultsUtil::setupTreeView(ui->diffTreeView, ui->diffSearch, diffProxy, DiffViewModel::InitialSortColumn, + DiffViewModel::SortRole); ui->diffTreeView->sortByColumn(DiffViewModel::InitialSortColumn, Qt::DescendingOrder); ResultsUtil::setupCostDelegate(m_model, ui->diffTreeView); + auto dockify = [](QWidget* widget, const QString& id, const QString& title, const QString& shortcut) { + auto* dock = new KDDockWidgets::DockWidget(id); + dock->setWidget(widget); + dock->setTitle(title); + dock->toggleAction()->setShortcut(shortcut); + return dock; + }; + + m_timelineDockA = dockify(m_timelineA, QStringLiteral("timelinea"), tr("Timeline A"), tr("Ctrl+A")); + m_contents->addDockWidget(m_timelineDockA, KDDockWidgets::Location_OnBottom); + m_timelineDockB = dockify(m_timelineB, QStringLiteral("timelineb"), tr("Timeline B"), tr("Ctrl+B")); + m_timelineDockA->addDockWidgetAsTab(m_timelineDockB); + + auto costThreshold = new QDoubleSpinBox(this); + costThreshold->setDecimals(2); + costThreshold->setMinimum(0); + costThreshold->setMaximum(99.90); + costThreshold->setPrefix(tr("Cost Threshold: ")); + costThreshold->setSuffix(QStringLiteral("%")); + costThreshold->setValue(0.01); + costThreshold->setSingleStep(0.01); + connect(costThreshold, static_cast(&QDoubleSpinBox::valueChanged), this, + [diffProxy](double threshold) { diffProxy->setThreshold(threshold); }); + + ui->bottomUpVerticalLayout->addWidget(costThreshold); + ui->bottomUpVerticalLayout->addWidget(m_contents); + auto repositionFilterBusyIndicator = [this] { auto geometry = m_filterBusyIndicator->geometry(); geometry.setWidth(width() / 2); @@ -104,6 +147,15 @@ DiffViewWidget::DiffViewWidget(QWidget* parent) } }); + connect(m_filterAndZoomStackA, &FilterAndZoomStack::filterChanged, this, [this](const Data::FilterAction& action) { + m_bFinished = true; + m_parserA->filterResults(action); + }); + connect(m_filterAndZoomStackB, &FilterAndZoomStack::filterChanged, this, [this](const Data::FilterAction& action) { + m_aFinished = true; + m_parserB->filterResults(action); + }); + { m_filterBusyIndicator = new QWidget(this); m_filterBusyIndicator->setMinimumHeight(100); diff --git a/src/diffviewwidget.h b/src/diffviewwidget.h index 23ad1d0df..7b627c90c 100644 --- a/src/diffviewwidget.h +++ b/src/diffviewwidget.h @@ -30,6 +30,7 @@ #include "data.h" #include +class QMenu; class PerfParser; class DiffViewModel; class TimeLineWidget; @@ -58,6 +59,9 @@ public slots: QScopedPointer ui; PerfParser* m_parserA; PerfParser* m_parserB; + FilterAndZoomStack* m_filterAndZoomStackA; + FilterAndZoomStack* m_filterAndZoomStackB; + QMenu* m_filterMenu; DiffViewModel* m_model; KDDockWidgets::MainWindow* m_contents; KDDockWidgets::DockWidget* m_timelineDockA; diff --git a/src/models/CMakeLists.txt b/src/models/CMakeLists.txt index 96f22d5ed..85aecc43b 100644 --- a/src/models/CMakeLists.txt +++ b/src/models/CMakeLists.txt @@ -16,6 +16,7 @@ add_library(models STATIC ../settings.cpp ../util.cpp callercalleeproxy.cpp + diffviewproxy.cpp ) target_link_libraries(models diff --git a/src/models/costdelegate.cpp b/src/models/costdelegate.cpp index 73ebe6905..e3bc7be7e 100644 --- a/src/models/costdelegate.cpp +++ b/src/models/costdelegate.cpp @@ -32,6 +32,7 @@ #include +// TODO: c++17 move to std clamp float clamp(float value, float low, float high) { if (value < low) diff --git a/src/models/diffviewproxy.h b/src/models/diffviewproxy.h new file mode 100644 index 000000000..a479b85c3 --- /dev/null +++ b/src/models/diffviewproxy.h @@ -0,0 +1,45 @@ +/* + diffviewproxy.h + + This file is part of Hotspot, the Qt GUI for performance analysis. + + Copyright (C) 2021 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com + Author: Lieven Hey + + Licensees holding valid commercial KDAB Hotspot licenses may use this file in + accordance with Hotspot Commercial License Agreement provided with the Software. + + Contact info@kdab.com if any conditions of this licensing are not clear to you. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#pragma once + +#include + +class DiffViewProxy : public QSortFilterProxyModel +{ +public: + explicit DiffViewProxy(QObject* parent = nullptr); + ~DiffViewProxy(); + + void setThreshold(double threshold); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex& parent) const override; + +private: + double m_threshold = 0.01; +};