aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmlprofiler/qmlprofilersummaryview.cpp
diff options
context:
space:
mode:
authorChristiaan Janssen <[email protected]>2011-04-08 13:05:39 +0200
committerChristiaan Janssen <[email protected]>2011-04-08 13:35:38 +0200
commit6ab68a1a5fd27526e041f1e0ae453f279e1e3c00 (patch)
treefee040812b786c9cbf943af6e7870d696f1f9fcc /src/plugins/qmlprofiler/qmlprofilersummaryview.cpp
parentd5ad4e8dd4873c78687a67815c172e6f0db8f621 (diff)
QmlProfiler: added summary view
Reviewed-by: Kai Koehne
Diffstat (limited to 'src/plugins/qmlprofiler/qmlprofilersummaryview.cpp')
-rw-r--r--src/plugins/qmlprofiler/qmlprofilersummaryview.cpp261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilersummaryview.cpp b/src/plugins/qmlprofiler/qmlprofilersummaryview.cpp
new file mode 100644
index 00000000000..eedbf309ee8
--- /dev/null
+++ b/src/plugins/qmlprofiler/qmlprofilersummaryview.cpp
@@ -0,0 +1,261 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation ([email protected])
+**
+** No Commercial Usage
+**
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at [email protected].
+**
+**************************************************************************/
+
+#include "qmlprofilersummaryview.h"
+
+#include <QtCore/QUrl>
+
+#include <QtGui/QHeaderView>
+#include <QtGui/QStandardItemModel>
+
+using namespace QmlProfiler::Internal;
+
+class QmlProfilerSummaryView::QmlProfilerSummaryViewPrivate
+{
+public:
+ QmlProfilerSummaryViewPrivate(QmlProfilerSummaryView *qq):q(qq) {}
+ ~QmlProfilerSummaryViewPrivate() {}
+
+ QmlProfilerSummaryView *q;
+
+ QStandardItemModel *m_model;
+
+ enum RangeType {
+ Painting,
+ Compiling,
+ Creating,
+ Binding,
+ HandlingSignal,
+
+ MaximumRangeType
+ };
+};
+
+class ProfilerItem : public QStandardItem
+{
+public:
+ ProfilerItem(const QString &text):QStandardItem ( text ) {}
+
+ virtual bool operator< ( const QStandardItem & other ) const
+ {
+ if (data().type() == QVariant::String) {
+ // first column
+ return data(Qt::UserRole+2).toString() == other.data(Qt::UserRole+2).toString() ?
+ data(Qt::UserRole+3).toInt() < other.data(Qt::UserRole+3).toInt() :
+ data(Qt::UserRole+2).toString() < other.data(Qt::UserRole+2).toString();
+ }
+
+ return data().toDouble() < other.data().toDouble();
+ }
+};
+
+QmlProfilerSummaryView::QmlProfilerSummaryView(QWidget *parent) :
+ QTreeView(parent), d(new QmlProfilerSummaryViewPrivate(this))
+{
+ setRootIsDecorated(false);
+ header()->setResizeMode(QHeaderView::Interactive);
+ header()->setMinimumSectionSize(100);
+ setSortingEnabled(false);
+
+ d->m_model = new QStandardItemModel(this);
+
+ setModel(d->m_model);
+
+ d->m_model->setColumnCount(7);
+ setHeaderLabels();
+
+ connect(this,SIGNAL(clicked(QModelIndex)), this,SLOT(jumpToItem(QModelIndex)));
+}
+
+QmlProfilerSummaryView::~QmlProfilerSummaryView()
+{
+ delete d->m_model;
+}
+
+void QmlProfilerSummaryView::clean()
+{
+ d->m_model->clear();
+ d->m_model->setColumnCount(7);
+ setHeaderLabels();
+ setSortingEnabled(false);
+}
+
+void QmlProfilerSummaryView::addRangedEvent(int type, qint64 startTime, qint64 length, const QStringList &data, const QString &fileName, int line)
+{
+ Q_UNUSED(startTime);
+ Q_UNUSED(data);
+
+ if (type != QmlProfilerSummaryViewPrivate::Binding && type != QmlProfilerSummaryViewPrivate::HandlingSignal)
+ return;
+
+ QString fname;
+ QString displayName;
+ if (!fileName.isEmpty()) {
+ fname = fileName;
+ QString localName = QUrl(fileName).toLocalFile();
+ displayName = localName.mid(localName.lastIndexOf(QChar('/'))+1)+QLatin1String(":")+QString::number(line);
+ } else {
+ // ignore anonymous bindings
+ return;
+ //fname = (type==QmlProfilerSummaryViewPrivate::Binding ? QLatin1String("[binding]") : QLatin1String("[signal]"));
+ //displayName = fname;
+ }
+
+ QString location = fname+":"+QString::number(line);
+
+
+ int rowNum = 0;
+ while (rowNum < d->m_model->rowCount()) {
+ if (d->m_model->item(rowNum,0)->data(Qt::UserRole+1) == location)
+ break;
+ rowNum++;
+ }
+
+ if (rowNum < d->m_model->rowCount()) {
+ double itemTime = d->m_model->item(rowNum,2)->data().toDouble() + length;
+ d->m_model->item(rowNum,2)->setData(QVariant(itemTime));
+ d->m_model->item(rowNum,2)->setText(displayTime(itemTime));
+
+ int callCount = d->m_model->item(rowNum,3)->data().toInt() + 1;
+ d->m_model->item(rowNum,3)->setData(QVariant(callCount));
+ d->m_model->item(rowNum,3)->setText(QString::number(callCount));
+
+ double maxTime = d->m_model->item(rowNum,5)->data().toDouble();
+ if (length > maxTime) {
+ d->m_model->item(rowNum,5)->setData(QVariant(length));
+ d->m_model->item(rowNum,5)->setText(displayTime(length));
+ }
+
+ double minTime = d->m_model->item(rowNum,6)->data().toDouble();
+ if (length < minTime) {
+ d->m_model->item(rowNum,6)->setData(QVariant(length));
+ d->m_model->item(rowNum,6)->setText(displayTime(length));
+ }
+
+ } else {
+ appendRow(displayName, fname, line, 0, length, 1, length, length, length);
+ }
+}
+
+void QmlProfilerSummaryView::complete()
+{
+ // compute percentages
+ double totalTime = 0;
+ int i;
+ for (i=0; i < d->m_model->rowCount(); i++)
+ totalTime += d->m_model->item(i,2)->data().toDouble();
+ for (i=0; i < d->m_model->rowCount(); i++) {
+ double time = d->m_model->item(i,2)->data().toDouble();
+ double percent = time * 100.0 / totalTime;
+ d->m_model->item(i,1)->setData(QVariant(percent));
+ d->m_model->item(i,1)->setText(QString::number(percent,'g',2)+QLatin1String(" %"));
+
+ int callCount = d->m_model->item(i,3)->data().toInt();
+ double tpc = callCount>0? time / callCount : 0;
+ d->m_model->item(i,4)->setData(QVariant(tpc));
+ d->m_model->item(i,4)->setText(displayTime(tpc));
+ }
+ setSortingEnabled(true);
+ sortByColumn(1,Qt::DescendingOrder);
+ resizeColumnToContents(0);
+}
+
+void QmlProfilerSummaryView::jumpToItem(const QModelIndex &index)
+{
+ int line = d->m_model->item(index.row(),0)->data(Qt::UserRole+3).toInt();
+ if (line == -1)
+ return;
+ QString fileName = d->m_model->item(index.row(),0)->data(Qt::UserRole+2).toString();
+ emit gotoSourceLocation(fileName, line);
+}
+
+void QmlProfilerSummaryView::appendRow(const QString &displayName,
+ const QString &fileName,
+ int line,
+ double percentTime,
+ double totalTime,
+ int nCalls,
+ double timePerCall,
+ double maxTime,
+ double minTime)
+{
+ QString location =fileName+":"+QString::number(line);
+ ProfilerItem *locationColumn = new ProfilerItem(displayName);
+ locationColumn->setData(QVariant(location),Qt::UserRole+1);
+ locationColumn->setData(QVariant(fileName),Qt::UserRole+2);
+ locationColumn->setData(QVariant(line),Qt::UserRole+3);
+ locationColumn->setEditable(false);
+ ProfilerItem *percentColumn = new ProfilerItem(QString::number(percentTime)+QLatin1String(" %"));
+ percentColumn->setData(QVariant(percentTime));
+ percentColumn->setEditable(false);
+ ProfilerItem *timeColumn = new ProfilerItem(displayTime(totalTime));
+ timeColumn->setData(QVariant(totalTime));
+ timeColumn->setEditable(false);
+ ProfilerItem *callsColumn = new ProfilerItem(QString::number(nCalls));
+ callsColumn->setData(QVariant(nCalls));
+ callsColumn->setEditable(false);
+ ProfilerItem *tpcColumn = new ProfilerItem(displayTime(timePerCall));
+ tpcColumn->setData(QVariant(timePerCall));
+ tpcColumn->setEditable(false);
+ ProfilerItem *maxTimeColumn = new ProfilerItem(displayTime(maxTime));
+ maxTimeColumn->setData(QVariant(maxTime));
+ maxTimeColumn->setEditable(false);
+ ProfilerItem *minTimeColumn = new ProfilerItem(displayTime(minTime));
+ minTimeColumn->setData(QVariant(minTime));
+ minTimeColumn->setEditable(false);
+
+ QList<QStandardItem *> newRow;
+ newRow << locationColumn << percentColumn << timeColumn << callsColumn << tpcColumn << maxTimeColumn << minTimeColumn;
+ d->m_model->appendRow(newRow);
+}
+
+QString QmlProfilerSummaryView::displayTime(double time) const
+{
+ if (time<1e6)
+ return QString::number(time/1e3,'f',3) + QString::fromUtf8(" \u03BCs");//(" \u03BCs");
+ if (time<1e9)
+ return QString::number(time/1e6,'f',3) + QLatin1String(" ms");
+
+ return QString::number(time/1e9,'f',3) + QLatin1String(" s");
+}
+
+void QmlProfilerSummaryView::setHeaderLabels()
+{
+ d->m_model->setHeaderData(0,Qt::Horizontal,QVariant(tr("location")));
+ d->m_model->setHeaderData(1,Qt::Horizontal,QVariant(tr("% time")));
+ d->m_model->setHeaderData(2,Qt::Horizontal,QVariant(tr("total time")));
+ d->m_model->setHeaderData(3,Qt::Horizontal,QVariant(tr("calls")));
+ d->m_model->setHeaderData(4,Qt::Horizontal,QVariant(tr("time per call")));
+ d->m_model->setHeaderData(5,Qt::Horizontal,QVariant(tr("longest time")));
+ d->m_model->setHeaderData(6,Qt::Horizontal,QVariant(tr("shortest time")));
+}