summaryrefslogtreecommitdiff
path: root/src/plugins/qmlprofiler
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-03-23 13:37:37 +0100
committerUlf Hermann <ulf.hermann@qt.io>2018-04-16 13:35:44 +0000
commit4aa432bb9a806843b40369316155df7393f6e195 (patch)
tree98d10876b8b1b6269440816cd493ff0aa052562a /src/plugins/qmlprofiler
parent495b9aa9c20be71dabf67a4296e86a17f0725c0a (diff)
downloadqt-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')
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.cpp35
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsmodel.h3
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsview.cpp463
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerstatisticsview.h18
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> &noteList = 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;
};