From b90200cb195d0fc30aba6782b9bb921ae6e91d17 Mon Sep 17 00:00:00 2001 From: Tim Henning Date: Thu, 17 Oct 2019 13:36:37 +0200 Subject: Tracing: CtfVisualizer: Add menu to restrict view to certain threads Add a new dropdown menu to select which threads should be displayed. If no threads are selected, all are shown (this is why the word 'restriction' was chosen). At the moment this only affects the timeline view, see the follow up for the statistics view. Change-Id: Ib3b08ea895e852189156e23feb8dea5f843cceb3 Reviewed-by: Ulf Hermann --- src/plugins/ctfvisualizer/ctftimelinemodel.cpp | 9 ++++-- src/plugins/ctfvisualizer/ctftimelinemodel.h | 2 ++ src/plugins/ctfvisualizer/ctftracemanager.cpp | 37 +++++++++++++++++++++---- src/plugins/ctfvisualizer/ctftracemanager.h | 6 ++++ src/plugins/ctfvisualizer/ctfvisualizertool.cpp | 33 ++++++++++++++++++++++ src/plugins/ctfvisualizer/ctfvisualizertool.h | 7 +++++ 6 files changed, 87 insertions(+), 7 deletions(-) (limited to 'src/plugins/ctfvisualizer') diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.cpp b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp index 748f03756e..2286771a96 100644 --- a/src/plugins/ctfvisualizer/ctftimelinemodel.cpp +++ b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp @@ -217,12 +217,17 @@ void CtfTimelineModel::finalize(double traceBegin, double traceEnd, const QStrin emit contentChanged(); } +int CtfTimelineModel::tid() const +{ + return m_threadId; +} + void CtfTimelineModel::updateName() { if (m_threadName.isEmpty()) { - setDisplayName(tr("> Thread %1").arg(m_threadId)); + setDisplayName(tr("Thread %1").arg(m_threadId)); } else { - setDisplayName(QString("> %1 (%2)").arg(m_threadName).arg(m_threadId)); + setDisplayName(QString("%1 (%2)").arg(m_threadName).arg(m_threadId)); } QString process = m_processName.isEmpty() ? QString::number(m_processId) : QString("%1 (%2)").arg(m_processName).arg(m_processId); diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.h b/src/plugins/ctfvisualizer/ctftimelinemodel.h index 4be3012ba4..b3c287183f 100644 --- a/src/plugins/ctfvisualizer/ctftimelinemodel.h +++ b/src/plugins/ctfvisualizer/ctftimelinemodel.h @@ -67,6 +67,8 @@ public: void finalize(double traceBegin, double traceEnd, const QString &processName, const QString &threadName); + int tid() const; + signals: void detailsRequested(const QString &eventName) const; diff --git a/src/plugins/ctfvisualizer/ctftracemanager.cpp b/src/plugins/ctfvisualizer/ctftracemanager.cpp index 855f834128..493fbff740 100644 --- a/src/plugins/ctfvisualizer/ctftracemanager.cpp +++ b/src/plugins/ctfvisualizer/ctftracemanager.cpp @@ -192,6 +192,7 @@ void CtfTraceManager::finalize() } } m_threadModels.remove(tid); + m_threadRestrictions.remove(tid); } } for (CtfTimelineModel *model: m_threadModels) { @@ -216,25 +217,51 @@ int CtfTraceManager::getSelectionId(const std::string &name) return *it; } +QList CtfTraceManager::getSortedThreads() const +{ + QList models = m_threadModels.values(); + std::sort(models.begin(), models.end(), [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool { + return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId) + : (std::abs(a->m_threadId) < std::abs(b->m_threadId)); + }); + return models; +} + +void CtfTraceManager::setThreadRestriction(int tid, bool restrictToThisThread) +{ + if (m_threadRestrictions.value(tid) == restrictToThisThread) + return; + + m_threadRestrictions[tid] = restrictToThisThread; + addModelsToAggregator(); +} + +bool CtfTraceManager::isRestrictedTo(int tid) const +{ + return m_threadRestrictions.value(tid); +} + void CtfTraceManager::addModelForThread(int threadId, int processId) { CtfTimelineModel *model = new CtfTimelineModel(m_modelAggregator, this, threadId, processId); m_threadModels.insert(threadId, model); + m_threadRestrictions.insert(threadId, false); connect(model, &CtfTimelineModel::detailsRequested, this, &CtfTraceManager::detailsRequested); } void CtfTraceManager::addModelsToAggregator() { - QList models = m_threadModels.values(); - std::sort(models.begin(), models.end(), [](const CtfTimelineModel *a, const CtfTimelineModel *b) -> bool { - return (a->m_processId != b->m_processId) ? (a->m_processId < b->m_processId) - : (std::abs(a->m_threadId) < std::abs(b->m_threadId)); + const QList models = getSortedThreads(); + + const bool showAll = std::none_of(m_threadRestrictions.begin(), m_threadRestrictions.end(), [](bool value) { + return value; }); QVariantList modelsToAdd; for (CtfTimelineModel *model: models) { - modelsToAdd.append(QVariant::fromValue(model)); + if (showAll || isRestrictedTo(model->tid())) + modelsToAdd.append(QVariant::fromValue(model)); } m_modelAggregator->setModels(modelsToAdd); } diff --git a/src/plugins/ctfvisualizer/ctftracemanager.h b/src/plugins/ctfvisualizer/ctftracemanager.h index 5de87eafad..5fe326fa09 100644 --- a/src/plugins/ctfvisualizer/ctftracemanager.h +++ b/src/plugins/ctfvisualizer/ctftracemanager.h @@ -64,6 +64,11 @@ public: int getSelectionId(const std::string &name); + QList getSortedThreads() const; + + void setThreadRestriction(int tid, bool restrictToThisThread); + bool isRestrictedTo(int tid) const; + signals: void detailsRequested(const QString &title); @@ -81,6 +86,7 @@ protected: QHash m_processNames; QHash m_threadNames; QMap m_name2selectionId; + QHash m_threadRestrictions; double m_traceBegin = std::numeric_limits::max(); double m_traceEnd = std::numeric_limits::min(); diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp index 96b1489978..2c7a38b7b7 100644 --- a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp +++ b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp @@ -29,6 +29,7 @@ #include "ctfstatisticsmodel.h" #include "ctfstatisticsview.h" +#include "ctftimelinemodel.h" #include "ctfvisualizertraceview.h" #include @@ -36,6 +37,7 @@ #include #include #include +#include #include #include @@ -62,6 +64,8 @@ CtfVisualizerTool::CtfVisualizerTool() , m_statisticsModel(new CtfStatisticsModel(this)) , m_statisticsView(nullptr) , m_traceManager(new CtfTraceManager(this, m_modelAggregator.get(), m_statisticsModel.get())) + , m_restrictToThreadsButton(new QToolButton) + , m_restrictToThreadsMenu(new QMenu(m_restrictToThreadsButton)) { ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); ActionContainer *options = ActionManager::createMenu(Constants::CtfVisualizerMenuId); @@ -78,6 +82,16 @@ CtfVisualizerTool::CtfVisualizerTool() options->addAction(command); m_perspective.setAboutToActivateCallback([this]() { createViews(); }); + + m_restrictToThreadsButton->setIcon(Utils::Icons::FILTER.icon()); + m_restrictToThreadsButton->setToolTip(tr("Restrict to threads")); + m_restrictToThreadsButton->setPopupMode(QToolButton::InstantPopup); + m_restrictToThreadsButton->setProperty("noArrow", true); + m_restrictToThreadsButton->setMenu(m_restrictToThreadsMenu); + connect(m_restrictToThreadsMenu, &QMenu::triggered, + this, &CtfVisualizerTool::toggleThreadRestriction); + + m_perspective.addToolBarWidget(m_restrictToThreadsButton); } CtfVisualizerTool::~CtfVisualizerTool() = default; @@ -116,6 +130,24 @@ void CtfVisualizerTool::createViews() m_perspective.setAboutToActivateCallback(Utils::Perspective::Callback()); } +void CtfVisualizerTool::setAvailableThreads(const QList &threads) +{ + m_restrictToThreadsMenu->clear(); + + for (auto timelineModel : threads) { + QAction *action = m_restrictToThreadsMenu->addAction(timelineModel->displayName()); + action->setCheckable(true); + action->setData(timelineModel->tid()); + action->setChecked(m_traceManager->isRestrictedTo(timelineModel->tid())); + } +} + +void CtfVisualizerTool::toggleThreadRestriction(QAction *action) +{ + const int tid = action->data().toInt(); + m_traceManager->setThreadRestriction(tid, action->isChecked()); +} + Timeline::TimelineModelAggregator *CtfVisualizerTool::modelAggregator() const { return m_modelAggregator.get(); @@ -169,6 +201,7 @@ void CtfVisualizerTool::loadJson() zoomControl()->setTrace(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20); zoomControl()->setRange(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20); } + setAvailableThreads(m_traceManager->getSortedThreads()); thread->deleteLater(); delete task; delete futureInterface; diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.h b/src/plugins/ctfvisualizer/ctfvisualizertool.h index c5085d0f04..c1bec1def1 100644 --- a/src/plugins/ctfvisualizer/ctfvisualizertool.h +++ b/src/plugins/ctfvisualizer/ctfvisualizertool.h @@ -40,6 +40,7 @@ namespace Internal { class CtfTraceManager; class CtfStatisticsModel; class CtfStatisticsView; +class CtfTimelineModel; class CtfVisualizerTraceView; @@ -63,6 +64,9 @@ private: void initialize(); void finalize(); + void setAvailableThreads(const QList &threads); + void toggleThreadRestriction(QAction *action); + Utils::Perspective m_perspective{Constants::CtfVisualizerPerspectiveId, tr("Chrome Trace Format Visualizer")}; @@ -77,6 +81,9 @@ private: CtfStatisticsView *m_statisticsView; const QScopedPointer m_traceManager; + + QToolButton *const m_restrictToThreadsButton; + QMenu *const m_restrictToThreadsMenu; }; } // namespace Internal -- cgit v1.2.3