diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-03-23 12:43:16 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-04-16 13:35:33 +0000 |
commit | 495b9aa9c20be71dabf67a4296e86a17f0725c0a (patch) | |
tree | d5589e36b43d54705d858c8c0d226e8a555c6bfa /src/plugins/qmlprofiler | |
parent | 42386dbdbcda06f192f61605111e3ea4e186a283 (diff) | |
download | qt-creator-495b9aa9c20be71dabf67a4296e86a17f0725c0a.tar.gz |
QmlProfiler: Make statistics models QAbstractItemModels
This way we will be able to replace the QStandardItemModels in a next
step.
Change-Id: I863fde958d29c8bf8c36aa1f501cb1224720ad7a
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/qmlprofiler')
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp | 310 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h | 55 | ||||
-rw-r--r-- | src/plugins/qmlprofiler/qmlprofilerstatisticsview.h | 33 |
3 files changed, 362 insertions, 36 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp index 96115309b2..9f49405880 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp @@ -26,6 +26,7 @@ #include "qmlprofilerstatisticsmodel.h" #include "qmlprofilermodelmanager.h" +#include <timeline/timelineformattime.h> #include <utils/algorithm.h> #include <utils/qtcassert.h> @@ -214,6 +215,189 @@ void QmlProfilerStatisticsModel::setRelativesModel(QmlProfilerStatisticsRelative m_calleesModel = relative; } +int QmlProfilerStatisticsModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : m_data.count() + 1; +} + +int QmlProfilerStatisticsModel::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : MaxMainField; +} + +QVariant QmlProfilerStatisticsModel::dataForMainEntry(const QModelIndex &index, int role) const +{ + switch (role) { + case FilterRole: + return m_rootDuration > 0 ? "+" : "-"; + case TypeIdRole: + return -1; + case Qt::TextColorRole: + return Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor); + case SortRole: + switch (index.column()) { + case MainTimeInPercent: + return 100; + case MainSelfTimeInPercent: + case MainSelfTime: + return 0; + case MainTotalTime: + case MainTimePerCall: + case MainMedianTime: + case MainMaxTime: + case MainMinTime: + return m_rootDuration; + } + Q_FALLTHROUGH(); + case Qt::DisplayRole: + switch (index.column()) { + case MainLocation: + return "<program>"; + case MainTimeInPercent: + return "100 %"; + case MainSelfTimeInPercent: + return "0.00 %"; + case MainSelfTime: + return Timeline::formatTime(0); + case MainCallCount: + return m_rootDuration > 0 ? 1 : 0; + case MainTotalTime: + case MainTimePerCall: + case MainMedianTime: + case MainMaxTime: + case MainMinTime: + return Timeline::formatTime(m_rootDuration); + case MainDetails: + return tr("Main program"); + default: + break; + } + Q_FALLTHROUGH(); + default: + return QVariant(); + } +} + +QVariant QmlProfilerStatisticsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (index.row() == m_data.count()) + return dataForMainEntry(index, role); + + const int typeIndex = index.row(); + const QmlEventType &type = m_modelManager->eventTypes().at(typeIndex); + const QmlEventStats &stats = m_data.at(typeIndex); + + switch (role) { + case FilterRole: + return stats.calls > 0 ? "+" : "-"; + case TypeIdRole: + return typeIndex; + case FilenameRole: + return type.location().filename(); + case LineRole: + return type.location().line(); + case ColumnRole: + return type.location().column(); + case Qt::ToolTipRole: + if (stats.recursive > 0) { + return (tr("+%1 in recursive calls") + .arg(Timeline::formatTime(stats.recursive))); + } else { + auto it = m_notes.constFind(typeIndex); + return it == m_notes.constEnd() ? QString() : it.value(); + } + case Qt::TextColorRole: + return (stats.recursive > 0 || m_notes.contains(typeIndex)) + ? Utils::creatorTheme()->color(Utils::Theme::Timeline_HighlightColor) + : Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor); + case SortRole: + switch (index.column()) { + case MainLocation: + return type.displayName(); + case MainTimeInPercent: + return durationPercent(typeIndex); + case MainTotalTime: + return stats.totalNonRecursive(); + case MainSelfTimeInPercent: + return durationSelfPercent(typeIndex); + case MainSelfTime: + return stats.self; + case MainTimePerCall: + return stats.average(); + case MainMedianTime: + return stats.median; + case MainMaxTime: + return stats.maximum; + case MainMinTime: + return stats.minimum; + case MainDetails: + return type.data(); + default: + break; + } + Q_FALLTHROUGH(); // Rest is same as Qt::DisplayRole + case Qt::DisplayRole: + switch (index.column()) { + case MainLocation: + return type.displayName().isEmpty() ? tr("<bytecode>") : type.displayName(); + case MainType: + return nameForType(type.rangeType()); + case MainTimeInPercent: + return QString::fromLatin1("%1 %").arg(durationPercent(typeIndex), 0, 'f', 2); + case MainTotalTime: + return Timeline::formatTime(stats.totalNonRecursive()); + case MainSelfTimeInPercent: + return QString::fromLatin1("%1 %").arg(durationSelfPercent(typeIndex), 0, 'f', 2); + case MainSelfTime: + return Timeline::formatTime(stats.self); + case MainCallCount: + return stats.calls; + case MainTimePerCall: + return Timeline::formatTime(stats.average()); + case MainMedianTime: + return Timeline::formatTime(stats.median); + case MainMaxTime: + return Timeline::formatTime(stats.maximum); + case MainMinTime: + return Timeline::formatTime(stats.minimum); + case MainDetails: + return type.data().isEmpty() ? tr("Source code not available") + : type.data(); + default: + QTC_ASSERT(false, return QVariant()); + } + default: + return QVariant(); + } +} + +QVariant QmlProfilerStatisticsModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole || orientation != Qt::Horizontal) + return QAbstractTableModel::headerData(section, orientation, role); + + switch (section) { + case MainCallCount: return tr("Calls"); + case MainDetails: return tr("Details"); + case MainLocation: return tr("Location"); + case MainMaxTime: return tr("Longest Time"); + case MainTimePerCall: return tr("Mean Time"); + case MainSelfTime: return tr("Self Time"); + case MainSelfTimeInPercent: return tr("Self Time in Percent"); + case MainMinTime: return tr("Shortest Time"); + case MainTimeInPercent: return tr("Time in Percent"); + case MainTotalTime: return tr("Total Time"); + case MainType: return tr("Type"); + case MainMedianTime: return tr("Median Time"); + case MaxMainField: + default: QTC_ASSERT(false, return QString()); + } +} + void QmlProfilerStatisticsModel::modelManagerStateChanged() { if (m_modelManager->state() == QmlProfilerModelManager::ClearingData) @@ -402,6 +586,131 @@ QmlProfilerStatisticsRelation QmlProfilerStatisticsRelativesModel::relation() co return m_relation; } +int QmlProfilerStatisticsRelativesModel::rowCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : m_data[m_relativeTypeIndex].count(); +} + +int QmlProfilerStatisticsRelativesModel::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : MaxRelativeField; +} + +QVariant QmlProfilerStatisticsRelativesModel::dataForMainEntry(qint64 totalDuration, int role, + int column) const +{ + switch (role) { + case TypeIdRole: + return -1; + case Qt::TextColorRole: + return Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor); + case SortRole: + if (column == RelativeTotalTime) + return totalDuration; + Q_FALLTHROUGH(); // rest is same as Qt::DisplayRole + case Qt::DisplayRole: + switch (column) { + case RelativeLocation: return "<program>"; + case RelativeTotalTime: return Timeline::formatTime(totalDuration); + case RelativeCallCount: return 1; + case RelativeDetails: return tr("Main Program"); + } + default: + return QVariant(); + } +} + +QVariant QmlProfilerStatisticsRelativesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + const int row = index.row(); + + auto main_it = m_data.find(m_relativeTypeIndex); + QTC_ASSERT(main_it != m_data.end(), return QVariant()); + + const QVector<QmlStatisticsRelativesData> &data = main_it.value(); + QTC_ASSERT(row >= 0 && row < data.length(), return QVariant()); + + const QmlStatisticsRelativesData &stats = data.at(row); + + if (stats.typeIndex < 0) + return dataForMainEntry(stats.duration, role, index.column()); + + const QmlEventType &type = m_modelManager->eventTypes().at(stats.typeIndex); + + switch (role) { + case TypeIdRole: + return stats.typeIndex; + case FilenameRole: + return type.location().filename(); + case LineRole: + return type.location().line(); + case ColumnRole: + return type.location().column(); + case Qt::ToolTipRole: + return stats.isRecursive ? tr("called recursively") : QString(); + case Qt::TextColorRole: + return stats.isRecursive + ? Utils::creatorTheme()->color(Utils::Theme::Timeline_HighlightColor) + : Utils::creatorTheme()->color(Utils::Theme::Timeline_TextColor); + case SortRole: + switch (index.column()) { + case RelativeLocation: + return type.displayName(); + case RelativeTotalTime: + return stats.duration; + case RelativeDetails: + return type.data(); + default: break; + } + Q_FALLTHROUGH(); // rest is same as Qt::DisplayRole + case Qt::DisplayRole: + switch (index.column()) { + case RelativeLocation: + return type.displayName().isEmpty() ? tr("<bytecode>") : type.displayName(); + case RelativeType: + return QmlProfilerStatisticsModel::nameForType(type.rangeType()); + case RelativeTotalTime: + return Timeline::formatTime(stats.duration); + case RelativeCallCount: + return stats.calls; + case RelativeDetails: + return type.data().isEmpty() ? tr("Source code not available") + : type.data(); + default: + QTC_ASSERT(false, return QVariant()); + } + default: + return QVariant(); + } +} + +QVariant QmlProfilerStatisticsRelativesModel::headerData(int section, Qt::Orientation orientation, + int role) const +{ + if (role != Qt::DisplayRole || orientation != Qt::Horizontal) + return QAbstractTableModel::headerData(section, orientation, role); + + switch (section) { + case RelativeLocation: + return relation() == QmlProfilerStatisticsCallees ? tr("Callee") : tr("Caller"); + case RelativeType: + return tr("Type"); + case RelativeTotalTime: + return tr("Total Time"); + case RelativeCallCount: + return tr("Calls"); + case RelativeDetails: + return relation() == QmlProfilerStatisticsCallees ? tr("Callee Description") + : tr("Caller Description"); + case MaxRelativeField: + default: + QTC_ASSERT(false, return QString()); + } +} + int QmlProfilerStatisticsRelativesModel::count() const { return m_data.count(); @@ -409,6 +718,7 @@ int QmlProfilerStatisticsRelativesModel::count() const void QmlProfilerStatisticsRelativesModel::clear() { + m_relativeTypeIndex = std::numeric_limits<int>::max(); m_data.clear(); m_callStack.clear(); m_compileStack.clear(); diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h index af53a56680..7b925acc9c 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h @@ -35,8 +35,8 @@ #include <QHash> #include <QStack> #include <QVector> -#include <QObject> #include <QPointer> +#include <QAbstractTableModel> namespace QmlProfiler { class QmlProfilerModelManager; @@ -47,7 +47,41 @@ enum QmlProfilerStatisticsRelation { QmlProfilerStatisticsCallers }; -class QmlProfilerStatisticsModel : public QObject +enum ItemRole { + SortRole = Qt::UserRole + 1, // Sort by data, not by displayed string + FilterRole, // Filter out non-range types + TypeIdRole, + FilenameRole, + LineRole, + ColumnRole +}; + +enum MainField { + MainLocation, + MainType, + MainTimeInPercent, + MainTotalTime, + MainSelfTimeInPercent, + MainSelfTime, + MainCallCount, + MainTimePerCall, + MainMedianTime, + MainMaxTime, + MainMinTime, + MainDetails, + MaxMainField +}; + +enum RelativeField { + RelativeLocation, + RelativeType, + RelativeTotalTime, + RelativeCallCount, + RelativeDetails, + MaxRelativeField +}; + +class QmlProfilerStatisticsModel : public QAbstractTableModel { Q_OBJECT public: @@ -118,6 +152,11 @@ public: void setRelativesModel(QmlProfilerStatisticsRelativesModel *childModel, QmlProfilerStatisticsRelation relation); + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + signals: void dataAvailable(); void notesAvailable(int typeIndex); @@ -129,6 +168,8 @@ private: void modelManagerStateChanged(); void notesChanged(int typeIndex); + QVariant dataForMainEntry(const QModelIndex &index, int role) const; + QVector<QmlEventStats> m_data; QPointer<QmlProfilerStatisticsRelativesModel> m_calleesModel; @@ -144,7 +185,7 @@ private: qint64 m_rootDuration = 0; }; -class QmlProfilerStatisticsRelativesModel : public QObject +class QmlProfilerStatisticsRelativesModel : public QAbstractTableModel { Q_OBJECT public: @@ -173,13 +214,21 @@ public: QmlProfilerStatisticsRelation relation() const; + int rowCount(const QModelIndex &parent) const override; + int columnCount(const QModelIndex &parent) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; signals: void dataAvailable(); protected: + QVariant dataForMainEntry(qint64 totalDuration, int role, int column) const; + QHash<int, QVector<QmlStatisticsRelativesData>> m_data; QPointer<QmlProfilerModelManager> m_modelManager; + int m_relativeTypeIndex = std::numeric_limits<int>::max(); + struct Frame { Frame(qint64 startTime = 0, int typeId = -1) : startTime(startTime), typeId(typeId) {} qint64 startTime; diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h index 3123c84ec0..88dd51ef58 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h @@ -42,39 +42,6 @@ namespace Internal { class QmlProfilerStatisticsMainView; class QmlProfilerStatisticsRelativesView; -enum ItemRole { - SortRole = Qt::UserRole + 1, // Sort by data, not by displayed string - TypeIdRole, - FilenameRole, - LineRole, - ColumnRole -}; - -enum MainField { - MainLocation, - MainType, - MainTimeInPercent, - MainTotalTime, - MainSelfTimeInPercent, - MainSelfTime, - MainCallCount, - MainTimePerCall, - MainMedianTime, - MainMaxTime, - MainMinTime, - MainDetails, - MaxMainField -}; - -enum RelativeField { - RelativeLocation, - RelativeType, - RelativeTotalTime, - RelativeCallCount, - RelativeDetails, - MaxRelativeField -}; - class QmlProfilerStatisticsView : public QmlProfilerEventsView { Q_OBJECT |