Commit 18332d15 authored by Ulf Hermann's avatar Ulf Hermann

Timeline: Move printTime() into Timeline and add hours, minutes, nanos

We should use it for all time printing instead of duplicating the code
everywhere.

Change-Id: I530baa31fd7044aefce6201fec0ab27c99a61a1d
Reviewed-by: Christian Kandeler's avatarChristian Kandeler <christian.kandeler@qt.io>
parent c2b89ae3
...@@ -16,8 +16,8 @@ SOURCES += \ ...@@ -16,8 +16,8 @@ SOURCES += \
$$PWD/timelinenotesmodel.cpp \ $$PWD/timelinenotesmodel.cpp \
$$PWD/timelineabstractrenderer.cpp \ $$PWD/timelineabstractrenderer.cpp \
$$PWD/timelineoverviewrenderer.cpp \ $$PWD/timelineoverviewrenderer.cpp \
$$PWD/timelinetheme.cpp $$PWD/timelinetheme.cpp \
$$PWD/timelineformattime.cpp
HEADERS += \ HEADERS += \
$$PWD/timeline_global.h \ $$PWD/timeline_global.h \
...@@ -39,7 +39,8 @@ HEADERS += \ ...@@ -39,7 +39,8 @@ HEADERS += \
$$PWD/timelineabstractrenderer_p.h \ $$PWD/timelineabstractrenderer_p.h \
$$PWD/timelineoverviewrenderer_p.h \ $$PWD/timelineoverviewrenderer_p.h \
$$PWD/timelineoverviewrenderer.h \ $$PWD/timelineoverviewrenderer.h \
$$PWD/timelinetheme.h $$PWD/timelinetheme.h \
$$PWD/timelineformattime.h
RESOURCES += \ RESOURCES += \
$$PWD/qml/timeline.qrc $$PWD/qml/timeline.qrc
......
...@@ -17,6 +17,7 @@ Project { ...@@ -17,6 +17,7 @@ Project {
"README", "README",
"timelineabstractrenderer.cpp", "timelineabstractrenderer.h", "timelineabstractrenderer.cpp", "timelineabstractrenderer.h",
"timelineabstractrenderer_p.h", "timelineabstractrenderer_p.h",
"timelineformattime.cpp", "timelineformattime.h",
"timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h", "timelineitemsrenderpass.cpp", "timelineitemsrenderpass.h",
"timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h", "timelinemodel.cpp", "timelinemodel.h", "timelinemodel_p.h",
"timelinemodelaggregator.cpp", "timelinemodelaggregator.h", "timelinemodelaggregator.cpp", "timelinemodelaggregator.h",
......
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "timelineformattime.h"
namespace Timeline {
QString formatTime(qint64 timestamp, qint64 reference)
{
static const char *decimalUnits[] = {"ns", "\xb5s", "ms", "s"};
static const double second = 1e9;
static const double minute = 60;
static const double hour = 60;
int round = 0;
int barrier = 1;
auto roundTo3 = [](double time, int round) {
// always show at least 3 significant digits
if (time < 10 && round < 2)
return 2;
else if (time < 100 && round < 1)
return 1;
else
return round;
};
for (uint i = 0, end = sizeof(decimalUnits) / sizeof(char *); i < end; ++i) {
const double dividend = barrier;
if (reference < barrier) {
round += 3;
barrier *= 1000;
} else {
barrier *= 10;
if (reference < barrier) {
round += 2;
barrier *= 100;
} else {
barrier *= 10;
if (reference < barrier)
round += 1;
barrier *= 10;
}
}
if (timestamp < barrier) {
double time = timestamp;
if (dividend > 1) {
time /= dividend;
round = roundTo3(time, round);
}
return QString::number(time, 'f', round)
+ QString::fromLatin1(decimalUnits[i]);
}
}
double seconds = timestamp / second;
if (seconds < minute) {
return QString::number(seconds, 'f', roundTo3(seconds, round)) + "s";
} else {
int minutes = seconds / minute;
seconds -= minutes * minute;
if (minutes < hour) {
return QString::fromLatin1("%1m %2s").arg(QString::number(minutes),
QString::number(seconds, 'f', round));
} else {
int hours = minutes / hour;
hours -= hours * hour;
if (reference < barrier * minute) {
return QString::fromLatin1("%1h %2m %3s").arg(QString::number(hours),
QString::number(minutes),
QString::number(seconds, 'f', round));
} else {
return QString::fromLatin1("%1h %2m").arg(QString::number(hours),
QString::number(minutes));
}
}
}
}
}
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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 The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include "timeline_global.h"
#include <QString>
#include <limits>
namespace Timeline {
QString TIMELINE_EXPORT formatTime(qint64 timestamp,
qint64 reference = std::numeric_limits<qint64>::max());
}
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "debugmessagesmodel.h" #include "debugmessagesmodel.h"
#include "qmlprofilerconstants.h" #include "qmlprofilerconstants.h"
#include <timeline/timelineformattime.h>
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
...@@ -78,7 +79,7 @@ QVariantMap DebugMessagesModel::details(int index) const ...@@ -78,7 +79,7 @@ QVariantMap DebugMessagesModel::details(int index) const
QVariantMap result; QVariantMap result;
result.insert(QLatin1String("displayName"), messageType(type.detailType())); result.insert(QLatin1String("displayName"), messageType(type.detailType()));
result.insert(tr("Timestamp"), QmlProfilerDataModel::formatTime(startTime(index))); result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index)));
result.insert(tr("Message"), m_data[index].text); result.insert(tr("Message"), m_data[index].text);
result.insert(tr("Location"), type.displayName()); result.insert(tr("Location"), type.displayName());
return result; return result;
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "qmlprofilermodelmanager.h" #include "qmlprofilermodelmanager.h"
#include "qmlprofilereventtypes.h" #include "qmlprofilereventtypes.h"
#include <timeline/timelineformattime.h>
#include <QKeyEvent> #include <QKeyEvent>
#include <QMouseEvent> #include <QMouseEvent>
#include <QMetaEnum> #include <QMetaEnum>
...@@ -75,7 +77,7 @@ QMetaEnum InputEventsModel::metaEnum(const char *name) ...@@ -75,7 +77,7 @@ QMetaEnum InputEventsModel::metaEnum(const char *name)
QVariantMap InputEventsModel::details(int index) const QVariantMap InputEventsModel::details(int index) const
{ {
QVariantMap result; QVariantMap result;
result.insert(tr("Timestamp"), QmlProfilerDataModel::formatTime(startTime(index))); result.insert(tr("Timestamp"), Timeline::formatTime(startTime(index)));
QString type; QString type;
const InputEvent &event = m_data[index]; const InputEvent &event = m_data[index];
switch (event.type) { switch (event.type) {
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "qmlprofilermodelmanager.h" #include "qmlprofilermodelmanager.h"
#include "qmlprofilereventtypes.h" #include "qmlprofilereventtypes.h"
#include <timeline/timelineformattime.h>
namespace QmlProfiler { namespace QmlProfiler {
namespace Internal { namespace Internal {
...@@ -119,7 +121,7 @@ QVariantMap PixmapCacheModel::details(int index) const ...@@ -119,7 +121,7 @@ QVariantMap PixmapCacheModel::details(int index) const
result.insert(QLatin1String("displayName"), tr("Image Loaded")); result.insert(QLatin1String("displayName"), tr("Image Loaded"));
if (m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].loadState != Finished) if (m_pixmaps[ev->urlIndex].sizes[ev->sizeIndex].loadState != Finished)
result.insert(tr("Result"), tr("Load Error")); result.insert(tr("Result"), tr("Load Error"));
result.insert(tr("Duration"), QmlProfilerDataModel::formatTime(duration(index))); result.insert(tr("Duration"), Timeline::formatTime(duration(index)));
} }
result.insert(tr("Cache Size"), QString::fromLatin1("%1 px").arg(ev->cacheSize)); result.insert(tr("Cache Size"), QString::fromLatin1("%1 px").arg(ev->cacheSize));
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "qmlprofilerdatamodel.h" #include "qmlprofilerdatamodel.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <timeline/timelineformattime.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QVector> #include <QVector>
...@@ -182,7 +183,7 @@ QVariantMap QmlProfilerAnimationsModel::details(int index) const ...@@ -182,7 +183,7 @@ QVariantMap QmlProfilerAnimationsModel::details(int index) const
QVariantMap result; QVariantMap result;
result.insert(QStringLiteral("displayName"), displayName()); result.insert(QStringLiteral("displayName"), displayName());
result.insert(tr("Duration"), QmlProfilerDataModel::formatTime(duration(index))); result.insert(tr("Duration"), Timeline::formatTime(duration(index)));
result.insert(tr("Framerate"), QString::fromLatin1("%1 FPS").arg(m_data[index].framerate)); result.insert(tr("Framerate"), QString::fromLatin1("%1 FPS").arg(m_data[index].framerate));
result.insert(tr("Animations"), QString::number(m_data[index].animationcount)); result.insert(tr("Animations"), QString::number(m_data[index].animationcount));
result.insert(tr("Context"), selectionId(index) == GuiThread ? tr("GUI Thread") : result.insert(tr("Context"), selectionId(index) == GuiThread ? tr("GUI Thread") :
......
...@@ -92,16 +92,6 @@ QString getInitialDetails(const QmlEventType &event) ...@@ -92,16 +92,6 @@ QString getInitialDetails(const QmlEventType &event)
return details; return details;
} }
QString QmlProfilerDataModel::formatTime(qint64 timestamp)
{
if (timestamp < 1e6)
return QString::number(timestamp/1e3f,'f',3) + trUtf8(" \xc2\xb5s");
if (timestamp < 1e9)
return QString::number(timestamp/1e6f,'f',3) + tr(" ms");
return QString::number(timestamp/1e9f,'f',3) + tr(" s");
}
QmlProfilerDataModel::QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder, QmlProfilerDataModel::QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder,
QmlProfilerModelManager *parent) : QmlProfilerModelManager *parent) :
QObject(parent), d_ptr(new QmlProfilerDataModelPrivate) QObject(parent), d_ptr(new QmlProfilerDataModelPrivate)
......
...@@ -39,8 +39,6 @@ class QMLPROFILER_EXPORT QmlProfilerDataModel : public QObject ...@@ -39,8 +39,6 @@ class QMLPROFILER_EXPORT QmlProfilerDataModel : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static QString formatTime(qint64 timestamp);
explicit QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder, explicit QmlProfilerDataModel(Utils::FileInProjectFinder *fileFinder,
QmlProfilerModelManager *parent); QmlProfilerModelManager *parent);
~QmlProfilerDataModel(); ~QmlProfilerDataModel();
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "timeline/timelinenotesrenderpass.h" #include "timeline/timelinenotesrenderpass.h"
#include "timeline/timelineitemsrenderpass.h" #include "timeline/timelineitemsrenderpass.h"
#include "timeline/timelineselectionrenderpass.h" #include "timeline/timelineselectionrenderpass.h"
#include "timeline/timelineformattime.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QVector> #include <QVector>
...@@ -223,7 +224,7 @@ QVariantMap QmlProfilerRangeModel::details(int index) const ...@@ -223,7 +224,7 @@ QVariantMap QmlProfilerRangeModel::details(int index) const
result.insert(QStringLiteral("displayName"), result.insert(QStringLiteral("displayName"),
tr(QmlProfilerModelManager::featureName(mainFeature()))); tr(QmlProfilerModelManager::featureName(mainFeature())));
result.insert(tr("Duration"), QmlProfilerDataModel::formatTime(duration(index))); result.insert(tr("Duration"), Timeline::formatTime(duration(index)));
result.insert(tr("Details"), types[id].data()); result.insert(tr("Details"), types[id].data());
result.insert(tr("Location"), types[id].displayName()); result.insert(tr("Location"), types[id].displayName());
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <coreplugin/minisplitter.h> #include <coreplugin/minisplitter.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <timeline/timelineformattime.h>
#include <QUrl> #include <QUrl>
#include <QHash> #include <QHash>
...@@ -573,7 +574,7 @@ void QmlProfilerStatisticsMainView::parseModel() ...@@ -573,7 +574,7 @@ void QmlProfilerStatisticsMainView::parseModel()
} }
if (d->m_fieldShown[TotalTime]) { if (d->m_fieldShown[TotalTime]) {
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.duration), newRow << new StatisticsViewItem(Timeline::formatTime(stats.duration),
stats.duration); stats.duration);
} }
...@@ -583,7 +584,7 @@ void QmlProfilerStatisticsMainView::parseModel() ...@@ -583,7 +584,7 @@ void QmlProfilerStatisticsMainView::parseModel()
} }
if (d->m_fieldShown[SelfTime]) { if (d->m_fieldShown[SelfTime]) {
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.durationSelf), newRow << new StatisticsViewItem(Timeline::formatTime(stats.durationSelf),
stats.durationSelf); stats.durationSelf);
} }
...@@ -591,22 +592,22 @@ void QmlProfilerStatisticsMainView::parseModel() ...@@ -591,22 +592,22 @@ void QmlProfilerStatisticsMainView::parseModel()
newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls); newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls);
if (d->m_fieldShown[TimePerCall]) { if (d->m_fieldShown[TimePerCall]) {
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.timePerCall), newRow << new StatisticsViewItem(Timeline::formatTime(stats.timePerCall),
stats.timePerCall); stats.timePerCall);
} }
if (d->m_fieldShown[MedianTime]) { if (d->m_fieldShown[MedianTime]) {
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.medianTime), newRow << new StatisticsViewItem(Timeline::formatTime(stats.medianTime),
stats.medianTime); stats.medianTime);
} }
if (d->m_fieldShown[MaxTime]) { if (d->m_fieldShown[MaxTime]) {
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.maxTime), newRow << new StatisticsViewItem(Timeline::formatTime(stats.maxTime),
stats.maxTime); stats.maxTime);
} }
if (d->m_fieldShown[MinTime]) { if (d->m_fieldShown[MinTime]) {
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.minTime), newRow << new StatisticsViewItem(Timeline::formatTime(stats.minTime),
stats.minTime); stats.minTime);
} }
...@@ -848,7 +849,7 @@ void QmlProfilerStatisticsRelativesView::rebuildTree( ...@@ -848,7 +849,7 @@ void QmlProfilerStatisticsRelativesView::rebuildTree(
type.displayName()); type.displayName());
const QString typeName = QmlProfilerStatisticsMainView::nameForType(type.rangeType()); const QString typeName = QmlProfilerStatisticsMainView::nameForType(type.rangeType());
newRow << new StatisticsViewItem(typeName, typeName); newRow << new StatisticsViewItem(typeName, typeName);
newRow << new StatisticsViewItem(QmlProfilerDataModel::formatTime(stats.duration), newRow << new StatisticsViewItem(Timeline::formatTime(stats.duration),
stats.duration); stats.duration);
newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls); newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls);
newRow << new StatisticsViewItem(type.data().isEmpty() ? tr("Source code not available") : newRow << new StatisticsViewItem(type.data().isEmpty() ? tr("Source code not available") :
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#include "qmlprofilermodelmanager.h" #include "qmlprofilermodelmanager.h"
#include "qmlprofilereventtypes.h" #include "qmlprofilereventtypes.h"
#include <timeline/timelineformattime.h>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
...@@ -122,7 +124,7 @@ QVariantMap SceneGraphTimelineModel::details(int index) const ...@@ -122,7 +124,7 @@ QVariantMap SceneGraphTimelineModel::details(int index) const
result.insert(QLatin1String("displayName"), tr(threadLabel(stage))); result.insert(QLatin1String("displayName"), tr(threadLabel(stage)));
result.insert(tr("Stage"), tr(StageLabels[stage])); result.insert(tr("Stage"), tr(StageLabels[stage]));
result.insert(tr("Duration"), QmlProfilerDataModel::formatTime(duration(index))); result.insert(tr("Duration"), Timeline::formatTime(duration(index)));
const int glyphCount = m_data[index].glyphCount; const int glyphCount = m_data[index].glyphCount;
if (glyphCount >= 0) if (glyphCount >= 0)
......
...@@ -24,6 +24,9 @@ ...@@ -24,6 +24,9 @@
****************************************************************************/ ****************************************************************************/
#include "debugmessagesmodel_test.h" #include "debugmessagesmodel_test.h"
#include <timeline/timelineformattime.h>
#include <QtTest> #include <QtTest>
namespace QmlProfiler { namespace QmlProfiler {
...@@ -93,7 +96,7 @@ void DebugMessagesModelTest::testDetails() ...@@ -93,7 +96,7 @@ void DebugMessagesModelTest::testDetails()
QCOMPARE(details.value(QLatin1String("displayName")).toString(), QCOMPARE(details.value(QLatin1String("displayName")).toString(),
model.tr(messageTypes[i % (QtMsgType::QtInfoMsg + 1)])); model.tr(messageTypes[i % (QtMsgType::QtInfoMsg + 1)]));
QCOMPARE(details.value(model.tr("Timestamp")).toString(), QCOMPARE(details.value(model.tr("Timestamp")).toString(),
QmlProfilerDataModel::formatTime(i)); Timeline::formatTime(i));
QCOMPARE(details.value(model.tr("Message")).toString(), QCOMPARE(details.value(model.tr("Message")).toString(),
QString::fromLatin1("message %1").arg(i)); QString::fromLatin1("message %1").arg(i));
QCOMPARE(details.value(model.tr("Location")).toString(), QCOMPARE(details.value(model.tr("Location")).toString(),
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include "inputeventsmodel_test.h" #include "inputeventsmodel_test.h"
#include "timeline/timelinemodel_p.h" #include "timeline/timelinemodel_p.h"
#include "timeline/timelineformattime.h"
#include <QtTest> #include <QtTest>
namespace QmlProfiler { namespace QmlProfiler {
...@@ -105,7 +107,7 @@ void InputEventsModelTest::testDetails() ...@@ -105,7 +107,7 @@ void InputEventsModelTest::testDetails()
{ {
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
const QVariantMap details = model.details(i); const QVariantMap details = model.details(i);
QCOMPARE(details[model.tr("Timestamp")].toString(), QmlProfilerDataModel::formatTime(i)); QCOMPARE(details[model.tr("Timestamp")].toString(), Timeline::formatTime(i));
QString displayName = details[QString("displayName")].toString(); QString displayName = details[QString("displayName")].toString();
QVERIFY(!displayName.isEmpty()); QVERIFY(!displayName.isEmpty());
switch (static_cast<InputEventType>(i % MaximumInputEventType)) { switch (static_cast<InputEventType>(i % MaximumInputEventType)) {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
****************************************************************************/ ****************************************************************************/
#include "pixmapcachemodel_test.h" #include "pixmapcachemodel_test.h"
#include <timeline/timelineformattime.h>
#include <QtTest> #include <QtTest>
namespace QmlProfiler { namespace QmlProfiler {
...@@ -248,7 +249,7 @@ void PixmapCacheModelTest::testConsistency() ...@@ -248,7 +249,7 @@ void PixmapCacheModelTest::testConsistency()
QVERIFY(expandedRow < model.expandedRowCount()); QVERIFY(expandedRow < model.expandedRowCount());
QVERIFY(details[QLatin1String("displayName")].toString() == model.tr("Image Loaded")); QVERIFY(details[QLatin1String("displayName")].toString() == model.tr("Image Loaded"));
QCOMPARE(details[model.tr("Duration")].toString(), QCOMPARE(details[model.tr("Duration")].toString(),
QmlProfilerDataModel::formatTime(model.duration(i))); Timeline::formatTime(model.duration(i)));
// In expanded view pixmaps of the same URL but different sizes are allowed to overlap. // In expanded view pixmaps of the same URL but different sizes are allowed to overlap.
// It looks bad, but that should be a rare thing. // It looks bad, but that should be a rare thing.
break; break;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
****************************************************************************/ ****************************************************************************/
#include "qmlprofileranimationsmodel_test.h" #include "qmlprofileranimationsmodel_test.h"
#include <timeline/timelineformattime.h>
#include <QtTest> #include <QtTest>
namespace QmlProfiler { namespace QmlProfiler {
...@@ -127,7 +128,7 @@ void QmlProfilerAnimationsModelTest::testDetails() ...@@ -127,7 +128,7 @@ void QmlProfilerAnimationsModelTest::testDetails()
QVariantMap details = model.details(i); QVariantMap details = model.details(i);
QCOMPARE(details["displayName"].toString(), model.displayName()); QCOMPARE(details["displayName"].toString(), model.displayName());
QCOMPARE(details[QmlProfilerAnimationsModel::tr("Duration")].toString(), QCOMPARE(details[QmlProfilerAnimationsModel::tr("Duration")].toString(),
QmlProfilerDataModel::formatTime(1)); Timeline::formatTime(1));
QCOMPARE(details[QmlProfilerAnimationsModel::tr("Framerate")].toString(), QCOMPARE(details[QmlProfilerAnimationsModel::tr("Framerate")].toString(),
QString::fromLatin1("%1 FPS").arg(frameRate(i))); QString::fromLatin1("%1 FPS").arg(frameRate(i)));