2013-08-08 13:28:08 +02:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2014-01-07 13:27:11 +01:00
|
|
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
2013-08-08 13:28:08 +02:00
|
|
|
** Contact: http://www.qt-project.org/legal
|
|
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator.
|
|
|
|
|
**
|
|
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Digia. For licensing terms and
|
|
|
|
|
** conditions see http://qt.digia.com/licensing. For further information
|
|
|
|
|
** use the contact form at http://qt.digia.com/contact-us.
|
|
|
|
|
**
|
|
|
|
|
** GNU Lesser General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
|
|
|
**
|
|
|
|
|
** In addition, as a special exception, Digia gives you certain additional
|
|
|
|
|
** rights. These rights are described in the Digia Qt LGPL Exception
|
|
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "qmlprofilertimelinemodelproxy.h"
|
|
|
|
|
#include "qmlprofilermodelmanager.h"
|
2014-02-18 17:32:20 +01:00
|
|
|
#include "qmlprofilerdatamodel.h"
|
2013-12-04 16:05:02 +01:00
|
|
|
#include "sortedtimelinemodel.h"
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
|
#include <QVector>
|
|
|
|
|
#include <QHash>
|
|
|
|
|
#include <QUrl>
|
|
|
|
|
#include <QString>
|
|
|
|
|
#include <QStack>
|
|
|
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
|
|
|
|
|
|
namespace QmlProfiler {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
|
|
|
|
struct CategorySpan {
|
|
|
|
|
bool expanded;
|
|
|
|
|
int expandedRows;
|
|
|
|
|
int contractedRows;
|
|
|
|
|
int rowStart;
|
|
|
|
|
};
|
|
|
|
|
|
2013-12-04 16:05:02 +01:00
|
|
|
class BasicTimelineModel::BasicTimelineModelPrivate : public SortedTimelineModel<BasicTimelineModel::QmlRangeEventStartInstance>
|
2013-08-08 13:28:08 +02:00
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
// convenience functions
|
|
|
|
|
void prepare();
|
|
|
|
|
void computeNestingContracted();
|
|
|
|
|
void computeExpandedLevels();
|
|
|
|
|
void findBindingLoops();
|
|
|
|
|
void computeRowStarts();
|
|
|
|
|
|
|
|
|
|
QVector <BasicTimelineModel::QmlRangeEventData> eventDict;
|
|
|
|
|
QVector <QString> eventHashes;
|
|
|
|
|
QVector <CategorySpan> categorySpan;
|
2014-01-10 16:43:43 +01:00
|
|
|
bool seenPaintEvent;
|
2014-02-14 16:20:13 +01:00
|
|
|
private:
|
|
|
|
|
Q_DECLARE_PUBLIC(BasicTimelineModel)
|
2013-08-08 13:28:08 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
BasicTimelineModel::BasicTimelineModel(QObject *parent)
|
2014-02-14 16:20:13 +01:00
|
|
|
: AbstractTimelineModel(new BasicTimelineModelPrivate, QLatin1String("BasicTimelineModel"),
|
|
|
|
|
parent)
|
2013-08-08 13:28:08 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::clear()
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(BasicTimelineModel);
|
2013-12-04 16:05:02 +01:00
|
|
|
d->SortedTimelineModel::clear();
|
2013-08-08 13:28:08 +02:00
|
|
|
d->eventDict.clear();
|
|
|
|
|
d->eventHashes.clear();
|
|
|
|
|
d->categorySpan.clear();
|
2014-01-10 16:43:43 +01:00
|
|
|
d->seenPaintEvent = false;
|
2013-08-08 13:28:08 +02:00
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::BasicTimelineModelPrivate::prepare()
|
|
|
|
|
{
|
|
|
|
|
categorySpan.clear();
|
|
|
|
|
for (int i = 0; i < QmlDebug::MaximumQmlEventType; i++) {
|
2014-01-10 16:43:43 +01:00
|
|
|
CategorySpan newCategory = {false, 1, 1, i};
|
2013-08-08 13:28:08 +02:00
|
|
|
categorySpan << newCategory;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-02-18 17:32:20 +01:00
|
|
|
bool BasicTimelineModel::eventAccepted(const QmlProfilerDataModel::QmlEventData &event) const
|
2013-08-08 13:28:08 +02:00
|
|
|
{
|
|
|
|
|
// only accept Qt4.x Painting events
|
|
|
|
|
if (event.eventType == QmlDebug::Painting)
|
2014-01-10 16:43:43 +01:00
|
|
|
return (event.bindingType == QmlDebug::QPainterEvent);
|
2013-08-08 13:28:08 +02:00
|
|
|
|
2014-02-10 11:32:56 +01:00
|
|
|
return (event.eventType <= QmlDebug::Javascript);
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::loadData()
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
clear();
|
2014-02-18 17:32:20 +01:00
|
|
|
QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel();
|
2013-08-08 13:28:08 +02:00
|
|
|
if (simpleModel->isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int lastEventId = 0;
|
|
|
|
|
|
|
|
|
|
d->prepare();
|
|
|
|
|
|
|
|
|
|
// collect events
|
2014-02-18 17:32:20 +01:00
|
|
|
const QVector<QmlProfilerDataModel::QmlEventData> eventList = simpleModel->getEvents();
|
|
|
|
|
foreach (const QmlProfilerDataModel::QmlEventData &event, eventList) {
|
2013-08-08 13:28:08 +02:00
|
|
|
if (!eventAccepted(event))
|
|
|
|
|
continue;
|
2014-01-10 16:43:43 +01:00
|
|
|
if (event.eventType == QmlDebug::Painting)
|
|
|
|
|
d->seenPaintEvent = true;
|
2013-08-08 13:28:08 +02:00
|
|
|
|
2014-02-18 17:32:20 +01:00
|
|
|
QString eventHash = QmlProfilerDataModel::getHashString(event);
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
// store in dictionary
|
|
|
|
|
if (!d->eventHashes.contains(eventHash)) {
|
|
|
|
|
QmlRangeEventData rangeEventData = {
|
|
|
|
|
event.displayName,
|
|
|
|
|
event.data.join(QLatin1String(" ")),
|
|
|
|
|
event.location,
|
|
|
|
|
(QmlDebug::QmlEventType)event.eventType,
|
|
|
|
|
lastEventId++ // event id
|
|
|
|
|
};
|
|
|
|
|
d->eventDict << rangeEventData;
|
|
|
|
|
d->eventHashes << eventHash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// store starttime-based instance
|
2013-12-04 16:05:02 +01:00
|
|
|
d->insert(event.startTime, event.duration, QmlRangeEventStartInstance(d->eventHashes.indexOf(eventHash)));
|
|
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, d->count(), eventList.count() * 6);
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, 2, 6);
|
2013-08-08 13:28:08 +02:00
|
|
|
|
2013-12-04 16:05:02 +01:00
|
|
|
// compute range nesting
|
|
|
|
|
d->computeNesting();
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
// compute nestingLevel - nonexpanded
|
|
|
|
|
d->computeNestingContracted();
|
|
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, 3, 6);
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
// compute nestingLevel - expanded
|
|
|
|
|
d->computeExpandedLevels();
|
|
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, 4, 6);
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
d->findBindingLoops();
|
|
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, 5, 6);
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
d->computeRowStarts();
|
|
|
|
|
|
2014-02-14 16:20:13 +01:00
|
|
|
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::BasicTimelineModelPrivate::computeNestingContracted()
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_Q(BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
int i;
|
2013-12-04 16:05:02 +01:00
|
|
|
int eventCount = count();
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
QList<int> nestingLevels;
|
|
|
|
|
QList< QHash<int, qint64> > endtimesPerNestingLevel;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < QmlDebug::MaximumQmlEventType; i++) {
|
|
|
|
|
nestingLevels << QmlDebug::Constants::QML_MIN_LEVEL;
|
|
|
|
|
QHash<int, qint64> dummyHash;
|
|
|
|
|
dummyHash[QmlDebug::Constants::QML_MIN_LEVEL] = 0;
|
|
|
|
|
endtimesPerNestingLevel << dummyHash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < eventCount; i++) {
|
2013-12-04 16:05:02 +01:00
|
|
|
qint64 st = ranges[i].start;
|
2013-08-08 13:28:08 +02:00
|
|
|
int type = q->getEventType(i);
|
|
|
|
|
|
|
|
|
|
// per type
|
|
|
|
|
if (endtimesPerNestingLevel[type][nestingLevels[type]] > st) {
|
|
|
|
|
nestingLevels[type]++;
|
|
|
|
|
} else {
|
|
|
|
|
while (nestingLevels[type] > QmlDebug::Constants::QML_MIN_LEVEL &&
|
|
|
|
|
endtimesPerNestingLevel[type][nestingLevels[type]-1] <= st)
|
|
|
|
|
nestingLevels[type]--;
|
|
|
|
|
}
|
|
|
|
|
endtimesPerNestingLevel[type][nestingLevels[type]] =
|
2013-12-04 16:05:02 +01:00
|
|
|
st + ranges[i].duration;
|
2013-08-08 13:28:08 +02:00
|
|
|
|
2013-12-04 16:05:02 +01:00
|
|
|
ranges[i].displayRowCollapsed = nestingLevels[type];
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nestingdepth
|
|
|
|
|
for (i = 0; i < eventCount; i++) {
|
|
|
|
|
int eventType = q->getEventType(i);
|
2013-12-04 16:05:02 +01:00
|
|
|
if (categorySpan[eventType].contractedRows <= ranges[i].displayRowCollapsed)
|
|
|
|
|
categorySpan[eventType].contractedRows = ranges[i].displayRowCollapsed + 1;
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::BasicTimelineModelPrivate::computeExpandedLevels()
|
|
|
|
|
{
|
|
|
|
|
QHash<int, int> eventRow;
|
2013-12-04 16:05:02 +01:00
|
|
|
int eventCount = count();
|
2013-08-08 13:28:08 +02:00
|
|
|
for (int i = 0; i < eventCount; i++) {
|
2013-12-04 16:05:02 +01:00
|
|
|
int eventId = ranges[i].eventId;
|
2013-08-08 13:28:08 +02:00
|
|
|
int eventType = eventDict[eventId].eventType;
|
|
|
|
|
if (!eventRow.contains(eventId)) {
|
|
|
|
|
eventRow[eventId] = categorySpan[eventType].expandedRows++;
|
|
|
|
|
}
|
2013-12-04 16:05:02 +01:00
|
|
|
ranges[i].displayRowExpanded = eventRow[eventId];
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::BasicTimelineModelPrivate::findBindingLoops()
|
|
|
|
|
{
|
|
|
|
|
typedef QPair<QString, int> CallStackEntry;
|
|
|
|
|
QStack<CallStackEntry> callStack;
|
|
|
|
|
|
2013-12-04 16:05:02 +01:00
|
|
|
for (int i = 0; i < count(); ++i) {
|
|
|
|
|
Range *event = &ranges[i];
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
BasicTimelineModel::QmlRangeEventData data = eventDict.at(event->eventId);
|
|
|
|
|
|
|
|
|
|
static QVector<QmlDebug::QmlEventType> acceptedTypes =
|
2014-02-19 11:42:38 +01:00
|
|
|
QVector<QmlDebug::QmlEventType>() << QmlDebug::Binding << QmlDebug::HandlingSignal;
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
if (!acceptedTypes.contains(data.eventType))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
const QString eventHash = eventHashes.at(event->eventId);
|
2013-12-04 16:05:02 +01:00
|
|
|
const Range *potentialParent = callStack.isEmpty()
|
|
|
|
|
? 0 : &ranges[callStack.top().second];
|
2013-08-08 13:28:08 +02:00
|
|
|
|
|
|
|
|
while (potentialParent
|
2013-12-04 16:05:02 +01:00
|
|
|
&& !(potentialParent->start + potentialParent->duration > event->start)) {
|
2013-08-08 13:28:08 +02:00
|
|
|
callStack.pop();
|
|
|
|
|
potentialParent = callStack.isEmpty() ? 0
|
2013-12-04 16:05:02 +01:00
|
|
|
: &ranges[callStack.top().second];
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// check whether event is already in stack
|
|
|
|
|
for (int ii = 0; ii < callStack.size(); ++ii) {
|
|
|
|
|
if (callStack.at(ii).first == eventHash) {
|
|
|
|
|
event->bindingLoopHead = callStack.at(ii).second;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CallStackEntry newEntry(eventHash, i);
|
|
|
|
|
callStack.push(newEntry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::BasicTimelineModelPrivate::computeRowStarts()
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_Q(BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
int rowStart = 0;
|
|
|
|
|
for (int i = 0; i < categorySpan.count(); i++) {
|
|
|
|
|
categorySpan[i].rowStart = rowStart;
|
|
|
|
|
rowStart += q->categoryDepth(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////// QML interface
|
|
|
|
|
|
|
|
|
|
bool BasicTimelineModel::expanded(int category) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
if (d->categorySpan.count() <= category)
|
|
|
|
|
return false;
|
|
|
|
|
return d->categorySpan[category].expanded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BasicTimelineModel::setExpanded(int category, bool expanded)
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
if (d->categorySpan.count() <= category)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
d->categorySpan[category].expanded = expanded;
|
|
|
|
|
d->computeRowStarts();
|
|
|
|
|
emit expandedChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::categoryDepth(int categoryIndex) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
// special for paint events: show only when empty model or there's actual events
|
2014-01-10 16:43:43 +01:00
|
|
|
if (categoryIndex == QmlDebug::Painting && !d->seenPaintEvent)
|
2013-08-08 13:28:08 +02:00
|
|
|
return 0;
|
2014-01-10 16:43:43 +01:00
|
|
|
if (d->categorySpan.count() <= categoryIndex)
|
|
|
|
|
return 1;
|
2013-08-08 13:28:08 +02:00
|
|
|
if (d->categorySpan[categoryIndex].expanded)
|
|
|
|
|
return d->categorySpan[categoryIndex].expandedRows;
|
|
|
|
|
else
|
|
|
|
|
return d->categorySpan[categoryIndex].contractedRows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::categoryCount() const
|
|
|
|
|
{
|
2014-02-10 11:32:56 +01:00
|
|
|
return 6;
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QString BasicTimelineModel::categoryLabel(int categoryIndex) const
|
|
|
|
|
{
|
|
|
|
|
switch (categoryIndex) {
|
|
|
|
|
case 0: return QCoreApplication::translate("MainView", "Painting"); break;
|
|
|
|
|
case 1: return QCoreApplication::translate("MainView", "Compiling"); break;
|
|
|
|
|
case 2: return QCoreApplication::translate("MainView", "Creating"); break;
|
|
|
|
|
case 3: return QCoreApplication::translate("MainView", "Binding"); break;
|
|
|
|
|
case 4: return QCoreApplication::translate("MainView", "Handling Signal"); break;
|
2014-02-10 11:32:56 +01:00
|
|
|
case 5: return QCoreApplication::translate("MainView", "Javascript"); break;
|
2013-08-08 13:28:08 +02:00
|
|
|
default: return QString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getEventType(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-12-04 16:05:02 +01:00
|
|
|
return d->eventDict[d->range(index).eventId].eventType;
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getEventCategory(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
int evTy = getEventType(index);
|
|
|
|
|
// special: paint events shown?
|
2014-01-10 16:43:43 +01:00
|
|
|
if (!d->seenPaintEvent)
|
2013-08-08 13:28:08 +02:00
|
|
|
return evTy - 1;
|
|
|
|
|
return evTy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getEventRow(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
if (d->categorySpan[getEventType(index)].expanded)
|
2013-12-04 16:05:02 +01:00
|
|
|
return d->range(index).displayRowExpanded + d->categorySpan[getEventType(index)].rowStart;
|
2013-08-08 13:28:08 +02:00
|
|
|
else
|
2013-12-04 16:05:02 +01:00
|
|
|
return d->range(index).displayRowCollapsed + d->categorySpan[getEventType(index)].rowStart;
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getEventId(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-12-04 16:05:02 +01:00
|
|
|
return d->range(index).eventId;
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getBindingLoopDest(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-12-04 16:05:02 +01:00
|
|
|
return d->range(index).bindingLoopHead;
|
2013-08-08 13:28:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QColor BasicTimelineModel::getColor(int index) const
|
|
|
|
|
{
|
|
|
|
|
int ndx = getEventId(index);
|
|
|
|
|
return QColor::fromHsl((ndx*25)%360, 76, 166);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVariantList BasicTimelineModel::getLabelsForCategory(int category) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
QVariantList result;
|
|
|
|
|
|
|
|
|
|
if (d->categorySpan.count() > category && d->categorySpan[category].expanded) {
|
|
|
|
|
int eventCount = d->eventDict.count();
|
|
|
|
|
for (int i = 0; i < eventCount; i++) {
|
|
|
|
|
if (d->eventDict[i].eventType == category) {
|
|
|
|
|
QVariantMap element;
|
|
|
|
|
element.insert(QLatin1String("displayName"), QVariant(d->eventDict[i].displayName));
|
|
|
|
|
element.insert(QLatin1String("description"), QVariant(d->eventDict[i].details));
|
|
|
|
|
element.insert(QLatin1String("id"), QVariant(d->eventDict[i].eventId));
|
|
|
|
|
result << element;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVariantList BasicTimelineModel::getEventDetails(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
QVariantList result;
|
|
|
|
|
int eventId = getEventId(index);
|
|
|
|
|
|
|
|
|
|
static const char trContext[] = "RangeDetails";
|
|
|
|
|
{
|
|
|
|
|
QVariantMap valuePair;
|
|
|
|
|
valuePair.insert(QLatin1String("title"), QVariant(categoryLabel(d->eventDict[eventId].eventType)));
|
|
|
|
|
result << valuePair;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// duration
|
|
|
|
|
{
|
|
|
|
|
QVariantMap valuePair;
|
2014-02-14 17:01:24 +01:00
|
|
|
valuePair.insert(QCoreApplication::translate(trContext, "Duration:"),
|
2014-02-18 17:32:20 +01:00
|
|
|
QVariant(QmlProfilerBaseModel::formatTime(d->range(index).duration)));
|
2013-08-08 13:28:08 +02:00
|
|
|
result << valuePair;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// details
|
|
|
|
|
{
|
|
|
|
|
QVariantMap valuePair;
|
|
|
|
|
QString detailsString = d->eventDict[eventId].details;
|
|
|
|
|
if (detailsString.length() > 40)
|
|
|
|
|
detailsString = detailsString.left(40) + QLatin1String("...");
|
|
|
|
|
valuePair.insert(QCoreApplication::translate(trContext, "Details:"), QVariant(detailsString));
|
|
|
|
|
result << valuePair;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// location
|
|
|
|
|
{
|
|
|
|
|
QVariantMap valuePair;
|
|
|
|
|
valuePair.insert(QCoreApplication::translate(trContext, "Location:"), QVariant(d->eventDict[eventId].displayName));
|
|
|
|
|
result << valuePair;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// isbindingloop
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const QVariantMap BasicTimelineModel::getEventLocation(int index) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
QVariantMap result;
|
|
|
|
|
int eventId = getEventId(index);
|
|
|
|
|
|
|
|
|
|
QmlDebug::QmlEventLocation location
|
|
|
|
|
= d->eventDict.at(eventId).location;
|
|
|
|
|
|
|
|
|
|
result.insert(QLatin1String("file"), location.filename);
|
|
|
|
|
result.insert(QLatin1String("line"), location.line);
|
|
|
|
|
result.insert(QLatin1String("column"), location.column);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getEventIdForHash(const QString &eventHash) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
return d->eventHashes.indexOf(eventHash);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BasicTimelineModel::getEventIdForLocation(const QString &filename, int line, int column) const
|
|
|
|
|
{
|
2014-02-14 16:20:13 +01:00
|
|
|
Q_D(const BasicTimelineModel);
|
2013-08-08 13:28:08 +02:00
|
|
|
// if this is called from v8 view, we don't have the column number, it will be -1
|
|
|
|
|
foreach (const QmlRangeEventData &eventData, d->eventDict) {
|
|
|
|
|
if (eventData.location.filename == filename &&
|
|
|
|
|
eventData.location.line == line &&
|
|
|
|
|
(column == -1 || eventData.location.column == column))
|
|
|
|
|
return eventData.eventId;
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|