diff --git a/src/plugins/qmlprofiler/qml/MainView.qml b/src/plugins/qmlprofiler/qml/MainView.qml
index a3e30a1a49f..a770d768e71 100644
--- a/src/plugins/qmlprofiler/qml/MainView.qml
+++ b/src/plugins/qmlprofiler/qml/MainView.qml
@@ -62,6 +62,9 @@ Rectangle {
property real elapsedTime
signal updateTimer
+ signal updateRangeButton
+ property bool selectionRangeMode: false
+
// ***** connections with external objects
Connections {
target: zoomControl
@@ -187,6 +190,16 @@ Rectangle {
zoomControl.setRange(startTime, startTime + newWindowLength);
}
+ function recenter( centerPoint ) {
+ var windowLength = view.endTime - view.startTime;
+ var newStart = Math.floor(centerPoint - windowLength/2);
+ if (newStart < 0)
+ newStart = 0;
+ if (newStart + windowLength > qmlEventList.traceEndTime())
+ newStart = qmlEventList.traceEndTime() - windowLength;
+ zoomControl.setRange(newStart, newStart + windowLength);
+ }
+
function hideRangeDetails() {
rangeDetails.visible = false;
rangeDetails.duration = "";
@@ -220,6 +233,11 @@ Rectangle {
selectionHighlight.visible = false;
}
+ onSelectionRangeModeChanged: {
+ selectionRangeControl.enabled = selectionRangeMode;
+ selectionRange.reset(selectionRangeMode);
+ }
+
// ***** child items
Timer {
id: elapsedTimer
@@ -408,9 +426,9 @@ Rectangle {
color:"transparent"
border.width: 2
border.color: "blue"
+ z: 1
radius: 2
visible: false
- z:1
}
MouseArea {
@@ -421,9 +439,66 @@ Rectangle {
root.hideRangeDetails();
}
}
+
+ MouseArea {
+ id: selectionRangeControl
+ enabled: false
+ width: flick.width
+ height: root.height
+ x: flick.contentX
+ hoverEnabled: enabled
+ z: 2
+
+ onReleased: {
+ selectionRange.releasedOnCreation();
+ }
+ onPressed: {
+ selectionRange.pressedOnCreation();
+ }
+ onMousePositionChanged: {
+ selectionRange.movedOnCreation();
+ }
+ }
+
+ SelectionRange {
+ id: selectionRange
+ visible: root.selectionRangeMode
+ height: root.height
+ z: 2
+ }
+
+ MouseArea {
+ id: selectionRangeDrag
+ enabled: selectionRange.ready
+ anchors.fill: selectionRange
+ drag.target: selectionRange
+ drag.axis: "XAxis"
+ drag.minimumX: 0
+ drag.maximumX: flick.contentWidth - selectionRange.width
+ onPressed: {
+ selectionRange.isDragging = true;
+ }
+ onReleased: {
+ selectionRange.isDragging = false;
+ }
+ onDoubleClicked: {
+ zoomControl.setRange(selectionRange.startTime, selectionRange.startTime+selectionRange.duration);
+ root.selectionRangeMode = false;
+ root.updateRangeButton();
+ }
+ }
}
}
+ SelectionRangeDetails {
+ id: selectionRangeDetails
+ visible: root.selectionRangeMode
+ startTime: selectionRange.startTimeString
+ duration: selectionRange.durationString
+ endTime: selectionRange.endTimeString
+ showDuration: selectionRange.width > 1
+ }
+
RangeDetails {
id: rangeDetails
}
diff --git a/src/plugins/qmlprofiler/qml/RangeDetails.qml b/src/plugins/qmlprofiler/qml/RangeDetails.qml
index 306fa4e76e0..d044fc0ed50 100644
--- a/src/plugins/qmlprofiler/qml/RangeDetails.qml
+++ b/src/plugins/qmlprofiler/qml/RangeDetails.qml
@@ -44,7 +44,7 @@ BorderImage {
property bool locked: !root.mouseOverSelection
- source: "popup.png"
+ source: "popup_green.png"
border {
left: 10; top: 10
right: 20; bottom: 20
diff --git a/src/plugins/qmlprofiler/qml/SelectionRange.qml b/src/plugins/qmlprofiler/qml/SelectionRange.qml
new file mode 100644
index 00000000000..b45d6b65e70
--- /dev/null
+++ b/src/plugins/qmlprofiler/qml/SelectionRange.qml
@@ -0,0 +1,272 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+import QtQuick 1.0
+
+Rectangle {
+ id: selectionRange
+
+ width: 1
+ color: "transparent"
+
+ property bool ready: visible && creationState === 3
+
+ property color lighterColor:"#6680b2f6"
+ property color darkerColor:"#666da1e8"
+ property color gapColor: "#336da1e8"
+ property color hardBorderColor: "#aa6da1e8"
+ property color thinColor: "blue"
+
+ property string startTimeString: detailedPrintTime(startTime)
+ property string endTimeString: detailedPrintTime(startTime+duration)
+ property string durationString: detailedPrintTime(duration)
+
+ property variant startTime: x * selectionRange.viewTimePerPixel
+ property variant duration: width * selectionRange.viewTimePerPixel
+ property variant viewTimePerPixel: 1
+ property variant creationState : 0
+
+ property variant x1
+ property variant x2
+ property variant x3: Math.min(x1, x2)
+ property variant x4: Math.max(x1, x2)
+
+ property bool isDragging: false
+
+ Connections {
+ target: zoomControl
+ onRangeChanged: {
+ var oldTimePerPixel = selectionRange.viewTimePerPixel;
+ selectionRange.viewTimePerPixel = Math.abs(zoomControl.endTime() - zoomControl.startTime()) / flick.width;
+ if (creationState === 3 && oldTimePerPixel != selectionRange.viewTimePerPixel) {
+ selectionRange.x = x * oldTimePerPixel / selectionRange.viewTimePerPixel;
+ selectionRange.width = width * oldTimePerPixel / selectionRange.viewTimePerPixel;
+ }
+ }
+ }
+
+ onCreationStateChanged: {
+ switch (creationState) {
+ case 0: color = "transparent"; break;
+ case 1: color = thinColor; break;
+ default: color = lighterColor; break;
+ }
+ }
+
+ onIsDraggingChanged: {
+ if (isDragging)
+ color = darkerColor;
+ else
+ color = lighterColor;
+ }
+
+ function reset(setVisible) {
+ width = 1;
+ creationState = 0;
+ visible = setVisible;
+ }
+
+ function setPos(pos) {
+ switch (creationState) {
+ case 1: {
+ width = 1;
+ x1 = pos;
+ x2 = pos;
+ x = pos;
+ break;
+ }
+ case 2: {
+ x2 = pos;
+ x = x3;
+ width = x4-x3;
+ break;
+ }
+ default: return;
+ }
+ }
+
+
+ function detailedPrintTime( t )
+ {
+ if (t <= 0) return "0";
+ if (t<1000) return t+" ns";
+ t = Math.floor(t/1000);
+ if (t<1000) return t+" μs";
+ if (t<1e6) return (t/1000) + " ms";
+ return (t/1e6) + " s";
+ }
+
+ // creation control
+ function releasedOnCreation() {
+ if (selectionRange.creationState === 2) {
+ flick.interactive = true;
+ selectionRange.creationState = 3;
+ selectionRangeControl.enabled = false;
+ }
+ }
+
+ function pressedOnCreation() {
+ if (selectionRange.creationState === 1) {
+ flick.interactive = false;
+ selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX);
+ selectionRange.creationState = 2;
+ }
+ }
+
+ function movedOnCreation() {
+ if (selectionRange.creationState === 0) {
+ selectionRange.creationState = 1;
+ }
+
+ if (!root.eventCount)
+ return;
+
+ if (!selectionRangeControl.pressed && selectionRange.creationState==3)
+ return;
+
+ if (selectionRangeControl.pressed) {
+ selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX);
+ } else {
+ selectionRange.setPos(selectionRangeControl.mouseX + flick.contentX);
+ }
+ }
+
+ Rectangle {
+ id: leftBorder
+
+ visible: selectionRange.creationState === 3
+
+ // used for dragging the borders
+ property real initialX: 0
+ property real initialWidth: 0
+
+ x: 0
+ height: parent.height
+ width: 1
+ color: darkerColor
+ border.color: hardBorderColor
+ border.width: 0
+
+ states: State {
+ name: "highlighted"
+ PropertyChanges {
+ target: leftBorder
+ width: 3
+ border.width: 2
+ }
+ }
+
+ onXChanged: if (x != 0) {
+ selectionRange.width = initialWidth - x;
+ selectionRange.x = initialX + x;
+ x = 0;
+ }
+
+ MouseArea {
+ x: -3
+ width: 7
+ y: 0
+ height: parent.height
+
+ drag.target: leftBorder
+ drag.axis: "XAxis"
+ drag.minimumX: -parent.initialX
+ drag.maximumX: parent.initialWidth - 2
+
+ hoverEnabled: true
+
+ onEntered: parent.state = "highlighted"
+ onExited: {
+ if (!pressed) parent.state = "";
+ }
+ onReleased: {
+ if (!containsMouse) parent.state = "" ;
+ }
+ onPressed: {
+ parent.initialX = selectionRange.x;
+ parent.initialWidth = selectionRange.width;
+ }
+ }
+ }
+
+ Rectangle {
+ id: rightBorder
+
+ visible: selectionRange.creationState === 3
+
+ x: selectionRange.width
+ height: parent.height
+ width: 1
+ color: darkerColor
+ border.color: hardBorderColor
+ border.width: 0
+
+ states: State {
+ name: "highlighted"
+ PropertyChanges {
+ target: rightBorder
+ width: 3
+ border.width: 2
+ }
+ }
+
+ onXChanged: {
+ if (x != selectionRange.width) {
+ selectionRange.width = x;
+ }
+ }
+
+ MouseArea {
+ x: -3
+ width: 7
+ y: 0
+ height: parent.height
+
+ drag.target: rightBorder
+ drag.axis: "XAxis"
+ drag.minimumX: 1
+ drag.maximumX: flick.contentWidth - selectionRange.x
+
+ hoverEnabled: true
+
+ onEntered: {
+ parent.state = "highlighted";
+ }
+ onExited: {
+ if (!pressed) parent.state = "";
+ }
+ onReleased: {
+ if (!containsMouse) parent.state = "";
+ }
+ }
+ }
+}
diff --git a/src/plugins/qmlprofiler/qml/SelectionRangeDetails.qml b/src/plugins/qmlprofiler/qml/SelectionRangeDetails.qml
new file mode 100644
index 00000000000..e4b2bb780d7
--- /dev/null
+++ b/src/plugins/qmlprofiler/qml/SelectionRangeDetails.qml
@@ -0,0 +1,113 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (info@qt.nokia.com)
+**
+**
+** GNU Lesser General Public License Usage
+**
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this file.
+** Please review the following information to ensure the GNU Lesser General
+** Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** Other Usage
+**
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at info@qt.nokia.com.
+**
+**************************************************************************/
+
+import QtQuick 1.0
+import Monitor 1.0
+
+BorderImage {
+ id: selectionRangeDetails
+
+ property string startTime
+ property string endTime
+ property string duration
+ property bool showDuration
+
+ source: "popup_orange.png"
+ border {
+ left: 10; top: 10
+ right: 20; bottom: 20
+ }
+
+ width: 170
+ height: childrenRect.height
+ z: 1
+ visible: false
+ x: 200
+ y: 125
+
+ //title
+ Text {
+ id: typeTitle
+ text: qsTr("Selection")
+ font.bold: true
+ y: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.horizontalCenterOffset: -5
+ }
+
+ //details
+ Column {
+ id: col
+ anchors.top: typeTitle.bottom
+ x: 2
+ Detail {
+ label: qsTr("Start")
+ content: selectionRangeDetails.startTime
+ }
+ Detail {
+ label: qsTr("End")
+ visible: selectionRangeDetails.showDuration
+ content: selectionRangeDetails.endTime
+ }
+ Detail {
+ label: qsTr("Duration")
+ visible: selectionRangeDetails.showDuration
+ content: selectionRangeDetails.duration
+ }
+ }
+
+ Text {
+ id: closeIcon
+ x: selectionRangeDetails.width - 24
+ y: 10
+ text:"X"
+ MouseArea {
+ anchors.fill: parent
+ anchors.leftMargin: -8
+ onClicked: {
+ root.selectionRangeMode = false;
+ root.updateRangeButton();
+ }
+ }
+ }
+
+ MouseArea {
+ width: col.width
+ height: col.height + typeTitle.height + 30
+ drag.target: parent
+ onClicked: {
+ if ((selectionRange.x < flick.contentX) ^ (selectionRange.x+selectionRange.width > flick.contentX + flick.width)) {
+ root.recenter(selectionRange.startTime + selectionRange.duration/2);
+ }
+ }
+ }
+}
diff --git a/src/plugins/qmlprofiler/qml/popup.png b/src/plugins/qmlprofiler/qml/popup_green.png
similarity index 100%
rename from src/plugins/qmlprofiler/qml/popup.png
rename to src/plugins/qmlprofiler/qml/popup_green.png
diff --git a/src/plugins/qmlprofiler/qml/popup_orange.png b/src/plugins/qmlprofiler/qml/popup_orange.png
new file mode 100644
index 00000000000..428f0648d0a
Binary files /dev/null and b/src/plugins/qmlprofiler/qml/popup_orange.png differ
diff --git a/src/plugins/qmlprofiler/qml/qmlprofiler.qrc b/src/plugins/qmlprofiler/qml/qmlprofiler.qrc
index dcd3e5f5dc6..21be444e1a7 100644
--- a/src/plugins/qmlprofiler/qml/qmlprofiler.qrc
+++ b/src/plugins/qmlprofiler/qml/qmlprofiler.qrc
@@ -3,7 +3,8 @@
Detail.qml
Label.qml
MainView.qml
- popup.png
+ popup_green.png
+ popup_orange.png
RangeDetails.qml
RangeMover.qml
TimeDisplay.qml
@@ -20,5 +21,9 @@
TimeMarks.qml
Overview.qml
Overview.js
+ range.png
+ range_pressed.png
+ SelectionRange.qml
+ SelectionRangeDetails.qml
diff --git a/src/plugins/qmlprofiler/qml/range.png b/src/plugins/qmlprofiler/qml/range.png
new file mode 100644
index 00000000000..756318d556a
Binary files /dev/null and b/src/plugins/qmlprofiler/qml/range.png differ
diff --git a/src/plugins/qmlprofiler/qml/range_pressed.png b/src/plugins/qmlprofiler/qml/range_pressed.png
new file mode 100644
index 00000000000..53c49ab3aef
Binary files /dev/null and b/src/plugins/qmlprofiler/qml/range_pressed.png differ
diff --git a/src/plugins/qmlprofiler/qmlprofiler.pro b/src/plugins/qmlprofiler/qmlprofiler.pro
index c800387f086..533fe433f09 100644
--- a/src/plugins/qmlprofiler/qmlprofiler.pro
+++ b/src/plugins/qmlprofiler/qmlprofiler.pro
@@ -58,6 +58,8 @@ OTHER_FILES += \
qml/TimeDisplay.qml \
qml/TimeMarks.qml \
qml/StatusDisplay.qml \
+ qml/SelectionRange.qml \
+ qml/SelectionRangeDetails.qml \
qml/Overview.qml \
qml/Overview.js
diff --git a/src/plugins/qmlprofiler/tracewindow.cpp b/src/plugins/qmlprofiler/tracewindow.cpp
index d426657a34d..5d33b9bbed8 100644
--- a/src/plugins/qmlprofiler/tracewindow.cpp
+++ b/src/plugins/qmlprofiler/tracewindow.cpp
@@ -41,7 +41,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -73,7 +72,7 @@ TraceWindow::TraceWindow(QWidget *parent)
m_timebar = new QDeclarativeView(this);
m_timebar->setResizeMode(QDeclarativeView::SizeRootObjectToView);
m_timebar->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- m_timebar->setMaximumHeight(24);
+ m_timebar->setFixedHeight(24);
m_overview = new QDeclarativeView(this);
m_overview->setResizeMode(QDeclarativeView::SizeRootObjectToView);
@@ -115,9 +114,9 @@ QWidget *TraceWindow::createToolbar()
{
Utils::StyledBar *bar = new Utils::StyledBar(this);
bar->setSingleRow(true);
- bar->setMinimumWidth(150);
- bar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- bar->resize(150, 24);
+ bar->setFixedWidth(150);
+ bar->setFixedHeight(24);
+
QHBoxLayout *toolBarLayout = new QHBoxLayout(bar);
toolBarLayout->setMargin(0);
toolBarLayout->setSpacing(0);
@@ -141,11 +140,20 @@ QWidget *TraceWindow::createToolbar()
buttonZoomOut->setToolTip(tr("Zoom out 10%"));
connect(buttonZoomOut, SIGNAL(clicked()), this, SIGNAL(zoomOut()));
connect(this, SIGNAL(enableToolbar(bool)), buttonZoomOut, SLOT(setEnabled(bool)));
+ m_buttonRange = new QToolButton;
+ m_buttonRange->setIcon(QIcon(":/qmlprofiler/range.png"));
+ m_buttonRange->setToolTip(tr("Select range"));
+ m_buttonRange->setCheckable(true);
+ m_buttonRange->setChecked(false);
+ connect(m_buttonRange, SIGNAL(clicked(bool)), this, SLOT(toggleRangeMode(bool)));
+ connect(this, SIGNAL(enableToolbar(bool)), m_buttonRange, SLOT(setEnabled(bool)));
+ connect(this, SIGNAL(rangeModeChanged(bool)), m_buttonRange, SLOT(setChecked(bool)));
toolBarLayout->addWidget(buttonPrev);
toolBarLayout->addWidget(buttonNext);
toolBarLayout->addWidget(buttonZoomIn);
toolBarLayout->addWidget(buttonZoomOut);
+ toolBarLayout->addWidget(m_buttonRange);
return bar;
}
@@ -186,6 +194,7 @@ void TraceWindow::reset(QDeclarativeDebugConnection *conn)
connect(m_mainView->rootObject(), SIGNAL(updateCursorPosition()), this, SLOT(updateCursorPosition()));
connect(m_mainView->rootObject(), SIGNAL(updateTimer()), this, SLOT(updateTimer()));
+ connect(m_mainView->rootObject(), SIGNAL(updateRangeButton()), this, SLOT(updateRangeButton()));
connect(m_eventList, SIGNAL(countChanged()), this, SLOT(updateToolbar()));
connect(this, SIGNAL(jumpToPrev()), m_mainView->rootObject(), SLOT(prevEvent()));
connect(this, SIGNAL(jumpToNext()), m_mainView->rootObject(), SLOT(nextEvent()));
@@ -239,6 +248,28 @@ void TraceWindow::updateToolbar()
emit enableToolbar(m_eventList && m_eventList->count()>0);
}
+void TraceWindow::toggleRangeMode(bool active)
+{
+ bool rangeMode = m_mainView->rootObject()->property("selectionRangeMode").toBool();
+ if (active != rangeMode) {
+ if (active)
+ m_buttonRange->setIcon(QIcon(":/qmlprofiler/range_pressed.png"));
+ else
+ m_buttonRange->setIcon(QIcon(":/qmlprofiler/range.png"));
+ m_mainView->rootObject()->setProperty("selectionRangeMode", QVariant(active));
+ }
+}
+
+void TraceWindow::updateRangeButton()
+{
+ bool rangeMode = m_mainView->rootObject()->property("selectionRangeMode").toBool();
+ if (rangeMode)
+ m_buttonRange->setIcon(QIcon(":/qmlprofiler/range_pressed.png"));
+ else
+ m_buttonRange->setIcon(QIcon(":/qmlprofiler/range.png"));
+ emit rangeModeChanged(rangeMode);
+}
+
void TraceWindow::setRecording(bool recording)
{
if (recording) {
diff --git a/src/plugins/qmlprofiler/tracewindow.h b/src/plugins/qmlprofiler/tracewindow.h
index 42b404c8212..7c34f1f2aa8 100644
--- a/src/plugins/qmlprofiler/tracewindow.h
+++ b/src/plugins/qmlprofiler/tracewindow.h
@@ -40,6 +40,7 @@
#include
#include
+#include
QT_BEGIN_NAMESPACE
class QDeclarativeView;
@@ -94,6 +95,9 @@ public slots:
void updateTimer();
void clearDisplay();
void updateToolbar();
+ void toggleRangeMode(bool);
+ void updateRangeButton();
+
void qmlComplete();
void v8Complete();
@@ -112,6 +116,7 @@ signals:
void jumpToNext();
void zoomIn();
void zoomOut();
+ void rangeModeChanged(bool);
void enableToolbar(bool);
void contextMenuRequested(const QPoint& position);
@@ -136,6 +141,8 @@ private:
bool m_v8DataReady;
QWeakPointer m_zoomControl;
+
+ QToolButton *m_buttonRange;
};
} // namespace Internal