From 267b96e18ef538a219e32322e2dfb70de6fe6e6b Mon Sep 17 00:00:00 2001
From: Christiaan Janssen <christiaan.janssen@nokia.com>
Date: Wed, 19 Oct 2011 14:28:21 +0200
Subject: [PATCH] QmlProfiler: Selection Range

Change-Id: Ifa39de4762c05dc859cbd764a10760a82821d74f
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
---
 src/plugins/qmlprofiler/qml/MainView.qml      |  77 ++++-
 src/plugins/qmlprofiler/qml/RangeDetails.qml  |   2 +-
 .../qmlprofiler/qml/SelectionRange.qml        | 272 ++++++++++++++++++
 .../qmlprofiler/qml/SelectionRangeDetails.qml | 113 ++++++++
 .../qml/{popup.png => popup_green.png}        | Bin
 src/plugins/qmlprofiler/qml/popup_orange.png  | Bin 0 -> 1364 bytes
 src/plugins/qmlprofiler/qml/qmlprofiler.qrc   |   7 +-
 src/plugins/qmlprofiler/qml/range.png         | Bin 0 -> 274 bytes
 src/plugins/qmlprofiler/qml/range_pressed.png | Bin 0 -> 266 bytes
 src/plugins/qmlprofiler/qmlprofiler.pro       |   2 +
 src/plugins/qmlprofiler/tracewindow.cpp       |  41 ++-
 src/plugins/qmlprofiler/tracewindow.h         |   7 +
 12 files changed, 513 insertions(+), 8 deletions(-)
 create mode 100644 src/plugins/qmlprofiler/qml/SelectionRange.qml
 create mode 100644 src/plugins/qmlprofiler/qml/SelectionRangeDetails.qml
 rename src/plugins/qmlprofiler/qml/{popup.png => popup_green.png} (100%)
 create mode 100644 src/plugins/qmlprofiler/qml/popup_orange.png
 create mode 100644 src/plugins/qmlprofiler/qml/range.png
 create mode 100644 src/plugins/qmlprofiler/qml/range_pressed.png

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 0000000000000000000000000000000000000000..428f0648d0a64229e3b2514b9ff68bac0c7fe39c
GIT binary patch
literal 1364
zcmV-a1*`grP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T700001b5ch_0Itp)
z=>Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2ipo1
z2?hxPvAT!=00h)YL_t(o!|j<*Y!p=-$G`8*zn%Tp?QU1aw$jo>Y~etxQLyo54ABIE
zs~2t<4jMTaJ((Uz2niC1i80~AO@nCAs8keDLm@!h6w|7OEUnwtZA*9AKi%Eg*_r3%
zO?{p2!Zx<c9{eT0?7YqF%x8YT_ul+|-zAJO001F`01%xDF1g0eIgW|P0Ki<w41g`T
z<r+KZFy;VplPkbc0MgLOH+SkS?Ryk&a4!gnfH6N~Hbo6a2(<w$G22QO7H7Yk8@o2}
z%E@1bI9QpxC44%-AcR1KTotkF#}0Idx^^6=s`i2&Y1O>Zc16;3P({O9%r*^JMgjSS
zxLLRtFO@Q>(F^C#9yxq=bOJz$yD7LB)#XU8Naf8F2YZ`3w*MU5+)aI(x+JWl<!0~L
znW=GO?BZwd@B4W05`ZFigS*Kix&qRfThgu5@4f2VwB=&U_C86Ev{J0Isev$2gJH!V
zY}(zDj}Kp-SV#-=S)8kmqrbl&5&-%7u>(DUwyobpdUmQ>umu}svd0H46h+sQEw7al
z6E}yZQdtftE+i%_GDZPNp{^argPXfOT2mAoZE7HlV8=Fc=#Bkv0cZvg1mFjt1JD2{
zeAgfVh;;MB!9G3O_HKCV^B&a6)IgXNlZlX;jK!|T7L!%B9|nL??_*Ex(Ic%I>TJFz
zI_1}UxAXyM0uTV;1>oTkl%4rW6>o5#H`=b$8_*kVm%=@}p5<_U0Z<iQ41@xRNSa=6
zK1iAl+2i#C@NpLbWe1W1@UL|fUJs*+1}dv6UmQAz(^jRp*4Nht8R1YGkDMY#&q?v4
zHbrn*h+e}0O59h$H45MZ%eh7X6ssxXsx?U?0ipt6LqxDzRZbcWu<8W;AMif`@&@No
z8LM)<Jf@7<OSWm$oy;~3*rs8+D`?jk6pSS;qfmE1%P7FiXNpzI{eMgTVk+@%ej#qw
z8*pj<FMD$6a_k|EJm~DLD+7gl@lw43^NG9GnZe1J(72b~Z6^Rmcc1!o*hnvq=4S8I
zZLwsh|77=Lqw}8+PtUlT_f?P-fOX;gxg(jWal4dFZaAEgUO@WpZ`R>YzP`fM1*dT@
z36M_8nFK)peta(1Y5zUc_IPB!8Vp1B_%;NtlucrBY!Dxw`sjx*M`oq~ECI*@$Z*f{
z?+T6_BJpZg8W^9uzssMRYz~E9B9ctiK$xt1T5k`tw?8=g)u%V&lP<V4_bh-smqeBU
zRi`F9H!_nb&)pt+CM<UrQ;CpWE)hx5C?NzylGnV?l?yp!rzh;>@7K!nBR?h%9X&m8
z>5utY0WK|g20)HSujI@{!aFJt@2Y~lPi=nZ<)@$9+uQMCWLsaatm%HLXljLuqv{*N
zDizFfAy<su_$hYg>SXMTk(n8O<01!iBA4RsK(2@&5n4SDhYbjzPE+lxAWc*fGEqgi
zwD=7T9wB!G#ranhBPa_$CN8zf<|jE9bpuK@0$No7a~vusq}C9$LI!}zt|t_wFz34>
z54*?J8d9MeswM&3!h@PZit{cnh-nozYREzw%EHB+v3NnPLTgxSipv6|A&8gN1k7c<
zS_A|?fw>~+q(!OL8rA^lhOAuzW{g!7(S=@B>{+D>a1R4yE_v-iBKj(&pEUa45dQ!e
WMt8QcC>u-w0000<MNUMnLSTZfiD$_G

literal 0
HcmV?d00001

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 @@
         <file>Detail.qml</file>
         <file>Label.qml</file>
         <file>MainView.qml</file>
-        <file>popup.png</file>
+        <file>popup_green.png</file>
+        <file>popup_orange.png</file>
         <file>RangeDetails.qml</file>
         <file>RangeMover.qml</file>
         <file>TimeDisplay.qml</file>
@@ -20,5 +21,9 @@
         <file>TimeMarks.qml</file>
         <file>Overview.qml</file>
         <file>Overview.js</file>
+        <file>range.png</file>
+        <file>range_pressed.png</file>
+        <file>SelectionRange.qml</file>
+        <file>SelectionRangeDetails.qml</file>
     </qresource>
 </RCC>
diff --git a/src/plugins/qmlprofiler/qml/range.png b/src/plugins/qmlprofiler/qml/range.png
new file mode 100644
index 0000000000000000000000000000000000000000..756318d556aef8690669b0abdcad1944a1244bd5
GIT binary patch
literal 274
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Zboia9_Fj=+krxpJY5_^EKcv8
z?8|plfum*rthhtE$Dc6BO<sHaLvGhg<txi7?I%y*D0Gt)OsH7#>H*vFd6KLL&Qx$c
z7qL5Xo@LMR)is(1d+bB!9+TS|k}~6F$=5x76W`u8P7hz7l-6<LdtShy2?|PcY#c)G
z`+fU!$wj>L#0iFKoh{e4SzPjavp0Y1wT&VL6OYFKIIm(Se8OjUb8#GdedPwpIo9bw
P*D-jy`njxgN@xNAyt-#i

literal 0
HcmV?d00001

diff --git a/src/plugins/qmlprofiler/qml/range_pressed.png b/src/plugins/qmlprofiler/qml/range_pressed.png
new file mode 100644
index 0000000000000000000000000000000000000000..53c49ab3aef746bf832c8c73b0b7f607a3072c2b
GIT binary patch
literal 266
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|*pj^6T^Rm@
z;DWu&Cj&(|3p^r=85p>QL70(Y)*K0-AbW|YuPgg)Zboi4&WK45eglQNJY5_^EKaWt
zcH}#tz_Gep|KrTshVyU2Z@7vdpORCk;&RlBk&)qywrBI?wCW5t22b$~Q<^+%z8zSW
zW9`A9<Dt0qs@>8Hjw<V$`uO+GP??-kYrpzih54h;5`O8OH&pI!xGg9%v3!!k&Xl;i
z$7^PW@lH!WcJ9^rt=G!=q%3^X9{%^cQ#RqgPeRBUVF`=QWc{tW1wdCZc)I$ztaD0e
F0sym#UKIcU

literal 0
HcmV?d00001

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 <QtDeclarative/QDeclarativeView>
 #include <QtDeclarative/QDeclarativeContext>
 #include <QtGui/QVBoxLayout>
-#include <QtGui/QToolButton>
 #include <QtGui/QGraphicsObject>
 #include <QtGui/QContextMenuEvent>
 #include <QtGui/QScrollBar>
@@ -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 <QtCore/QPointer>
 #include <QtGui/QWidget>
+#include <QtGui/QToolButton>
 
 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<ZoomControl> m_zoomControl;
+
+    QToolButton *m_buttonRange;
 };
 
 } // namespace Internal
-- 
GitLab