diff --git a/src/plugins/ctfvisualizer/ctftimelinemodel.cpp b/src/plugins/ctfvisualizer/ctftimelinemodel.cpp index 748f03756e9..2286771a965 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 4be3012ba4a..b3c287183f5 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 855f8341288..493fbff7402 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; } -void CtfTraceManager::addModelForThread(int threadId, int processId) -{ - CtfTimelineModel *model = new CtfTimelineModel(m_modelAggregator, this, threadId, processId); - m_threadModels.insert(threadId, model); - connect(model, &CtfTimelineModel::detailsRequested, this, - &CtfTraceManager::detailsRequested); -} - -void CtfTraceManager::addModelsToAggregator() +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() +{ + 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 5de87eafad1..5fe326fa09e 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 96b1489978f..2c7a38b7b74 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 c5085d0f041..c1bec1def13 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