2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2017-08-15 18:44:18 +02:00
|
|
|
|
2016-12-19 18:47:06 +01:00
|
|
|
#include "qmlprofilertextmark.h"
|
2017-08-15 18:44:18 +02:00
|
|
|
|
2016-12-19 18:47:06 +01:00
|
|
|
#include "qmlprofilerconstants.h"
|
2017-08-15 18:44:18 +02:00
|
|
|
#include "qmlprofilerviewmanager.h"
|
|
|
|
|
#include "qmlprofilerstatisticsview.h"
|
2023-01-09 13:14:39 +01:00
|
|
|
#include "qmlprofilertr.h"
|
2016-12-19 18:47:06 +01:00
|
|
|
|
2017-05-29 16:04:31 +02:00
|
|
|
#include <QLabel>
|
2016-12-19 18:47:06 +01:00
|
|
|
#include <QLayout>
|
2017-05-29 16:04:31 +02:00
|
|
|
#include <QPainter>
|
2016-12-19 18:47:06 +01:00
|
|
|
|
2018-05-02 15:02:00 +02:00
|
|
|
using namespace Utils;
|
|
|
|
|
|
2016-12-19 18:47:06 +01:00
|
|
|
namespace QmlProfiler {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2017-08-15 18:44:18 +02:00
|
|
|
QmlProfilerTextMark::QmlProfilerTextMark(QmlProfilerViewManager *viewManager, int typeId,
|
2022-04-27 11:02:16 +02:00
|
|
|
const FilePath &fileName, int lineNumber)
|
2023-01-09 13:14:39 +01:00
|
|
|
: TextMark(fileName, lineNumber, {Tr::tr("QML Profiler"), Constants::TEXT_MARK_CATEGORY})
|
2022-04-27 11:02:16 +02:00
|
|
|
, m_viewManager(viewManager)
|
2016-12-19 18:47:06 +01:00
|
|
|
{
|
2022-04-27 11:02:16 +02:00
|
|
|
addTypeId(typeId);
|
2016-12-19 18:47:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QmlProfilerTextMark::addTypeId(int typeId)
|
|
|
|
|
{
|
|
|
|
|
m_typeIds.append(typeId);
|
|
|
|
|
|
2019-01-28 09:10:46 +01:00
|
|
|
const QmlProfilerStatisticsView *statisticsView = m_viewManager->statisticsView();
|
|
|
|
|
QTC_ASSERT(statisticsView, return);
|
|
|
|
|
|
2022-04-27 11:02:16 +02:00
|
|
|
setLineAnnotation(statisticsView->summary(m_typeIds));
|
2016-12-19 18:47:06 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QmlProfilerTextMarkModel::QmlProfilerTextMarkModel(QObject *parent) : QObject(parent)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QmlProfilerTextMarkModel::~QmlProfilerTextMarkModel()
|
|
|
|
|
{
|
|
|
|
|
qDeleteAll(m_marks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QmlProfilerTextMarkModel::clear()
|
|
|
|
|
{
|
|
|
|
|
qDeleteAll(m_marks);
|
|
|
|
|
m_marks.clear();
|
|
|
|
|
m_ids.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QmlProfilerTextMarkModel::addTextMarkId(int typeId, const QmlEventLocation &location)
|
|
|
|
|
{
|
|
|
|
|
m_ids.insert(location.filename(), {typeId, location.line(), location.column()});
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-15 18:44:18 +02:00
|
|
|
void QmlProfilerTextMarkModel::createMarks(QmlProfilerViewManager *viewManager,
|
|
|
|
|
const QString &fileName)
|
2016-12-19 18:47:06 +01:00
|
|
|
{
|
|
|
|
|
auto first = m_ids.find(fileName);
|
|
|
|
|
QVarLengthArray<TextMarkId> ids;
|
|
|
|
|
|
|
|
|
|
for (auto it = first; it != m_ids.end() && it.key() == fileName;) {
|
|
|
|
|
ids.append({it->typeId, it->lineNumber > 0 ? it->lineNumber : 1, it->columnNumber});
|
|
|
|
|
it = m_ids.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::sort(ids.begin(), ids.end(), [](const TextMarkId &a, const TextMarkId &b) {
|
|
|
|
|
return (a.lineNumber == b.lineNumber) ? (a.columnNumber < b.columnNumber)
|
|
|
|
|
: (a.lineNumber < b.lineNumber);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
int lineNumber = -1;
|
2018-11-24 12:14:44 +01:00
|
|
|
for (const auto &id : ids) {
|
|
|
|
|
if (id.lineNumber == lineNumber) {
|
|
|
|
|
m_marks.last()->addTypeId(id.typeId);
|
2016-12-19 18:47:06 +01:00
|
|
|
} else {
|
2018-11-24 12:14:44 +01:00
|
|
|
lineNumber = id.lineNumber;
|
2018-05-02 15:02:00 +02:00
|
|
|
m_marks << new QmlProfilerTextMark(viewManager,
|
2018-11-24 12:14:44 +01:00
|
|
|
id.typeId,
|
2019-05-28 13:49:26 +02:00
|
|
|
FilePath::fromString(fileName),
|
2018-11-24 12:14:44 +01:00
|
|
|
id.lineNumber);
|
2016-12-19 18:47:06 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-05-29 18:04:07 +02:00
|
|
|
void QmlProfilerTextMarkModel::showTextMarks()
|
|
|
|
|
{
|
2022-10-07 14:46:06 +02:00
|
|
|
for (QmlProfilerTextMark *mark : std::as_const(m_marks))
|
2018-05-29 18:04:07 +02:00
|
|
|
mark->setVisible(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void QmlProfilerTextMarkModel::hideTextMarks()
|
|
|
|
|
{
|
2022-10-07 14:46:06 +02:00
|
|
|
for (QmlProfilerTextMark *mark : std::as_const(m_marks))
|
2018-05-29 18:04:07 +02:00
|
|
|
mark->setVisible(false);
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-20 08:28:10 +02:00
|
|
|
bool QmlProfilerTextMark::addToolTipContent(QLayout *target) const
|
2016-12-19 18:47:06 +01:00
|
|
|
{
|
2019-01-28 09:10:46 +01:00
|
|
|
const QmlProfilerStatisticsView *statisticsView = m_viewManager->statisticsView();
|
|
|
|
|
QTC_ASSERT(statisticsView, return false);
|
|
|
|
|
|
2018-11-24 12:14:44 +01:00
|
|
|
auto layout = new QGridLayout;
|
2016-12-19 18:47:06 +01:00
|
|
|
layout->setHorizontalSpacing(10);
|
|
|
|
|
for (int row = 0, rowEnd = m_typeIds.length(); row != rowEnd; ++row) {
|
2022-04-27 11:02:16 +02:00
|
|
|
int typeId = m_typeIds[row];
|
2019-01-28 09:10:46 +01:00
|
|
|
const QStringList typeDetails = statisticsView->details(m_typeIds[row]);
|
2016-12-19 18:47:06 +01:00
|
|
|
for (int column = 0, columnEnd = typeDetails.length(); column != columnEnd; ++column) {
|
|
|
|
|
QLabel *label = new QLabel;
|
|
|
|
|
label->setAlignment(column == columnEnd - 1 ? Qt::AlignRight : Qt::AlignLeft);
|
2022-04-27 11:02:16 +02:00
|
|
|
if (column == 0) {
|
|
|
|
|
label->setTextFormat(Qt::RichText);
|
|
|
|
|
label->setTextInteractionFlags(Qt::LinksAccessibleByMouse
|
|
|
|
|
| Qt::LinksAccessibleByKeyboard);
|
|
|
|
|
label->setText(QString("<a href='selectType' style='text-decoration:none'>%1</a>")
|
|
|
|
|
.arg(typeDetails[column]));
|
|
|
|
|
QObject::connect(label,
|
|
|
|
|
&QLabel::linkActivated,
|
|
|
|
|
m_viewManager,
|
|
|
|
|
[this, typeId]() {
|
|
|
|
|
emit m_viewManager->typeSelected(typeId);
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
label->setTextFormat(Qt::PlainText);
|
|
|
|
|
label->setText(typeDetails[column]);
|
|
|
|
|
}
|
2016-12-19 18:47:06 +01:00
|
|
|
layout->addWidget(label, row, column);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
target->addItem(layout);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace QmlProfiler
|
|
|
|
|
|
|
|
|
|
|