diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2018-03-23 13:37:37 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2018-04-16 13:35:44 +0000 |
commit | 4aa432bb9a806843b40369316155df7393f6e195 (patch) | |
tree | 98d10876b8b1b6269440816cd493ff0aa052562a /src/plugins/qmlprofiler | |
parent | 495b9aa9c20be71dabf67a4296e86a17f0725c0a (diff) | |
download | qt-creator-4aa432bb9a806843b40369316155df7393f6e195.tar.gz |
QmlProfiler: Eliminate QStandardItemModel from statistics
This resolves the data duplication between model manager and statistics
models, that gets in the way of updating the details strings on the fly.
Task-number: QTCREATORBUG-20106
Change-Id: I1c4881f903402dff936267de03b84d05ab7c39ca
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
Diffstat (limited to 'src/plugins/qmlprofiler')
4 files changed, 95 insertions, 424 deletions
diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp index 9f49405880..72525fdc9c 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp @@ -105,11 +105,13 @@ void QmlProfilerStatisticsModel::restrictToFeatures(quint64 features) return; clear(); + beginResetModel(); if (!m_modelManager->replayEvents(m_modelManager->traceTime()->startTime(), m_modelManager->traceTime()->endTime(), std::bind(&QmlProfilerStatisticsModel::loadEvent, this, std::placeholders::_1, std::placeholders::_2))) { + endResetModel(); emit m_modelManager->error(tr("Could not re-read events from temporary trace file.")); clear(); } else { @@ -195,6 +197,7 @@ QString QmlProfilerStatisticsModel::summary(const QVector<int> &typeIds) const void QmlProfilerStatisticsModel::clear() { + beginResetModel(); m_rootDuration = 0; m_data.clear(); m_notes.clear(); @@ -204,6 +207,7 @@ void QmlProfilerStatisticsModel::clear() m_calleesModel->clear(); if (!m_callersModel.isNull()) m_callersModel->clear(); + endResetModel(); } void QmlProfilerStatisticsModel::setRelativesModel(QmlProfilerStatisticsRelativesModel *relative, @@ -400,12 +404,21 @@ QVariant QmlProfilerStatisticsModel::headerData(int section, Qt::Orientation ori void QmlProfilerStatisticsModel::modelManagerStateChanged() { - if (m_modelManager->state() == QmlProfilerModelManager::ClearingData) + switch (m_modelManager->state()) { + case QmlProfilerModelManager::ClearingData: clear(); + break; + case QmlProfilerModelManager::AcquiringData: + beginResetModel(); + break; + default: + break; + } } void QmlProfilerStatisticsModel::notesChanged(int typeIndex) { + static const QVector<int> noteRoles({Qt::ToolTipRole, Qt::TextColorRole}); const QmlProfilerNotesModel *notesModel = m_modelManager->notesModel(); if (typeIndex == -1) { m_notes.clear(); @@ -418,6 +431,7 @@ void QmlProfilerStatisticsModel::notesChanged(int typeIndex) } else { note.append(QStringLiteral("\n")).append(notesModel->text(noteId)); } + emit dataChanged(index(noteType, 0), index(noteType, MainDetails), noteRoles); } } } else { @@ -430,6 +444,7 @@ void QmlProfilerStatisticsModel::notesChanged(int typeIndex) newNotes << notesModel->text(it->toInt()); } m_notes[typeIndex] = newNotes.join(QStringLiteral("\n")); + emit dataChanged(index(typeIndex, 0), index(typeIndex, MainDetails), noteRoles); } } @@ -492,6 +507,7 @@ void QmlProfilerStatisticsModel::finalize() { for (QmlEventStats &stats : m_data) stats.finalize(); + endResetModel(); emit dataAvailable(); } @@ -711,6 +727,21 @@ QVariant QmlProfilerStatisticsRelativesModel::headerData(int section, Qt::Orient } } +bool QmlProfilerStatisticsRelativesModel::setData(const QModelIndex &index, const QVariant &value, + int role) +{ + bool ok = false; + const int typeIndex = value.toInt(&ok); + if (index.isValid() || !ok || role != TypeIdRole) { + return QAbstractTableModel::setData(index, value, role); + } else { + beginResetModel(); + m_relativeTypeIndex = typeIndex; + endResetModel(); + return true; + } +} + int QmlProfilerStatisticsRelativesModel::count() const { return m_data.count(); @@ -718,10 +749,12 @@ int QmlProfilerStatisticsRelativesModel::count() const void QmlProfilerStatisticsRelativesModel::clear() { + beginResetModel(); m_relativeTypeIndex = std::numeric_limits<int>::max(); m_data.clear(); m_callStack.clear(); m_compileStack.clear(); + endResetModel(); } } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h index 7b925acc9c..d6a5beb39a 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h @@ -218,6 +218,9 @@ public: 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; + + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + signals: void dataAvailable(); diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp index 24cb91c58f..7d97b85fb4 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp @@ -33,7 +33,6 @@ #include <QUrl> #include <QHash> -#include <QStandardItem> #include <QHeaderView> #include <QApplication> #include <QClipboard> @@ -41,6 +40,7 @@ #include <QVBoxLayout> #include <QHBoxLayout> #include <QMenu> +#include <QSortFilterProxyModel> #include <functional> @@ -49,64 +49,6 @@ namespace Internal { const int DEFAULT_SORT_COLUMN = MainTimeInPercent; -struct SortPreserver { - SortPreserver(Utils::TreeView *view) : view(view) - { - const QHeaderView *header = view->header(); - column = header->sortIndicatorSection(); - order = header->sortIndicatorOrder(); - view->setSortingEnabled(false); - } - - ~SortPreserver() - { - view->setSortingEnabled(true); - view->sortByColumn(column, order); - } - - int column = DEFAULT_SORT_COLUMN; - Qt::SortOrder order = Qt::DescendingOrder; - Utils::TreeView *view = nullptr; -}; - -struct Colors { - QColor noteBackground = QColor("orange"); - QColor defaultBackground = QColor("white"); -}; - -struct RootEventType : public QmlEventType { - RootEventType() : QmlEventType(MaximumMessage, MaximumRangeType, -1, - QmlEventLocation("<program>", 1, 1), - QmlProfilerStatisticsMainView::tr("Main Program"), - QmlProfilerStatisticsMainView::tr("<program>")) - { - } -}; - -Q_GLOBAL_STATIC(Colors, colors) -Q_GLOBAL_STATIC(RootEventType, rootEventType) - -class StatisticsViewItem : public QStandardItem -{ -public: - StatisticsViewItem(const QString &text, const QVariant &sort) : QStandardItem(text) - { - setData(sort, SortRole); - } - - virtual bool operator<(const QStandardItem &other) const - { - if (data(SortRole).type() == QVariant::String) { - // Strings should be case-insensitive compared - return data(SortRole).toString().compare(other.data(SortRole).toString(), - Qt::CaseInsensitive) < 0; - } else { - // For everything else the standard comparison should be OK - return QStandardItem::operator<(other); - } - } -}; - static void setViewDefaults(Utils::TreeView *view) { view->setFrameStyle(QFrame::NoFrame); @@ -116,68 +58,12 @@ static void setViewDefaults(Utils::TreeView *view) header->setMinimumSectionSize(50); } -static QString displayHeader(MainField header) -{ - switch (header) { - case MainCallCount: - return QmlProfilerStatisticsMainView::tr("Calls"); - case MainDetails: - return QmlProfilerStatisticsMainView::tr("Details"); - case MainLocation: - return QmlProfilerStatisticsMainView::tr("Location"); - case MainMaxTime: - return QmlProfilerStatisticsMainView::tr("Longest Time"); - case MainTimePerCall: - return QmlProfilerStatisticsMainView::tr("Mean Time"); - case MainSelfTime: - return QmlProfilerStatisticsMainView::tr("Self Time"); - case MainSelfTimeInPercent: - return QmlProfilerStatisticsMainView::tr("Self Time in Percent"); - case MainMinTime: - return QmlProfilerStatisticsMainView::tr("Shortest Time"); - case MainTimeInPercent: - return QmlProfilerStatisticsMainView::tr("Time in Percent"); - case MainTotalTime: - return QmlProfilerStatisticsMainView::tr("Total Time"); - case MainType: - return QmlProfilerStatisticsMainView::tr("Type"); - case MainMedianTime: - return QmlProfilerStatisticsMainView::tr("Median Time"); - case MaxMainField: - QTC_ASSERT(false, break); - } - return QString(); -} - -static QString displayHeader(RelativeField header, QmlProfilerStatisticsRelation relation) -{ - switch (header) { - case RelativeLocation: - return relation == QmlProfilerStatisticsCallees - ? QmlProfilerStatisticsMainView::tr("Callee") - : QmlProfilerStatisticsMainView::tr("Caller"); - case RelativeType: - return displayHeader(MainType); - case RelativeTotalTime: - return displayHeader(MainTotalTime); - case RelativeCallCount: - return displayHeader(MainCallCount); - case RelativeDetails: - return relation == QmlProfilerStatisticsCallees - ? QmlProfilerStatisticsMainView::tr("Callee Description") - : QmlProfilerStatisticsMainView::tr("Caller Description"); - case MaxRelativeField: - QTC_ASSERT(false, break); - } - return QString(); -} - -static void getSourceLocation(QStandardItem *infoItem, +static void getSourceLocation(const QModelIndex &index, std::function<void (const QString &, int, int)> receiver) { - int line = infoItem->data(LineRole).toInt(); - int column = infoItem->data(ColumnRole).toInt(); - QString fileName = infoItem->data(FilenameRole).toString(); + const int line = index.data(LineRole).toInt(); + const int column = index.data(ColumnRole).toInt(); + const QString fileName = index.data(FilenameRole).toString(); if (line != -1 && !fileName.isEmpty()) receiver(fileName, line, column); } @@ -234,13 +120,6 @@ QmlProfilerStatisticsView::QmlProfilerStatisticsView(QmlProfilerModelManager *pr setLayout(groupLayout); } -void QmlProfilerStatisticsView::clear() -{ - m_mainView->clear(); - m_calleesView->clear(); - m_callersView->clear(); -} - QString QmlProfilerStatisticsView::summary(const QVector<int> &typeIds) const { return m_mainView->summary(typeIds); @@ -344,33 +223,30 @@ QmlProfilerStatisticsMainView::QmlProfilerStatisticsMainView(QmlProfilerStatisti setViewDefaults(this); setObjectName(QLatin1String("QmlProfilerEventsTable")); - m_standardItemModel.reset(new QStandardItemModel); - m_standardItemModel->setSortRole(SortRole); - setModel(m_standardItemModel.get()); - connect(this, &QAbstractItemView::activated, this, &QmlProfilerStatisticsMainView::jumpToItem); + auto sortModel = new QSortFilterProxyModel(this); + sortModel->setSourceModel(model); + sortModel->setSortRole(SortRole); + sortModel->setSortCaseSensitivity(Qt::CaseInsensitive); + sortModel->setFilterRole(FilterRole); + sortModel->setFilterKeyColumn(MainType); + sortModel->setFilterFixedString("+"); + + setModel(sortModel); - connect(m_model.get(), &QmlProfilerStatisticsModel::dataAvailable, - this, &QmlProfilerStatisticsMainView::buildModel); - connect(m_model.get(), &QmlProfilerStatisticsModel::notesAvailable, - this, &QmlProfilerStatisticsMainView::updateNotes); + connect(this, &QAbstractItemView::activated, this, &QmlProfilerStatisticsMainView::jumpToItem); setSortingEnabled(true); sortByColumn(DEFAULT_SORT_COLUMN, Qt::DescendingOrder); - buildModel(); -} + setShowExtendedStatistics(m_showExtendedStatistics); + setRootIsDecorated(false); -QmlProfilerStatisticsMainView::~QmlProfilerStatisticsMainView() -{ - clear(); + resizeColumnToContents(MainLocation); + resizeColumnToContents(MainType); } -void QmlProfilerStatisticsMainView::setHeaderLabels() +QmlProfilerStatisticsMainView::~QmlProfilerStatisticsMainView() { - for (int i = 0; i < MaxMainField; ++i) { - m_standardItemModel->setHeaderData(i, Qt::Horizontal, - displayHeader(static_cast<MainField>(i))); - } } void QmlProfilerStatisticsMainView::setShowExtendedStatistics(bool show) @@ -393,59 +269,6 @@ bool QmlProfilerStatisticsMainView::showExtendedStatistics() const return m_showExtendedStatistics; } -void QmlProfilerStatisticsMainView::clear() -{ - SortPreserver sorter(this); - m_standardItemModel->clear(); - m_standardItemModel->setColumnCount(MaxMainField); - setHeaderLabels(); -} - -void QmlProfilerStatisticsMainView::buildModel() -{ - clear(); - - { - SortPreserver sorter(this); - parseModel(); - setShowExtendedStatistics(m_showExtendedStatistics); - setRootIsDecorated(false); - } - - resizeColumnToContents(MainLocation); - resizeColumnToContents(MainType); -} - -void QmlProfilerStatisticsMainView::updateNotes(int typeIndex) -{ - const QVector<QmlProfilerStatisticsModel::QmlEventStats> &eventList = m_model->getData(); - const QHash<int, QString> ¬eList = m_model->getNotes(); - QStandardItem *rootItem = m_standardItemModel->invisibleRootItem(); - - for (int rowIndex = 0; rowIndex < rootItem->rowCount(); ++rowIndex) { - int rowType = rootItem->child(rowIndex)->data(TypeIdRole).toInt(); - if (rowType == -1 || (rowType != typeIndex && typeIndex != -1)) - continue; - const QmlProfilerStatisticsModel::QmlEventStats &stats = eventList[rowType]; - - for (int columnIndex = 0; columnIndex < rootItem->columnCount(); ++columnIndex) { - QStandardItem *item = rootItem->child(rowIndex, columnIndex); - QHash<int, QString>::ConstIterator it = noteList.find(rowType); - if (it != noteList.end()) { - item->setBackground(colors()->noteBackground); - item->setToolTip(it.value()); - } else if (stats.recursive > 0) { - item->setBackground(colors()->noteBackground); - item->setToolTip(tr("+%1 in recursive calls") - .arg(Timeline::formatTime(stats.recursive))); - } else if (!item->toolTip().isEmpty()){ - item->setBackground(colors()->defaultBackground); - item->setToolTip(QString()); - } - } - } -} - void QmlProfilerStatisticsMainView::restrictToFeatures(quint64 features) { m_model->restrictToFeatures(features); @@ -466,132 +289,40 @@ QStringList QmlProfilerStatisticsMainView::details(int typeId) const return m_model->details(typeId); } -void QmlProfilerStatisticsMainView::parseModel() -{ - const QVector<QmlProfilerStatisticsModel::QmlEventStats> &eventList = m_model->getData(); - const QVector<QmlEventType> &typeList = m_model->getTypes(); - - QmlProfilerStatisticsModel::QmlEventStats rootEventStats; - rootEventStats.total = rootEventStats.maximum = rootEventStats.minimum = rootEventStats.median - = m_model->rootDuration(); - rootEventStats.calls = rootEventStats.total > 0 ? 1 : 0; - - for (int typeIndex = -1; typeIndex < eventList.size(); ++typeIndex) { - const QmlProfilerStatisticsModel::QmlEventStats &stats = typeIndex >= 0 - ? eventList[typeIndex] : rootEventStats; - if (stats.calls == 0) - continue; - - const QmlEventType &type = typeIndex >= 0 ? typeList[typeIndex] : *rootEventType(); - QStandardItem *rootItem = m_standardItemModel->invisibleRootItem(); - QList<QStandardItem *> newRow; - - newRow << new StatisticsViewItem( - type.displayName().isEmpty() ? tr("<bytecode>") : type.displayName(), - type.displayName()); - - QString typeString = QmlProfilerStatisticsModel::nameForType(type.rangeType()); - newRow << new StatisticsViewItem(typeString, typeString); - - const double percent = m_model->durationPercent(typeIndex); - newRow << new StatisticsViewItem(QString::number(percent, 'f', 2) - + QLatin1String(" %"), percent); - - newRow << new StatisticsViewItem( - Timeline::formatTime(stats.totalNonRecursive()), - stats.totalNonRecursive()); - - const double percentSelf = m_model->durationSelfPercent(typeIndex); - newRow << new StatisticsViewItem(QString::number(percentSelf, 'f', 2) - + QLatin1String(" %"), percentSelf); - - newRow << new StatisticsViewItem(Timeline::formatTime(stats.self), - stats.self); - - newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls); - - const qint64 timePerCall = stats.average(); - newRow << new StatisticsViewItem(Timeline::formatTime(timePerCall), - timePerCall); - - newRow << new StatisticsViewItem(Timeline::formatTime(stats.median), - stats.median); - - newRow << new StatisticsViewItem(Timeline::formatTime(stats.maximum), - stats.maximum); - - newRow << new StatisticsViewItem(Timeline::formatTime(stats.minimum), - stats.minimum); - - newRow << new StatisticsViewItem(type.data().isEmpty() ? tr("Source code not available") - : type.data(), type.data()); - - // no edit - foreach (QStandardItem *item, newRow) - item->setEditable(false); - - // metadata - QStandardItem *first = newRow.at(MainLocation); - first->setData(typeIndex, TypeIdRole); - const QmlEventLocation location(type.location()); - first->setData(location.filename(), FilenameRole); - first->setData(location.line(), LineRole); - first->setData(location.column(), ColumnRole); - - // append - rootItem->appendRow(newRow); - } -} - -QStandardItem *QmlProfilerStatisticsMainView::itemFromIndex(const QModelIndex &index) const -{ - QStandardItem *indexItem = m_standardItemModel->itemFromIndex(index); - if (indexItem->parent()) - return indexItem->parent()->child(indexItem->row()); - else - return m_standardItemModel->item(index.row()); -} - int QmlProfilerStatisticsMainView::selectedTypeId() const { - QModelIndex index = selectedModelIndex(); - if (!index.isValid()) - return -1; - QStandardItem *item = m_standardItemModel->item(index.row()); - return item->data(TypeIdRole).toInt(); + return model()->data(selectedModelIndex(), TypeIdRole).toInt(); } void QmlProfilerStatisticsMainView::jumpToItem(const QModelIndex &index) { - QStandardItem *infoItem = itemFromIndex(index); - // show in editor - getSourceLocation(infoItem, [this](const QString &fileName, int line, int column) { + getSourceLocation(index, [this](const QString &fileName, int line, int column) { emit gotoSourceLocation(fileName, line, column); }); // show in callers/callees subwindow - emit typeSelected(infoItem->data(TypeIdRole).toInt()); + emit typeSelected(model()->data(index, TypeIdRole).toInt()); } -void QmlProfilerStatisticsMainView::selectItem(const QStandardItem *item) +void QmlProfilerStatisticsMainView::selectItem(const QModelIndex &index) { // If the same item is already selected, don't reselect it. - QModelIndex index = m_standardItemModel->indexFromItem(item); if (index != currentIndex()) { setCurrentIndex(index); // show in callers/callees subwindow - emit typeSelected(itemFromIndex(index)->data(TypeIdRole).toInt()); + emit typeSelected(index.data(TypeIdRole).toInt()); } } void QmlProfilerStatisticsMainView::selectType(int typeIndex) { - for (int i = 0; i < m_standardItemModel->rowCount(); i++) { - QStandardItem *infoItem = m_standardItemModel->item(i); - if (infoItem->data(TypeIdRole).toInt() == typeIndex) { - selectItem(infoItem); + QAbstractItemModel *itemModel = model(); + for (int i = 0; i < itemModel->rowCount(); i++) { + QModelIndex index = itemModel->index(i, MainLocation); + if (itemModel->data(index, TypeIdRole).toInt() == typeIndex) { + selectItem(index); return; } } @@ -606,16 +337,15 @@ QModelIndex QmlProfilerStatisticsMainView::selectedModelIndex() const return sel.first(); } -QString QmlProfilerStatisticsMainView::textForItem(QStandardItem *item) const +QString QmlProfilerStatisticsMainView::textForItem(const QModelIndex &index) const { QString str; // item's data - int colCount = m_standardItemModel->columnCount(); + const int colCount = model()->columnCount(); for (int j = 0; j < colCount; ++j) { - QStandardItem *colItem = item->parent() ? item->parent()->child(item->row(),j) : - m_standardItemModel->item(item->row(),j); - str += colItem->data(Qt::DisplayRole).toString(); + const QModelIndex cellIndex = model()->index(index.row(), j); + str += cellIndex.data(Qt::DisplayRole).toString(); if (j < colCount-1) str += QLatin1Char('\t'); } str += QLatin1Char('\n'); @@ -626,20 +356,24 @@ QString QmlProfilerStatisticsMainView::textForItem(QStandardItem *item) const void QmlProfilerStatisticsMainView::copyTableToClipboard() const { QString str; + + const QAbstractItemModel *itemModel = model(); + // headers - int columnCount = m_standardItemModel->columnCount(); + const int columnCount = itemModel->columnCount(); for (int i = 0; i < columnCount; ++i) { - str += m_standardItemModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); + str += itemModel->headerData(i, Qt::Horizontal, Qt::DisplayRole).toString(); if (i < columnCount - 1) str += QLatin1Char('\t'); else str += QLatin1Char('\n'); } + // data - int rowCount = m_standardItemModel->rowCount(); - for (int i = 0; i != rowCount; ++i) { - str += textForItem(m_standardItemModel->item(i)); - } + const int rowCount = itemModel->rowCount(); + for (int i = 0; i != rowCount; ++i) + str += textForItem(itemModel->index(i, 0)); + QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(str, QClipboard::Selection); clipboard->setText(str, QClipboard::Clipboard); @@ -647,7 +381,7 @@ void QmlProfilerStatisticsMainView::copyTableToClipboard() const void QmlProfilerStatisticsMainView::copyRowToClipboard() const { - QString str = textForItem(m_standardItemModel->itemFromIndex(selectedModelIndex())); + QString str = textForItem(selectedModelIndex()); QClipboard *clipboard = QApplication::clipboard(); clipboard->setText(str, QClipboard::Selection); clipboard->setText(str, QClipboard::Clipboard); @@ -658,21 +392,18 @@ QmlProfilerStatisticsRelativesView::QmlProfilerStatisticsRelativesView( m_model(model) { setViewDefaults(this); - QStandardItemModel *itemModel = new QStandardItemModel(this); - itemModel->setSortRole(SortRole); - setModel(itemModel); + auto sortModel = new QSortFilterProxyModel(this); + sortModel->setSourceModel(model); + sortModel->setSortRole(SortRole); + sortModel->setSortCaseSensitivity(Qt::CaseInsensitive); + setModel(sortModel); setRootIsDecorated(false); - updateHeader(); setSortingEnabled(true); sortByColumn(DEFAULT_SORT_COLUMN, Qt::DescendingOrder); connect(this, &QAbstractItemView::activated, this, &QmlProfilerStatisticsRelativesView::jumpToItem); - - // Clear when new data available as the selection may be invalid now. - connect(m_model.get(), &QmlProfilerStatisticsRelativesModel::dataAvailable, - this, &QmlProfilerStatisticsRelativesView::clear); } QmlProfilerStatisticsRelativesView::~QmlProfilerStatisticsRelativesView() @@ -681,100 +412,18 @@ QmlProfilerStatisticsRelativesView::~QmlProfilerStatisticsRelativesView() void QmlProfilerStatisticsRelativesView::displayType(int typeIndex) { - SortPreserver sorter(this); - rebuildTree(m_model->getData(typeIndex)); - - updateHeader(); + model()->setData(QModelIndex(), typeIndex, TypeIdRole); resizeColumnToContents(RelativeLocation); } -void QmlProfilerStatisticsRelativesView::rebuildTree( - const QVector<QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData> &data) -{ - Q_ASSERT(treeModel()); - treeModel()->clear(); - - QStandardItem *topLevelItem = treeModel()->invisibleRootItem(); - const QVector<QmlEventType> &typeList = m_model->getTypes(); - - for (auto it = data.constBegin(); it != data.constEnd(); ++it) { - const QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData &stats = *it; - const QmlEventType &type = stats.typeIndex != -1 ? typeList[stats.typeIndex] - : *rootEventType(); - QList<QStandardItem *> newRow; - - // ToDo: here we were going to search for the data in the other model - // maybe we should store the data in this model and get it here - // no indirections at this level of abstraction! - newRow << new StatisticsViewItem( - type.displayName().isEmpty() ? tr("<bytecode>") : type.displayName(), - type.displayName()); - const QString typeName = QmlProfilerStatisticsModel::nameForType(type.rangeType()); - newRow << new StatisticsViewItem(typeName, typeName); - newRow << new StatisticsViewItem(Timeline::formatTime(stats.duration), - stats.duration); - newRow << new StatisticsViewItem(QString::number(stats.calls), stats.calls); - newRow << new StatisticsViewItem(type.data().isEmpty() ? tr("Source code not available") : - type.data(), type.data()); - - QStandardItem *first = newRow.at(RelativeLocation); - first->setData(stats.typeIndex, TypeIdRole); - const QmlEventLocation location(type.location()); - first->setData(location.filename(), FilenameRole); - first->setData(location.line(), LineRole); - first->setData(location.column(), ColumnRole); - - if (stats.isRecursive) { - foreach (QStandardItem *item, newRow) { - item->setBackground(colors()->noteBackground); - item->setToolTip(tr("called recursively")); - } - } - - foreach (QStandardItem *item, newRow) - item->setEditable(false); - - topLevelItem->appendRow(newRow); - } -} - -void QmlProfilerStatisticsRelativesView::clear() -{ - if (treeModel()) { - SortPreserver sorter(this); - treeModel()->clear(); - updateHeader(); - } -} - -void QmlProfilerStatisticsRelativesView::updateHeader() -{ - const QmlProfilerStatisticsRelation relation = m_model->relation(); - if (QStandardItemModel *model = treeModel()) { - model->setColumnCount(MaxRelativeField); - for (int i = 0; i < MaxRelativeField; ++i) { - model->setHeaderData(i, Qt::Horizontal, - displayHeader(static_cast<RelativeField>(i), relation)); - } - } -} - -QStandardItemModel *QmlProfilerStatisticsRelativesView::treeModel() -{ - return qobject_cast<QStandardItemModel *>(model()); -} - void QmlProfilerStatisticsRelativesView::jumpToItem(const QModelIndex &index) { - if (treeModel()) { - QStandardItem *infoItem = treeModel()->item(index.row()); - // show in editor - getSourceLocation(infoItem, [this](const QString &fileName, int line, int column) { - emit gotoSourceLocation(fileName, line, column); - }); + // show in editor + getSourceLocation(index, [this](const QString &fileName, int line, int column) { + emit gotoSourceLocation(fileName, line, column); + }); - emit typeClicked(infoItem->data(TypeIdRole).toInt()); - } + emit typeClicked(index.data(TypeIdRole).toInt()); } } // namespace Internal diff --git a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h index 88dd51ef58..542cf05e1a 100644 --- a/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h +++ b/src/plugins/qmlprofiler/qmlprofilerstatisticsview.h @@ -34,7 +34,6 @@ #include <utils/itemviews.h> #include <QPointer> -#include <QStandardItemModel> namespace QmlProfiler { namespace Internal { @@ -49,7 +48,6 @@ public: explicit QmlProfilerStatisticsView(QmlProfilerModelManager *profilerModelManager, QWidget *parent = nullptr); ~QmlProfilerStatisticsView() override = default; - void clear() override; QString summary(const QVector<int> &typeIds) const; QStringList details(int typeId) const; @@ -89,11 +87,8 @@ public: void setShowExtendedStatistics(bool); bool showExtendedStatistics() const; - void clear(); void jumpToItem(const QModelIndex &index); void selectType(int typeIndex); - void buildModel(); - void updateNotes(int typeIndex); void restrictToFeatures(quint64 features); bool isRestrictedToRange() const; @@ -106,14 +101,10 @@ signals: void typeSelected(int typeIndex); private: - void selectItem(const QStandardItem *item); - void setHeaderLabels(); - void parseModel(); - QStandardItem *itemFromIndex(const QModelIndex &index) const; - QString textForItem(QStandardItem *item) const; + void selectItem(const QModelIndex &index); + QString textForItem(const QModelIndex &index) const; std::unique_ptr<QmlProfilerStatisticsModel> m_model; - std::unique_ptr<QStandardItemModel> m_standardItemModel; bool m_showExtendedStatistics = false; }; @@ -126,17 +117,12 @@ public: void displayType(int typeIndex); void jumpToItem(const QModelIndex &); - void clear(); signals: void typeClicked(int typeIndex); void gotoSourceLocation(const QString &fileName, int lineNumber, int columnNumber); private: - void rebuildTree( - const QVector<QmlProfilerStatisticsRelativesModel::QmlStatisticsRelativesData> &data); - void updateHeader(); - QStandardItemModel *treeModel(); std::unique_ptr<QmlProfilerStatisticsRelativesModel> m_model; }; |