forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/2.3'
Conflicts: qtcreator.pri share/qtcreator/dumper/dumper.py share/qtcreator/qml/qmlpuppet/instances/objectnodeinstance.h src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp src/plugins/valgrind/valgrind.pro tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp Change-Id: Ic2d347012d89d697e6382f156e64f9619da88300
This commit is contained in:
@@ -941,6 +941,8 @@ void Context2D::beginPainting()
|
||||
return;
|
||||
|
||||
if (m_pixmap.width() != m_width || m_pixmap.height() != m_height) {
|
||||
if (m_painter.isActive())
|
||||
m_painter.end();
|
||||
m_pixmap = QPixmap(m_width, m_height);
|
||||
m_pixmap.fill(parent()->property("color").value<QColor>());
|
||||
}
|
||||
|
||||
@@ -6,26 +6,25 @@
|
||||
**
|
||||
** Contact: Nokia Corporation (info@qt.nokia.com)
|
||||
**
|
||||
** No Commercial Usage
|
||||
**
|
||||
** This file contains pre-release code and may not be distributed.
|
||||
** You may use this file in accordance with the terms and conditions
|
||||
** contained in the Technology Preview License Agreement accompanying
|
||||
** this package.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, 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.
|
||||
** 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
|
||||
** 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.
|
||||
**
|
||||
@@ -33,12 +32,9 @@
|
||||
|
||||
.pragma library
|
||||
|
||||
var values = [ ]; //events
|
||||
var ranges = [ ];
|
||||
var frameFps = [ ];
|
||||
var xmargin = 0;
|
||||
var ymargin = 0;
|
||||
var drawFpsGraph = false;
|
||||
var nestingDepth = [];
|
||||
|
||||
var names = [ "Painting", "Compiling", "Creating", "Binding", "Handling Signal"]
|
||||
@@ -49,26 +45,12 @@ var xRayColors = [ "#6699CCB3", "#6699CCCC", "#6699B3CC", "#669999CC", "#66CC99B
|
||||
|
||||
function reset()
|
||||
{
|
||||
values = [];
|
||||
ranges = [];
|
||||
frameFps = [];
|
||||
xmargin = 0;
|
||||
ymargin = 0;
|
||||
nestingDepth = [];
|
||||
}
|
||||
|
||||
function calcFps()
|
||||
{
|
||||
if (drawFpsGraph) {
|
||||
if (values.length)
|
||||
frameFps = new Array(values.length - 1);
|
||||
for (var i = 0; i < values.length - 1; ++i) {
|
||||
var frameTime = (values[i + 1] - values[i]) / 1000000;
|
||||
frameFps[i] = 1000 / frameTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//draw background of the graph
|
||||
function drawGraph(canvas, ctxt, region)
|
||||
{
|
||||
@@ -83,7 +65,7 @@ function drawGraph(canvas, ctxt, region)
|
||||
//draw the actual data to be graphed
|
||||
function drawData(canvas, ctxt, region)
|
||||
{
|
||||
if (values.length == 0 && ranges.length == 0)
|
||||
if (ranges.length == 0)
|
||||
return;
|
||||
|
||||
var width = canvas.canvasSize.width - xmargin;
|
||||
@@ -115,24 +97,6 @@ function drawData(canvas, ctxt, region)
|
||||
highest[ranges[ii].type] = xx+size;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawFpsGraph) {
|
||||
//draw fps overlay
|
||||
var heightScale = height / 60;
|
||||
ctxt.beginPath();
|
||||
ctxt.moveTo(0,0);
|
||||
for (var i = 1; i < values.length; ++i) {
|
||||
var xx = (values[i] - ranges[0].start) * spacing + xmargin;
|
||||
ctxt.lineTo(xx, height - frameFps[i-1]*heightScale)
|
||||
}
|
||||
ctxt.lineTo(width, 0);
|
||||
ctxt.closePath();
|
||||
var grad = ctxt.createLinearGradient(0, 0, 0, canvas.canvasSize.height);
|
||||
grad.addColorStop(0, "rgba(255,128,128,.5)");
|
||||
grad.addColorStop(1, "rgba(255,0,0,.5)");
|
||||
ctxt.fillStyle = grad;
|
||||
ctxt.fill();
|
||||
}
|
||||
}
|
||||
|
||||
function plot(canvas, ctxt, region)
|
||||
@@ -143,7 +107,7 @@ function plot(canvas, ctxt, region)
|
||||
|
||||
function xScale(canvas)
|
||||
{
|
||||
if (values.length === 0 && ranges.length === 0)
|
||||
if (ranges.length === 0)
|
||||
return;
|
||||
|
||||
var width = canvas.canvasSize.width - xmargin;
|
||||
|
||||
@@ -38,6 +38,7 @@ Rectangle {
|
||||
id: root
|
||||
|
||||
property bool dataAvailable: false;
|
||||
property int eventCount: 0;
|
||||
|
||||
// move the cursor in the editor
|
||||
signal updateCursorPosition
|
||||
@@ -53,6 +54,7 @@ Rectangle {
|
||||
Plotter.reset();
|
||||
view.clearData();
|
||||
root.dataAvailable = false;
|
||||
root.eventCount = 0;
|
||||
rangeMover.x = 2
|
||||
rangeMover.opacity = 0
|
||||
}
|
||||
@@ -128,14 +130,6 @@ Rectangle {
|
||||
//handle debug data coming from C++
|
||||
Connections {
|
||||
target: connection
|
||||
onEvent: {
|
||||
if (root.dataAvailable) {
|
||||
root.clearData();
|
||||
}
|
||||
|
||||
if (!root.dataAvailable && event === 0) //### only handle paint event
|
||||
Plotter.values.push(time);
|
||||
}
|
||||
|
||||
onRange: {
|
||||
if (root.dataAvailable) {
|
||||
@@ -151,19 +145,22 @@ Rectangle {
|
||||
Plotter.ranges.push( { type: type, start: startTime, duration: length, label: data, fileName: fileName, line: line, nestingLevel: nestingInType, nestingDepth: Plotter.nestingDepth[type] } );
|
||||
if (nestingInType == 1)
|
||||
Plotter.nestingDepth[type] = 1;
|
||||
root.eventCount = Plotter.ranges.length;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
onComplete: {
|
||||
root.dataAvailable = true;
|
||||
Plotter.calcFps();
|
||||
view.visible = true;
|
||||
view.setRanges(Plotter.ranges);
|
||||
view.updateTimeline();
|
||||
canvas.requestPaint();
|
||||
rangeMover.x = 1 //### hack to get view to display things immediately
|
||||
rangeMover.x = 0
|
||||
rangeMover.opacity = 1
|
||||
if (Plotter.ranges.length > 0) {
|
||||
view.visible = true;
|
||||
view.setRanges(Plotter.ranges);
|
||||
view.updateTimeline();
|
||||
canvas.requestPaint();
|
||||
rangeMover.x = 1 //### hack to get view to display things immediately
|
||||
rangeMover.x = 0
|
||||
rangeMover.opacity = 1
|
||||
}
|
||||
}
|
||||
|
||||
onClear: {
|
||||
@@ -500,4 +497,8 @@ Rectangle {
|
||||
height: flick.height + labels.y
|
||||
visible: false
|
||||
}
|
||||
|
||||
StatusDisplay {
|
||||
anchors.centerIn: flick
|
||||
}
|
||||
}
|
||||
|
||||
106
src/plugins/qmlprofiler/qml/StatusDisplay.qml
Normal file
106
src/plugins/qmlprofiler/qml/StatusDisplay.qml
Normal file
@@ -0,0 +1,106 @@
|
||||
import QtQuick 1.0
|
||||
import "MainView.js" as Plotter
|
||||
|
||||
Rectangle {
|
||||
id: statusDisplay
|
||||
|
||||
property real percentage : 0
|
||||
property int eventCount: root.eventCount
|
||||
onEventCountChanged: {
|
||||
if (state=="loading" && eventCount > 0 && root.elapsedTime > 0) {
|
||||
percentage = Math.min(1.0,
|
||||
(Plotter.ranges[Plotter.ranges.length-1].start - Plotter.ranges[0].start) / root.elapsedTime * 1e-9 );
|
||||
}
|
||||
}
|
||||
|
||||
width: 200
|
||||
height: displayColumn.height + 20
|
||||
|
||||
visible: false;
|
||||
|
||||
color: "#CCD0CC"
|
||||
border.width: 1
|
||||
border.color: "#AAAEAA";
|
||||
radius: 4
|
||||
|
||||
Column {
|
||||
id: displayColumn
|
||||
y: 10
|
||||
spacing: 5
|
||||
Text {
|
||||
id: statusText
|
||||
width: statusDisplay.width
|
||||
horizontalAlignment: "AlignHCenter"
|
||||
y: 10
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: progressBar
|
||||
|
||||
visible: false
|
||||
|
||||
width: statusDisplay.width - 20
|
||||
height: 20
|
||||
x: 10
|
||||
color: "transparent"
|
||||
border.width: 1
|
||||
border.color: "#AAAEAA"
|
||||
Rectangle {
|
||||
x: 1
|
||||
y: 1
|
||||
width: (parent.width-1) * statusDisplay.percentage
|
||||
color: Qt.rgba(0.37 + 0.2*(1 - statusDisplay.percentage), 0.58, 0.37, 1);
|
||||
height: parent.height-1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
// no data available
|
||||
State {
|
||||
when: (root.eventCount == 0) && !connection.recording;
|
||||
PropertyChanges {
|
||||
target: statusDisplay
|
||||
visible: true
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: statusText
|
||||
text: qsTr("No QML events recorded");
|
||||
}
|
||||
},
|
||||
// running app
|
||||
State {
|
||||
when: connection.recording;
|
||||
PropertyChanges {
|
||||
target: statusDisplay
|
||||
visible: true
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: statusText
|
||||
text: qsTr("Profiling application");
|
||||
}
|
||||
},
|
||||
// loading data
|
||||
State {
|
||||
name: "loading"
|
||||
when: (!root.dataAvailable) && (root.eventCount > 0);
|
||||
PropertyChanges {
|
||||
target: statusDisplay
|
||||
visible: true
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: statusText
|
||||
text: qsTr("Loading data");
|
||||
}
|
||||
|
||||
PropertyChanges {
|
||||
target: progressBar
|
||||
visible: true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
@@ -103,7 +103,7 @@ TiledCanvas {
|
||||
}
|
||||
|
||||
function drawBackgroundBars( ctxt, region ) {
|
||||
var barHeight = labels.height / labels.rowCount;
|
||||
var barHeight = Math.round(labels.height / labels.rowCount);
|
||||
var originY = labels.y
|
||||
for (var i=0; i<labels.rowCount; i++) {
|
||||
ctxt.fillStyle = i%2 ? "#f3f3f3" : "white"
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
<file>magnifier-plus.png</file>
|
||||
<file>recordOff.png</file>
|
||||
<file>recordOn.png</file>
|
||||
<file>StatusDisplay.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -59,7 +59,8 @@ OTHER_FILES += \
|
||||
qml/RangeDetails.qml \
|
||||
qml/RangeMover.qml \
|
||||
qml/MainView.js \
|
||||
qml/TimeDisplay.qml
|
||||
qml/TimeDisplay.qml \
|
||||
qml/StatusDisplay.qml
|
||||
|
||||
FORMS += \
|
||||
qmlprofilerattachdialog.ui
|
||||
|
||||
@@ -173,6 +173,19 @@ void QmlProfilerEngine::stop()
|
||||
|
||||
void QmlProfilerEngine::stopped()
|
||||
{
|
||||
// user feedback
|
||||
if (d->m_running && d->m_fetchingData) {
|
||||
Core::ICore * const core = Core::ICore::instance();
|
||||
QMessageBox *killedWarning = new QMessageBox(core->mainWindow());
|
||||
killedWarning->setIcon(QMessageBox::Warning);
|
||||
killedWarning->setWindowTitle(tr("QML Profiler"));
|
||||
killedWarning->setText(tr("Application finished before loading profiled data.\n Please use the stop button instead."));
|
||||
killedWarning->setStandardButtons(QMessageBox::Ok);
|
||||
killedWarning->setDefaultButton(QMessageBox::Ok);
|
||||
killedWarning->setModal(false);
|
||||
killedWarning->show();
|
||||
}
|
||||
|
||||
d->m_running = false;
|
||||
AnalyzerManager::stopTool(); // FIXME: Needed?
|
||||
emit finished();
|
||||
@@ -265,7 +278,7 @@ void QmlProfilerEngine::wrongSetupMessageBoxFinished(int button)
|
||||
{
|
||||
if (button == QMessageBox::Help) {
|
||||
Core::HelpManager *helpManager = Core::HelpManager::instance();
|
||||
helpManager->handleHelpRequest("creator-qml-performance-monitor.html");
|
||||
helpManager->handleHelpRequest("qthelp://com.nokia.qtcreator/doc/creator-qml-performance-monitor.html");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -125,11 +125,16 @@ void QmlProfilerEventStatistics::clear()
|
||||
d->m_rootHash.clear();
|
||||
}
|
||||
|
||||
QList <QmlEventData *> QmlProfilerEventStatistics::getEventList()
|
||||
QList <QmlEventData *> QmlProfilerEventStatistics::getEventList() const
|
||||
{
|
||||
return d->m_rootHash.values();
|
||||
}
|
||||
|
||||
int QmlProfilerEventStatistics::eventCount() const
|
||||
{
|
||||
return d->m_rootHash.size();
|
||||
}
|
||||
|
||||
void QmlProfilerEventStatistics::addRangedEvent(int type, int nestingLevel, int nestingInType, qint64 startTime, qint64 length,
|
||||
const QStringList &data, const QString &fileName, int line)
|
||||
{
|
||||
|
||||
@@ -85,7 +85,8 @@ public:
|
||||
explicit QmlProfilerEventStatistics(QObject *parent = 0);
|
||||
~QmlProfilerEventStatistics();
|
||||
|
||||
QmlEventList getEventList();
|
||||
QmlEventList getEventList() const;
|
||||
int eventCount() const;
|
||||
|
||||
signals:
|
||||
void dataReady();
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
#include <QtGui/QTabWidget>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QMessageBox>
|
||||
#include <QtGui/QDockWidget>
|
||||
|
||||
using namespace Analyzer;
|
||||
using namespace QmlProfiler::Internal;
|
||||
@@ -216,6 +217,7 @@ IAnalyzerEngine *QmlProfilerTool::createEngine(const AnalyzerStartParameters &sp
|
||||
|
||||
connect(engine, SIGNAL(processRunning(int)), this, SLOT(connectClient(int)));
|
||||
connect(engine, SIGNAL(finished()), this, SLOT(disconnectClient()));
|
||||
connect(engine, SIGNAL(finished()), this, SLOT(correctTimer()));
|
||||
connect(engine, SIGNAL(stopRecording()), this, SLOT(stopRecording()));
|
||||
connect(d->m_traceWindow, SIGNAL(viewUpdated()), engine, SLOT(dataReceived()));
|
||||
connect(this, SIGNAL(connectionFailed()), engine, SLOT(finishProcess()));
|
||||
@@ -295,6 +297,11 @@ QWidget *QmlProfilerTool::createWidgets()
|
||||
QDockWidget *callerDock = AnalyzerManager::createDockWidget
|
||||
(this, tr("Callers"), d->m_callerView, Qt::BottomDockWidgetArea);
|
||||
|
||||
eventsDock->show();
|
||||
timelineDock->show();
|
||||
calleeDock->show();
|
||||
callerDock->show();
|
||||
|
||||
mw->splitDockWidget(mw->toolBarDockWidget(), eventsDock, Qt::Vertical);
|
||||
mw->tabifyDockWidget(eventsDock, timelineDock);
|
||||
mw->tabifyDockWidget(timelineDock, calleeDock);
|
||||
@@ -329,8 +336,9 @@ QWidget *QmlProfilerTool::createWidgets()
|
||||
palette.setColor(QPalette::WindowText, Qt::white);
|
||||
timeLabel->setPalette(palette);
|
||||
timeLabel->setIndent(10);
|
||||
|
||||
connect(d->m_traceWindow, SIGNAL(viewUpdated()), this, SLOT(correctTimer()));
|
||||
connect(this, SIGNAL(setTimeLabel(QString)), timeLabel, SLOT(setText(QString)));
|
||||
correctTimer();
|
||||
layout->addWidget(timeLabel);
|
||||
|
||||
toolbarWidget->setLayout(layout);
|
||||
@@ -426,6 +434,11 @@ void QmlProfilerTool::gotoSourceLocation(const QString &fileUrl, int lineNumber)
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProfilerTool::correctTimer() {
|
||||
if (d->m_statistics->eventCount() == 0)
|
||||
updateTimer(0);
|
||||
}
|
||||
|
||||
void QmlProfilerTool::updateTimer(qreal elapsedSeconds)
|
||||
{
|
||||
QString timeString = QString::number(elapsedSeconds,'f',1);
|
||||
|
||||
@@ -72,6 +72,7 @@ public slots:
|
||||
|
||||
void gotoSourceLocation(const QString &fileUrl, int lineNumber);
|
||||
void updateTimer(qreal elapsedSeconds);
|
||||
void correctTimer();
|
||||
|
||||
void clearDisplay();
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ void TimelineView::updateTimeline(bool updateStartX)
|
||||
|
||||
// Show items
|
||||
int z = 0;
|
||||
for (int i = maxsample-1; i >= minsample; --i) {
|
||||
for (int i = maxsample; i >= minsample; --i) {
|
||||
QDeclarativeItem *item = 0;
|
||||
item = m_items.value(i);
|
||||
bool creating = false;
|
||||
|
||||
Reference in New Issue
Block a user