Skip to content

Commit d54b806

Browse files
committed
add Favourites to TimeLineWidget
this allows the user to group important timelines together so that he can compare them better
1 parent c897a66 commit d54b806

File tree

6 files changed

+56
-9
lines changed

6 files changed

+56
-9
lines changed

src/models/eventmodel.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ enum class Tag : quint8
2929
Processes,
3030
Threads,
3131
Tracepoints,
32+
Favorites,
3233
LAST_TAG,
3334
};
3435
const auto DATATAG_SHIFT = sizeof(Tag) * 8;
@@ -83,6 +84,7 @@ int EventModel::rowCount(const QModelIndex& parent) const
8384
case Tag::Cpus:
8485
case Tag::Threads:
8586
case Tag::Tracepoints:
87+
case Tag::Favorites:
8688
return 0;
8789
break;
8890
case Tag::Processes:
@@ -95,11 +97,13 @@ int EventModel::rowCount(const QModelIndex& parent) const
9597
return m_processes.size();
9698
case 2:
9799
return m_data.tracepoints.size();
100+
case 3:
101+
return m_favourites.size();
98102
default:
99103
Q_ASSERT(false);
100104
}
101105
case Tag::Root:
102-
return m_data.tracepoints.isEmpty() ? 2 : 3;
106+
return 4;
103107
case Tag::LAST_TAG:
104108
Q_ASSERT(false);
105109
};
@@ -166,6 +170,8 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
166170
return tr("Processes");
167171
case 2:
168172
return tr("Tracepoints");
173+
case 3:
174+
return tr("Favorites");
169175
}
170176
} else if (role == Qt::ToolTipRole) {
171177
if (index.row() == 0) {
@@ -175,6 +181,8 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
175181
return tr("Event timelines for the individual threads and processes.");
176182
} else if (index.row() == 2) {
177183
return tr("Event timelines for tracepoints");
184+
} else if (index.row() == 3) {
185+
return tr("A list of favourites to group important events");
178186
}
179187
} else if (role == SortRole) {
180188
return index.row();
@@ -244,6 +252,10 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
244252
} else if (tag == Tag::Tracepoints) {
245253
tracepoint = &m_data.tracepoints[index.row()];
246254
Q_ASSERT(tracepoint);
255+
} else if (tag == Tag::Favorites) {
256+
auto& favourite = m_favourites[index.row()];
257+
auto res = data(favourite, role);
258+
return res;
247259
}
248260

249261
if (role == ThreadStartRole) {
@@ -467,17 +479,21 @@ QModelIndex EventModel::index(int row, int column, const QModelIndex& parent) co
467479
case Tag::Cpus:
468480
case Tag::Tracepoints:
469481
case Tag::Threads:
482+
case Tag::Favorites:
470483
break;
471484
case Tag::Root: // root has the 1st level children: Overview
472485
return createIndex(row, column, static_cast<quintptr>(Tag::Overview));
473486
case Tag::Overview: // 2nd level children: Cpus and the Processes
474-
if (parent.row() == 0)
487+
if (parent.row() == 0) {
475488
return createIndex(row, column, static_cast<quintptr>(Tag::Cpus));
476-
else if (parent.row() == 1)
489+
} else if (parent.row() == 1) {
477490
return createIndex(row, column, static_cast<quintptr>(Tag::Processes));
478-
else {
491+
} else if (parent.row() == 2) {
479492
return createIndex(row, column, static_cast<quintptr>(Tag::Tracepoints));
493+
} else if (parent.row() == 3) {
494+
return createIndex(row, column, static_cast<quintptr>(Tag::Favorites));
480495
}
496+
break;
481497
case Tag::Processes: // 3rd level children: Threads
482498
return createIndex(row, column, combineDataTag(Tag::Threads, parent.row()));
483499
}
@@ -497,14 +513,24 @@ QModelIndex EventModel::parent(const QModelIndex& child) const
497513
return createIndex(0, 0, static_cast<quintptr>(Tag::Overview));
498514
case Tag::Processes:
499515
return createIndex(1, 0, static_cast<quintptr>(Tag::Overview));
500-
case Tag::Tracepoints: {
516+
case Tag::Tracepoints:
501517
return createIndex(2, 0, static_cast<qintptr>(Tag::Overview));
502-
}
503-
case Tag::Threads: {
518+
case Tag::Favorites:
519+
return createIndex(3, 0, static_cast<qintptr>(Tag::Overview));
520+
case Tag::Threads:
504521
const auto parentRow = tagData(child.internalId());
505522
return createIndex(parentRow, 0, static_cast<quintptr>(Tag::Processes));
506523
}
507-
}
508524

509525
return {};
510526
}
527+
528+
void EventModel::addToFavourites(const QModelIndex& index)
529+
{
530+
int position = m_favourites.size();
531+
beginInsertRows(createIndex(3, 0), position, position + 1);
532+
m_favourites.push_back(index);
533+
endInsertRows();
534+
beginResetModel();
535+
endResetModel();
536+
}

src/models/eventmodel.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,13 @@ class EventModel : public QAbstractItemModel
7171
QString name;
7272
};
7373

74+
public:
75+
void addToFavourites(const QModelIndex& index);
76+
7477
private:
7578
Data::EventResults m_data;
7679
QVector<Process> m_processes;
80+
QVector<QModelIndex> m_favourites;
7781
Data::TimeRange m_time;
7882
quint64 m_totalOnCpuTime = 0;
7983
quint64 m_totalOffCpuTime = 0;

src/models/timelinedelegate.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <QHelpEvent>
1414
#include <QMenu>
1515
#include <QPainter>
16+
#include <QSortFilterProxyModel>
1617
#include <QToolTip>
1718

1819
#include "../util.h"
@@ -133,6 +134,11 @@ Data::Events::const_iterator findEvent(const Data::Events::const_iterator& begin
133134
auto it = std::lower_bound(begin, end, time, byTime);
134135
// it points to the first item for which our predicate returns false, we want to find the item before that
135136
// so decrement it if possible or return begin otherwise
137+
138+
// it can be end so it->time cases an buffer overflow
139+
if (it == end) {
140+
return end;
141+
}
136142
return (it == begin || it->time == time) ? it : (it - 1);
137143
}
138144
}
@@ -456,6 +462,13 @@ bool TimeLineDelegate::eventFilter(QObject* watched, QEvent* event)
456462
const auto isMainThread = threadStartTime == minTime && threadEndTime == maxTime;
457463
const auto cpuId = index.data(EventModel::CpuIdRole).value<quint32>();
458464
const auto numCpus = index.data(EventModel::NumCpusRole).value<uint>();
465+
466+
contextMenu->addAction(QIcon::fromTheme(QStringLiteral("favorite")), tr("Add to favorites"), this,
467+
[this, index] {
468+
auto model = qobject_cast<const QSortFilterProxyModel*>(index.model());
469+
emit addToFavourites(model->mapToSource(index));
470+
});
471+
459472
if (isTimeSpanSelected && (minTime != timeSlice.start || maxTime != timeSlice.end)) {
460473
contextMenu->addAction(QIcon::fromTheme(QStringLiteral("zoom-in")), tr("Zoom In On Selection"), this,
461474
[this, timeSlice]() { m_filterAndZoomStack->zoomIn(timeSlice); });

src/models/timelinedelegate.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class TimeLineDelegate : public QStyledItemDelegate
6464

6565
signals:
6666
void stacksHovered(const QSet<qint32>& stacks);
67+
void addToFavourites(const QModelIndex& index);
6768

6869
protected:
6970
bool eventFilter(QObject* watched, QEvent* event) override;

src/timelinewidget.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ TimeLineWidget::TimeLineWidget(PerfParser* parser, QMenu* filterMenu, FilterAndZ
110110
m_timeLineDelegate->setEventType(typeId);
111111
});
112112

113+
connect(m_timeLineDelegate, &TimeLineDelegate::addToFavourites, this,
114+
[eventModel](const QModelIndex& index) { eventModel->addToFavourites(index); });
115+
113116
connect(m_timeLineDelegate, &TimeLineDelegate::stacksHovered, this, [this](const QSet<qint32>& stackIds) {
114117
if (stackIds.isEmpty()) {
115118
++m_currentHoverStacksJobId;

tests/modeltests/tst_models.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ private slots:
537537
model.setData(events);
538538

539539
QCOMPARE(model.columnCount(), static_cast<int>(EventModel::NUM_COLUMNS));
540-
QCOMPARE(model.rowCount(), 2);
540+
QCOMPARE(model.rowCount(), 4);
541541

542542
auto simplifiedEvents = events;
543543
simplifiedEvents.cpus.remove(1);

0 commit comments

Comments
 (0)