diff options
Diffstat (limited to 'src/plugins/qmlprofiler/qmlprofilereventview.cpp')
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilereventview.cpp | 668 |
1 files changed, 232 insertions, 436 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilereventview.cpp b/src/plugins/qmlprofiler/qmlprofilereventview.cpp index d04a0203e0..01d8504510 100644 --- a/src/plugins/qmlprofiler/qmlprofilereventview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilereventview.cpp @@ -68,6 +68,9 @@ Q_GLOBAL_STATIC(Colors, colors) //////////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////////// + class EventsViewItem : public QStandardItem { public: @@ -100,50 +103,52 @@ public: QmlProfilerEventsWidget *q; - Analyzer::IAnalyzerTool *m_profilerTool; + QmlProfilerTool *m_profilerTool; QmlProfilerViewManager *m_viewContainer; QmlProfilerEventsMainView *m_eventTree; - QmlProfilerEventsParentsAndChildrenView *m_eventChildren; - QmlProfilerEventsParentsAndChildrenView *m_eventParents; - QmlProfilerDataModel *m_profilerDataModel; + QmlProfilerEventRelativesView *m_eventChildren; + QmlProfilerEventRelativesView *m_eventParents; - bool m_globalStatsEnabled; + QmlProfilerEventsModelProxy *modelProxy; + bool globalStats; }; QmlProfilerEventsWidget::QmlProfilerEventsWidget(QWidget *parent, - Analyzer::IAnalyzerTool *profilerTool, + QmlProfilerTool *profilerTool, QmlProfilerViewManager *container, - QmlProfilerDataModel *profilerDataModel ) + QmlProfilerModelManager *profilerModelManager ) + : QWidget(parent), d(new QmlProfilerEventsWidgetPrivate(this)) { setObjectName(QLatin1String("QmlProfilerEventsView")); - d->m_profilerDataModel = profilerDataModel; - connect(d->m_profilerDataModel, SIGNAL(stateChanged()), + d->modelProxy = new QmlProfilerEventsModelProxy(profilerModelManager, this); + connect(profilerModelManager, SIGNAL(stateChanged()), this, SLOT(profilerDataModelStateChanged())); - d->m_eventTree = new QmlProfilerEventsMainView(QmlProfilerEventsMainView::EventsView, this, d->m_profilerDataModel); + d->m_eventTree = new QmlProfilerEventsMainView(this, d->modelProxy); connect(d->m_eventTree, SIGNAL(gotoSourceLocation(QString,int,int)), this, SIGNAL(gotoSourceLocation(QString,int,int))); - connect(d->m_eventTree, SIGNAL(showEventInTimeline(int)), this, SIGNAL(showEventInTimeline(int))); - - d->m_eventChildren = new QmlProfilerEventsParentsAndChildrenView( - QmlProfilerEventsParentsAndChildrenView::ChildrenView, - this, - d->m_profilerDataModel); - d->m_eventParents = new QmlProfilerEventsParentsAndChildrenView( - QmlProfilerEventsParentsAndChildrenView::ParentsView, - this, - d->m_profilerDataModel); - connect(d->m_eventTree, SIGNAL(eventSelected(int)), d->m_eventChildren, SLOT(displayEvent(int))); - connect(d->m_eventTree, SIGNAL(eventSelected(int)), d->m_eventParents, SLOT(displayEvent(int))); - connect(d->m_eventChildren, SIGNAL(eventClicked(int)), d->m_eventTree, SLOT(selectEvent(int))); - connect(d->m_eventParents, SIGNAL(eventClicked(int)), d->m_eventTree, SLOT(selectEvent(int))); + connect(d->m_eventTree, SIGNAL(eventSelected(QString)), this, SIGNAL(eventSelectedByHash(QString))); + + d->m_eventChildren = new QmlProfilerEventRelativesView( + profilerModelManager, + new QmlProfilerEventChildrenModelProxy(profilerModelManager, d->modelProxy, this), + this); + d->m_eventParents = new QmlProfilerEventRelativesView( + profilerModelManager, + new QmlProfilerEventParentsModelProxy(profilerModelManager, d->modelProxy, this), + this); + connect(d->m_eventTree, SIGNAL(eventSelected(QString)), d->m_eventChildren, SLOT(displayEvent(QString))); + connect(d->m_eventTree, SIGNAL(eventSelected(QString)), d->m_eventParents, SLOT(displayEvent(QString))); + connect(d->m_eventChildren, SIGNAL(eventClicked(QString)), d->m_eventTree, SLOT(selectEvent(QString))); + connect(d->m_eventParents, SIGNAL(eventClicked(QString)), d->m_eventTree, SLOT(selectEvent(QString))); // widget arrangement QVBoxLayout *groupLayout = new QVBoxLayout; groupLayout->setContentsMargins(0,0,0,0); groupLayout->setSpacing(0); + Core::MiniSplitter *splitterVertical = new Core::MiniSplitter; splitterVertical->addWidget(d->m_eventTree); Core::MiniSplitter *splitterHorizontal = new Core::MiniSplitter; @@ -159,30 +164,17 @@ QmlProfilerEventsWidget::QmlProfilerEventsWidget(QWidget *parent, d->m_profilerTool = profilerTool; d->m_viewContainer = container; - d->m_globalStatsEnabled = true; + d->globalStats = true; } QmlProfilerEventsWidget::~QmlProfilerEventsWidget() { + delete d->modelProxy; delete d; } void QmlProfilerEventsWidget::profilerDataModelStateChanged() { - if (d->m_profilerDataModel) { - QmlProfilerDataModel::State newState = d->m_profilerDataModel->currentState(); - if (newState == QmlProfilerDataModel::Empty) - clear(); - } -} - -void QmlProfilerEventsWidget::switchToV8View() -{ - setObjectName(QLatin1String("QmlProfilerV8ProfileView")); - d->m_eventTree->setViewType(QmlProfilerEventsMainView::V8ProfileView); - d->m_eventParents->setViewType(QmlProfilerEventsParentsAndChildrenView::V8ParentsView); - d->m_eventChildren->setViewType(QmlProfilerEventsParentsAndChildrenView::V8ChildrenView); - setToolTip(tr("Trace information from the v8 JavaScript engine. Available only in Qt5 based applications.")); } void QmlProfilerEventsWidget::clear() @@ -194,9 +186,8 @@ void QmlProfilerEventsWidget::clear() void QmlProfilerEventsWidget::getStatisticsInRange(qint64 rangeStart, qint64 rangeEnd) { - clear(); - d->m_eventTree->getStatisticsInRange(rangeStart, rangeEnd); - d->m_globalStatsEnabled = d->m_eventTree->isRangeGlobal(rangeStart, rangeEnd); + d->modelProxy->limitToRange(rangeStart, rangeEnd); + d->globalStats = (rangeStart == -1) && (rangeEnd == -1); } QModelIndex QmlProfilerEventsWidget::selectedItem() const @@ -215,11 +206,10 @@ void QmlProfilerEventsWidget::contextMenuEvent(QContextMenuEvent *ev) QAction *getLocalStatsAction = 0; QAction *getGlobalStatsAction = 0; - QmlProfilerTool *profilerTool = qobject_cast<QmlProfilerTool *>(d->m_profilerTool); QPoint position = ev->globalPos(); - if (profilerTool) { - QList <QAction *> commonActions = profilerTool->profilerContextMenuActions(); + if (d->m_profilerTool) { + QList <QAction *> commonActions = d->m_profilerTool->profilerContextMenuActions(); foreach (QAction *act, commonActions) { menu.addAction(act); } @@ -231,23 +221,18 @@ void QmlProfilerEventsWidget::contextMenuEvent(QContextMenuEvent *ev) copyRowAction = menu.addAction(tr("Copy Row")); copyTableAction = menu.addAction(tr("Copy Table")); - if (isQml()) { - // only for qml events view, not for v8 - showExtendedStatsAction = menu.addAction(tr("Extended Event Statistics")); - showExtendedStatsAction->setCheckable(true); - showExtendedStatsAction->setChecked(showExtendedStatistics()); - } + showExtendedStatsAction = menu.addAction(tr("Extended Event Statistics")); + showExtendedStatsAction->setCheckable(true); + showExtendedStatsAction->setChecked(showExtendedStatistics()); } - if (isQml()) { - menu.addSeparator(); - getLocalStatsAction = menu.addAction(tr("Limit Events Pane to Current Range")); - if (!d->m_viewContainer->hasValidSelection()) - getLocalStatsAction->setEnabled(false); - getGlobalStatsAction = menu.addAction(tr("Reset Events Pane")); - if (hasGlobalStats()) - getGlobalStatsAction->setEnabled(false); - } + menu.addSeparator(); + getLocalStatsAction = menu.addAction(tr("Limit Events Pane to Current Range")); + if (!d->m_viewContainer->hasValidSelection()) + getLocalStatsAction->setEnabled(false); + getGlobalStatsAction = menu.addAction(tr("Reset Events Pane")); + if (hasGlobalStats()) + getGlobalStatsAction->setEnabled(false); QAction *selectedAction = menu.exec(position); @@ -260,12 +245,8 @@ void QmlProfilerEventsWidget::contextMenuEvent(QContextMenuEvent *ev) getStatisticsInRange(d->m_viewContainer->selectionStart(), d->m_viewContainer->selectionEnd()); } - if (selectedAction == getGlobalStatsAction) { - if (d->m_profilerDataModel) { - getStatisticsInRange(d->m_profilerDataModel->traceStartTime(), - d->m_profilerDataModel->traceEndTime()); - } - } + if (selectedAction == getGlobalStatsAction) + getStatisticsInRange(-1, -1); if (selectedAction == showExtendedStatsAction) setShowExtendedStatistics(!showExtendedStatistics()); } @@ -294,24 +275,20 @@ void QmlProfilerEventsWidget::copyRowToClipboard() const d->m_eventTree->copyRowToClipboard(); } -void QmlProfilerEventsWidget::updateSelectedEvent(int eventId) const +void QmlProfilerEventsWidget::updateSelectedEvent(const QString &eventHash) const { - if (d->m_eventTree->selectedEventId() != eventId) - d->m_eventTree->selectEvent(eventId); + if (d->m_eventTree->selectedEventHash() != eventHash) + d->m_eventTree->selectEvent(eventHash); } void QmlProfilerEventsWidget::selectBySourceLocation(const QString &filename, int line, int column) { - // This slot is used to connect the javascript pane with the qml events pane - // Our javascript trace data does not store column information - // thus we ignore it here - Q_UNUSED(column); - d->m_eventTree->selectEventByLocation(filename, line); + d->m_eventTree->selectEventByLocation(filename, line, column); } bool QmlProfilerEventsWidget::hasGlobalStats() const { - return d->m_globalStatsEnabled; + return d->globalStats; } void QmlProfilerEventsWidget::setShowExtendedStatistics(bool show) @@ -324,15 +301,6 @@ bool QmlProfilerEventsWidget::showExtendedStatistics() const return d->m_eventTree->showExtendedStatistics(); } -bool QmlProfilerEventsWidget::isQml() const -{ - return d->m_eventTree->viewType() == QmlProfilerEventsMainView::EventsView; -} -bool QmlProfilerEventsWidget::isV8() const -{ - return d->m_eventTree->viewType() == QmlProfilerEventsMainView::V8ProfileView; -} - //////////////////////////////////////////////////////////////////////////////////// class QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate @@ -340,17 +308,14 @@ class QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate public: QmlProfilerEventsMainViewPrivate(QmlProfilerEventsMainView *qq) : q(qq) {} - void buildModelFromList(const QList<QmlRangeEventData *> &list, QStandardItem *parentItem ); - void buildV8ModelFromList( const QList<QV8EventData *> &list ); int getFieldCount(); - QString textForItem(QStandardItem *item, bool recursive) const; + QString textForItem(QStandardItem *item, bool recursive = false) const; QmlProfilerEventsMainView *q; - QmlProfilerEventsMainView::ViewTypes m_viewType; - QmlProfilerDataModel *m_profilerDataModel; + QmlProfilerEventsModelProxy *modelProxy; QStandardItemModel *m_model; QList<bool> m_fieldShown; QHash<int, int> m_columnIndex; // maps field enum to column index @@ -362,49 +327,52 @@ public: //////////////////////////////////////////////////////////////////////////////////// -QmlProfilerEventsMainView::QmlProfilerEventsMainView(ViewTypes viewType, - QWidget *parent, - QmlProfilerDataModel *dataModel) - : QTreeView(parent), d(new QmlProfilerEventsMainViewPrivate(this)) +QmlProfilerEventsMainView::QmlProfilerEventsMainView(QWidget *parent, + QmlProfilerEventsModelProxy *modelProxy) +: QmlProfilerTreeView(parent), d(new QmlProfilerEventsMainViewPrivate(this)) { setObjectName(QLatin1String("QmlProfilerEventsTable")); - header()->setResizeMode(QHeaderView::Interactive); - header()->setDefaultSectionSize(100); - header()->setMinimumSectionSize(50); + setSortingEnabled(false); - setFrameStyle(QFrame::NoFrame); d->m_model = new QStandardItemModel(this); setModel(d->m_model); connect(this,SIGNAL(clicked(QModelIndex)), this,SLOT(jumpToItem(QModelIndex))); - d->m_profilerDataModel = dataModel; - connect(d->m_profilerDataModel,SIGNAL(stateChanged()), - this,SLOT(profilerDataModelStateChanged())); - connect(d->m_profilerDataModel,SIGNAL(detailsChanged(int,QString)), - this,SLOT(changeDetailsForEvent(int,QString))); - + d->modelProxy = modelProxy; + connect(d->modelProxy,SIGNAL(dataAvailable()), this, SLOT(buildModel())); +// connect(d->modelProxy,SIGNAL(stateChanged()), +// this,SLOT(profilerDataModelStateChanged())); d->m_firstNumericColumn = 0; d->m_preventSelectBounce = false; d->m_showExtendedStatistics = false; - setViewType(viewType); + setFieldViewable(Name, true); + setFieldViewable(Type, true); + setFieldViewable(TimeInPercent, true); + setFieldViewable(TotalTime, true); + setFieldViewable(SelfTimeInPercent, false); + setFieldViewable(SelfTime, false); + setFieldViewable(CallCount, true); + setFieldViewable(TimePerCall, true); + setFieldViewable(MaxTime, true); + setFieldViewable(MinTime, true); + setFieldViewable(MedianTime, true); + setFieldViewable(Details, true); + + buildModel(); } QmlProfilerEventsMainView::~QmlProfilerEventsMainView() { clear(); + //delete d->modelProxy; delete d->m_model; delete d; } void QmlProfilerEventsMainView::profilerDataModelStateChanged() { - if (d->m_profilerDataModel) { - QmlProfilerDataModel::State newState = d->m_profilerDataModel->currentState(); - if (newState == QmlProfilerDataModel::Done) - buildModel(); - } } void QmlProfilerEventsMainView::setFieldViewable(Fields field, bool show) @@ -419,52 +387,6 @@ void QmlProfilerEventsMainView::setFieldViewable(Fields field, bool show) } } -QmlProfilerEventsMainView::ViewTypes QmlProfilerEventsMainView::viewType() const -{ - return d->m_viewType; -} - -void QmlProfilerEventsMainView::setViewType(ViewTypes type) -{ - d->m_viewType = type; - switch (type) { - case EventsView: { - setObjectName(QLatin1String("QmlProfilerEventsTable")); - setFieldViewable(Name, true); - setFieldViewable(Type, true); - setFieldViewable(Percent, true); - setFieldViewable(TotalDuration, true); - setFieldViewable(SelfPercent, false); - setFieldViewable(SelfDuration, false); - setFieldViewable(CallCount, true); - setFieldViewable(TimePerCall, true); - setFieldViewable(MaxTime, true); - setFieldViewable(MinTime, true); - setFieldViewable(MedianTime, true); - setFieldViewable(Details, true); - break; - } - case V8ProfileView: { - setObjectName(QLatin1String("QmlProfilerV8ProfileTable")); - setFieldViewable(Name, true); - setFieldViewable(Type, false); - setFieldViewable(Percent, true); - setFieldViewable(TotalDuration, true); - setFieldViewable(SelfPercent, true); - setFieldViewable(SelfDuration, true); - setFieldViewable(CallCount, false); - setFieldViewable(TimePerCall, false); - setFieldViewable(MaxTime, false); - setFieldViewable(MinTime, false); - setFieldViewable(MedianTime, false); - setFieldViewable(Details, true); - break; - } - default: break; - } - - buildModel(); -} void QmlProfilerEventsMainView::setHeaderLabels() { @@ -474,53 +396,53 @@ void QmlProfilerEventsMainView::setHeaderLabels() d->m_columnIndex.clear(); if (d->m_fieldShown[Name]) { d->m_columnIndex[Name] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Location"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Location))); d->m_firstNumericColumn++; } if (d->m_fieldShown[Type]) { d->m_columnIndex[Type] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Type"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Type))); d->m_firstNumericColumn++; } - if (d->m_fieldShown[Percent]) { - d->m_columnIndex[Percent] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Time in Percent"))); + if (d->m_fieldShown[TimeInPercent]) { + d->m_columnIndex[TimeInPercent] = fieldIndex; + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(TimeInPercent))); } - if (d->m_fieldShown[TotalDuration]) { - d->m_columnIndex[TotalDuration] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Total Time"))); + if (d->m_fieldShown[TotalTime]) { + d->m_columnIndex[TotalTime] = fieldIndex; + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(TotalTime))); } - if (d->m_fieldShown[SelfPercent]) { + if (d->m_fieldShown[SelfTimeInPercent]) { d->m_columnIndex[Type] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Self Time in Percent"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(SelfTimeInPercent))); } - if (d->m_fieldShown[SelfDuration]) { - d->m_columnIndex[SelfDuration] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Self Time"))); + if (d->m_fieldShown[SelfTime]) { + d->m_columnIndex[SelfTime] = fieldIndex; + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(SelfTime))); } if (d->m_fieldShown[CallCount]) { d->m_columnIndex[CallCount] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Calls"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(CallCount))); } if (d->m_fieldShown[TimePerCall]) { d->m_columnIndex[TimePerCall] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Mean Time"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(TimePerCall))); } if (d->m_fieldShown[MedianTime]) { d->m_columnIndex[MedianTime] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Median Time"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(MedianTime))); } if (d->m_fieldShown[MaxTime]) { d->m_columnIndex[MaxTime] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Longest Time"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(MaxTime))); } if (d->m_fieldShown[MinTime]) { d->m_columnIndex[MinTime] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Shortest Time"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(MinTime))); } if (d->m_fieldShown[Details]) { d->m_columnIndex[Details] = fieldIndex; - d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(tr("Details"))); + d->m_model->setHeaderData(fieldIndex++, Qt::Horizontal, QVariant(displayHeader(Details))); } } @@ -570,47 +492,41 @@ int QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::getFieldCount() void QmlProfilerEventsMainView::buildModel() { - if (d->m_profilerDataModel) { - clear(); - if (d->m_viewType == V8ProfileView) - d->buildV8ModelFromList( d->m_profilerDataModel->getV8Events() ); - else - d->buildModelFromList( d->m_profilerDataModel->getEventDescriptions(), d->m_model->invisibleRootItem() ); - - setShowExtendedStatistics(d->m_showExtendedStatistics); + clear(); + parseModelProxy(); + setShowExtendedStatistics(d->m_showExtendedStatistics); - setRootIsDecorated(false); - setSortingEnabled(true); - sortByColumn(d->m_firstNumericColumn,Qt::DescendingOrder); + setRootIsDecorated(false); + setSortingEnabled(true); + sortByColumn(d->m_firstNumericColumn,Qt::DescendingOrder); - expandAll(); - if (d->m_fieldShown[Name]) - resizeColumnToContents(0); + expandAll(); + if (d->m_fieldShown[Name]) + resizeColumnToContents(0); - if (d->m_fieldShown[Type]) - resizeColumnToContents(d->m_fieldShown[Name]?1:0); - collapseAll(); - } + if (d->m_fieldShown[Type]) + resizeColumnToContents(d->m_fieldShown[Name]?1:0); + collapseAll(); } -void QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::buildModelFromList( const QList<QmlRangeEventData *> &list, QStandardItem *parentItem) +void QmlProfilerEventsMainView::parseModelProxy() { - foreach (QmlRangeEventData *binding, list) { - if (binding->calls == 0) - continue; - + const QList <QmlProfilerEventsModelProxy::QmlEventStats> eventList = d->modelProxy->getData(); + foreach (const QmlProfilerEventsModelProxy::QmlEventStats &event, eventList) { + QStandardItem *parentItem = d->m_model->invisibleRootItem(); QList<QStandardItem *> newRow; - if (m_fieldShown[Name]) - newRow << new EventsViewItem(binding->displayName); - if (m_fieldShown[Type]) { - QString typeString = QmlProfilerEventsMainView::nameForType(binding->eventType); + if (d->m_fieldShown[Name]) + newRow << new EventsViewItem(event.displayName); + + if (d->m_fieldShown[Type]) { + QString typeString = QmlProfilerEventsMainView::nameForType(event.eventType); QString toolTipText; - if (binding->eventType == Binding) { - if (binding->bindingType == (int)OptimizedBinding) { + if (event.eventType == Binding) { + if (event.bindingType == (int)OptimizedBinding) { typeString = typeString + tr(" (Opt)"); toolTipText = tr("Binding is evaluated by the optimized engine."); - } else if (binding->bindingType == (int)V8Binding) { + } else if (event.bindingType == (int)V8Binding) { toolTipText = tr("Binding not optimized (e.g. has side effects or assignments,\n" "references to elements in other files, loops, etc.)"); @@ -622,44 +538,44 @@ void QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::buildModelFrom newRow.last()->setToolTip(toolTipText); } - if (m_fieldShown[Percent]) { - newRow << new EventsViewItem(QString::number(binding->percentOfTime,'f',2)+QLatin1String(" %")); - newRow.last()->setData(QVariant(binding->percentOfTime)); + if (d->m_fieldShown[TimeInPercent]) { + newRow << new EventsViewItem(QString::number(event.percentOfTime,'f',2)+QLatin1String(" %")); + newRow.last()->setData(QVariant(event.percentOfTime)); } - if (m_fieldShown[TotalDuration]) { - newRow << new EventsViewItem(displayTime(binding->duration)); - newRow.last()->setData(QVariant(binding->duration)); + if (d->m_fieldShown[TotalTime]) { + newRow << new EventsViewItem(displayTime(event.duration)); + newRow.last()->setData(QVariant(event.duration)); } - if (m_fieldShown[CallCount]) { - newRow << new EventsViewItem(QString::number(binding->calls)); - newRow.last()->setData(QVariant(binding->calls)); + if (d->m_fieldShown[CallCount]) { + newRow << new EventsViewItem(QString::number(event.calls)); + newRow.last()->setData(QVariant(event.calls)); } - if (m_fieldShown[TimePerCall]) { - newRow << new EventsViewItem(displayTime(binding->timePerCall)); - newRow.last()->setData(QVariant(binding->timePerCall)); + if (d->m_fieldShown[TimePerCall]) { + newRow << new EventsViewItem(displayTime(event.timePerCall)); + newRow.last()->setData(QVariant(event.timePerCall)); } - if (m_fieldShown[MedianTime]) { - newRow << new EventsViewItem(displayTime(binding->medianTime)); - newRow.last()->setData(QVariant(binding->medianTime)); + if (d->m_fieldShown[MedianTime]) { + newRow << new EventsViewItem(displayTime(event.medianTime)); + newRow.last()->setData(QVariant(event.medianTime)); } - if (m_fieldShown[MaxTime]) { - newRow << new EventsViewItem(displayTime(binding->maxTime)); - newRow.last()->setData(QVariant(binding->maxTime)); + if (d->m_fieldShown[MaxTime]) { + newRow << new EventsViewItem(displayTime(event.maxTime)); + newRow.last()->setData(QVariant(event.maxTime)); } - if (m_fieldShown[MinTime]) { - newRow << new EventsViewItem(displayTime(binding->minTime)); - newRow.last()->setData(QVariant(binding->minTime)); + if (d->m_fieldShown[MinTime]) { + newRow << new EventsViewItem(displayTime(event.minTime)); + newRow.last()->setData(QVariant(event.minTime)); } - if (m_fieldShown[Details]) { - newRow << new EventsViewItem(binding->details); - newRow.last()->setData(QVariant(binding->details)); + if (d->m_fieldShown[Details]) { + newRow << new EventsViewItem(event.details); + newRow.last()->setData(QVariant(event.details)); } @@ -670,16 +586,17 @@ void QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::buildModelFrom item->setEditable(false); // metadata - newRow.at(0)->setData(QVariant(binding->eventHashStr),EventHashStrRole); - newRow.at(0)->setData(QVariant(binding->location.filename),FilenameRole); - newRow.at(0)->setData(QVariant(binding->location.line),LineRole); - newRow.at(0)->setData(QVariant(binding->location.column),ColumnRole); - newRow.at(0)->setData(QVariant(binding->eventId),EventIdRole); - if (binding->isBindingLoop) + newRow.at(0)->setData(QVariant(event.eventHashStr),EventHashStrRole); + newRow.at(0)->setData(QVariant(event.location.filename),FilenameRole); + newRow.at(0)->setData(QVariant(event.location.line),LineRole); + newRow.at(0)->setData(QVariant(event.location.column),ColumnRole); + + if (event.isBindingLoop) { foreach (QStandardItem *item, newRow) { item->setBackground(colors()->bindingLoopBackground); item->setToolTip(tr("Binding loop detected.")); } + } // append parentItem->appendRow(newRow); @@ -687,58 +604,6 @@ void QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::buildModelFrom } } -void QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::buildV8ModelFromList(const QList<QV8EventData *> &list) -{ - for (int index = 0; index < list.count(); index++) { - QV8EventData *v8event = list.at(index); - QList<QStandardItem *> newRow; - - if (m_fieldShown[Name]) - newRow << new EventsViewItem(v8event->displayName); - - if (m_fieldShown[Percent]) { - newRow << new EventsViewItem(QString::number(v8event->totalPercent,'f',2)+QLatin1String(" %")); - newRow.last()->setData(QVariant(v8event->totalPercent)); - } - - if (m_fieldShown[TotalDuration]) { - newRow << new EventsViewItem(displayTime(v8event->totalTime)); - newRow.last()->setData(QVariant(v8event->totalTime)); - } - - if (m_fieldShown[SelfPercent]) { - newRow << new EventsViewItem(QString::number(v8event->selfPercent,'f',2)+QLatin1String(" %")); - newRow.last()->setData(QVariant(v8event->selfPercent)); - } - - if (m_fieldShown[SelfDuration]) { - newRow << new EventsViewItem(displayTime(v8event->selfTime)); - newRow.last()->setData(QVariant(v8event->selfTime)); - } - - if (m_fieldShown[Details]) { - newRow << new EventsViewItem(v8event->functionName); - newRow.last()->setData(QVariant(v8event->functionName)); - } - - if (!newRow.isEmpty()) { - // no edit - foreach (QStandardItem *item, newRow) - item->setEditable(false); - - // metadata - newRow.at(0)->setData(QString::fromLatin1("%1:%2").arg(v8event->filename, QString::number(v8event->line)), EventHashStrRole); - newRow.at(0)->setData(QVariant(v8event->filename), FilenameRole); - newRow.at(0)->setData(QVariant(v8event->line), LineRole); - newRow.at(0)->setData(QVariant(0),ColumnRole); // v8 events have no column info - newRow.at(0)->setData(QVariant(v8event->eventId), EventIdRole); - - // append - m_model->invisibleRootItem()->appendRow(newRow); - } - } -} - QString QmlProfilerEventsMainView::displayTime(double time) { if (time < 1e6) @@ -763,26 +628,16 @@ QString QmlProfilerEventsMainView::nameForType(int typeNumber) void QmlProfilerEventsMainView::getStatisticsInRange(qint64 rangeStart, qint64 rangeEnd) { - if (d->m_profilerDataModel) - d->m_profilerDataModel->compileStatistics(rangeStart, rangeEnd); - buildModel(); -} - -bool QmlProfilerEventsMainView::isRangeGlobal(qint64 rangeStart, qint64 rangeEnd) const -{ - if (d->m_profilerDataModel) - return d->m_profilerDataModel->traceStartTime() == rangeStart && d->m_profilerDataModel->traceEndTime() == rangeEnd; - else - return true; + d->modelProxy->limitToRange(rangeStart, rangeEnd); } -int QmlProfilerEventsMainView::selectedEventId() const +QString QmlProfilerEventsMainView::selectedEventHash() const { QModelIndex index = selectedItem(); if (!index.isValid()) - return -1; + return QString(); QStandardItem *item = d->m_model->item(index.row(), 0); - return item->data(EventIdRole).toInt(); + return item->data(EventHashStrRole).toString(); } @@ -807,20 +662,16 @@ void QmlProfilerEventsMainView::jumpToItem(const QModelIndex &index) emit gotoSourceLocation(fileName, line, column); // show in callers/callees subwindow - emit eventSelected(infoItem->data(EventIdRole).toInt()); - - // show in timelinerenderer - if (d->m_viewType == EventsView) - emit showEventInTimeline(infoItem->data(EventIdRole).toInt()); + emit eventSelected(infoItem->data(EventHashStrRole).toString()); d->m_preventSelectBounce = false; } -void QmlProfilerEventsMainView::selectEvent(int eventId) +void QmlProfilerEventsMainView::selectEvent(const QString &eventHash) { for (int i=0; i<d->m_model->rowCount(); i++) { QStandardItem *infoItem = d->m_model->item(i, 0); - if (infoItem->data(EventIdRole).toInt() == eventId) { + if (infoItem->data(EventHashStrRole).toString() == eventHash) { setCurrentIndex(d->m_model->indexFromItem(infoItem)); jumpToItem(currentIndex()); return; @@ -828,14 +679,18 @@ void QmlProfilerEventsMainView::selectEvent(int eventId) } } -void QmlProfilerEventsMainView::selectEventByLocation(const QString &filename, int line) +void QmlProfilerEventsMainView::selectEventByLocation(const QString &filename, int line, int column) { if (d->m_preventSelectBounce) return; for (int i=0; i<d->m_model->rowCount(); i++) { QStandardItem *infoItem = d->m_model->item(i, 0); - if (currentIndex() != d->m_model->indexFromItem(infoItem) && infoItem->data(FilenameRole).toString() == filename && infoItem->data(LineRole).toInt() == line) { + if (currentIndex() != d->m_model->indexFromItem(infoItem) && + infoItem->data(FilenameRole).toString() == filename && + infoItem->data(LineRole).toInt() == line && + (column == -1 || + infoItem->data(ColumnRole).toInt() == column)) { setCurrentIndex(d->m_model->indexFromItem(infoItem)); jumpToItem(currentIndex()); return; @@ -852,23 +707,7 @@ QModelIndex QmlProfilerEventsMainView::selectedItem() const return sel.first(); } -void QmlProfilerEventsMainView::changeDetailsForEvent(int eventId, const QString &newString) -{ - // available only for QML - if (d->m_viewType != EventsView) - return; - - for (int i=0; i<d->m_model->rowCount(); i++) { - QStandardItem *infoItem = d->m_model->item(i, 0); - if (infoItem->data(EventIdRole).toInt() == eventId) { - d->m_model->item(i,d->m_columnIndex[Details])->setData(QVariant(newString),Qt::DisplayRole); - d->m_model->item(i,d->m_columnIndex[Details])->setData(QVariant(newString)); - return; - } - } -} - -QString QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::textForItem(QStandardItem *item, bool recursive = true) const +QString QmlProfilerEventsMainView::QmlProfilerEventsMainViewPrivate::textForItem(QStandardItem *item, bool recursive) const { QString str; @@ -932,116 +771,82 @@ void QmlProfilerEventsMainView::copyRowToClipboard() const //////////////////////////////////////////////////////////////////////////////////// -QmlProfilerEventsParentsAndChildrenView::QmlProfilerEventsParentsAndChildrenView( - SubViewType subtableType, QWidget *parent, QmlProfilerDataModel *model) - : QTreeView(parent) +class QmlProfilerEventRelativesView::QmlProfilerEventParentsViewPrivate +{ +public: + QmlProfilerEventParentsViewPrivate(QmlProfilerEventRelativesView *qq):q(qq) {} + ~QmlProfilerEventParentsViewPrivate() {} + + QmlProfilerEventRelativesModelProxy *modelProxy; + + QmlProfilerEventRelativesView *q; +}; + +QmlProfilerEventRelativesView::QmlProfilerEventRelativesView(QmlProfilerModelManager *modelManager, QmlProfilerEventRelativesModelProxy *modelProxy, QWidget *parent) + : QmlProfilerTreeView(parent), d(new QmlProfilerEventParentsViewPrivate(this)) { - m_profilerDataModel = model; + Q_UNUSED(modelManager); + setSortingEnabled(false); + d->modelProxy = modelProxy; setModel(new QStandardItemModel(this)); setRootIsDecorated(false); - setFrameStyle(QFrame::NoFrame); - m_subtableType = subtableType; updateHeader(); connect(this,SIGNAL(clicked(QModelIndex)), this,SLOT(jumpToItem(QModelIndex))); } -QmlProfilerEventsParentsAndChildrenView::~QmlProfilerEventsParentsAndChildrenView() -{ -} - -void QmlProfilerEventsParentsAndChildrenView::setViewType(SubViewType type) +QmlProfilerEventRelativesView::~QmlProfilerEventRelativesView() { - m_subtableType = type; - updateHeader(); + delete d; } -void QmlProfilerEventsParentsAndChildrenView::displayEvent(int eventId) +void QmlProfilerEventRelativesView::displayEvent(const QString &eventHash) { - if (!m_profilerDataModel) - return; - - bool isV8 = m_subtableType == V8ParentsView || m_subtableType == V8ChildrenView; - bool isChildren = m_subtableType == ChildrenView || m_subtableType == V8ChildrenView; - - if (isV8) { - QV8EventData *v8event = m_profilerDataModel->v8EventDescription(eventId); - if (v8event) { - if (isChildren) { - QList <QV8EventSub *> childrenList = v8event->childrenHash.values(); - rebuildTree((QObject *)&childrenList); - } - else { - QList <QV8EventSub *> parentList = v8event->parentHash.values(); - rebuildTree((QObject *)&parentList); - } - } - } else { - QmlRangeEventData *qmlEvent = m_profilerDataModel->eventDescription(eventId); - if (qmlEvent) { - if (isChildren) { - QList <QmlRangeEventRelative *> childrenList = qmlEvent->childrenHash.values(); - rebuildTree((QObject *)&childrenList); - } - else { - QList <QmlRangeEventRelative *> parentList = qmlEvent->parentHash.values(); - rebuildTree((QObject *)&parentList); - } - } - } + rebuildTree(d->modelProxy->getData(eventHash)); updateHeader(); resizeColumnToContents(0); setSortingEnabled(true); - if (isV8) - sortByColumn(1); - else - sortByColumn(2); + sortByColumn(2); } -void QmlProfilerEventsParentsAndChildrenView::rebuildTree(void *profilerDataModel) +void QmlProfilerEventRelativesView::rebuildTree(QmlProfilerEventRelativesModelProxy::QmlEventRelativesMap eventMap) { Q_ASSERT(treeModel()); treeModel()->clear(); QStandardItem *topLevelItem = treeModel()->invisibleRootItem(); - bool isV8 = m_subtableType == V8ParentsView || m_subtableType == V8ChildrenView; - - QList <QmlRangeEventRelative *> *qmlList = static_cast< QList <QmlRangeEventRelative *> *>(profilerDataModel); - QList <QV8EventSub*> *v8List = static_cast< QList <QV8EventSub *> *>(profilerDataModel); - int listLength; - if (!isV8) - listLength = qmlList->length(); - else - listLength = v8List->length(); - - for (int index=0; index < listLength; index++) { + //foreach (const QmlProfilerEventParentsModelProxy::QmlEventParentData &event, eventMap.values()) { + foreach (const QString &key, eventMap.keys()) { + const QmlProfilerEventRelativesModelProxy::QmlEventRelativesData &event = eventMap[key]; QList<QStandardItem *> newRow; - if (!isV8) { - QmlRangeEventRelative *event = qmlList->at(index); - - newRow << new EventsViewItem(event->reference->displayName); - newRow << new EventsViewItem(QmlProfilerEventsMainView::nameForType(event->reference->eventType)); - newRow << new EventsViewItem(QmlProfilerEventsMainView::displayTime(event->duration)); - newRow << new EventsViewItem(QString::number(event->calls)); - newRow << new EventsViewItem(event->reference->details); - newRow.at(0)->setData(QVariant(event->reference->eventId), EventIdRole); - newRow.at(2)->setData(QVariant(event->duration)); - newRow.at(3)->setData(QVariant(event->calls)); - if (event->inLoopPath) - foreach (QStandardItem *item, newRow) { - item->setBackground(colors()->bindingLoopBackground); - item->setToolTip(tr("Part of binding loop.")); - } - } else { - QV8EventSub *event = v8List->at(index); - newRow << new EventsViewItem(event->reference->displayName); - newRow << new EventsViewItem(QmlProfilerEventsMainView::displayTime(event->totalTime)); - newRow << new EventsViewItem(event->reference->functionName); - newRow.at(0)->setData(QVariant(event->reference->eventId), EventIdRole); - newRow.at(1)->setData(QVariant(event->totalTime)); + + // ToDo: here we were going to search for the data in the other modelproxy + // maybe we should store the data in this proxy and get it here + // no indirections at this level of abstraction! + newRow << new EventsViewItem(event.displayName); + newRow << new EventsViewItem(QmlProfilerEventsMainView::nameForType(event.eventType)); + newRow << new EventsViewItem(QmlProfilerEventsMainView::displayTime(event.duration)); + newRow << new EventsViewItem(QString::number(event.calls)); + newRow << new EventsViewItem(event.details); + +// newRow << new EventsViewItem(event->reference->displayName); +// newRow << new EventsViewItem(QmlProfilerEventsMainView::nameForType(event->reference->eventType)); +// newRow << new EventsViewItem(QmlProfilerEventsMainView::displayTime(event->duration)); +// newRow << new EventsViewItem(QString::number(event->calls)); +// newRow << new EventsViewItem(event->reference->details); + newRow.at(0)->setData(QVariant(key), EventHashStrRole); + newRow.at(2)->setData(QVariant(event.duration)); + newRow.at(3)->setData(QVariant(event.calls)); + + if (event.isBindingLoop) { + foreach (QStandardItem *item, newRow) { + item->setBackground(colors()->bindingLoopBackground); + item->setToolTip(tr("Part of binding loop.")); + } } + foreach (QStandardItem *item, newRow) item->setEditable(false); @@ -1049,7 +854,7 @@ void QmlProfilerEventsParentsAndChildrenView::rebuildTree(void *profilerDataMode } } -void QmlProfilerEventsParentsAndChildrenView::clear() +void QmlProfilerEventRelativesView::clear() { if (treeModel()) { treeModel()->clear(); @@ -1057,52 +862,43 @@ void QmlProfilerEventsParentsAndChildrenView::clear() } } -void QmlProfilerEventsParentsAndChildrenView::updateHeader() +void QmlProfilerEventRelativesView::updateHeader() { - bool isV8 = m_subtableType == V8ParentsView || m_subtableType == V8ChildrenView; - bool isChildren = m_subtableType == ChildrenView || m_subtableType == V8ChildrenView; - - header()->setResizeMode(QHeaderView::Interactive); - header()->setDefaultSectionSize(100); - header()->setMinimumSectionSize(50); + bool calleesView = qobject_cast<QmlProfilerEventChildrenModelProxy *>(d->modelProxy) != 0; if (treeModel()) { - if (isV8) - treeModel()->setColumnCount(3); - else - treeModel()->setColumnCount(5); + treeModel()->setColumnCount(5); int columnIndex = 0; - if (isChildren) - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Callee"))); + if (calleesView) + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(Callee))); else - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Caller"))); + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(Caller))); + + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(Type))); - if (!isV8) - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Type"))); + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(TotalTime))); - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Total Time"))); + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(CallCount))); - if (!isV8) - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Calls"))); - if (isChildren) - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Callee Description"))); + if (calleesView) + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(CalleeDescription))); else - treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(tr("Caller Description"))); + treeModel()->setHeaderData(columnIndex++, Qt::Horizontal, QVariant(displayHeader(CallerDescription))); } } -QStandardItemModel *QmlProfilerEventsParentsAndChildrenView::treeModel() +QStandardItemModel *QmlProfilerEventRelativesView::treeModel() { return qobject_cast<QStandardItemModel *>(model()); } -void QmlProfilerEventsParentsAndChildrenView::jumpToItem(const QModelIndex &index) +void QmlProfilerEventRelativesView::jumpToItem(const QModelIndex &index) { if (treeModel()) { QStandardItem *infoItem = treeModel()->item(index.row(), 0); - emit eventClicked(infoItem->data(EventIdRole).toInt()); + emit eventClicked(infoItem->data(EventHashStrRole).toString()); } } |