From d1cd1a490c30850a51f4e8c21b549f50682328a4 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Tue, 24 Jun 2014 14:16:30 +0200 Subject: [PATCH 1/4] ios: correctly replace cryptic Locked message when deploying Change-Id: I19e33d5c7e35f9d76c81469d3772bc800ce1760b Reviewed-by: Richard Moe Gustavsen --- src/plugins/ios/iosrunner.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp index a7e7a184a17..4f2c14f2328 100644 --- a/src/plugins/ios/iosrunner.cpp +++ b/src/plugins/ios/iosrunner.cpp @@ -217,11 +217,11 @@ void IosRunner::handleErrorMsg(IosToolHandler *handler, const QString &msg) TaskHub::addTask(Task::Warning, tr("Run failed. The settings in the Organizer window of Xcode might be incorrect."), ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); - } else if (msg.contains(lockedErr)) { + } else if (res.contains(lockedErr)) { QString message = tr("The device is locked, please unlock."); TaskHub::addTask(Task::Error, message, ProjectExplorer::Constants::TASK_CATEGORY_DEPLOYMENT); - res.replace(lockedErr, msg); + res.replace(lockedErr, message); } QRegExp qmlPortRe(QLatin1String("QML Debugger: Waiting for connection on port ([0-9]+)...")); int index = qmlPortRe.indexIn(msg); From 63ca524069da8c78f5925bb2b713f13bb799025b Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 18 Jun 2014 11:20:41 +0200 Subject: [PATCH 2/4] QmlProfiler: Put height of rows in the timeline into the model Like that we can provide functionality to interactively resize rows in the model so that one can zoom in to more interesting parts. Change-Id: I31f14cd8aa37703240ebec744ca2e77188fb0f27 Reviewed-by: Kai Koehne --- .../qmlprofiler/abstracttimelinemodel.cpp | 60 ++++++++++++++++++ .../qmlprofiler/abstracttimelinemodel.h | 6 ++ .../qmlprofiler/abstracttimelinemodel_p.h | 1 + src/plugins/qmlprofiler/qml/CategoryLabel.qml | 51 +++++++-------- src/plugins/qmlprofiler/qml/MainView.qml | 2 - src/plugins/qmlprofiler/qml/TimeMarks.qml | 35 +++++++---- .../qmlprofiler/timelinemodelaggregator.cpp | 21 +++++++ .../qmlprofiler/timelinemodelaggregator.h | 5 ++ src/plugins/qmlprofiler/timelinerenderer.cpp | 63 +++++++++++++------ src/plugins/qmlprofiler/timelinerenderer.h | 1 + 10 files changed, 180 insertions(+), 65 deletions(-) diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp index 2f10e17e064..ae5646dfca2 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -32,6 +32,7 @@ namespace QmlProfiler { +static const int DefaultRowHeight = 30; AbstractTimelineModel::AbstractTimelineModel(AbstractTimelineModelPrivate *dd, const QString &name, const QString &label, QmlDebug::Message message, @@ -122,6 +123,63 @@ bool AbstractTimelineModel::isEmpty() const return count() == 0; } +int AbstractTimelineModel::rowHeight(int rowNumber) const +{ + Q_D(const AbstractTimelineModel); + if (!expanded()) + return DefaultRowHeight; + + if (d->rowOffsets.length() > rowNumber) + return d->rowOffsets[rowNumber] - (rowNumber > 0 ? d->rowOffsets[rowNumber - 1] : 0); + return DefaultRowHeight; +} + +int AbstractTimelineModel::rowOffset(int rowNumber) const +{ + Q_D(const AbstractTimelineModel); + if (rowNumber == 0) + return 0; + if (!expanded()) + return DefaultRowHeight * rowNumber; + + if (d->rowOffsets.length() >= rowNumber) + return d->rowOffsets[rowNumber - 1]; + if (!d->rowOffsets.empty()) + return d->rowOffsets.last() + (rowNumber - 1 - d->rowOffsets.length()) * DefaultRowHeight; + return rowNumber * DefaultRowHeight; +} + +void AbstractTimelineModel::setRowHeight(int rowNumber, int height) +{ + Q_D(AbstractTimelineModel); + if (!expanded()) + return; + if (height < DefaultRowHeight) + height = DefaultRowHeight; + + int nextOffset = d->rowOffsets.empty() ? 0 : d->rowOffsets.last(); + while (d->rowOffsets.length() <= rowNumber) + d->rowOffsets << (nextOffset += DefaultRowHeight); + int difference = height - d->rowOffsets[rowNumber] + + (rowNumber > 0 ? d->rowOffsets[rowNumber - 1] : 0); + if (difference != 0) { + for (; rowNumber < d->rowOffsets.length(); ++rowNumber) { + d->rowOffsets[rowNumber] += difference; + } + emit rowHeightChanged(); + } +} + +int AbstractTimelineModel::height() const +{ + Q_D(const AbstractTimelineModel); + int depth = rowCount(); + if (!expanded() || d->rowOffsets.empty()) + return depth * DefaultRowHeight; + + return d->rowOffsets.last() + (depth - d->rowOffsets.length()) * DefaultRowHeight; +} + qint64 AbstractTimelineModel::traceStartTime() const { Q_D(const AbstractTimelineModel); @@ -192,6 +250,8 @@ void AbstractTimelineModel::dataChanged() default: break; } + + d->rowOffsets.clear(); } bool AbstractTimelineModel::eventAccepted(const QmlProfilerDataModel::QmlEventTypeData &event) const diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.h b/src/plugins/qmlprofiler/abstracttimelinemodel.h index 813384d989e..ef407afafb9 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.h @@ -54,6 +54,11 @@ public: bool isEmpty() const; // Methods are directly passed on to the private model and relying on its virtual methods. + int rowHeight(int rowNumber) const; + int rowOffset(int rowNumber) const; + void setRowHeight(int rowNumber, int height); + int height() const; + Q_INVOKABLE qint64 lastTimeMark() const; Q_INVOKABLE qint64 traceStartTime() const; Q_INVOKABLE qint64 traceEndTime() const; @@ -91,6 +96,7 @@ public: signals: void expandedChanged(); + void rowHeightChanged(); protected: enum BoxColorProperties { diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel_p.h b/src/plugins/qmlprofiler/abstracttimelinemodel_p.h index c8a70ada0f5..4cc42cd8eb6 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel_p.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel_p.h @@ -47,6 +47,7 @@ public: virtual int findFirstIndexNoParents(qint64 startTime) const = 0; virtual int findLastIndex(qint64 endTime) const = 0; + QVector rowOffsets; QString name; QmlProfilerModelManager *modelManager; int modelId; diff --git a/src/plugins/qmlprofiler/qml/CategoryLabel.qml b/src/plugins/qmlprofiler/qml/CategoryLabel.qml index c3240352347..cf4588c6b75 100644 --- a/src/plugins/qmlprofiler/qml/CategoryLabel.qml +++ b/src/plugins/qmlprofiler/qml/CategoryLabel.qml @@ -32,30 +32,25 @@ import QtQuick 2.1 Item { id: labelContainer property string text: qmlProfilerModelProxy.title(modelIndex) - property bool expanded: false - property int modelIndex: index; - + property bool expanded: trigger(qmlProfilerModelProxy.expanded(modelIndex)) + property int modelIndex: index + property int bindingTrigger: 1 property var descriptions: [] property var extdescriptions: [] property var eventIds: [] - visible: qmlProfilerModelProxy.rowCount(modelIndex) > 0; + function trigger(i) { + return i * bindingTrigger * bindingTrigger; + } - height: root.singleRowHeight + visible: trigger(qmlProfilerModelProxy.rowCount(modelIndex)) > 0 + + height: trigger(qmlProfilerModelProxy.height(modelIndex)) width: 150 - Component.onCompleted: { - updateHeight(); - } - - function updateHeight() { - height = root.singleRowHeight * qmlProfilerModelProxy.rowCount(modelIndex); - } - function getDescriptions() { - expanded = qmlProfilerModelProxy.expanded(modelIndex); + bindingTrigger = -bindingTrigger; backgroundMarks.requestPaint(); - visible = qmlProfilerModelProxy.rowCount(modelIndex) > 0; if (!visible) return; @@ -71,18 +66,13 @@ Item { descriptions = desc; eventIds = ids; extdescriptions = extdesc; - updateHeight(); } Connections { target: qmlProfilerModelProxy - onExpandedChanged: { - getDescriptions(); - } - - onStateChanged: { - getDescriptions(); - } + onExpandedChanged: getDescriptions(); + onStateChanged: getDescriptions() + onRowHeightChanged: getDescriptions() } Text { @@ -91,7 +81,7 @@ Item { font.pixelSize: 12 text: labelContainer.text color: "#232323" - height: root.singleRowHeight + height: trigger(qmlProfilerModelProxy.rowHeight(modelIndex, 0)) width: 140 verticalAlignment: Text.AlignVCenter } @@ -105,20 +95,21 @@ Item { } Column { - y: root.singleRowHeight + anchors.top: txt.bottom visible: expanded Repeater { model: descriptions.length Rectangle { width: labelContainer.width - height: root.singleRowHeight + height: trigger(qmlProfilerModelProxy.rowHeight(modelIndex, index + 1)) color: "#eaeaea" border.width: 1 border.color:"#c8c8c8" Text { - height: root.singleRowHeight - x: 5 - width: 140 + anchors.fill: parent + anchors.leftMargin: 5 + anchors.rightMargin: 5 + text: descriptions[index] textFormat: Text.PlainText elide: Text.ElideRight @@ -143,7 +134,7 @@ Item { Image { source: expanded ? "arrow_down.png" : "arrow_right.png" x: parent.width - 12 - y: Math.floor((root.singleRowHeight - height) / 2) + y: 9 smooth: false MouseArea { anchors.fill: parent diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml index db38cab72f9..5d54cf5e923 100644 --- a/src/plugins/qmlprofiler/qml/MainView.qml +++ b/src/plugins/qmlprofiler/qml/MainView.qml @@ -36,8 +36,6 @@ Rectangle { // ***** properties - property int singleRowHeight: 30 - property alias selectionLocked : view.selectionLocked property bool lockItemSelection : false diff --git a/src/plugins/qmlprofiler/qml/TimeMarks.qml b/src/plugins/qmlprofiler/qml/TimeMarks.qml index b482023fd59..a2e2d49bc2b 100644 --- a/src/plugins/qmlprofiler/qml/TimeMarks.qml +++ b/src/plugins/qmlprofiler/qml/TimeMarks.qml @@ -102,21 +102,30 @@ Canvas { function drawBackgroundBars( context, region ) { var colorIndex = true; - // row background - var backgroundOffset = y < 0 ? -y : -(y % (2 * root.singleRowHeight)); - for (var currentY= backgroundOffset; currentY < Math.min(height, labels.height - y); currentY += root.singleRowHeight) { - context.fillStyle = colorIndex ? "#f0f0f0" : "white"; - context.strokeStyle = colorIndex ? "#f0f0f0" : "white"; - context.fillRect(0, currentY, width, root.singleRowHeight); - colorIndex = !colorIndex; - } - // separators - var cumulatedHeight = 0; - for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount() && cumulatedHeight < y + height; modelIndex++) { - cumulatedHeight += root.singleRowHeight * qmlProfilerModelProxy.rowCount(modelIndex); - if (cumulatedHeight < y) + var cumulatedHeight = y < 0 ? -y : 0; + for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) { + var modelHeight = qmlProfilerModelProxy.height(modelIndex); + if (cumulatedHeight + modelHeight < y) { + cumulatedHeight += modelHeight; + if (qmlProfilerModelProxy.rowCount(modelIndex) % 2 !== 0) + colorIndex = !colorIndex; continue; + } + + for (var row = 0; row < qmlProfilerModelProxy.rowCount(modelIndex); ++row) { + // row background + var rowHeight = qmlProfilerModelProxy.rowHeight(modelIndex, row) + cumulatedHeight += rowHeight; + colorIndex = !colorIndex; + if (cumulatedHeight < y - rowHeight) + continue; + context.strokeStyle = context.fillStyle = colorIndex ? "#f0f0f0" : "white"; + context.fillRect(0, cumulatedHeight - rowHeight - y, width, rowHeight); + + if (cumulatedHeight > y + height) + return; + } context.strokeStyle = "#B0B0B0"; context.beginPath(); diff --git a/src/plugins/qmlprofiler/timelinemodelaggregator.cpp b/src/plugins/qmlprofiler/timelinemodelaggregator.cpp index 0d7bb543c2f..cfa33b2af72 100644 --- a/src/plugins/qmlprofiler/timelinemodelaggregator.cpp +++ b/src/plugins/qmlprofiler/timelinemodelaggregator.cpp @@ -91,6 +91,7 @@ void TimelineModelAggregator::addModel(AbstractTimelineModel *m) { d->modelList << m; connect(m,SIGNAL(expandedChanged()),this,SIGNAL(expandedChanged())); + connect(m,SIGNAL(rowHeightChanged()),this,SIGNAL(rowHeightChanged())); } QStringList TimelineModelAggregator::categoryTitles() const @@ -141,6 +142,26 @@ qint64 TimelineModelAggregator::lastTimeMark() const return mark; } +int TimelineModelAggregator::height(int modelIndex) const +{ + return d->modelList[modelIndex]->height(); +} + +int TimelineModelAggregator::rowHeight(int modelIndex, int row) const +{ + return d->modelList[modelIndex]->rowHeight(row); +} + +int TimelineModelAggregator::rowOffset(int modelIndex, int row) const +{ + return d->modelList[modelIndex]->rowOffset(row); +} + +void TimelineModelAggregator::setRowHeight(int modelIndex, int row, int height) +{ + d->modelList[modelIndex]->setRowHeight(row, height); +} + bool TimelineModelAggregator::expanded(int modelIndex) const { return d->modelList[modelIndex]->expanded(); diff --git a/src/plugins/qmlprofiler/timelinemodelaggregator.h b/src/plugins/qmlprofiler/timelinemodelaggregator.h index 8e1a933cb9b..b2690b53626 100644 --- a/src/plugins/qmlprofiler/timelinemodelaggregator.h +++ b/src/plugins/qmlprofiler/timelinemodelaggregator.h @@ -62,6 +62,10 @@ public: Q_INVOKABLE qint64 lastTimeMark() const; + Q_INVOKABLE int height(int modelIndex) const; + Q_INVOKABLE int rowHeight(int modelIndex, int row) const; + Q_INVOKABLE void setRowHeight(int modelIndex, int row, int height); + Q_INVOKABLE int rowOffset(int modelIndex, int row) const; Q_INVOKABLE bool expanded(int modelIndex) const; Q_INVOKABLE void setExpanded(int modelIndex, bool expanded); Q_INVOKABLE int rowCount(int modelIndex) const; @@ -93,6 +97,7 @@ signals: void dataAvailable(); void stateChanged(); void expandedChanged(); + void rowHeightChanged(); protected slots: void dataChanged(); diff --git a/src/plugins/qmlprofiler/timelinerenderer.cpp b/src/plugins/qmlprofiler/timelinerenderer.cpp index 356761a3c2e..518aff5f2b8 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.cpp +++ b/src/plugins/qmlprofiler/timelinerenderer.cpp @@ -41,8 +41,6 @@ using namespace QmlProfiler::Internal; -const int DefaultRowHeight = 30; - TimelineRenderer::TimelineRenderer(QQuickPaintedItem *parent) : QQuickPaintedItem(parent), m_startTime(0), m_endTime(0), m_spacing(0), m_spacedDuration(0), m_lastStartTime(0), m_lastEndTime(0) @@ -130,18 +128,20 @@ void TimelineRenderer::drawItemsToPainter(QPainter *p, int modelIndex, int fromI p->setPen(Qt::transparent); int modelRowStart = 0; for (int mi = 0; mi < modelIndex; mi++) - modelRowStart += m_profilerModelProxy->rowCount(mi); + modelRowStart += m_profilerModelProxy->height(mi); for (int i = fromIndex; i <= toIndex; i++) { int currentX, currentY, itemWidth, itemHeight; int rowNumber = m_profilerModelProxy->getEventRow(modelIndex, i); - currentY = (modelRowStart + rowNumber) * DefaultRowHeight - y(); + currentY = modelRowStart + m_profilerModelProxy->rowOffset(modelIndex, rowNumber) - y(); if (currentY >= height()) continue; - itemHeight = DefaultRowHeight * m_profilerModelProxy->getHeight(modelIndex, i); - currentY += DefaultRowHeight - itemHeight; + itemHeight = m_profilerModelProxy->rowHeight(modelIndex, rowNumber) * + m_profilerModelProxy->getHeight(modelIndex, i); + + currentY += m_profilerModelProxy->rowHeight(modelIndex, rowNumber) - itemHeight; if (currentY + itemHeight < 0) continue; @@ -164,7 +164,7 @@ void TimelineRenderer::drawSelectionBoxes(QPainter *p, int modelIndex, int fromI int modelRowStart = 0; for (int mi = 0; mi < modelIndex; mi++) - modelRowStart += m_profilerModelProxy->rowCount(mi); + modelRowStart += m_profilerModelProxy->height(mi); p->save(); @@ -183,16 +183,19 @@ void TimelineRenderer::drawSelectionBoxes(QPainter *p, int modelIndex, int fromI if (m_profilerModelProxy->getEventId(modelIndex, i) != id) continue; - currentY = (modelRowStart + m_profilerModelProxy->getEventRow(modelIndex, i)) * DefaultRowHeight - y(); - if (currentY + DefaultRowHeight < 0 || height() < currentY) + int row = m_profilerModelProxy->getEventRow(modelIndex, i); + int rowHeight = m_profilerModelProxy->rowHeight(modelIndex, row); + + currentY = modelRowStart + m_profilerModelProxy->rowOffset(modelIndex, row) - y(); + if (currentY + rowHeight < 0 || height() < currentY) continue; getItemXExtent(modelIndex, i, currentX, itemWidth); if (i == m_selectedItem) - selectedItemRect = QRect(currentX, currentY - 1, itemWidth, DefaultRowHeight + 1); + selectedItemRect = QRect(currentX, currentY - 1, itemWidth, rowHeight + 1); else - p->drawRect(currentX, currentY, itemWidth, DefaultRowHeight); + p->drawRect(currentX, currentY, itemWidth, rowHeight); } // draw the selected item rectangle the last, so that it's overlayed @@ -209,7 +212,7 @@ void TimelineRenderer::drawBindingLoopMarkers(QPainter *p, int modelIndex, int f int destindex; int xfrom, xto, width; int yfrom, yto; - int radius = DefaultRowHeight / 3; + int radius = 10; QPen shadowPen = QPen(QColor("grey"),2); QPen markerPen = QPen(QColor("orange"),2); QBrush shadowBrush = QBrush(QColor("grey")); @@ -222,12 +225,14 @@ void TimelineRenderer::drawBindingLoopMarkers(QPainter *p, int modelIndex, int f // to getItemXExtent(modelIndex, destindex, xto, width); xto += width / 2; - yto = getYPosition(modelIndex, destindex) + DefaultRowHeight / 2 - y(); + yto = getYPosition(modelIndex, destindex) + + m_profilerModelProxy->rowHeight(modelIndex, destindex) / 2 - y(); // from getItemXExtent(modelIndex, i, xfrom, width); xfrom += width / 2; - yfrom = getYPosition(modelIndex, i) + DefaultRowHeight / 2 - y(); + yfrom = getYPosition(modelIndex, i) + + m_profilerModelProxy->rowHeight(modelIndex, i) / 2 - y(); // radius (derived from width of origin event) radius = 5; @@ -260,11 +265,29 @@ void TimelineRenderer::drawBindingLoopMarkers(QPainter *p, int modelIndex, int f p->restore(); } +int TimelineRenderer::rowFromPosition(int y) +{ + int ret = 0; + for (int modelIndex = 0; modelIndex < m_profilerModelProxy->modelCount(); modelIndex++) { + int modelHeight = m_profilerModelProxy->height(modelIndex); + if (y < modelHeight) { + for (int row = 0; row < m_profilerModelProxy->rowCount(modelIndex); ++row) { + y -= m_profilerModelProxy->rowHeight(modelIndex, row); + if (y < 0) return ret; + ++ret; + } + } else { + y -= modelHeight; + ret += m_profilerModelProxy->rowCount(modelIndex); + } + } + return ret; +} + int TimelineRenderer::modelFromPosition(int y) { - y = y / DefaultRowHeight; for (int modelIndex = 0; modelIndex < m_profilerModelProxy->modelCount(); modelIndex++) { - y -= m_profilerModelProxy->rowCount(modelIndex); + y -= m_profilerModelProxy->height(modelIndex); if (y < 0) return modelIndex; } @@ -328,7 +351,7 @@ void TimelineRenderer::manageHovered(int mouseX, int mouseY) // Make the "selected" area 3 pixels wide by adding/subtracting 1 to catch very narrow events. qint64 startTime = (mouseX - 1) * (m_endTime - m_startTime) / width() + m_startTime; qint64 endTime = (mouseX + 1) * (m_endTime - m_startTime) / width() + m_startTime; - int row = (mouseY + y()) / DefaultRowHeight; + int row = rowFromPosition(mouseY + y()); int modelIndex = modelFromPosition(mouseY + y()); // already covered? nothing to do @@ -404,10 +427,10 @@ int TimelineRenderer::getYPosition(int modelIndex, int index) const int modelRowStart = 0; for (int mi = 0; mi < modelIndex; mi++) - modelRowStart += m_profilerModelProxy->rowCount(mi); + modelRowStart += m_profilerModelProxy->height(mi); - int y = DefaultRowHeight * (modelRowStart + m_profilerModelProxy->getEventRow(modelIndex, index)); - return y; + return modelRowStart + m_profilerModelProxy->rowOffset(modelIndex, + m_profilerModelProxy->getEventRow(modelIndex, index)); } void TimelineRenderer::selectNext() diff --git a/src/plugins/qmlprofiler/timelinerenderer.h b/src/plugins/qmlprofiler/timelinerenderer.h index db6871462b3..587438f6044 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.h +++ b/src/plugins/qmlprofiler/timelinerenderer.h @@ -172,6 +172,7 @@ private: void drawSelectionBoxes(QPainter *p, int modelIndex, int fromIndex, int toIndex); void drawBindingLoopMarkers(QPainter *p, int modelIndex, int fromIndex, int toIndex); int modelFromPosition(int y); + int rowFromPosition(int y); void manageClicked(); void manageHovered(int mouseX, int mouseY); From f30cbf971147e633666c17ba80795b7cb3561a2f Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Wed, 18 Jun 2014 15:47:20 +0200 Subject: [PATCH 3/4] QmlProfiler: allow interactive resizing of rows in timeline Task-number: QTCREATORBUG-12337 Change-Id: Ib9ddb128605831841023bb3cc9aed758ed171de9 Reviewed-by: Kai Koehne --- src/plugins/qmlprofiler/qml/CategoryLabel.qml | 14 ++++++++++++++ src/plugins/qmlprofiler/timelinerenderer.cpp | 8 ++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmlprofiler/qml/CategoryLabel.qml b/src/plugins/qmlprofiler/qml/CategoryLabel.qml index cf4588c6b75..872483bb8e7 100644 --- a/src/plugins/qmlprofiler/qml/CategoryLabel.qml +++ b/src/plugins/qmlprofiler/qml/CategoryLabel.qml @@ -39,6 +39,8 @@ Item { property var extdescriptions: [] property var eventIds: [] + readonly property int dragHeight: 5 + function trigger(i) { return i * bindingTrigger * bindingTrigger; } @@ -116,16 +118,28 @@ Item { verticalAlignment: Text.AlignVCenter } MouseArea { + property bool resizing: false anchors.fill: parent hoverEnabled: true + cursorShape: (resizing || height - mouseY < dragHeight) ? Qt.SizeVerCursor : + Qt.ArrowCursor; onEntered: changeToolTip(extdescriptions[index]); onExited: changeToolTip(""); + onPressed: resizing = (height - mouseY < dragHeight); + + onReleased: resizing = false; + onClicked: { if (mouse.modifiers & Qt.ShiftModifier) view.selectPrevFromId(modelIndex,eventIds[index]); else view.selectNextFromId(modelIndex,eventIds[index]); } + + onMouseYChanged: { + if (resizing) + qmlProfilerModelProxy.setRowHeight(modelIndex, index + 1, mouseY); + } } } } diff --git a/src/plugins/qmlprofiler/timelinerenderer.cpp b/src/plugins/qmlprofiler/timelinerenderer.cpp index 518aff5f2b8..13d7462ff4f 100644 --- a/src/plugins/qmlprofiler/timelinerenderer.cpp +++ b/src/plugins/qmlprofiler/timelinerenderer.cpp @@ -53,12 +53,16 @@ TimelineRenderer::TimelineRenderer(QQuickPaintedItem *parent) : void TimelineRenderer::setProfilerModelProxy(QObject *profilerModelProxy) { - if (m_profilerModelProxy) + if (m_profilerModelProxy) { disconnect(m_profilerModelProxy, SIGNAL(expandedChanged()), this, SLOT(requestPaint())); + disconnect(m_profilerModelProxy, SIGNAL(rowHeightChanged()), this, SLOT(requestPaint())); + } m_profilerModelProxy = qobject_cast(profilerModelProxy); - if (m_profilerModelProxy) + if (m_profilerModelProxy) { connect(m_profilerModelProxy, SIGNAL(expandedChanged()), this, SLOT(requestPaint())); + connect(m_profilerModelProxy, SIGNAL(rowHeightChanged()), this, SLOT(requestPaint())); + } emit profilerModelProxyChanged(m_profilerModelProxy); } From 0d695617f1968b8bbaa46c15f892d82807b1ac49 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Mon, 23 Jun 2014 12:34:37 +0200 Subject: [PATCH 4/4] QmlProfiler: Add scales to rows in timeline If you resize the rows to at least double their default size and if the model specifies a scale it will be drawn as additional horizontal lines and numbers in the background. Change-Id: I02844b4102e043031ee04daa45666dc3f8da1d2e Task-number: QTCREATORBUG-12337 Reviewed-by: Kai Koehne --- .../qmlprofiler/abstracttimelinemodel.cpp | 12 ++++ .../qmlprofiler/abstracttimelinemodel.h | 2 + src/plugins/qmlprofiler/qml/TimeMarks.qml | 58 ++++++++++++++++++- .../qmlprofiler/timelinemodelaggregator.cpp | 10 ++++ .../qmlprofiler/timelinemodelaggregator.h | 2 + 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp index ae5646dfca2..581b1708bb8 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.cpp +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.cpp @@ -237,6 +237,18 @@ float AbstractTimelineModel::getHeight(int index) const return 1.0f; } +int AbstractTimelineModel::rowMinValue(int rowNumber) const +{ + Q_UNUSED(rowNumber); + return 0; +} + +int AbstractTimelineModel::rowMaxValue(int rowNumber) const +{ + Q_UNUSED(rowNumber); + return 0; +} + void AbstractTimelineModel::dataChanged() { Q_D(AbstractTimelineModel); diff --git a/src/plugins/qmlprofiler/abstracttimelinemodel.h b/src/plugins/qmlprofiler/abstracttimelinemodel.h index ef407afafb9..ea0486970a6 100644 --- a/src/plugins/qmlprofiler/abstracttimelinemodel.h +++ b/src/plugins/qmlprofiler/abstracttimelinemodel.h @@ -93,6 +93,8 @@ public: Q_INVOKABLE virtual int getEventIdForLocation(const QString &filename, int line, int column) const; Q_INVOKABLE virtual int getBindingLoopDest(int index) const; Q_INVOKABLE virtual float getHeight(int index) const; + virtual int rowMinValue(int rowNumber) const; + virtual int rowMaxValue(int rowNumber) const; signals: void expandedChanged(); diff --git a/src/plugins/qmlprofiler/qml/TimeMarks.qml b/src/plugins/qmlprofiler/qml/TimeMarks.qml index a2e2d49bc2b..d3e9c6f66cc 100644 --- a/src/plugins/qmlprofiler/qml/TimeMarks.qml +++ b/src/plugins/qmlprofiler/qml/TimeMarks.qml @@ -35,6 +35,10 @@ Canvas { objectName: "TimeMarks" contextType: "2d" + readonly property int scaleMinHeight: 60 + readonly property int scaleStepping: 30 + readonly property string units: " kMGT" + property real startTime property real endTime property real timePerPixel @@ -70,8 +74,6 @@ Canvas { var lineStart = y < 0 ? -y : 0; var lineEnd = Math.min(height, labels.height - y); - context.fillStyle = "#000000"; - context.font = "8px sans-serif"; for (var ii = 0; ii < blockCount+1; ii++) { var x = Math.floor(ii*pixelsPerBlock - realStartPos); context.strokeStyle = "#B0B0B0"; @@ -99,9 +101,27 @@ Canvas { } } + function prettyPrintScale(amount) { + var unitOffset = 0; + for (unitOffset = 0; amount > (1 << ((unitOffset + 1) * 10)); ++unitOffset) {} + var result = (amount >> (unitOffset * 10)); + if (result < 100) { + var comma = Math.round(((amount >> ((unitOffset - 1) * 10)) & 1023) * + (result < 10 ? 100 : 10) / 1024); + if (comma < 10 && result < 10) + return result + ".0" + comma + units[unitOffset]; + else + return result + "." + comma + units[unitOffset]; + } else { + return result + units[unitOffset]; + } + } + function drawBackgroundBars( context, region ) { var colorIndex = true; + context.font = "8px sans-serif"; + // separators var cumulatedHeight = y < 0 ? -y : 0; for (var modelIndex = 0; modelIndex < qmlProfilerModelProxy.modelCount(); ++modelIndex) { @@ -123,6 +143,40 @@ Canvas { context.strokeStyle = context.fillStyle = colorIndex ? "#f0f0f0" : "white"; context.fillRect(0, cumulatedHeight - rowHeight - y, width, rowHeight); + if (rowHeight >= scaleMinHeight) { + var minVal = qmlProfilerModelProxy.rowMinValue(modelIndex, row); + var maxVal = qmlProfilerModelProxy.rowMaxValue(modelIndex, row); + if (minVal !== maxVal) { + context.strokeStyle = context.fillStyle = "#B0B0B0"; + + var stepValUgly = Math.ceil((maxVal - minVal) / + Math.floor(rowHeight / scaleStepping)); + + // align to clean 2**x + var stepVal = 1; + while (stepValUgly >>= 1) + stepVal <<= 1; + + var stepHeight = rowHeight / (maxVal - minVal); + + for (var step = minVal; step <= maxVal - stepVal; step += stepVal) { + var offset = cumulatedHeight - step * stepHeight - y; + context.beginPath(); + context.moveTo(0, offset); + context.lineTo(width, offset); + context.stroke(); + context.fillText(prettyPrintScale(step), 5, offset - 2); + } + context.beginPath(); + context.moveTo(0, cumulatedHeight - rowHeight - y); + context.lineTo(width, cumulatedHeight - rowHeight - y); + context.stroke(); + context.fillText(prettyPrintScale(maxVal), 5, + cumulatedHeight - rowHeight - y + 8); + + } + } + if (cumulatedHeight > y + height) return; } diff --git a/src/plugins/qmlprofiler/timelinemodelaggregator.cpp b/src/plugins/qmlprofiler/timelinemodelaggregator.cpp index cfa33b2af72..b696f7f4959 100644 --- a/src/plugins/qmlprofiler/timelinemodelaggregator.cpp +++ b/src/plugins/qmlprofiler/timelinemodelaggregator.cpp @@ -182,6 +182,16 @@ const QString TimelineModelAggregator::title(int modelIndex) const return d->modelList[modelIndex]->title(); } +int TimelineModelAggregator::rowMinValue(int modelIndex, int row) const +{ + return d->modelList[modelIndex]->rowMinValue(row); +} + +int TimelineModelAggregator::rowMaxValue(int modelIndex, int row) const +{ + return d->modelList[modelIndex]->rowMaxValue(row); +} + int TimelineModelAggregator::findFirstIndex(int modelIndex, qint64 startTime) const { return d->modelList[modelIndex]->findFirstIndex(startTime); diff --git a/src/plugins/qmlprofiler/timelinemodelaggregator.h b/src/plugins/qmlprofiler/timelinemodelaggregator.h index b2690b53626..60a401b96a6 100644 --- a/src/plugins/qmlprofiler/timelinemodelaggregator.h +++ b/src/plugins/qmlprofiler/timelinemodelaggregator.h @@ -70,6 +70,8 @@ public: Q_INVOKABLE void setExpanded(int modelIndex, bool expanded); Q_INVOKABLE int rowCount(int modelIndex) const; Q_INVOKABLE const QString title(int modelIndex) const; + Q_INVOKABLE int rowMinValue(int modelIndex, int row) const; + Q_INVOKABLE int rowMaxValue(int modelIndex, int row) const; int findFirstIndex(int modelIndex, qint64 startTime) const; int findFirstIndexNoParents(int modelIndex, qint64 startTime) const;