Skip to content

Commit e481527

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 2955100 commit e481527

File tree

6 files changed

+82
-7
lines changed

6 files changed

+82
-7
lines changed

src/models/eventmodel.cpp

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,19 @@ enum class Tag : quint8
2929
Processes,
3030
Threads,
3131
Tracepoints,
32+
Favorites,
3233
};
3334

3435
enum OverViewRow : quint8
3536
{
3637
Cpu_Row,
3738
Process_Row,
3839
Tracepoint_Row,
40+
Favorite_Row,
3941
};
40-
constexpr auto numRows = Tracepoint_Row + 1;
42+
constexpr auto numRows = Favorite_Row + 1;
4143

42-
constexpr auto LAST_TAG = Tag::Tracepoints;
44+
constexpr auto LAST_TAG = Tag::Favorites;
4345

4446
const auto DATATAG_SHIFT = sizeof(Tag) * 8;
4547
const auto DATATAG_UNSHIFT = (sizeof(quintptr) - sizeof(Tag)) * 8;
@@ -93,6 +95,7 @@ int EventModel::rowCount(const QModelIndex& parent) const
9395
case Tag::Cpus:
9496
case Tag::Threads:
9597
case Tag::Tracepoints:
98+
case Tag::Favorites:
9699
return 0;
97100
break;
98101
case Tag::Processes:
@@ -105,6 +108,8 @@ int EventModel::rowCount(const QModelIndex& parent) const
105108
return m_processes.size();
106109
case OverViewRow::Tracepoint_Row:
107110
return m_data.tracepoints.size();
111+
case OverViewRow::Favorite_Row:
112+
return m_favourites.size();
108113
default:
109114
Q_UNREACHABLE();
110115
}
@@ -173,6 +178,8 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
173178
return tr("Processes");
174179
case OverViewRow::Tracepoint_Row:
175180
return tr("Tracepoints");
181+
case 3:
182+
return tr("Favorites");
176183
}
177184
} else if (role == Qt::ToolTipRole) {
178185
switch (static_cast<OverViewRow>(index.row())) {
@@ -183,6 +190,8 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
183190
return tr("Event timelines for the individual threads and processes.");
184191
case OverViewRow::Tracepoint_Row:
185192
return tr("Event timelines for tracepoints");
193+
case OverViewRow::Favorite_Row:
194+
return tr("A list of favourites to group important events");
186195
}
187196
} else if (role == SortRole) {
188197
return index.row();
@@ -250,6 +259,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
250259
Q_ASSERT(thread);
251260
} else if (tag == Tag::Tracepoints) {
252261
tracepoint = &m_data.tracepoints[index.row()];
262+
} else if (tag == Tag::Favorites) {
263+
auto& favourite = m_favourites[index.row()];
264+
return data(favourite, role);
253265
}
254266

255267
if (role == ThreadStartRole) {
@@ -263,6 +275,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
263275
case Tag::Processes:
264276
case Tag::Tracepoints:
265277
return m_time.start;
278+
case Tag::Favorites:
279+
// there are handled elsewhere
280+
Q_UNREACHABLE();
266281
}
267282
} else if (role == ThreadEndRole) {
268283
switch (tag) {
@@ -275,6 +290,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
275290
case Tag::Processes:
276291
case Tag::Tracepoints:
277292
return m_time.end;
293+
case Tag::Favorites:
294+
// there are handled elsewhere
295+
Q_UNREACHABLE();
278296
}
279297
} else if (role == ThreadNameRole) {
280298
switch (tag) {
@@ -288,6 +306,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
288306
case Tag::Processes:
289307
case Tag::Tracepoints:
290308
return {};
309+
case Tag::Favorites:
310+
// there are handled elsewhere
311+
Q_UNREACHABLE();
291312
}
292313
} else if (role == ThreadIdRole) {
293314
switch (tag) {
@@ -300,6 +321,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
300321
case Tag::Processes:
301322
case Tag::Tracepoints:
302323
return Data::INVALID_TID;
324+
case Tag::Favorites:
325+
// there are handled elsewhere
326+
Q_UNREACHABLE();
303327
}
304328
} else if (role == ProcessIdRole) {
305329
switch (tag) {
@@ -312,6 +336,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
312336
case Tag::Processes:
313337
case Tag::Tracepoints:
314338
return Data::INVALID_PID;
339+
case Tag::Favorites:
340+
// there are handled elsewhere
341+
Q_UNREACHABLE();
315342
}
316343
} else if (role == CpuIdRole) {
317344
switch (tag) {
@@ -324,6 +351,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
324351
case Tag::Threads:
325352
case Tag::Tracepoints:
326353
return Data::INVALID_CPU_ID;
354+
case Tag::Favorites:
355+
// there are handled elsewhere
356+
Q_UNREACHABLE();
327357
}
328358
} else if (role == EventsRole) {
329359
switch (tag) {
@@ -338,6 +368,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
338368
case Tag::Overview:
339369
case Tag::Processes:
340370
return QVariant::fromValue(Data::Events());
371+
case Tag::Favorites:
372+
// there are handled elsewhere
373+
Q_UNREACHABLE();
341374
}
342375
} else if (role == SortRole) {
343376
if (index.column() == ThreadColumn) {
@@ -353,6 +386,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
353386
case Tag::Overview:
354387
case Tag::Processes:
355388
return {};
389+
case Tag::Favorites:
390+
// there are handled elsewhere
391+
Q_UNREACHABLE();
356392
}
357393
} else {
358394
switch (tag) {
@@ -367,6 +403,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
367403
case Tag::Overview:
368404
case Tag::Processes:
369405
return {};
406+
case Tag::Favorites:
407+
// there are handled elsewhere
408+
Q_UNREACHABLE();
370409
}
371410
}
372411
}
@@ -386,6 +425,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
386425
case Tag::Overview:
387426
case Tag::Processes:
388427
return {};
428+
case Tag::Favorites:
429+
// there are handled elsewhere
430+
Q_UNREACHABLE();
389431
}
390432
} else if (role == Qt::ToolTipRole) {
391433
QString tooltip;
@@ -426,6 +468,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
426468
case Tag::Overview:
427469
case Tag::Processes:
428470
break;
471+
case Tag::Favorites:
472+
// there are handled elsewhere
473+
Q_UNREACHABLE();
429474
}
430475

431476
tooltip += tr("Number of Events: %1 (%2% of the total)")
@@ -447,6 +492,9 @@ QVariant EventModel::data(const QModelIndex& index, int role) const
447492
case Tag::Overview:
448493
case Tag::Processes:
449494
return {};
495+
case Tag::Favorites:
496+
// there are handled elsewhere
497+
Q_UNREACHABLE();
450498
}
451499
}
452500
break;
@@ -521,6 +569,7 @@ QModelIndex EventModel::index(int row, int column, const QModelIndex& parent) co
521569
case Tag::Cpus:
522570
case Tag::Tracepoints:
523571
case Tag::Threads:
572+
case Tag::Favorites:
524573
break;
525574
case Tag::Root: // root has the 1st level children: Overview
526575
return createIndex(row, column, static_cast<quintptr>(Tag::Overview));
@@ -532,8 +581,8 @@ QModelIndex EventModel::index(int row, int column, const QModelIndex& parent) co
532581
return createIndex(row, column, static_cast<quintptr>(Tag::Processes));
533582
case OverViewRow::Tracepoint_Row:
534583
return createIndex(row, column, static_cast<quintptr>(Tag::Tracepoints));
535-
default:
536-
Q_UNREACHABLE();
584+
case OverViewRow::Favorite_Row:
585+
return createIndex(row, column, static_cast<quintptr>(Tag::Favorites));
537586
}
538587
case Tag::Processes: // 3rd level children: Threads
539588
return createIndex(row, column, combineDataTag(Tag::Threads, parent.row()));
@@ -555,11 +604,20 @@ QModelIndex EventModel::parent(const QModelIndex& child) const
555604
return createIndex(OverViewRow::Process_Row, 0, static_cast<quintptr>(Tag::Overview));
556605
case Tag::Tracepoints:
557606
return createIndex(OverViewRow::Tracepoint_Row, 0, static_cast<qintptr>(Tag::Overview));
558-
case Tag::Threads: {
607+
case Tag::Favorites:
608+
return createIndex(OverViewRow::Favorite_Row, 0, static_cast<qintptr>(Tag::Overview));
609+
case Tag::Threads:
559610
const auto parentRow = tagData(child.internalId());
560611
return createIndex(parentRow, 0, static_cast<quintptr>(Tag::Processes));
561612
}
562-
}
563613

564614
return {};
565615
}
616+
617+
void EventModel::addToFavourites(const QModelIndex& index)
618+
{
619+
const int position = m_favourites.size();
620+
beginInsertRows(createIndex(Favorite_Row, 0, static_cast<quintptr>(Tag::Overview)), position, position);
621+
m_favourites.push_back(index);
622+
endInsertRows();
623+
}

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: 9 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"
@@ -460,6 +461,14 @@ bool TimeLineDelegate::eventFilter(QObject* watched, QEvent* event)
460461
const auto isMainThread = threadStartTime == minTime && threadEndTime == maxTime;
461462
const auto cpuId = index.data(EventModel::CpuIdRole).value<quint32>();
462463
const auto numCpus = index.data(EventModel::NumCpusRole).value<uint>();
464+
465+
contextMenu->addAction(QIcon::fromTheme(QStringLiteral("favorite")), tr("Add to favorites"), this,
466+
[this, index] {
467+
auto model = qobject_cast<const QSortFilterProxyModel*>(index.model());
468+
Q_ASSERT(model);
469+
emit addToFavourites(model->mapToSource(index));
470+
});
471+
463472
if (isTimeSpanSelected && (minTime != timeSlice.start || maxTime != timeSlice.end)) {
464473
contextMenu->addAction(QIcon::fromTheme(QStringLiteral("zoom-in")), tr("Zoom In On Selection"), this,
465474
[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)