From fbce58bf8cd626aca2b93b4df0d237a392f9b6c3 Mon Sep 17 00:00:00 2001 From: Christiaan Janssen <christiaan.janssen@nokia.com> Date: Wed, 22 Jun 2011 17:58:58 +0200 Subject: [PATCH] QmlProfiler: Callers and Callees separate views Change-Id: Ifa3939eeda2a473722cbd8dfac33794a15d8c453 Reviewed-on: http://codereview.qt.nokia.com/678 Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com> Reviewed-by: Christiaan Janssen <christiaan.janssen@nokia.com> --- src/plugins/qmlprofiler/qmlprofiler.pro | 6 +- ...treeview.cpp => qmlprofilercalleeview.cpp} | 41 ++- ...calltreeview.h => qmlprofilercalleeview.h} | 16 +- .../qmlprofiler/qmlprofilercallerview.cpp | 288 ++++++++++++++++++ .../qmlprofiler/qmlprofilercallerview.h | 70 +++++ src/plugins/qmlprofiler/qmlprofilertool.cpp | 38 ++- 6 files changed, 417 insertions(+), 42 deletions(-) rename src/plugins/qmlprofiler/{qmlprofilercalltreeview.cpp => qmlprofilercalleeview.cpp} (86%) rename src/plugins/qmlprofiler/{qmlprofilercalltreeview.h => qmlprofilercalleeview.h} (85%) create mode 100644 src/plugins/qmlprofiler/qmlprofilercallerview.cpp create mode 100644 src/plugins/qmlprofiler/qmlprofilercallerview.h diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro index 00330638669..54d616b41a2 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.pro +++ b/src/plugins/qmlprofiler/qmlprofiler.pro @@ -25,7 +25,8 @@ SOURCES += \ qmlprojectanalyzerruncontrolfactory.cpp \ localqmlprofilerrunner.cpp \ codaqmlprofilerrunner.cpp \ - qmlprofilercalltreeview.cpp + qmlprofilercalleeview.cpp \ + qmlprofilercallerview.cpp HEADERS += \ qmlprofilerconstants.h \ @@ -41,7 +42,8 @@ HEADERS += \ abstractqmlprofilerrunner.h \ localqmlprofilerrunner.h \ codaqmlprofilerrunner.h \ - qmlprofilercalltreeview.h + qmlprofilercalleeview.h \ + qmlprofilercallerview.h RESOURCES += \ qml/qml.qrc diff --git a/src/plugins/qmlprofiler/qmlprofilercalltreeview.cpp b/src/plugins/qmlprofiler/qmlprofilercalleeview.cpp similarity index 86% rename from src/plugins/qmlprofiler/qmlprofilercalltreeview.cpp rename to src/plugins/qmlprofiler/qmlprofilercalleeview.cpp index 8eda0accea7..71fd7677b97 100644 --- a/src/plugins/qmlprofiler/qmlprofilercalltreeview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilercalleeview.cpp @@ -31,7 +31,7 @@ ** **************************************************************************/ -#include "qmlprofilercalltreeview.h" +#include "qmlprofilercalleeview.h" #include <QtCore/QUrl> #include <QtCore/QHash> @@ -74,15 +74,15 @@ enum ItemRole { LineRole = Qt::UserRole+3 }; -class QmlProfilerCallTreeView::QmlProfilerCallTreeViewPrivate +class QmlProfilerCalleeView::QmlProfilerCalleeViewPrivate { public: - QmlProfilerCallTreeViewPrivate(QmlProfilerCallTreeView *qq) : q(qq) {} + QmlProfilerCalleeViewPrivate(QmlProfilerCalleeView *qq) : q(qq) {} void recursiveClearHash(BindingHash *hash); void buildModelFromHash( BindingHash *hash, QStandardItem *parentItem ); - QmlProfilerCallTreeView *q; + QmlProfilerCalleeView *q; QStandardItemModel *m_model; // ToDo: avoid unnecessary allocations by using global hash @@ -91,10 +91,10 @@ public: QList<BindingData *> m_bindingBuffer; }; -QmlProfilerCallTreeView::QmlProfilerCallTreeView(QWidget *parent) : - QTreeView(parent), d(new QmlProfilerCallTreeViewPrivate(this)) +QmlProfilerCalleeView::QmlProfilerCalleeView(QWidget *parent) : + QTreeView(parent), d(new QmlProfilerCalleeViewPrivate(this)) { - setObjectName("QmlProfilerCallTreeView"); + setObjectName("QmlProfilerCalleeView"); setRootIsDecorated(true); header()->setResizeMode(QHeaderView::Interactive); header()->setMinimumSectionSize(50); @@ -111,26 +111,25 @@ QmlProfilerCallTreeView::QmlProfilerCallTreeView(QWidget *parent) : connect(this,SIGNAL(clicked(QModelIndex)), this,SLOT(jumpToItem(QModelIndex))); } -QmlProfilerCallTreeView::~QmlProfilerCallTreeView() +QmlProfilerCalleeView::~QmlProfilerCalleeView() { clean(); delete d->m_model; } -void QmlProfilerCallTreeView::clean() +void QmlProfilerCalleeView::clean() { d->m_model->clear(); d->m_model->setColumnCount(3); // clean the hashes d->recursiveClearHash(&d->m_rootHash); -// d->recursiveClearHash(&d->m_globalHash); setHeaderLabels(); setSortingEnabled(false); } -void QmlProfilerCallTreeView::addRangedEvent(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length, +void QmlProfilerCalleeView::addRangedEvent(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length, const QStringList &data, const QString &fileName, int line) { Q_UNUSED(startTime); @@ -206,7 +205,7 @@ void QmlProfilerCallTreeView::addRangedEvent(int type, int nestingLevel, int nes } } -void QmlProfilerCallTreeView::complete() +void QmlProfilerCalleeView::complete() { // build the model from the hashed data d->buildModelFromHash( &d->m_rootHash, d->m_model->invisibleRootItem()); @@ -216,7 +215,7 @@ void QmlProfilerCallTreeView::complete() resizeColumnToContents(1); } -void QmlProfilerCallTreeView::jumpToItem(const QModelIndex &index) +void QmlProfilerCalleeView::jumpToItem(const QModelIndex &index) { QStandardItem *clickedItem = d->m_model->itemFromIndex(index); QStandardItem *infoItem; @@ -232,14 +231,14 @@ void QmlProfilerCallTreeView::jumpToItem(const QModelIndex &index) emit gotoSourceLocation(fileName, line); } -void QmlProfilerCallTreeView::setHeaderLabels() +void QmlProfilerCalleeView::setHeaderLabels() { d->m_model->setHeaderData(0, Qt::Horizontal, QVariant(tr("Location"))); d->m_model->setHeaderData(1, Qt::Horizontal, QVariant(tr("Type"))); d->m_model->setHeaderData(2, Qt::Horizontal, QVariant(tr("Details"))); } -void QmlProfilerCallTreeView::QmlProfilerCallTreeViewPrivate::recursiveClearHash(BindingHash *hash) { +void QmlProfilerCalleeView::QmlProfilerCalleeViewPrivate::recursiveClearHash(BindingHash *hash) { QHashIterator<QString, BindingData *> it(*hash); while (it.hasNext()) { it.next(); @@ -253,16 +252,16 @@ void QmlProfilerCallTreeView::QmlProfilerCallTreeViewPrivate::recursiveClearHash inline QString nameForType(int typeNumber) { switch (typeNumber) { - case 0: return QmlProfilerCallTreeView::tr("Paint"); - case 1: return QmlProfilerCallTreeView::tr("Compile"); - case 2: return QmlProfilerCallTreeView::tr("Create"); - case 3: return QmlProfilerCallTreeView::tr("Binding"); - case 4: return QmlProfilerCallTreeView::tr("Signal"); + case 0: return QmlProfilerCalleeView::tr("Paint"); + case 1: return QmlProfilerCalleeView::tr("Compile"); + case 2: return QmlProfilerCalleeView::tr("Create"); + case 3: return QmlProfilerCalleeView::tr("Binding"); + case 4: return QmlProfilerCalleeView::tr("Signal"); } return QString(); } -void QmlProfilerCallTreeView::QmlProfilerCallTreeViewPrivate::buildModelFromHash( BindingHash *hash, QStandardItem *parentItem ) +void QmlProfilerCalleeView::QmlProfilerCalleeViewPrivate::buildModelFromHash( BindingHash *hash, QStandardItem *parentItem ) { QHashIterator<QString, BindingData *> it(*hash); diff --git a/src/plugins/qmlprofiler/qmlprofilercalltreeview.h b/src/plugins/qmlprofiler/qmlprofilercalleeview.h similarity index 85% rename from src/plugins/qmlprofiler/qmlprofilercalltreeview.h rename to src/plugins/qmlprofiler/qmlprofilercalleeview.h index bcdc622e8f8..8d436dab2d6 100644 --- a/src/plugins/qmlprofiler/qmlprofilercalltreeview.h +++ b/src/plugins/qmlprofiler/qmlprofilercalleeview.h @@ -31,21 +31,21 @@ ** **************************************************************************/ -#ifndef QMLPROFILERCALLTREEVIEW_H -#define QMLPROFILERCALLTREEVIEW_H +#ifndef QMLPROFILERCALLEEVIEW_H +#define QMLPROFILERCALLEEVIEW_H #include <QTreeView> namespace QmlProfiler { namespace Internal { -class QmlProfilerCallTreeView : public QTreeView +class QmlProfilerCalleeView : public QTreeView { Q_OBJECT public: - explicit QmlProfilerCallTreeView(QWidget *parent = 0); - ~QmlProfilerCallTreeView(); + explicit QmlProfilerCalleeView(QWidget *parent = 0); + ~QmlProfilerCalleeView(); signals: void gotoSourceLocation(const QString &fileName, int lineNumber); @@ -58,8 +58,8 @@ public slots: void jumpToItem(const QModelIndex &index); private: - class QmlProfilerCallTreeViewPrivate; - QmlProfilerCallTreeViewPrivate *d; + class QmlProfilerCalleeViewPrivate; + QmlProfilerCalleeViewPrivate *d; void setHeaderLabels(); }; @@ -67,4 +67,4 @@ private: } // namespace Internal } // namespace QmlProfiler -#endif // QMLPROFILERCALLTREEVIEW_H +#endif // QMLPROFILERCALLEEVIEW_H diff --git a/src/plugins/qmlprofiler/qmlprofilercallerview.cpp b/src/plugins/qmlprofiler/qmlprofilercallerview.cpp new file mode 100644 index 00000000000..92cece6058d --- /dev/null +++ b/src/plugins/qmlprofiler/qmlprofilercallerview.cpp @@ -0,0 +1,288 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** 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 info@qt.nokia.com. +** +**************************************************************************/ + +#include "qmlprofilercallerview.h" + +#include <QtCore/QUrl> +#include <QtCore/QHash> + +#include <QtGui/QHeaderView> +#include <QtGui/QStandardItemModel> + +using namespace QmlProfiler::Internal; + +struct BindingData +{ + BindingData() : displayname(0) , filename(0) , location(0) , details(0), + line(0), rangeType(0), level(-1), parentList(0) {} + ~BindingData() { + delete displayname; + delete filename; + delete location; + delete parentList; + } + QString *displayname; + QString *filename; + QString *location; + QString *details; + int line; + int rangeType; + qint64 level; + QList< BindingData *> *parentList; +}; + +typedef QHash<QString, BindingData *> BindingHash; +typedef QList<BindingData *> BindingList; + +enum ItemRole { + LocationRole = Qt::UserRole+1, + FilenameRole = Qt::UserRole+2, + LineRole = Qt::UserRole+3 +}; + +class QmlProfilerCallerView::QmlProfilerCallerViewPrivate +{ +public: + QmlProfilerCallerViewPrivate(QmlProfilerCallerView *qq) : q(qq) {} + + void recursiveClearHash(BindingHash *hash); + void buildModelFromList( BindingList *list, QStandardItem *parentItem, BindingList *listSoFar ); + + QmlProfilerCallerView *q; + + QStandardItemModel *m_model; + BindingHash m_rootHash; + QHash<int, BindingList> m_pendingChildren; + int m_lastLevel; +}; + +QmlProfilerCallerView::QmlProfilerCallerView(QWidget *parent) : + QTreeView(parent), d(new QmlProfilerCallerViewPrivate(this)) +{ + setObjectName("QmlProfilerCallerView"); + setRootIsDecorated(true); + header()->setResizeMode(QHeaderView::Interactive); + header()->setMinimumSectionSize(50); + setSortingEnabled(false); + setFrameStyle(QFrame::NoFrame); + + d->m_model = new QStandardItemModel(this); + + setModel(d->m_model); + + d->m_model->setColumnCount(3); + setHeaderLabels(); + + connect(this,SIGNAL(clicked(QModelIndex)), this,SLOT(jumpToItem(QModelIndex))); + + d->m_lastLevel = -1; +} + +QmlProfilerCallerView::~QmlProfilerCallerView() +{ + clean(); + delete d->m_model; +} + +void QmlProfilerCallerView::clean() +{ + d->m_model->clear(); + d->m_model->setColumnCount(3); + + foreach (int levelNumber, d->m_pendingChildren.keys()) + d->m_pendingChildren[levelNumber].clear(); + + d->m_lastLevel = -1; + + // clean the hashes + d->recursiveClearHash(&d->m_rootHash); + + setHeaderLabels(); + setSortingEnabled(false); +} + +void QmlProfilerCallerView::addRangedEvent(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length, + const QStringList &data, const QString &fileName, int line) +{ + Q_UNUSED(startTime); + Q_UNUSED(nestingInType); + Q_UNUSED(length); + + const QChar colon = QLatin1Char(':'); + QString localName, displayName, location, details; + + if (fileName.isEmpty()) { + displayName = tr("<bytecode>"); + location = QLatin1String("--"); + + } else { + localName = QUrl(fileName).toLocalFile(); + displayName = localName.mid(localName.lastIndexOf(QChar('/')) + 1) + colon + QString::number(line); + location = fileName+colon+QString::number(line); + } + + if (data.isEmpty()) + details = tr("Source code not available"); + else + details = data.join(" ").replace('\n'," "); + + + // New Data: if it's not in the hash, put it there + // if it's in the hash, get the reference from the hash + BindingData *newBinding; + BindingHash::iterator it = d->m_rootHash.find(location); + if (it != d->m_rootHash.end()) { + newBinding = it.value(); + } else { + newBinding = new BindingData; + newBinding->displayname = new QString(displayName); + newBinding->filename = new QString(fileName); + newBinding->line = line; + newBinding->level = nestingLevel; + newBinding->rangeType = type; + newBinding->location = new QString(location); + newBinding->details = new QString(details); + newBinding->parentList = new BindingList(); + d->m_rootHash.insert(location, newBinding); + } + + if (nestingLevel < d->m_lastLevel) { + // I'm the parent of the former + if (d->m_pendingChildren.contains(nestingLevel+1)) { + foreach (BindingData *child, d->m_pendingChildren[nestingLevel + 1]) { + if (!child->parentList->contains(newBinding)) + child->parentList->append(newBinding); + } + d->m_pendingChildren[nestingLevel + 1].clear(); + } + + } + + if (nestingLevel > 1 && !d->m_pendingChildren[nestingLevel].contains(newBinding)) { + // I'm not root... there will come a parent later + d->m_pendingChildren[nestingLevel].append(newBinding); + } + + d->m_lastLevel = nestingLevel; +} + +void QmlProfilerCallerView::complete() +{ + // build the model from the hashed data + BindingList bindingList = d->m_rootHash.values(); + BindingList emptyList; + d->buildModelFromList(&bindingList, d->m_model->invisibleRootItem(), &emptyList); + + expandAll(); + resizeColumnToContents(0); + resizeColumnToContents(1); + collapseAll(); +} + +void QmlProfilerCallerView::jumpToItem(const QModelIndex &index) +{ + QStandardItem *clickedItem = d->m_model->itemFromIndex(index); + QStandardItem *infoItem; + if (clickedItem->parent()) + infoItem = clickedItem->parent()->child(clickedItem->row(), 0); + else + infoItem = d->m_model->item(index.row(), 0); + + int line = infoItem->data(Qt::UserRole+3).toInt(); + if (line == -1) + return; + QString fileName = infoItem->data(Qt::UserRole+2).toString(); + emit gotoSourceLocation(fileName, line); +} + +void QmlProfilerCallerView::setHeaderLabels() +{ + d->m_model->setHeaderData(0, Qt::Horizontal, QVariant(tr("Location"))); + d->m_model->setHeaderData(1, Qt::Horizontal, QVariant(tr("Type"))); + d->m_model->setHeaderData(2, Qt::Horizontal, QVariant(tr("Details"))); +} + +// ToDo: property clean the stored data +void QmlProfilerCallerView::QmlProfilerCallerViewPrivate::recursiveClearHash(BindingHash *hash) { + QHashIterator<QString, BindingData *> it(*hash); + while (it.hasNext()) { + it.next(); + delete it.value(); + } + hash->clear(); +} + +inline QString nameForType(int typeNumber) +{ + switch (typeNumber) { + case 0: return QmlProfilerCallerView::tr("Paint"); + case 1: return QmlProfilerCallerView::tr("Compile"); + case 2: return QmlProfilerCallerView::tr("Create"); + case 3: return QmlProfilerCallerView::tr("Binding"); + case 4: return QmlProfilerCallerView::tr("Signal"); + } + return QString(); +} + +void QmlProfilerCallerView::QmlProfilerCallerViewPrivate::buildModelFromList( BindingList *list, QStandardItem *parentItem, BindingList *listSoFar ) +{ + foreach (BindingData *binding, *list) { + if (listSoFar->contains(binding)) + continue; + + QStandardItem *nameColumn = new QStandardItem(*binding->displayname); + nameColumn->setEditable(false); + + QStandardItem *typeColumn = new QStandardItem(nameForType(binding->rangeType)); + typeColumn->setEditable(false); + + QStandardItem *detailsColumn = new QStandardItem(*binding->details); + detailsColumn->setEditable(false); + + QStandardItem *firstColumn = nameColumn; + firstColumn->setData(QVariant(*binding->location),LocationRole); + firstColumn->setData(QVariant(*binding->filename),FilenameRole); + firstColumn->setData(QVariant(binding->line),LineRole); + + QList<QStandardItem *> newRow; + newRow << nameColumn << typeColumn << detailsColumn; + parentItem->appendRow(newRow); + if (!binding->parentList->isEmpty()) { + // avoid infinite loops due to recursive functions + BindingList newParentList(*listSoFar); + newParentList.append(binding); + + buildModelFromList(binding->parentList, nameColumn, &newParentList); + } + } +} diff --git a/src/plugins/qmlprofiler/qmlprofilercallerview.h b/src/plugins/qmlprofiler/qmlprofilercallerview.h new file mode 100644 index 00000000000..71ceb69b061 --- /dev/null +++ b/src/plugins/qmlprofiler/qmlprofilercallerview.h @@ -0,0 +1,70 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** 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 info@qt.nokia.com. +** +**************************************************************************/ + +#ifndef QMLPROFILERCALLERVIEW_H +#define QMLPROFILERCALLERVIEW_H + +#include <QTreeView> + +namespace QmlProfiler { +namespace Internal { + +class QmlProfilerCallerView : public QTreeView +{ + Q_OBJECT + +public: + explicit QmlProfilerCallerView(QWidget *parent = 0); + ~QmlProfilerCallerView(); + +signals: + void gotoSourceLocation(const QString &fileName, int lineNumber); + +public slots: + void clean(); + void addRangedEvent(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length, + const QStringList &data, const QString &fileName, int line); + void complete(); + void jumpToItem(const QModelIndex &index); + +private: + class QmlProfilerCallerViewPrivate; + QmlProfilerCallerViewPrivate *d; + + void setHeaderLabels(); +}; + +} // namespace Internal +} // namespace QmlProfiler + +#endif // QMLPROFILERCALLERVIEW_H diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index 9084b3f9777..321a35de0b0 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -37,7 +37,8 @@ #include "qmlprofilerconstants.h" #include "qmlprofilerattachdialog.h" #include "qmlprofilersummaryview.h" -#include "qmlprofilercalltreeview.h" +#include "qmlprofilercalleeview.h" +#include "qmlprofilercallerview.h" #include "tracewindow.h" #include "timelineview.h" @@ -92,7 +93,8 @@ public: int m_connectionAttempts; TraceWindow *m_traceWindow; QmlProfilerSummaryView *m_summary; - QmlProfilerCallTreeView *m_calltree; + QmlProfilerCalleeView *m_calleetree; + QmlProfilerCallerView *m_callertree; ProjectExplorer::Project *m_project; Utils::FileInProjectFinder m_projectFinder; ProjectExplorer::RunConfiguration *m_runConfiguration; @@ -223,12 +225,20 @@ void QmlProfilerTool::initializeDockWidgets() connect(d->m_summary, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int))); - d->m_calltree = new QmlProfilerCallTreeView(mw); + d->m_calleetree = new QmlProfilerCalleeView(mw); connect(d->m_traceWindow, SIGNAL(range(int,int,int,qint64,qint64,QStringList,QString,int)), - d->m_calltree, SLOT(addRangedEvent(int,int,int,qint64,qint64,QStringList,QString,int))); + d->m_calleetree, SLOT(addRangedEvent(int,int,int,qint64,qint64,QStringList,QString,int))); connect(d->m_traceWindow, SIGNAL(viewUpdated()), - d->m_calltree, SLOT(complete())); - connect(d->m_calltree, SIGNAL(gotoSourceLocation(QString,int)), + d->m_calleetree, SLOT(complete())); + connect(d->m_calleetree, SIGNAL(gotoSourceLocation(QString,int)), + this, SLOT(gotoSourceLocation(QString,int))); + + d->m_callertree = new QmlProfilerCallerView(mw); + connect(d->m_traceWindow, SIGNAL(range(int,int,int,qint64,qint64,QStringList,QString,int)), + d->m_callertree, SLOT(addRangedEvent(int,int,int,qint64,qint64,QStringList,QString,int))); + connect(d->m_traceWindow, SIGNAL(viewUpdated()), + d->m_callertree, SLOT(complete())); + connect(d->m_callertree, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int))); Core::ICore *core = Core::ICore::instance(); @@ -256,13 +266,18 @@ void QmlProfilerTool::initializeDockWidgets() analyzerMgr->createDockWidget(this, tr("Timeline"), d->m_traceWindow, Qt::BottomDockWidgetArea); - QDockWidget *calltreeDock = - analyzerMgr->createDockWidget(this, tr("Dependencies"), - d->m_calltree, Qt::BottomDockWidgetArea); + QDockWidget *calleeDock = + analyzerMgr->createDockWidget(this, tr("Callees"), + d->m_calleetree, Qt::BottomDockWidgetArea); + + QDockWidget *callerDock = + analyzerMgr->createDockWidget(this, tr("Callers"), + d->m_callertree, Qt::BottomDockWidgetArea); mw->splitDockWidget(mw->toolBarDockWidget(), summaryDock, Qt::Vertical); mw->tabifyDockWidget(summaryDock, timelineDock); - mw->tabifyDockWidget(timelineDock, calltreeDock); + mw->tabifyDockWidget(timelineDock, calleeDock); + mw->tabifyDockWidget(calleeDock, callerDock); } @@ -402,7 +417,8 @@ void QmlProfilerTool::clearDisplay() { d->m_traceWindow->clearDisplay(); d->m_summary->clean(); - d->m_calltree->clean(); + d->m_calleetree->clean(); + d->m_callertree->clean(); } void QmlProfilerTool::attach() -- GitLab