QmlProfiler: Allow only one category per model in timeline

This simplifies the code a lot and allows for more flexibility
when interacting with the data.

Change-Id: I69630071eee66840e905fcd95ba8c708742d58b6
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Ulf Hermann
2014-06-06 17:36:11 +02:00
parent eef83495ea
commit accc92ae47
15 changed files with 135 additions and 334 deletions

View File

@@ -57,14 +57,6 @@ void AbstractTimelineModel::setModelManager(QmlProfilerModelManager *modelManage
d->modelId = d->modelManager->registerModelProxy(); d->modelId = d->modelManager->registerModelProxy();
} }
QStringList AbstractTimelineModel::categoryTitles() const
{
QStringList retString;
for (int i = 0; i < categoryCount(); i++)
retString << categoryLabel(i);
return retString;
}
QString AbstractTimelineModel::name() const QString AbstractTimelineModel::name() const
{ {
Q_D(const AbstractTimelineModel); Q_D(const AbstractTimelineModel);
@@ -169,14 +161,6 @@ int AbstractTimelineModel::getEventIdForLocation(const QString &filename, int li
return -1; return -1;
} }
int AbstractTimelineModel::rowCount() const
{
int count = 0;
for (int i=0; i<categoryCount(); i++)
count += categoryDepth(i);
return count;
}
int AbstractTimelineModel::getBindingLoopDest(int index) const int AbstractTimelineModel::getBindingLoopDest(int index) const
{ {
Q_UNUSED(index); Q_UNUSED(index);

View File

@@ -50,7 +50,6 @@ public:
// Trivial methods implemented by the abstract model itself // Trivial methods implemented by the abstract model itself
void setModelManager(QmlProfilerModelManager *modelManager); void setModelManager(QmlProfilerModelManager *modelManager);
QStringList categoryTitles() const;
QString name() const; QString name() const;
bool isEmpty() const; bool isEmpty() const;
@@ -60,7 +59,6 @@ public:
Q_INVOKABLE qint64 traceEndTime() const; Q_INVOKABLE qint64 traceEndTime() const;
Q_INVOKABLE qint64 traceDuration() const; Q_INVOKABLE qint64 traceDuration() const;
Q_INVOKABLE int getState() const; Q_INVOKABLE int getState() const;
Q_INVOKABLE int rowCount() const;
Q_INVOKABLE qint64 getDuration(int index) const; Q_INVOKABLE qint64 getDuration(int index) const;
Q_INVOKABLE qint64 getStartTime(int index) const; Q_INVOKABLE qint64 getStartTime(int index) const;
Q_INVOKABLE qint64 getEndTime(int index) const; Q_INVOKABLE qint64 getEndTime(int index) const;
@@ -70,17 +68,15 @@ public:
int count() const; int count() const;
// Methods that have to be implemented by child models // Methods that have to be implemented by child models
Q_INVOKABLE virtual bool expanded(int category) const = 0; virtual bool expanded() const = 0;
Q_INVOKABLE virtual void setExpanded(int category, bool expanded) = 0; virtual void setExpanded(bool expanded) = 0;
Q_INVOKABLE virtual int categoryDepth(int categoryIndex) const = 0; virtual int rowCount() const = 0;
Q_INVOKABLE virtual int categoryCount() const = 0; virtual const QString title() const = 0;
Q_INVOKABLE virtual const QString categoryLabel(int categoryIndex) const = 0;
Q_INVOKABLE virtual int getEventId(int index) const = 0; Q_INVOKABLE virtual int getEventId(int index) const = 0;
Q_INVOKABLE virtual QColor getColor(int index) const = 0; Q_INVOKABLE virtual QColor getColor(int index) const = 0;
Q_INVOKABLE virtual const QVariantList getLabelsForCategory(int category) const = 0; virtual const QVariantList getLabels() const = 0;
Q_INVOKABLE virtual const QVariantList getEventDetails(int index) const = 0; Q_INVOKABLE virtual const QVariantList getEventDetails(int index) const = 0;
virtual int getEventType(int index) const = 0; virtual int getEventType(int index) const = 0;
virtual int getEventCategory(int index) const = 0;
virtual int getEventRow(int index) const = 0; virtual int getEventRow(int index) const = 0;
virtual void loadData() = 0; virtual void loadData() = 0;
virtual void clear() = 0; virtual void clear() = 0;

View File

@@ -31,16 +31,15 @@ import QtQuick 2.1
Item { Item {
id: labelContainer id: labelContainer
property string text: qmlProfilerModelProxy.categoryLabel(modelIndex, categoryIndex) property string text: qmlProfilerModelProxy.title(modelIndex)
property bool expanded: false property bool expanded: false
property int categoryIndex: qmlProfilerModelProxy.correctedCategoryIndexForModel(modelIndex, index) property int modelIndex: index;
property int modelIndex: qmlProfilerModelProxy.modelIndexForCategory(index);
property var descriptions: [] property var descriptions: []
property var extdescriptions: [] property var extdescriptions: []
property var eventIds: [] property var eventIds: []
visible: qmlProfilerModelProxy.categoryDepth(modelIndex, categoryIndex) > 0; visible: qmlProfilerModelProxy.rowCount(modelIndex) > 0;
height: root.singleRowHeight height: root.singleRowHeight
width: 150 width: 150
@@ -50,18 +49,18 @@ Item {
} }
function updateHeight() { function updateHeight() {
height = root.singleRowHeight * qmlProfilerModelProxy.categoryDepth(modelIndex, categoryIndex); height = root.singleRowHeight * qmlProfilerModelProxy.rowCount(modelIndex);
} }
function getDescriptions() { function getDescriptions() {
visible = qmlProfilerModelProxy.categoryDepth(modelIndex, categoryIndex) > 0; visible = qmlProfilerModelProxy.rowCount(modelIndex) > 0;
if (!visible) if (!visible)
return; return;
var desc=[]; var desc=[];
var ids=[]; var ids=[];
var extdesc=[]; var extdesc=[];
var labelList = qmlProfilerModelProxy.getLabelsForCategory(modelIndex, categoryIndex); var labelList = qmlProfilerModelProxy.getLabels(modelIndex);
for (var i = 0; i < labelList.length; i++ ) { for (var i = 0; i < labelList.length; i++ ) {
desc[i] = labelList[i].description; desc[i] = labelList[i].description;
ids[i] = labelList[i].id; ids[i] = labelList[i].id;
@@ -76,7 +75,7 @@ Item {
Connections { Connections {
target: qmlProfilerModelProxy target: qmlProfilerModelProxy
onExpandedChanged: { onExpandedChanged: {
expanded = qmlProfilerModelProxy.expanded(modelIndex, categoryIndex); expanded = qmlProfilerModelProxy.expanded(modelIndex);
backgroundMarks.requestPaint(); backgroundMarks.requestPaint();
getDescriptions(); getDescriptions();
} }
@@ -155,7 +154,7 @@ Item {
onClicked: { onClicked: {
// Don't try to expand empty models. // Don't try to expand empty models.
if (expanded || qmlProfilerModelProxy.count(modelIndex) > 0) if (expanded || qmlProfilerModelProxy.count(modelIndex) > 0)
qmlProfilerModelProxy.setExpanded(modelIndex, categoryIndex, !expanded); qmlProfilerModelProxy.setExpanded(modelIndex, !expanded);
} }
} }
} }

View File

@@ -208,7 +208,7 @@ Rectangle {
color: root.color color: root.color
height: col.height height: col.height
property int rowCount: qmlProfilerModelProxy.categoryCount(); property int rowCount: qmlProfilerModelProxy.modelCount();
Column { Column {
id: col id: col

View File

@@ -48,13 +48,10 @@ function drawData(canvas, ctxt)
var bump = 10; var bump = 10;
var height = canvas.height - bump; var height = canvas.height - bump;
var typeCount = qmlProfilerModelProxy.visibleCategories(); var blockHeight = height / qmlProfilerModelProxy.modelCount();
var blockHeight = height / typeCount;
var spacing = width / qmlProfilerModelProxy.traceDuration(); var spacing = width / qmlProfilerModelProxy.traceDuration();
var modelRowStart = 0;
for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) { for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) {
for (var ii = canvas.offset; ii < qmlProfilerModelProxy.count(modelIndex); for (var ii = canvas.offset; ii < qmlProfilerModelProxy.count(modelIndex);
ii += canvas.increment) { ii += canvas.increment) {
@@ -69,22 +66,18 @@ function drawData(canvas, ctxt)
xx = Math.round(xx); xx = Math.round(xx);
var rowNumber = modelRowStart + qmlProfilerModelProxy.getEventCategoryInModel(modelIndex, ii);
var itemHeight = qmlProfilerModelProxy.getHeight(modelIndex,ii) * blockHeight; var itemHeight = qmlProfilerModelProxy.getHeight(modelIndex,ii) * blockHeight;
var yy = (rowNumber + 1) * blockHeight - itemHeight ; var yy = (modelIndex + 1) * blockHeight - itemHeight ;
ctxt.fillStyle = qmlProfilerModelProxy.getColor(modelIndex, ii); ctxt.fillStyle = qmlProfilerModelProxy.getColor(modelIndex, ii);
ctxt.fillRect(xx, bump + yy, eventWidth, itemHeight); ctxt.fillRect(xx, bump + yy, eventWidth, itemHeight);
} }
modelRowStart += qmlProfilerModelProxy.categoryCount(modelIndex);
} }
// binding loops // binding loops
ctxt.strokeStyle = "orange"; ctxt.strokeStyle = "orange";
ctxt.lineWidth = 2; ctxt.lineWidth = 2;
var radius = 1; var radius = 1;
modelRowStart = 0;
for (modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) { for (modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) {
for (ii = canvas.offset; ii < qmlProfilerModelProxy.count(modelIndex); for (ii = canvas.offset; ii < qmlProfilerModelProxy.count(modelIndex);
ii += canvas.increment) { ii += canvas.increment) {
@@ -92,15 +85,12 @@ function drawData(canvas, ctxt)
var xcenter = Math.round(qmlProfilerModelProxy.getStartTime(modelIndex,ii) + var xcenter = Math.round(qmlProfilerModelProxy.getStartTime(modelIndex,ii) +
qmlProfilerModelProxy.getDuration(modelIndex,ii) - qmlProfilerModelProxy.getDuration(modelIndex,ii) -
qmlProfilerModelProxy.traceStartTime()) * spacing; qmlProfilerModelProxy.traceStartTime()) * spacing;
var ycenter = Math.round(bump + (modelRowStart + var ycenter = Math.round(bump + blockHeight * modelIndex + blockHeight / 2);
qmlProfilerModelProxy.getEventCategoryInModel(modelIndex, ii)) *
blockHeight + blockHeight/2);
ctxt.beginPath(); ctxt.beginPath();
ctxt.arc(xcenter, ycenter, radius, 0, 2*Math.PI, true); ctxt.arc(xcenter, ycenter, radius, 0, 2*Math.PI, true);
ctxt.stroke(); ctxt.stroke();
} }
} }
modelRowStart += qmlProfilerModelProxy.categoryCount(modelIndex);
} }
} }

View File

@@ -114,8 +114,7 @@ Canvas {
// separators // separators
var cumulatedHeight = 0; var cumulatedHeight = 0;
for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount() && cumulatedHeight < y + height; modelIndex++) { for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount() && cumulatedHeight < y + height; modelIndex++) {
for (var i=0; i<qmlProfilerModelProxy.categoryCount(modelIndex); i++) { cumulatedHeight += root.singleRowHeight * qmlProfilerModelProxy.rowCount(modelIndex);
cumulatedHeight += root.singleRowHeight * qmlProfilerModelProxy.categoryDepth(modelIndex, i);
if (cumulatedHeight < y) if (cumulatedHeight < y)
continue; continue;
@@ -125,7 +124,6 @@ Canvas {
context.lineTo(width, cumulatedHeight - y); context.lineTo(width, cumulatedHeight - y);
context.stroke(); context.stroke();
} }
}
// bottom // bottom
if (height > labels.height - y) { if (height > labels.height - y) {

View File

@@ -149,9 +149,8 @@ void PaintEventsModelProxy::loadData()
/////////////////// QML interface /////////////////// QML interface
int PaintEventsModelProxy::categoryDepth(int categoryIndex) const int PaintEventsModelProxy::rowCount() const
{ {
Q_UNUSED(categoryIndex);
Q_D(const PaintEventsModelProxy); Q_D(const PaintEventsModelProxy);
if (isEmpty()) if (isEmpty())
return d->seenForeignPaintEvent ? 0 : 1; return d->seenForeignPaintEvent ? 0 : 1;
@@ -191,9 +190,8 @@ float PaintEventsModelProxy::getHeight(int index) const
d->maxGuiThreadAnimations : d->maxRenderThreadAnimations) * 0.85f + 0.15f; d->maxGuiThreadAnimations : d->maxRenderThreadAnimations) * 0.85f + 0.15f;
} }
const QVariantList PaintEventsModelProxy::getLabelsForCategory(int category) const const QVariantList PaintEventsModelProxy::getLabels() const
{ {
Q_UNUSED(category);
Q_D(const PaintEventsModelProxy); Q_D(const PaintEventsModelProxy);
QVariantList result; QVariantList result;
@@ -224,7 +222,7 @@ const QVariantList PaintEventsModelProxy::getEventDetails(int index) const
static const char trContext[] = "RangeDetails"; static const char trContext[] = "RangeDetails";
{ {
QVariantMap valuePair; QVariantMap valuePair;
valuePair.insert(QLatin1String("title"), QVariant(categoryLabel(0))); valuePair.insert(QLatin1String("title"), QVariant(title()));
result << valuePair; result << valuePair;
} }

View File

@@ -64,14 +64,14 @@ public:
void loadData(); void loadData();
void clear(); void clear();
Q_INVOKABLE int categoryDepth(int categoryIndex) const; Q_INVOKABLE int rowCount() const;
Q_INVOKABLE int getEventId(int index) const; Q_INVOKABLE int getEventId(int index) const;
int getEventRow(int index) const; int getEventRow(int index) const;
Q_INVOKABLE QColor getColor(int index) const; Q_INVOKABLE QColor getColor(int index) const;
Q_INVOKABLE float getHeight(int index) const; Q_INVOKABLE float getHeight(int index) const;
Q_INVOKABLE const QVariantList getLabelsForCategory(int category) const; Q_INVOKABLE const QVariantList getLabels() const;
Q_INVOKABLE const QVariantList getEventDetails(int index) const; Q_INVOKABLE const QVariantList getEventDetails(int index) const;
private slots: private slots:

View File

@@ -31,6 +31,7 @@
#include "qmlprofilermodelmanager.h" #include "qmlprofilermodelmanager.h"
#include "qmlprofilerdatamodel.h" #include "qmlprofilerdatamodel.h"
#include "sortedtimelinemodel.h" #include "sortedtimelinemodel.h"
#include "singlecategorytimelinemodel_p.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QVector> #include <QVector>
@@ -44,69 +45,53 @@
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
struct CategorySpan { class RangeTimelineModel::RangeTimelineModelPrivate :
bool expanded; public SortedTimelineModel<RangeTimelineModel::QmlRangeEventStartInstance,
int expandedRows; SingleCategoryTimelineModel::SingleCategoryTimelineModelPrivate>
int contractedRows;
int rowStart;
};
class BasicTimelineModel::BasicTimelineModelPrivate : public SortedTimelineModel<BasicTimelineModel::QmlRangeEventStartInstance>
{ {
public: public:
// convenience functions // convenience functions
void prepare();
void computeNestingContracted(); void computeNestingContracted();
void computeExpandedLevels(); void computeExpandedLevels();
void findBindingLoops(); void findBindingLoops();
void computeRowStarts();
QVector <BasicTimelineModel::QmlRangeEventData> eventDict; QVector <RangeTimelineModel::QmlRangeEventData> eventDict;
QVector <QString> eventHashes; QVector <QString> eventHashes;
QVector <CategorySpan> categorySpan; int expandedRows;
int contractedRows;
bool seenPaintEvent; bool seenPaintEvent;
private: private:
Q_DECLARE_PUBLIC(BasicTimelineModel) Q_DECLARE_PUBLIC(RangeTimelineModel)
}; };
BasicTimelineModel::BasicTimelineModel(QObject *parent) RangeTimelineModel::RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *parent)
: AbstractTimelineModel(new BasicTimelineModelPrivate, QLatin1String("BasicTimelineModel"), : SingleCategoryTimelineModel(new RangeTimelineModelPrivate,
parent) QLatin1String("RangeTimelineModel"), categoryLabel(rangeType),
QmlDebug::MaximumMessage, rangeType, parent)
{ {
Q_D(BasicTimelineModel); Q_D(RangeTimelineModel);
d->seenPaintEvent = false; d->seenPaintEvent = false;
d->expandedRows = 1;
d->contractedRows = 1;
} }
void BasicTimelineModel::clear() void RangeTimelineModel::clear()
{ {
Q_D(BasicTimelineModel); Q_D(RangeTimelineModel);
d->clear(); d->clear();
d->eventDict.clear(); d->eventDict.clear();
d->eventHashes.clear(); d->eventHashes.clear();
d->categorySpan.clear(); d->expandedRows = 1;
d->contractedRows = 1;
d->seenPaintEvent = false; d->seenPaintEvent = false;
d->expanded = false;
d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1); d->modelManager->modelProxyCountUpdated(d->modelId, 0, 1);
} }
void BasicTimelineModel::BasicTimelineModelPrivate::prepare() void RangeTimelineModel::loadData()
{ {
categorySpan.clear(); Q_D(RangeTimelineModel);
for (int i = 0; i < QmlDebug::MaximumRangeType; i++) {
CategorySpan newCategory = {false, 1, 1, i};
categorySpan << newCategory;
}
}
bool BasicTimelineModel::eventAccepted(const QmlProfilerDataModel::QmlEventData &event) const
{
// Accept all range types. Qt5 paint events aren't ranges
return (event.rangeType != QmlDebug::MaximumRangeType);
}
void BasicTimelineModel::loadData()
{
Q_D(BasicTimelineModel);
clear(); clear();
QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel(); QmlProfilerDataModel *simpleModel = d->modelManager->qmlModel();
if (simpleModel->isEmpty()) if (simpleModel->isEmpty())
@@ -114,8 +99,6 @@ void BasicTimelineModel::loadData()
int lastEventId = 0; int lastEventId = 0;
d->prepare();
QMap<QString, int> eventIdsByHash; QMap<QString, int> eventIdsByHash;
// collect events // collect events
@@ -136,7 +119,6 @@ void BasicTimelineModel::loadData()
event.displayName, event.displayName,
event.data.join(QLatin1String(" ")), event.data.join(QLatin1String(" ")),
event.location, event.location,
event.rangeType,
lastEventId++ // event id lastEventId++ // event id
}; };
d->eventDict << rangeEventData; d->eventDict << rangeEventData;
@@ -168,19 +150,16 @@ void BasicTimelineModel::loadData()
d->modelManager->modelProxyCountUpdated(d->modelId, 4, 6); d->modelManager->modelProxyCountUpdated(d->modelId, 4, 6);
d->findBindingLoops(); d->findBindingLoops();
d->modelManager->modelProxyCountUpdated(d->modelId, 5, 6); d->modelManager->modelProxyCountUpdated(d->modelId, 5, 6);
d->computeRowStarts();
d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1); d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
} }
void BasicTimelineModel::BasicTimelineModelPrivate::computeNestingContracted() void RangeTimelineModel::RangeTimelineModelPrivate::computeNestingContracted()
{ {
Q_Q(BasicTimelineModel); Q_Q(RangeTimelineModel);
int i; int i;
int eventCount = count(); int eventCount = count();
@@ -214,42 +193,35 @@ void BasicTimelineModel::BasicTimelineModelPrivate::computeNestingContracted()
// nestingdepth // nestingdepth
for (i = 0; i < eventCount; i++) { for (i = 0; i < eventCount; i++) {
int eventType = q->getEventType(i); if (contractedRows <= ranges[i].displayRowCollapsed)
if (categorySpan[eventType].contractedRows <= ranges[i].displayRowCollapsed) contractedRows = ranges[i].displayRowCollapsed + 1;
categorySpan[eventType].contractedRows = ranges[i].displayRowCollapsed + 1;
} }
} }
void BasicTimelineModel::BasicTimelineModelPrivate::computeExpandedLevels() void RangeTimelineModel::RangeTimelineModelPrivate::computeExpandedLevels()
{ {
QHash<int, int> eventRow; QHash<int, int> eventRow;
int eventCount = count(); int eventCount = count();
for (int i = 0; i < eventCount; i++) { for (int i = 0; i < eventCount; i++) {
int eventId = ranges[i].eventId; int eventId = ranges[i].eventId;
int eventType = eventDict[eventId].eventType;
if (!eventRow.contains(eventId)) { if (!eventRow.contains(eventId)) {
eventRow[eventId] = categorySpan[eventType].expandedRows++; eventRow[eventId] = expandedRows++;
} }
ranges[i].displayRowExpanded = eventRow[eventId]; ranges[i].displayRowExpanded = eventRow[eventId];
} }
} }
void BasicTimelineModel::BasicTimelineModelPrivate::findBindingLoops() void RangeTimelineModel::RangeTimelineModelPrivate::findBindingLoops()
{ {
if (rangeType != QmlDebug::Binding && rangeType != QmlDebug::HandlingSignal)
return;
typedef QPair<QString, int> CallStackEntry; typedef QPair<QString, int> CallStackEntry;
QStack<CallStackEntry> callStack; QStack<CallStackEntry> callStack;
for (int i = 0; i < count(); ++i) { for (int i = 0; i < count(); ++i) {
Range *event = &ranges[i]; Range *event = &ranges[i];
BasicTimelineModel::QmlRangeEventData data = eventDict.at(event->eventId);
static QVector<QmlDebug::RangeType> acceptedTypes =
QVector<QmlDebug::RangeType>() << QmlDebug::Binding << QmlDebug::HandlingSignal;
if (!acceptedTypes.contains(data.eventType))
continue;
const QString eventHash = eventHashes.at(event->eventId); const QString eventHash = eventHashes.at(event->eventId);
const Range *potentialParent = callStack.isEmpty() const Range *potentialParent = callStack.isEmpty()
? 0 : &ranges[callStack.top().second]; ? 0 : &ranges[callStack.top().second];
@@ -276,57 +248,21 @@ void BasicTimelineModel::BasicTimelineModelPrivate::findBindingLoops()
} }
void BasicTimelineModel::BasicTimelineModelPrivate::computeRowStarts()
{
Q_Q(BasicTimelineModel);
int rowStart = 0;
for (int i = 0; i < categorySpan.count(); i++) {
categorySpan[i].rowStart = rowStart;
rowStart += q->categoryDepth(i);
}
}
/////////////////// QML interface /////////////////// QML interface
bool BasicTimelineModel::expanded(int category) const int RangeTimelineModel::rowCount() const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
if (d->categorySpan.count() <= category)
return false;
return d->categorySpan[category].expanded;
}
void BasicTimelineModel::setExpanded(int category, bool expanded)
{
Q_D(BasicTimelineModel);
if (d->categorySpan.count() <= category)
return;
d->categorySpan[category].expanded = expanded;
d->computeRowStarts();
emit expandedChanged();
}
int BasicTimelineModel::categoryDepth(int categoryIndex) const
{
Q_D(const BasicTimelineModel);
// special for paint events: show only when empty model or there's actual events // special for paint events: show only when empty model or there's actual events
if (categoryIndex == QmlDebug::Painting && !d->seenPaintEvent) if (d->rangeType == QmlDebug::Painting && !d->seenPaintEvent)
return 0; return 0;
if (d->categorySpan.count() <= categoryIndex) if (d->expanded)
return 1; return d->expandedRows;
if (d->categorySpan[categoryIndex].expanded)
return d->categorySpan[categoryIndex].expandedRows;
else else
return d->categorySpan[categoryIndex].contractedRows; return d->contractedRows;
} }
int BasicTimelineModel::categoryCount() const QString RangeTimelineModel::categoryLabel(int categoryIndex)
{
return 6;
}
const QString BasicTimelineModel::categoryLabel(int categoryIndex) const
{ {
switch (categoryIndex) { switch (categoryIndex) {
case 0: return QCoreApplication::translate("MainView", "Painting"); break; case 0: return QCoreApplication::translate("MainView", "Painting"); break;
@@ -339,57 +275,47 @@ const QString BasicTimelineModel::categoryLabel(int categoryIndex) const
} }
} }
int BasicTimelineModel::getEventType(int index) const int RangeTimelineModel::getEventType(int index) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
return d->eventDict[d->range(index).eventId].eventType; Q_UNUSED(index);
return d->rangeType;
} }
int BasicTimelineModel::getEventCategory(int index) const int RangeTimelineModel::getEventRow(int index) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
int evTy = getEventType(index); if (d->expanded)
// special: paint events shown? return d->range(index).displayRowExpanded;
if (!d->seenPaintEvent)
return evTy - 1;
return evTy;
}
int BasicTimelineModel::getEventRow(int index) const
{
Q_D(const BasicTimelineModel);
if (d->categorySpan[getEventType(index)].expanded)
return d->range(index).displayRowExpanded + d->categorySpan[getEventType(index)].rowStart;
else else
return d->range(index).displayRowCollapsed + d->categorySpan[getEventType(index)].rowStart; return d->range(index).displayRowCollapsed;
} }
int BasicTimelineModel::getEventId(int index) const int RangeTimelineModel::getEventId(int index) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
return d->range(index).eventId; return d->range(index).eventId;
} }
int BasicTimelineModel::getBindingLoopDest(int index) const int RangeTimelineModel::getBindingLoopDest(int index) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
return d->range(index).bindingLoopHead; return d->range(index).bindingLoopHead;
} }
QColor BasicTimelineModel::getColor(int index) const QColor RangeTimelineModel::getColor(int index) const
{ {
return getEventColor(index); return getEventColor(index);
} }
const QVariantList BasicTimelineModel::getLabelsForCategory(int category) const const QVariantList RangeTimelineModel::getLabels() const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
QVariantList result; QVariantList result;
if (d->categorySpan.count() > category && d->categorySpan[category].expanded) { if (d->expanded) {
int eventCount = d->eventDict.count(); int eventCount = d->eventDict.count();
for (int i = 0; i < eventCount; i++) { for (int i = 0; i < eventCount; i++) {
if (d->eventDict[i].eventType == category) {
QVariantMap element; QVariantMap element;
element.insert(QLatin1String("displayName"), QVariant(d->eventDict[i].displayName)); element.insert(QLatin1String("displayName"), QVariant(d->eventDict[i].displayName));
element.insert(QLatin1String("description"), QVariant(d->eventDict[i].details)); element.insert(QLatin1String("description"), QVariant(d->eventDict[i].details));
@@ -397,21 +323,20 @@ const QVariantList BasicTimelineModel::getLabelsForCategory(int category) const
result << element; result << element;
} }
} }
}
return result; return result;
} }
const QVariantList BasicTimelineModel::getEventDetails(int index) const const QVariantList RangeTimelineModel::getEventDetails(int index) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
QVariantList result; QVariantList result;
int eventId = getEventId(index); int eventId = getEventId(index);
static const char trContext[] = "RangeDetails"; static const char trContext[] = "RangeDetails";
{ {
QVariantMap valuePair; QVariantMap valuePair;
valuePair.insert(QLatin1String("title"), QVariant(categoryLabel(d->eventDict[eventId].eventType))); valuePair.insert(QLatin1String("title"), QVariant(categoryLabel(d->rangeType)));
result << valuePair; result << valuePair;
} }
@@ -447,9 +372,9 @@ const QVariantList BasicTimelineModel::getEventDetails(int index) const
return result; return result;
} }
const QVariantMap BasicTimelineModel::getEventLocation(int index) const const QVariantMap RangeTimelineModel::getEventLocation(int index) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
QVariantMap result; QVariantMap result;
int eventId = getEventId(index); int eventId = getEventId(index);
@@ -463,15 +388,15 @@ const QVariantMap BasicTimelineModel::getEventLocation(int index) const
return result; return result;
} }
int BasicTimelineModel::getEventIdForHash(const QString &eventHash) const int RangeTimelineModel::getEventIdForHash(const QString &eventHash) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
return d->eventHashes.indexOf(eventHash); return d->eventHashes.indexOf(eventHash);
} }
int BasicTimelineModel::getEventIdForLocation(const QString &filename, int line, int column) const int RangeTimelineModel::getEventIdForLocation(const QString &filename, int line, int column) const
{ {
Q_D(const BasicTimelineModel); Q_D(const RangeTimelineModel);
// if this is called from v8 view, we don't have the column number, it will be -1 // if this is called from v8 view, we don't have the column number, it will be -1
foreach (const QmlRangeEventData &eventData, d->eventDict) { foreach (const QmlRangeEventData &eventData, d->eventDict) {
if (eventData.location.filename == filename && if (eventData.location.filename == filename &&

View File

@@ -31,8 +31,7 @@
#ifndef QMLPROFILERTIMELINEMODELPROXY_H #ifndef QMLPROFILERTIMELINEMODELPROXY_H
#define QMLPROFILERTIMELINEMODELPROXY_H #define QMLPROFILERTIMELINEMODELPROXY_H
#include <QObject> #include "singlecategorytimelinemodel.h"
#include "abstracttimelinemodel.h"
#include <qmldebug/qmlprofilereventtypes.h> #include <qmldebug/qmlprofilereventtypes.h>
#include <qmldebug/qmlprofilereventlocation.h> #include <qmldebug/qmlprofilereventlocation.h>
#include <QVariantList> #include <QVariantList>
@@ -44,7 +43,7 @@ class QmlProfilerModelManager;
namespace Internal { namespace Internal {
class BasicTimelineModel : public AbstractTimelineModel class RangeTimelineModel : public SingleCategoryTimelineModel
{ {
Q_OBJECT Q_OBJECT
public: public:
@@ -53,8 +52,6 @@ public:
QString displayName; QString displayName;
QString details; QString details;
QmlDebug::QmlEventLocation location; QmlDebug::QmlEventLocation location;
QmlDebug::RangeType eventType;
int eventId; // separate int eventId; // separate
}; };
@@ -73,7 +70,7 @@ public:
int bindingLoopHead; int bindingLoopHead;
}; };
BasicTimelineModel(QObject *parent = 0); RangeTimelineModel(QmlDebug::RangeType rangeType, QObject *parent = 0);
void loadData(); void loadData();
void clear(); void clear();
@@ -81,32 +78,25 @@ public:
// QML interface // QML interface
Q_INVOKABLE bool expanded(int category) const; Q_INVOKABLE int rowCount() const;
Q_INVOKABLE void setExpanded(int category, bool expanded); static QString categoryLabel(int categoryIndex);
Q_INVOKABLE int categoryDepth(int categoryIndex) const;
Q_INVOKABLE int categoryCount() const;
Q_INVOKABLE const QString categoryLabel(int categoryIndex) const;
int getEventType(int index) const; int getEventType(int index) const;
int getEventCategory(int index) const;
int getEventRow(int index) const; int getEventRow(int index) const;
Q_INVOKABLE int getEventId(int index) const; Q_INVOKABLE int getEventId(int index) const;
int getBindingLoopDest(int index) const; int getBindingLoopDest(int index) const;
Q_INVOKABLE QColor getColor(int index) const; Q_INVOKABLE QColor getColor(int index) const;
Q_INVOKABLE const QVariantList getLabelsForCategory(int category) const; Q_INVOKABLE const QVariantList getLabels() const;
Q_INVOKABLE const QVariantList getEventDetails(int index) const; Q_INVOKABLE const QVariantList getEventDetails(int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int index) const;
Q_INVOKABLE int getEventIdForHash(const QString &eventHash) const; Q_INVOKABLE int getEventIdForHash(const QString &eventHash) const;
Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const; Q_INVOKABLE int getEventIdForLocation(const QString &filename, int line, int column) const;
private slots:
bool eventAccepted(const QmlProfilerDataModel::QmlEventData &event) const;
private: private:
class BasicTimelineModelPrivate; class RangeTimelineModelPrivate;
Q_DECLARE_PRIVATE(BasicTimelineModel) Q_DECLARE_PRIVATE(RangeTimelineModel)
}; };
} }

View File

@@ -39,7 +39,7 @@ SingleCategoryTimelineModel::SingleCategoryTimelineModel(SingleCategoryTimelineM
{ {
Q_D(SingleCategoryTimelineModel); Q_D(SingleCategoryTimelineModel);
d->expanded = false; d->expanded = false;
d->label = label; d->title = label;
d->message = message; d->message = message;
d->rangeType = rangeType; d->rangeType = rangeType;
} }
@@ -52,33 +52,25 @@ bool SingleCategoryTimelineModel::eventAccepted(const QmlProfilerDataModel::QmlE
return (event.rangeType == d->rangeType && event.message == d->message); return (event.rangeType == d->rangeType && event.message == d->message);
} }
bool SingleCategoryTimelineModel::expanded(int categoryIndex) const bool SingleCategoryTimelineModel::expanded() const
{ {
Q_D(const SingleCategoryTimelineModel); Q_D(const SingleCategoryTimelineModel);
Q_UNUSED(categoryIndex);
return d->expanded; return d->expanded;
} }
void SingleCategoryTimelineModel::setExpanded(int categoryIndex, bool expanded) void SingleCategoryTimelineModel::setExpanded(bool expanded)
{ {
Q_D(SingleCategoryTimelineModel); Q_D(SingleCategoryTimelineModel);
Q_UNUSED(categoryIndex);
if (expanded != d->expanded) { if (expanded != d->expanded) {
d->expanded = expanded; d->expanded = expanded;
emit expandedChanged(); emit expandedChanged();
} }
} }
int SingleCategoryTimelineModel::categoryCount() const const QString SingleCategoryTimelineModel::title() const
{
return 1;
}
const QString SingleCategoryTimelineModel::categoryLabel(int categoryIndex) const
{ {
Q_D(const SingleCategoryTimelineModel); Q_D(const SingleCategoryTimelineModel);
Q_UNUSED(categoryIndex); return d->title;
return d->label;
} }
int SingleCategoryTimelineModel::getEventType(int index) const int SingleCategoryTimelineModel::getEventType(int index) const
@@ -88,10 +80,4 @@ int SingleCategoryTimelineModel::getEventType(int index) const
return (d->message << 8) + d->rangeType; return (d->message << 8) + d->rangeType;
} }
int SingleCategoryTimelineModel::getEventCategory(int index) const
{
Q_UNUSED(index);
return 0;
}
} }

View File

@@ -40,14 +40,11 @@ class QMLPROFILER_EXPORT SingleCategoryTimelineModel : public AbstractTimelineMo
Q_OBJECT Q_OBJECT
public: public:
bool eventAccepted(const QmlProfilerDataModel::QmlEventData &event) const; bool eventAccepted(const QmlProfilerDataModel::QmlEventData &event) const;
Q_INVOKABLE bool expanded(int) const; bool expanded() const;
Q_INVOKABLE void setExpanded(int, bool expanded); void setExpanded(bool expanded);
Q_INVOKABLE int categoryCount() const;
int getEventType(int index) const; int getEventType(int index) const;
Q_INVOKABLE int getEventCategory(int index) const; const QString title() const;
Q_INVOKABLE const QString categoryLabel(int categoryIndex) const;
protected: protected:
class SingleCategoryTimelineModelPrivate; class SingleCategoryTimelineModelPrivate;

View File

@@ -39,7 +39,7 @@ class SingleCategoryTimelineModel::SingleCategoryTimelineModelPrivate :
public AbstractTimelineModel::AbstractTimelineModelPrivate { public AbstractTimelineModel::AbstractTimelineModelPrivate {
public: public:
bool expanded; bool expanded;
QString label; QString title;
QmlDebug::Message message; QmlDebug::Message message;
QmlDebug::RangeType rangeType; QmlDebug::RangeType rangeType;
}; };

View File

@@ -77,9 +77,11 @@ void TimelineModelAggregator::setModelManager(QmlProfilerModelManager *modelMana
paintEventsModelProxy->setModelManager(modelManager); paintEventsModelProxy->setModelManager(modelManager);
addModel(paintEventsModelProxy); addModel(paintEventsModelProxy);
BasicTimelineModel *basicTimelineModel = new BasicTimelineModel(this); for (int i = 0; i < QmlDebug::MaximumRangeType; ++i) {
basicTimelineModel->setModelManager(modelManager); RangeTimelineModel *rangeModel = new RangeTimelineModel((QmlDebug::RangeType)i, this);
addModel(basicTimelineModel); rangeModel->setModelManager(modelManager);
addModel(rangeModel);
}
} }
void TimelineModelAggregator::addModel(AbstractTimelineModel *m) void TimelineModelAggregator::addModel(AbstractTimelineModel *m)
@@ -90,31 +92,11 @@ void TimelineModelAggregator::addModel(AbstractTimelineModel *m)
connect(m,SIGNAL(stateChanged()),this,SIGNAL(stateChanged())); connect(m,SIGNAL(stateChanged()),this,SIGNAL(stateChanged()));
} }
// order?
int TimelineModelAggregator::categoryCount() const
{
int categoryCount = 0;
foreach (const AbstractTimelineModel *modelProxy, d->modelList)
categoryCount += modelProxy->categoryCount();
return categoryCount;
}
int TimelineModelAggregator::visibleCategories() const
{
int categoryCount = 0;
foreach (const AbstractTimelineModel *modelProxy, d->modelList) {
for (int i = 0; i < modelProxy->categoryCount(); i++)
if (modelProxy->categoryDepth(i) > 0)
categoryCount ++;
}
return categoryCount;
}
QStringList TimelineModelAggregator::categoryTitles() const QStringList TimelineModelAggregator::categoryTitles() const
{ {
QStringList retString; QStringList retString;
foreach (const AbstractTimelineModel *modelProxy, d->modelList) foreach (const AbstractTimelineModel *modelProxy, d->modelList)
retString += modelProxy->categoryTitles(); retString << modelProxy->title();
return retString; return retString;
} }
@@ -158,24 +140,14 @@ qint64 TimelineModelAggregator::lastTimeMark() const
return mark; return mark;
} }
bool TimelineModelAggregator::expanded(int modelIndex, int category) const bool TimelineModelAggregator::expanded(int modelIndex) const
{ {
return d->modelList[modelIndex]->expanded(category); return d->modelList[modelIndex]->expanded();
} }
void TimelineModelAggregator::setExpanded(int modelIndex, int category, bool expanded) void TimelineModelAggregator::setExpanded(int modelIndex, bool expanded)
{ {
d->modelList[modelIndex]->setExpanded(category, expanded); d->modelList[modelIndex]->setExpanded(expanded);
}
int TimelineModelAggregator::categoryDepth(int modelIndex, int categoryIndex) const
{
return d->modelList[modelIndex]->categoryDepth(categoryIndex);
}
int TimelineModelAggregator::categoryCount(int modelIndex) const
{
return d->modelList[modelIndex]->categoryCount();
} }
int TimelineModelAggregator::rowCount(int modelIndex) const int TimelineModelAggregator::rowCount(int modelIndex) const
@@ -183,29 +155,9 @@ int TimelineModelAggregator::rowCount(int modelIndex) const
return d->modelList[modelIndex]->rowCount(); return d->modelList[modelIndex]->rowCount();
} }
const QString TimelineModelAggregator::categoryLabel(int modelIndex, int categoryIndex) const const QString TimelineModelAggregator::title(int modelIndex) const
{ {
return d->modelList[modelIndex]->categoryLabel(categoryIndex); return d->modelList[modelIndex]->title();
}
int TimelineModelAggregator::modelIndexForCategory(int absoluteCategoryIndex) const
{
int categoryIndex = absoluteCategoryIndex;
for (int modelIndex = 0; modelIndex < d->modelList.count(); modelIndex++)
if (categoryIndex < d->modelList[modelIndex]->categoryCount())
return modelIndex;
else
categoryIndex -= d->modelList[modelIndex]->categoryCount();
return modelCount()-1;
}
int TimelineModelAggregator::correctedCategoryIndexForModel(int modelIndex, int absoluteCategoryIndex) const
{
int categoryIndex = absoluteCategoryIndex;
for (int mi = 0; mi < modelIndex; mi++)
categoryIndex -= d->modelList[mi]->categoryCount();
return categoryIndex;
} }
int TimelineModelAggregator::findFirstIndex(int modelIndex, qint64 startTime) const int TimelineModelAggregator::findFirstIndex(int modelIndex, qint64 startTime) const
@@ -228,11 +180,6 @@ int TimelineModelAggregator::getEventType(int modelIndex, int index) const
return d->modelList[modelIndex]->getEventType(index); return d->modelList[modelIndex]->getEventType(index);
} }
int TimelineModelAggregator::getEventCategoryInModel(int modelIndex, int index) const
{
return d->modelList[modelIndex]->getEventCategory(index);
}
int TimelineModelAggregator::getEventRow(int modelIndex, int index) const int TimelineModelAggregator::getEventRow(int modelIndex, int index) const
{ {
return d->modelList[modelIndex]->getEventRow(index); return d->modelList[modelIndex]->getEventRow(index);
@@ -273,9 +220,9 @@ float TimelineModelAggregator::getHeight(int modelIndex, int index) const
return d->modelList[modelIndex]->getHeight(index); return d->modelList[modelIndex]->getHeight(index);
} }
const QVariantList TimelineModelAggregator::getLabelsForCategory(int modelIndex, int category) const const QVariantList TimelineModelAggregator::getLabels(int modelIndex) const
{ {
return d->modelList[modelIndex]->getLabelsForCategory(category); return d->modelList[modelIndex]->getLabels();
} }
const QVariantList TimelineModelAggregator::getEventDetails(int modelIndex, int index) const const QVariantList TimelineModelAggregator::getEventDetails(int modelIndex, int index) const

View File

@@ -46,9 +46,6 @@ public:
void setModelManager(QmlProfilerModelManager *modelManager); void setModelManager(QmlProfilerModelManager *modelManager);
void addModel(AbstractTimelineModel *m); void addModel(AbstractTimelineModel *m);
Q_INVOKABLE int categoryCount() const;
Q_INVOKABLE int visibleCategories() const;
Q_INVOKABLE QStringList categoryTitles() const; Q_INVOKABLE QStringList categoryTitles() const;
Q_INVOKABLE int count(int modelIndex = -1) const; Q_INVOKABLE int count(int modelIndex = -1) const;
void clear(); void clear();
@@ -65,19 +62,16 @@ public:
Q_INVOKABLE qint64 lastTimeMark() const; Q_INVOKABLE qint64 lastTimeMark() const;
Q_INVOKABLE bool expanded(int modelIndex, int category) const; Q_INVOKABLE bool expanded(int modelIndex) const;
Q_INVOKABLE void setExpanded(int modelIndex, int category, bool expanded); Q_INVOKABLE void setExpanded(int modelIndex, bool expanded);
Q_INVOKABLE int categoryDepth(int modelIndex, int categoryIndex) const;
Q_INVOKABLE int categoryCount(int modelIndex) const;
Q_INVOKABLE int rowCount(int modelIndex) const; Q_INVOKABLE int rowCount(int modelIndex) const;
Q_INVOKABLE const QString categoryLabel(int modelIndex, int categoryIndex) const; Q_INVOKABLE const QString title(int modelIndex) const;
int findFirstIndex(int modelIndex, qint64 startTime) const; int findFirstIndex(int modelIndex, qint64 startTime) const;
int findFirstIndexNoParents(int modelIndex, qint64 startTime) const; int findFirstIndexNoParents(int modelIndex, qint64 startTime) const;
int findLastIndex(int modelIndex, qint64 endTime) const; int findLastIndex(int modelIndex, qint64 endTime) const;
int getEventType(int modelIndex, int index) const; int getEventType(int modelIndex, int index) const;
Q_INVOKABLE int getEventCategoryInModel(int modelIndex, int index) const;
int getEventRow(int modelIndex, int index) const; int getEventRow(int modelIndex, int index) const;
Q_INVOKABLE qint64 getDuration(int modelIndex, int index) const; Q_INVOKABLE qint64 getDuration(int modelIndex, int index) const;
Q_INVOKABLE qint64 getStartTime(int modelIndex, int index) const; Q_INVOKABLE qint64 getStartTime(int modelIndex, int index) const;
@@ -87,7 +81,7 @@ public:
Q_INVOKABLE QColor getColor(int modelIndex, int index) const; Q_INVOKABLE QColor getColor(int modelIndex, int index) const;
Q_INVOKABLE float getHeight(int modelIndex, int index) const; Q_INVOKABLE float getHeight(int modelIndex, int index) const;
Q_INVOKABLE const QVariantList getLabelsForCategory(int modelIndex, int category) const; Q_INVOKABLE const QVariantList getLabels(int modelIndex) const;
Q_INVOKABLE const QVariantList getEventDetails(int modelIndex, int index) const; Q_INVOKABLE const QVariantList getEventDetails(int modelIndex, int index) const;
Q_INVOKABLE const QVariantMap getEventLocation(int modelIndex, int index) const; Q_INVOKABLE const QVariantMap getEventLocation(int modelIndex, int index) const;
@@ -96,9 +90,6 @@ public:
Q_INVOKABLE int getEventIdForLocation(int modelIndex, const QString &filename, int line, Q_INVOKABLE int getEventIdForLocation(int modelIndex, const QString &filename, int line,
int column) const; int column) const;
Q_INVOKABLE int modelIndexForCategory(int absoluteCategoryIndex) const;
Q_INVOKABLE int correctedCategoryIndexForModel(int modelIndex, int absoluteCategoryIndex) const;
signals: signals:
void dataAvailable(); void dataAvailable();
void stateChanged(); void stateChanged();