forked from qt-creator/qt-creator
Add qmlinspector plugin.
This commit is contained in:
@@ -37,6 +37,10 @@ SUBDIRS = plugin_coreplugin \
|
|||||||
plugin_mercurial \
|
plugin_mercurial \
|
||||||
debugger/dumper.pro
|
debugger/dumper.pro
|
||||||
|
|
||||||
|
contains(QT_CONFIG, declarative) {
|
||||||
|
SUBDIRS += plugin_qmlinspector
|
||||||
|
}
|
||||||
|
|
||||||
plugin_coreplugin.subdir = coreplugin
|
plugin_coreplugin.subdir = coreplugin
|
||||||
|
|
||||||
plugin_welcome.subdir = welcome
|
plugin_welcome.subdir = welcome
|
||||||
@@ -180,6 +184,11 @@ plugin_qmlprojectmanager.depends += plugin_projectexplorer
|
|||||||
plugin_qmlprojectmanager.depends += plugin_help
|
plugin_qmlprojectmanager.depends += plugin_help
|
||||||
plugin_qmlprojectmanager.depends += plugin_qmleditor
|
plugin_qmlprojectmanager.depends += plugin_qmleditor
|
||||||
|
|
||||||
|
plugin_qmlinspector.subdir = qmlinspector
|
||||||
|
plugin_qmlinspector.depends += plugin_projectexplorer
|
||||||
|
plugin_qmlinspector.depends += plugin_coreplugin
|
||||||
|
plugin_qmlinspector.depends += plugin_texteditor
|
||||||
|
|
||||||
plugin_mercurial.subdir = mercurial
|
plugin_mercurial.subdir = mercurial
|
||||||
plugin_mercurial.depends = plugin_texteditor
|
plugin_mercurial.depends = plugin_texteditor
|
||||||
plugin_mercurial.depends = plugin_vcsbase
|
plugin_mercurial.depends = plugin_vcsbase
|
||||||
|
|||||||
28
src/plugins/qmlinspector/QmlInspector.pluginspec
Normal file
28
src/plugins/qmlinspector/QmlInspector.pluginspec
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<plugin name="QmlInspector" version="1.3.80" compatVersion="1.3.80">
|
||||||
|
<vendor>Nokia Corporation</vendor>
|
||||||
|
<copyright>(C) 2008-2009 Nokia Corporation</copyright>
|
||||||
|
<license>
|
||||||
|
Commercial Usage
|
||||||
|
|
||||||
|
Licensees holding valid Qt Commercial licenses may use this plugin in
|
||||||
|
accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
Software or, alternatively, in accordance with the terms contained in
|
||||||
|
a written agreement between you and Nokia.
|
||||||
|
|
||||||
|
GNU Lesser General Public License Usage
|
||||||
|
|
||||||
|
Alternatively, this plugin may be used under the terms of the GNU Lesser
|
||||||
|
General Public License version 2.1 as published by the Free Software
|
||||||
|
Foundation. 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.</license>
|
||||||
|
<description>Qml support</description>
|
||||||
|
<url>http://qt.nokia.com</url>
|
||||||
|
<dependencyList>
|
||||||
|
<dependency name="QmlProjectManager" version="1.3.80"/>
|
||||||
|
<dependency name="ProjectExplorer" version="1.3.80"/>
|
||||||
|
<dependency name="CppTools" version="1.3.80"/>
|
||||||
|
<dependency name="CppEditor" version="1.3.80"/>
|
||||||
|
<dependency name="Help" version="1.3.80"/>
|
||||||
|
</dependencyList>
|
||||||
|
</plugin>
|
||||||
569
src/plugins/qmlinspector/components/canvasframerate.cpp
Normal file
569
src/plugins/qmlinspector/components/canvasframerate.cpp
Normal file
@@ -0,0 +1,569 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "canvasframerate.h"
|
||||||
|
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/qstringlist.h>
|
||||||
|
#include <QtCore/qdatastream.h>
|
||||||
|
#include <QtCore/qmargins.h>
|
||||||
|
|
||||||
|
#include <QtGui/qapplication.h>
|
||||||
|
#include <QtGui/qpainter.h>
|
||||||
|
#include <QtGui/qtooltip.h>
|
||||||
|
#include <QtGui/qslider.h>
|
||||||
|
#include <QtGui/qscrollbar.h>
|
||||||
|
#include <QtGui/qspinbox.h>
|
||||||
|
#include <QtGui/qgroupbox.h>
|
||||||
|
#include <QtGui/qboxlayout.h>
|
||||||
|
#include <QtGui/qlabel.h>
|
||||||
|
#include <QtGui/qlineedit.h>
|
||||||
|
#include <QtGui/qpushbutton.h>
|
||||||
|
#include <QtGui/qtabwidget.h>
|
||||||
|
#include <QtGui/qevent.h>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QLineGraph : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
QLineGraph(QAbstractSlider *slider, QWidget * = 0);
|
||||||
|
|
||||||
|
void setPosition(int);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addSample(int, int, int, bool);
|
||||||
|
void setResolutionForHeight(int);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void paintEvent(QPaintEvent *);
|
||||||
|
virtual void mouseMoveEvent(QMouseEvent *);
|
||||||
|
virtual void leaveEvent(QEvent *);
|
||||||
|
virtual void wheelEvent(QWheelEvent *event);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void sliderChanged(int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void updateSlider();
|
||||||
|
void drawSample(QPainter *, int, const QRect &, QList<QRect> *);
|
||||||
|
void drawTime(QPainter *, const QRect &);
|
||||||
|
QRect findContainingRect(const QList<QRect> &rects, const QPoint &pos) const;
|
||||||
|
struct Sample {
|
||||||
|
int sample[3];
|
||||||
|
bool isBreak;
|
||||||
|
};
|
||||||
|
QList<Sample> _samples;
|
||||||
|
|
||||||
|
QAbstractSlider *slider;
|
||||||
|
int position;
|
||||||
|
int samplesPerWidth;
|
||||||
|
int resolutionForHeight;
|
||||||
|
bool ignoreScroll;
|
||||||
|
QMargins graphMargins;
|
||||||
|
|
||||||
|
QList<QRect> rectsPaintTime; // time to do a paintEvent()
|
||||||
|
QList<QRect> rectsTimeBetween; // time between frames
|
||||||
|
QRect highlightedBar;
|
||||||
|
};
|
||||||
|
|
||||||
|
QLineGraph::QLineGraph(QAbstractSlider *slider, QWidget *parent)
|
||||||
|
: QWidget(parent), slider(slider), position(-1), samplesPerWidth(99), resolutionForHeight(50),
|
||||||
|
ignoreScroll(false), graphMargins(65, 10, 71, 35)
|
||||||
|
{
|
||||||
|
setMouseTracking(true);
|
||||||
|
|
||||||
|
slider->setMaximum(0);
|
||||||
|
slider->setMinimum(0);
|
||||||
|
slider->setSingleStep(1);
|
||||||
|
|
||||||
|
connect(slider, SIGNAL(valueChanged(int)), this, SLOT(sliderChanged(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::sliderChanged(int v)
|
||||||
|
{
|
||||||
|
if (ignoreScroll)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (v == slider->maximum())
|
||||||
|
position = -1;
|
||||||
|
else
|
||||||
|
position = v;
|
||||||
|
|
||||||
|
update();
|
||||||
|
|
||||||
|
// update highlightedRect
|
||||||
|
QPoint pos = mapFromGlobal(QCursor::pos());
|
||||||
|
if (geometry().contains(pos)) {
|
||||||
|
QMouseEvent *me = new QMouseEvent(QEvent::MouseMove, pos,
|
||||||
|
Qt::NoButton, Qt::NoButton, Qt::NoModifier);
|
||||||
|
QApplication::postEvent(this, me);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::clear()
|
||||||
|
{
|
||||||
|
_samples.clear();
|
||||||
|
rectsPaintTime.clear();
|
||||||
|
rectsTimeBetween.clear();
|
||||||
|
highlightedBar = QRect();
|
||||||
|
position = -1;
|
||||||
|
|
||||||
|
updateSlider();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::updateSlider()
|
||||||
|
{
|
||||||
|
ignoreScroll = true;
|
||||||
|
slider->setMaximum(qMax(0, _samples.count() - samplesPerWidth - 1));
|
||||||
|
|
||||||
|
if (position == -1) {
|
||||||
|
slider->setValue(slider->maximum());
|
||||||
|
} else {
|
||||||
|
slider->setValue(position);
|
||||||
|
}
|
||||||
|
ignoreScroll = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::addSample(int a, int b, int d, bool isBreak)
|
||||||
|
{
|
||||||
|
Sample s;
|
||||||
|
s.isBreak = isBreak;
|
||||||
|
s.sample[0] = a;
|
||||||
|
s.sample[1] = b;
|
||||||
|
s.sample[2] = d;
|
||||||
|
_samples << s;
|
||||||
|
updateSlider();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::setPosition(int p)
|
||||||
|
{
|
||||||
|
sliderChanged(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::drawTime(QPainter *p, const QRect &rect)
|
||||||
|
{
|
||||||
|
if (_samples.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int first = position;
|
||||||
|
if (first == -1)
|
||||||
|
first = qMax(0, _samples.count() - samplesPerWidth - 1);
|
||||||
|
int last = qMin(_samples.count() - 1, first + samplesPerWidth);
|
||||||
|
|
||||||
|
qreal scaleX = qreal(rect.width()) / qreal(samplesPerWidth);
|
||||||
|
|
||||||
|
int t = 0;
|
||||||
|
|
||||||
|
for (int ii = first; ii <= last; ++ii) {
|
||||||
|
int sampleTime = _samples.at(ii).sample[2] / 1000;
|
||||||
|
if (sampleTime != t) {
|
||||||
|
|
||||||
|
int xEnd = rect.left() + scaleX * (ii - first);
|
||||||
|
p->drawLine(xEnd, rect.bottom(), xEnd, rect.bottom() + 7);
|
||||||
|
|
||||||
|
QRect text(xEnd - 30, rect.bottom() + 10, 60, 30);
|
||||||
|
|
||||||
|
p->drawText(text, Qt::AlignHCenter | Qt::AlignTop, QString::number(_samples.at(ii).sample[2]));
|
||||||
|
|
||||||
|
t = sampleTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::drawSample(QPainter *p, int s, const QRect &rect, QList<QRect> *record)
|
||||||
|
{
|
||||||
|
if (_samples.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
int first = position;
|
||||||
|
if (first == -1)
|
||||||
|
first = qMax(0, _samples.count() - samplesPerWidth - 1);
|
||||||
|
int last = qMin(_samples.count() - 1, first + samplesPerWidth);
|
||||||
|
|
||||||
|
qreal scaleY = qreal(rect.height()) / resolutionForHeight;
|
||||||
|
qreal scaleX = qreal(rect.width()) / qreal(samplesPerWidth);
|
||||||
|
|
||||||
|
int xEnd;
|
||||||
|
int lastXEnd = rect.left();
|
||||||
|
|
||||||
|
p->save();
|
||||||
|
p->setPen(Qt::NoPen);
|
||||||
|
for (int ii = first + 1; ii <= last; ++ii) {
|
||||||
|
|
||||||
|
xEnd = rect.left() + scaleX * (ii - first);
|
||||||
|
int yEnd = rect.bottom() - _samples.at(ii).sample[s] * scaleY;
|
||||||
|
|
||||||
|
if (!(s == 0 && _samples.at(ii).isBreak)) {
|
||||||
|
QRect bar(lastXEnd, yEnd, scaleX, _samples.at(ii).sample[s] * scaleY);
|
||||||
|
record->append(bar);
|
||||||
|
p->drawRect(bar);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastXEnd = xEnd;
|
||||||
|
}
|
||||||
|
p->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::paintEvent(QPaintEvent *)
|
||||||
|
{
|
||||||
|
QPainter p(this);
|
||||||
|
p.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QRect r(graphMargins.left(), graphMargins.top(),
|
||||||
|
width() - graphMargins.right(), height() - graphMargins.bottom());
|
||||||
|
|
||||||
|
p.save();
|
||||||
|
p.rotate(-90);
|
||||||
|
p.translate(-r.height()/2 - r.width()/2 - graphMargins.right(), -r.height()/2);
|
||||||
|
p.drawText(r, Qt::AlignCenter, tr("Frame rate"));
|
||||||
|
p.restore();
|
||||||
|
|
||||||
|
p.setBrush(QColor("lightsteelblue"));
|
||||||
|
rectsTimeBetween.clear();
|
||||||
|
drawSample(&p, 0, r, &rectsTimeBetween);
|
||||||
|
|
||||||
|
p.setBrush(QColor("pink"));
|
||||||
|
rectsPaintTime.clear();
|
||||||
|
drawSample(&p, 1, r, &rectsPaintTime);
|
||||||
|
|
||||||
|
if (!highlightedBar.isNull()) {
|
||||||
|
p.setBrush(Qt::darkGreen);
|
||||||
|
p.drawRect(highlightedBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.drawRect(r);
|
||||||
|
|
||||||
|
slider->setGeometry(x() + r.x(), slider->y(), r.width(), slider->height());
|
||||||
|
|
||||||
|
for (int ii = 0; ii <= resolutionForHeight; ++ii) {
|
||||||
|
int y = 1 + r.bottom() - ii * r.height() / resolutionForHeight;
|
||||||
|
|
||||||
|
if ((ii % 10) == 0) {
|
||||||
|
p.drawLine(r.left() - 20, y, r.left(), y);
|
||||||
|
QRect text(r.left() - 20 - 53, y - 10, 50, 20);
|
||||||
|
p.drawText(text, Qt::AlignRight | Qt::AlignVCenter, QString::number(ii));
|
||||||
|
} else {
|
||||||
|
p.drawLine(r.left() - 7, y, r.left(), y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawTime(&p, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
QPoint pos = event->pos();
|
||||||
|
|
||||||
|
QRect rect = findContainingRect(rectsPaintTime, pos);
|
||||||
|
if (rect.isNull())
|
||||||
|
rect = findContainingRect(rectsTimeBetween, pos);
|
||||||
|
|
||||||
|
if (!highlightedBar.isNull())
|
||||||
|
update(highlightedBar.adjusted(-1, -1, 1, 1));
|
||||||
|
highlightedBar = rect;
|
||||||
|
|
||||||
|
if (!rect.isNull()) {
|
||||||
|
QRect graph(graphMargins.left(), graphMargins.top(),
|
||||||
|
width() - graphMargins.right(), height() - graphMargins.bottom());
|
||||||
|
qreal scaleY = qreal(graph.height()) / resolutionForHeight;
|
||||||
|
QToolTip::showText(event->globalPos(), QString::number(qRound(rect.height() / scaleY)), this, rect);
|
||||||
|
update(rect.adjusted(-1, -1, 1, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::leaveEvent(QEvent *)
|
||||||
|
{
|
||||||
|
if (!highlightedBar.isNull()) {
|
||||||
|
QRect bar = highlightedBar.adjusted(-1, -1, 1, 1);
|
||||||
|
highlightedBar = QRect();
|
||||||
|
update(bar);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::wheelEvent(QWheelEvent *event)
|
||||||
|
{
|
||||||
|
QWheelEvent we(QPoint(0,0), event->delta(), event->buttons(), event->modifiers(), event->orientation());
|
||||||
|
QApplication::sendEvent(slider, &we);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QLineGraph::setResolutionForHeight(int resolution)
|
||||||
|
{
|
||||||
|
resolutionForHeight = resolution;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect QLineGraph::findContainingRect(const QList<QRect> &rects, const QPoint &pos) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<rects.count(); ++i) {
|
||||||
|
if (rects[i].contains(pos))
|
||||||
|
return rects[i];
|
||||||
|
}
|
||||||
|
return QRect();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class GraphWindow : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
GraphWindow(QWidget *parent = 0);
|
||||||
|
|
||||||
|
virtual QSize sizeHint() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addSample(int, int, int, bool);
|
||||||
|
void setResolutionForHeight(int);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLineGraph *m_graph;
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphWindow::GraphWindow(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
QSlider *scroll = new QSlider(Qt::Horizontal);
|
||||||
|
scroll->setFocusPolicy(Qt::WheelFocus);
|
||||||
|
m_graph = new QLineGraph(scroll);
|
||||||
|
|
||||||
|
setFocusPolicy(Qt::WheelFocus);
|
||||||
|
setFocusProxy(scroll);
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 5, 0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->addWidget(m_graph, 2);
|
||||||
|
layout->addWidget(new QLabel(tr("Total time elapsed (ms)")), 0, Qt::AlignHCenter);
|
||||||
|
layout->addWidget(scroll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphWindow::addSample(int a, int b, int d, bool isBreak)
|
||||||
|
{
|
||||||
|
m_graph->addSample(a, b, d, isBreak);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphWindow::setResolutionForHeight(int res)
|
||||||
|
{
|
||||||
|
m_graph->setResolutionForHeight(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GraphWindow::clear()
|
||||||
|
{
|
||||||
|
m_graph->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize GraphWindow::sizeHint() const
|
||||||
|
{
|
||||||
|
return QSize(400, 220);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CanvasFrameRatePlugin : public QmlDebugClient
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CanvasFrameRatePlugin(QmlDebugConnection *client);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void sample(int, int, int, bool);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void messageReceived(const QByteArray &);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int lb;
|
||||||
|
int ld;
|
||||||
|
};
|
||||||
|
|
||||||
|
CanvasFrameRatePlugin::CanvasFrameRatePlugin(QmlDebugConnection *client)
|
||||||
|
: QmlDebugClient(QLatin1String("CanvasFrameRate"), client), lb(-1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRatePlugin::messageReceived(const QByteArray &data)
|
||||||
|
{
|
||||||
|
QByteArray rwData = data;
|
||||||
|
QDataStream stream(&rwData, QIODevice::ReadOnly);
|
||||||
|
|
||||||
|
int b; int c; int d; bool isBreak;
|
||||||
|
stream >> b >> c >> d >> isBreak;
|
||||||
|
|
||||||
|
if (lb != -1)
|
||||||
|
emit sample(c, lb, ld, isBreak);
|
||||||
|
|
||||||
|
lb = b;
|
||||||
|
ld = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
CanvasFrameRate::CanvasFrameRate(QWidget *parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
m_plugin(0)
|
||||||
|
{
|
||||||
|
m_tabs = new QTabWidget(this);
|
||||||
|
|
||||||
|
QHBoxLayout *bottom = new QHBoxLayout;
|
||||||
|
bottom->setMargin(0);
|
||||||
|
bottom->setSpacing(10);
|
||||||
|
|
||||||
|
m_res = new QSpinBox;
|
||||||
|
m_res->setRange(30, 200);
|
||||||
|
m_res->setValue(m_res->minimum());
|
||||||
|
m_res->setSingleStep(10);
|
||||||
|
m_res->setSuffix(QLatin1String("ms"));
|
||||||
|
bottom->addWidget(new QLabel(tr("Resolution:")));
|
||||||
|
bottom->addWidget(m_res);
|
||||||
|
|
||||||
|
bottom->addStretch();
|
||||||
|
|
||||||
|
m_clearButton = new QPushButton(tr("Clear"));
|
||||||
|
connect(m_clearButton, SIGNAL(clicked()), SLOT(clearGraph()));
|
||||||
|
bottom->addWidget(m_clearButton);
|
||||||
|
|
||||||
|
QPushButton *pb = new QPushButton(tr("New Graph"), this);
|
||||||
|
connect(pb, SIGNAL(clicked()), this, SLOT(newTab()));
|
||||||
|
bottom->addWidget(pb);
|
||||||
|
|
||||||
|
m_group = new QGroupBox(tr("Enabled"));
|
||||||
|
m_group->setCheckable(true);
|
||||||
|
m_group->setChecked(false);
|
||||||
|
connect(m_group, SIGNAL(toggled(bool)), SLOT(enabledToggled(bool)));
|
||||||
|
|
||||||
|
QVBoxLayout *groupLayout = new QVBoxLayout(m_group);
|
||||||
|
groupLayout->setContentsMargins(5, 0, 5, 0);
|
||||||
|
groupLayout->setSpacing(2);
|
||||||
|
groupLayout->addWidget(m_tabs);
|
||||||
|
groupLayout->addLayout(bottom);
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
layout->setContentsMargins(0, 10, 0, 0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->addWidget(m_group);
|
||||||
|
setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::reset(QmlDebugConnection *conn)
|
||||||
|
{
|
||||||
|
delete m_plugin;
|
||||||
|
m_plugin = 0;
|
||||||
|
|
||||||
|
QWidget *w;
|
||||||
|
for (int i=0; i<m_tabs->count(); ++i) {
|
||||||
|
w = m_tabs->widget(i);
|
||||||
|
m_tabs->removeTab(i);
|
||||||
|
delete w;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn) {
|
||||||
|
connect(conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||||
|
SLOT(connectionStateChanged(QAbstractSocket::SocketState)));
|
||||||
|
if (conn->state() == QAbstractSocket::ConnectedState)
|
||||||
|
handleConnected(conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::connectionStateChanged(QAbstractSocket::SocketState state)
|
||||||
|
{
|
||||||
|
if (state == QAbstractSocket::UnconnectedState) {
|
||||||
|
delete m_plugin;
|
||||||
|
m_plugin = 0;
|
||||||
|
} else if (state == QAbstractSocket::ConnectedState) {
|
||||||
|
handleConnected(qobject_cast<QmlDebugConnection*>(sender()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::handleConnected(QmlDebugConnection *conn)
|
||||||
|
{
|
||||||
|
delete m_plugin;
|
||||||
|
m_plugin = new CanvasFrameRatePlugin(conn);
|
||||||
|
enabledToggled(m_group->isChecked());
|
||||||
|
newTab();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::setSizeHint(const QSize &size)
|
||||||
|
{
|
||||||
|
m_sizeHint = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSize CanvasFrameRate::sizeHint() const
|
||||||
|
{
|
||||||
|
return m_sizeHint;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::clearGraph()
|
||||||
|
{
|
||||||
|
if (m_tabs->count()) {
|
||||||
|
GraphWindow *w = qobject_cast<GraphWindow*>(m_tabs->currentWidget());
|
||||||
|
if (w)
|
||||||
|
w->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::newTab()
|
||||||
|
{
|
||||||
|
if (!m_plugin)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_tabs->count()) {
|
||||||
|
QWidget *w = m_tabs->widget(m_tabs->count() - 1);
|
||||||
|
QObject::disconnect(m_plugin, SIGNAL(sample(int,int,int,bool)),
|
||||||
|
w, SLOT(addSample(int,int,int,bool)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = m_tabs->count();
|
||||||
|
|
||||||
|
GraphWindow *graph = new GraphWindow;
|
||||||
|
graph->setResolutionForHeight(m_res->value());
|
||||||
|
connect(m_plugin, SIGNAL(sample(int,int,int,bool)),
|
||||||
|
graph, SLOT(addSample(int,int,int,bool)));
|
||||||
|
connect(m_res, SIGNAL(valueChanged(int)),
|
||||||
|
graph, SLOT(setResolutionForHeight(int)));
|
||||||
|
|
||||||
|
QString name = QLatin1String("Graph ") + QString::number(count + 1);
|
||||||
|
m_tabs->addTab(graph, name);
|
||||||
|
m_tabs->setCurrentIndex(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CanvasFrameRate::enabledToggled(bool checked)
|
||||||
|
{
|
||||||
|
if (m_plugin)
|
||||||
|
static_cast<QmlDebugClient *>(m_plugin)->setEnabled(checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#include "canvasframerate.moc"
|
||||||
80
src/plugins/qmlinspector/components/canvasframerate.h
Normal file
80
src/plugins/qmlinspector/components/canvasframerate.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef CANVASFRAMERATE_H
|
||||||
|
#define CANVASFRAMERATE_H
|
||||||
|
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
|
||||||
|
#include <QtCore/qpointer.h>
|
||||||
|
#include <QtGui/qwidget.h>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QTabWidget;
|
||||||
|
class QSlider;
|
||||||
|
class QGroupBox;
|
||||||
|
class QLabel;
|
||||||
|
class QSpinBox;
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
class CanvasFrameRatePlugin;
|
||||||
|
|
||||||
|
class CanvasFrameRate : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
CanvasFrameRate(QWidget *parent = 0);
|
||||||
|
|
||||||
|
void reset(QmlDebugConnection *conn);
|
||||||
|
|
||||||
|
void setSizeHint(const QSize &);
|
||||||
|
virtual QSize sizeHint() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void clearGraph();
|
||||||
|
void newTab();
|
||||||
|
void enabledToggled(bool);
|
||||||
|
void connectionStateChanged(QAbstractSocket::SocketState state);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void handleConnected(QmlDebugConnection *conn);
|
||||||
|
|
||||||
|
QGroupBox *m_group;
|
||||||
|
QTabWidget *m_tabs;
|
||||||
|
QSpinBox *m_res;
|
||||||
|
QPushButton *m_clearButton;
|
||||||
|
CanvasFrameRatePlugin *m_plugin;
|
||||||
|
QSize m_sizeHint;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // CANVASFRAMERATE_H
|
||||||
|
|
||||||
209
src/plugins/qmlinspector/components/engine.cpp
Normal file
209
src/plugins/qmlinspector/components/engine.cpp
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "engine.h"
|
||||||
|
#include "objectpropertiesview.h"
|
||||||
|
#include "expressionquerywidget.h"
|
||||||
|
#include "objecttree.h"
|
||||||
|
#include "watchtable.h"
|
||||||
|
|
||||||
|
#include <private/qmlenginedebug_p.h>
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
#include <private/qmldebugservice_p.h>
|
||||||
|
|
||||||
|
#include <QtDeclarative/qmlcomponent.h>
|
||||||
|
#include <QtDeclarative/qmlgraphicsitem.h>
|
||||||
|
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QHBoxLayout>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QTabWidget>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class DebuggerEngineItem : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString name READ name CONSTANT);
|
||||||
|
Q_PROPERTY(int engineId READ engineId CONSTANT);
|
||||||
|
|
||||||
|
public:
|
||||||
|
DebuggerEngineItem(const QString &name, int id)
|
||||||
|
: m_name(name), m_engineId(id) {}
|
||||||
|
|
||||||
|
QString name() const { return m_name; }
|
||||||
|
int engineId() const { return m_engineId; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_name;
|
||||||
|
int m_engineId;
|
||||||
|
};
|
||||||
|
|
||||||
|
EnginePane::EnginePane(QmlDebugConnection *conn, QWidget *parent)
|
||||||
|
: QWidget(parent), m_client(new QmlEngineDebug(conn, this)), m_engines(0), m_context(0), m_watchTableModel(0), m_exprQueryWidget(0)
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
||||||
|
QFile enginesFile(":/engines.qml");
|
||||||
|
enginesFile.open(QFile::ReadOnly);
|
||||||
|
Q_ASSERT(enginesFile.isOpen());
|
||||||
|
|
||||||
|
m_engineView = new QmlView(this);
|
||||||
|
m_engineView->rootContext()->setContextProperty("engines", qVariantFromValue(&m_engineItems));
|
||||||
|
m_engineView->setContentResizable(true);
|
||||||
|
m_engineView->setQml(enginesFile.readAll());
|
||||||
|
m_engineView->execute();
|
||||||
|
m_engineView->setFixedHeight(100);
|
||||||
|
QObject::connect(m_engineView->root(), SIGNAL(engineClicked(int)),
|
||||||
|
this, SLOT(engineSelected(int)));
|
||||||
|
QObject::connect(m_engineView->root(), SIGNAL(refreshEngines()),
|
||||||
|
this, SLOT(refreshEngines()));
|
||||||
|
|
||||||
|
m_engineView->setVisible(false);
|
||||||
|
layout->addWidget(m_engineView);
|
||||||
|
|
||||||
|
QSplitter *splitter = new QSplitter;
|
||||||
|
|
||||||
|
m_objTree = new ObjectTree(m_client, this);
|
||||||
|
m_propertiesView = new ObjectPropertiesView(m_client);
|
||||||
|
m_watchTableModel = new WatchTableModel(m_client, this);
|
||||||
|
|
||||||
|
m_watchTableView = new WatchTableView(m_watchTableModel);
|
||||||
|
m_watchTableView->setModel(m_watchTableModel);
|
||||||
|
WatchTableHeaderView *header = new WatchTableHeaderView(m_watchTableModel);
|
||||||
|
m_watchTableView->setHorizontalHeader(header);
|
||||||
|
|
||||||
|
connect(m_objTree, SIGNAL(currentObjectChanged(QmlDebugObjectReference)),
|
||||||
|
m_propertiesView, SLOT(reload(QmlDebugObjectReference)));
|
||||||
|
connect(m_objTree, SIGNAL(expressionWatchRequested(QmlDebugObjectReference,QString)),
|
||||||
|
m_watchTableModel, SLOT(expressionWatchRequested(QmlDebugObjectReference,QString)));
|
||||||
|
|
||||||
|
connect(m_propertiesView, SIGNAL(activated(QmlDebugObjectReference,QmlDebugPropertyReference)),
|
||||||
|
m_watchTableModel, SLOT(togglePropertyWatch(QmlDebugObjectReference,QmlDebugPropertyReference)));
|
||||||
|
|
||||||
|
connect(m_watchTableModel, SIGNAL(watchCreated(QmlDebugWatch*)),
|
||||||
|
m_propertiesView, SLOT(watchCreated(QmlDebugWatch*)));
|
||||||
|
|
||||||
|
connect(m_watchTableView, SIGNAL(objectActivated(int)),
|
||||||
|
m_objTree, SLOT(setCurrentObject(int)));
|
||||||
|
|
||||||
|
m_exprQueryWidget = new ExpressionQueryWidget(ExpressionQueryWidget::SeparateEntryMode, m_client);
|
||||||
|
connect(m_objTree, SIGNAL(currentObjectChanged(QmlDebugObjectReference)),
|
||||||
|
m_exprQueryWidget, SLOT(setCurrentObject(QmlDebugObjectReference)));
|
||||||
|
|
||||||
|
QSplitter *propertiesTab = new QSplitter(Qt::Vertical);
|
||||||
|
propertiesTab->addWidget(m_propertiesView);
|
||||||
|
propertiesTab->addWidget(m_exprQueryWidget);
|
||||||
|
propertiesTab->setStretchFactor(0, 2);
|
||||||
|
propertiesTab->setStretchFactor(1, 1);
|
||||||
|
|
||||||
|
m_tabs = new QTabWidget(this);
|
||||||
|
m_tabs->addTab(propertiesTab, tr("Properties"));
|
||||||
|
m_tabs->addTab(m_watchTableView, tr("Watched"));
|
||||||
|
|
||||||
|
splitter->addWidget(m_objTree);
|
||||||
|
splitter->addWidget(m_tabs);
|
||||||
|
splitter->setStretchFactor(1, 2);
|
||||||
|
layout->addWidget(splitter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnginePane::engineSelected(int id)
|
||||||
|
{
|
||||||
|
qWarning() << "Engine selected" << id;
|
||||||
|
queryContext(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnginePane::queryContext(int id)
|
||||||
|
{
|
||||||
|
if (m_context) {
|
||||||
|
delete m_context;
|
||||||
|
m_context = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_context = m_client->queryRootContexts(QmlDebugEngineReference(id), this);
|
||||||
|
if (!m_context->isWaiting())
|
||||||
|
contextChanged();
|
||||||
|
else
|
||||||
|
QObject::connect(m_context, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(contextChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnginePane::contextChanged()
|
||||||
|
{
|
||||||
|
//dump(m_context->rootContext(), 0);
|
||||||
|
|
||||||
|
foreach (const QmlDebugObjectReference &object, m_context->rootContext().objects())
|
||||||
|
m_objTree->reload(object.debugId());
|
||||||
|
|
||||||
|
delete m_context; m_context = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnginePane::refreshEngines()
|
||||||
|
{
|
||||||
|
if (m_engines)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_engines = m_client->queryAvailableEngines(this);
|
||||||
|
if (!m_engines->isWaiting())
|
||||||
|
enginesChanged();
|
||||||
|
else
|
||||||
|
QObject::connect(m_engines, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(enginesChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnginePane::enginesChanged()
|
||||||
|
{
|
||||||
|
qDeleteAll(m_engineItems);
|
||||||
|
m_engineItems.clear();
|
||||||
|
|
||||||
|
QList<QmlDebugEngineReference> engines = m_engines->engines();
|
||||||
|
delete m_engines; m_engines = 0;
|
||||||
|
|
||||||
|
if (engines.isEmpty())
|
||||||
|
qWarning("qmldebugger: no engines found!");
|
||||||
|
|
||||||
|
for (int ii = 0; ii < engines.count(); ++ii)
|
||||||
|
m_engineItems << new DebuggerEngineItem(engines.at(ii).name(),
|
||||||
|
engines.at(ii).debugId());
|
||||||
|
|
||||||
|
m_engineView->rootContext()->setContextProperty("engines", qVariantFromValue(&m_engineItems));
|
||||||
|
|
||||||
|
m_engineView->setVisible(m_engineItems.count() > 1);
|
||||||
|
if (m_engineItems.count() == 1)
|
||||||
|
engineSelected(qobject_cast<DebuggerEngineItem*>(m_engineItems.at(0))->engineId());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "engine.moc"
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
91
src/plugins/qmlinspector/components/engine.h
Normal file
91
src/plugins/qmlinspector/components/engine.h
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef ENGINE_H
|
||||||
|
#define ENGINE_H
|
||||||
|
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
|
||||||
|
#include <QtDeclarative/qmlengine.h>
|
||||||
|
#include <QtDeclarative/qmlcontext.h>
|
||||||
|
#include <QtDeclarative/qmlview.h>
|
||||||
|
|
||||||
|
#include <QtCore/qpointer.h>
|
||||||
|
#include <QtGui/qwidget.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class ObjectPropertiesView;
|
||||||
|
class QmlDebugConnection;
|
||||||
|
class QmlDebugPropertyReference;
|
||||||
|
class QmlDebugWatch;
|
||||||
|
class ObjectTree;
|
||||||
|
class WatchTableModel;
|
||||||
|
class WatchTableView;
|
||||||
|
class ExpressionQueryWidget;
|
||||||
|
|
||||||
|
class QTabWidget;
|
||||||
|
|
||||||
|
class EnginePane : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
EnginePane(QmlDebugConnection *, QWidget *parent = 0);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void refreshEngines();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void enginesChanged();
|
||||||
|
|
||||||
|
void queryContext(int);
|
||||||
|
void contextChanged();
|
||||||
|
|
||||||
|
void engineSelected(int);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QmlEngineDebug *m_client;
|
||||||
|
QmlDebugEnginesQuery *m_engines;
|
||||||
|
QmlDebugRootContextQuery *m_context;
|
||||||
|
|
||||||
|
ObjectTree *m_objTree;
|
||||||
|
QTabWidget *m_tabs;
|
||||||
|
WatchTableView *m_watchTableView;
|
||||||
|
WatchTableModel *m_watchTableModel;
|
||||||
|
ExpressionQueryWidget *m_exprQueryWidget;
|
||||||
|
|
||||||
|
QmlView *m_engineView;
|
||||||
|
QList<QObject *> m_engineItems;
|
||||||
|
|
||||||
|
ObjectPropertiesView *m_propertiesView;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // ENGINE_H
|
||||||
|
|
||||||
BIN
src/plugins/qmlinspector/components/engine.png
Normal file
BIN
src/plugins/qmlinspector/components/engine.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.2 KiB |
46
src/plugins/qmlinspector/components/engines.qml
Normal file
46
src/plugins/qmlinspector/components/engines.qml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import Qt 4.6
|
||||||
|
|
||||||
|
Item {
|
||||||
|
height: 100
|
||||||
|
id: Root
|
||||||
|
signal engineClicked(int id)
|
||||||
|
signal refreshEngines()
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
Repeater {
|
||||||
|
model: engines
|
||||||
|
Item {
|
||||||
|
width: 100; height: 100;
|
||||||
|
Image {
|
||||||
|
id: EngineIcon;
|
||||||
|
source: "qrc:/engine.png"
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Text {
|
||||||
|
anchors.top: EngineIcon.bottom;
|
||||||
|
text: modelData.name + "(" + modelData.engineId + ")"
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
MouseRegion {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: Root.engineClicked(modelData.engineId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Image {
|
||||||
|
y: 15
|
||||||
|
source: "qrc:/refresh.png";
|
||||||
|
width: 75;
|
||||||
|
height: 63;
|
||||||
|
smooth: true
|
||||||
|
anchors.right: parent.right
|
||||||
|
MouseRegion {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: Root.refreshEngines()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
264
src/plugins/qmlinspector/components/expressionquerywidget.cpp
Normal file
264
src/plugins/qmlinspector/components/expressionquerywidget.cpp
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "expressionquerywidget.h"
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
|
||||||
|
#include <QtGui/qlabel.h>
|
||||||
|
#include <QtGui/qtextedit.h>
|
||||||
|
#include <QtGui/qlineedit.h>
|
||||||
|
#include <QtGui/qpushbutton.h>
|
||||||
|
#include <QtGui/qevent.h>
|
||||||
|
#include <QtGui/qgroupbox.h>
|
||||||
|
#include <QtGui/qtextobject.h>
|
||||||
|
#include <QtGui/qlayout.h>
|
||||||
|
|
||||||
|
ExpressionQueryWidget::ExpressionQueryWidget(Mode mode, QmlEngineDebug *client, QWidget *parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
m_mode(mode),
|
||||||
|
m_client(client),
|
||||||
|
m_query(0),
|
||||||
|
m_textEdit(new QTextEdit),
|
||||||
|
m_lineEdit(0)
|
||||||
|
{
|
||||||
|
m_prompt = QLatin1String(">> ");
|
||||||
|
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||||
|
layout->setMargin(0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
layout->addWidget(m_textEdit);
|
||||||
|
|
||||||
|
updateTitle();
|
||||||
|
|
||||||
|
if (m_mode == SeparateEntryMode) {
|
||||||
|
m_lineEdit = new QLineEdit;
|
||||||
|
connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(executeExpression()));
|
||||||
|
QHBoxLayout *hbox = new QHBoxLayout;
|
||||||
|
hbox->setMargin(5);
|
||||||
|
hbox->setSpacing(5);
|
||||||
|
hbox->addWidget(new QLabel(tr("Expression:")));
|
||||||
|
hbox->addWidget(m_lineEdit);
|
||||||
|
layout->addLayout(hbox);
|
||||||
|
|
||||||
|
m_textEdit->setReadOnly(true);
|
||||||
|
m_lineEdit->installEventFilter(this);
|
||||||
|
} else {
|
||||||
|
m_textEdit->installEventFilter(this);
|
||||||
|
appendPrompt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::setEngineDebug(QmlEngineDebug *client)
|
||||||
|
{
|
||||||
|
m_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::clear()
|
||||||
|
{
|
||||||
|
m_textEdit->clear();
|
||||||
|
if (m_lineEdit)
|
||||||
|
m_lineEdit->clear();
|
||||||
|
if (m_mode == ShellMode)
|
||||||
|
appendPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::updateTitle()
|
||||||
|
{
|
||||||
|
if (m_currObject.debugId() < 0) {
|
||||||
|
m_title = tr("Expression queries");
|
||||||
|
} else {
|
||||||
|
QString desc = QLatin1String("<")
|
||||||
|
+ m_currObject.className() + QLatin1String(": ")
|
||||||
|
+ (m_currObject.name().isEmpty() ? QLatin1String("<unnamed>") : m_currObject.name())
|
||||||
|
+ QLatin1String(">");
|
||||||
|
m_title = tr("Expression queries (using context for %1)" , "Selected object").arg(desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::appendPrompt()
|
||||||
|
{
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
|
||||||
|
if (m_mode == SeparateEntryMode) {
|
||||||
|
m_textEdit->insertPlainText("\n");
|
||||||
|
} else {
|
||||||
|
m_textEdit->setTextColor(Qt::gray);
|
||||||
|
m_textEdit->append(m_prompt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::setCurrentObject(const QmlDebugObjectReference &obj)
|
||||||
|
{
|
||||||
|
m_currObject = obj;
|
||||||
|
updateTitle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::checkCurrentContext()
|
||||||
|
{
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
|
||||||
|
if (m_currObject.debugId() != -1 && m_currObject.debugId() != m_objectAtLastFocus.debugId())
|
||||||
|
showCurrentContext();
|
||||||
|
m_objectAtLastFocus = m_currObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::showCurrentContext()
|
||||||
|
{
|
||||||
|
if (m_mode == ShellMode) {
|
||||||
|
// clear the initial prompt
|
||||||
|
if (m_textEdit->document()->lineCount() == 1)
|
||||||
|
m_textEdit->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
m_textEdit->setTextColor(Qt::darkGreen);
|
||||||
|
m_textEdit->append(m_currObject.className()
|
||||||
|
+ QLatin1String(": ")
|
||||||
|
+ (m_currObject.name().isEmpty() ? QLatin1String("<unnamed object>") : m_currObject.name()));
|
||||||
|
appendPrompt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::executeExpression()
|
||||||
|
{
|
||||||
|
if (!m_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_mode == SeparateEntryMode)
|
||||||
|
m_expr = m_lineEdit->text().trimmed();
|
||||||
|
else
|
||||||
|
m_expr = m_expr.trimmed();
|
||||||
|
|
||||||
|
if (!m_expr.isEmpty() && m_currObject.debugId() != -1) {
|
||||||
|
if (m_query)
|
||||||
|
delete m_query;
|
||||||
|
m_query = m_client->queryExpressionResult(m_currObject.debugId(), m_expr, this);
|
||||||
|
if (!m_query->isWaiting())
|
||||||
|
showResult();
|
||||||
|
else
|
||||||
|
QObject::connect(m_query, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(showResult()));
|
||||||
|
|
||||||
|
m_lastExpr = m_expr;
|
||||||
|
if (m_lineEdit)
|
||||||
|
m_lineEdit->clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExpressionQueryWidget::showResult()
|
||||||
|
{
|
||||||
|
if (m_query) {
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
QVariant value = m_query->result();
|
||||||
|
QString result;
|
||||||
|
|
||||||
|
if (value.type() == QVariant::List || value.type() == QVariant::StringList) {
|
||||||
|
result = tr("<%1 items>", "%1 = number of items").arg(value.toList().count());
|
||||||
|
} else if (value.isNull()) {
|
||||||
|
result = QLatin1String("<no value>");
|
||||||
|
} else {
|
||||||
|
result = value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_mode == SeparateEntryMode) {
|
||||||
|
m_textEdit->setTextColor(Qt::black);
|
||||||
|
m_textEdit->setFontWeight(QFont::Bold);
|
||||||
|
m_textEdit->insertPlainText(m_expr + " : ");
|
||||||
|
m_textEdit->setFontWeight(QFont::Normal);
|
||||||
|
m_textEdit->insertPlainText(result);
|
||||||
|
} else {
|
||||||
|
m_textEdit->setTextColor(Qt::darkGreen);
|
||||||
|
m_textEdit->insertPlainText(" => ");
|
||||||
|
m_textEdit->setTextColor(Qt::black);
|
||||||
|
m_textEdit->insertPlainText(result);
|
||||||
|
}
|
||||||
|
appendPrompt();
|
||||||
|
m_expr.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExpressionQueryWidget::eventFilter(QObject *obj, QEvent *event)
|
||||||
|
{
|
||||||
|
if (obj == m_textEdit) {
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
{
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
int key = keyEvent->key();
|
||||||
|
if (key == Qt::Key_Return || key == Qt::Key_Enter) {
|
||||||
|
executeExpression();
|
||||||
|
return true;
|
||||||
|
} else if (key == Qt::Key_Backspace) {
|
||||||
|
// ensure m_expr doesn't contain backspace characters
|
||||||
|
QTextCursor cursor = m_textEdit->textCursor();
|
||||||
|
bool atLastLine = !(cursor.block().next().isValid());
|
||||||
|
if (!atLastLine)
|
||||||
|
return true;
|
||||||
|
if (cursor.columnNumber() <= m_prompt.count())
|
||||||
|
return true;
|
||||||
|
cursor.deletePreviousChar();
|
||||||
|
m_expr = cursor.block().text().mid(m_prompt.count());
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
m_textEdit->setTextColor(Qt::black);
|
||||||
|
m_expr += keyEvent->text();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::FocusIn:
|
||||||
|
checkCurrentContext();
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (obj == m_lineEdit) {
|
||||||
|
switch (event->type()) {
|
||||||
|
case QEvent::KeyPress:
|
||||||
|
{
|
||||||
|
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
|
||||||
|
int key = keyEvent->key();
|
||||||
|
if (key == Qt::Key_Up && m_lineEdit->text() != m_lastExpr) {
|
||||||
|
m_expr = m_lineEdit->text();
|
||||||
|
if (!m_lastExpr.isEmpty())
|
||||||
|
m_lineEdit->setText(m_lastExpr);
|
||||||
|
} else if (key == Qt::Key_Down) {
|
||||||
|
m_lineEdit->setText(m_expr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QEvent::FocusIn:
|
||||||
|
checkCurrentContext();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QWidget::eventFilter(obj, event);
|
||||||
|
}
|
||||||
94
src/plugins/qmlinspector/components/expressionquerywidget.h
Normal file
94
src/plugins/qmlinspector/components/expressionquerywidget.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef EXPRESSIONQUERYWIDGET_H
|
||||||
|
#define EXPRESSIONQUERYWIDGET_H
|
||||||
|
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
|
||||||
|
#include <QtGui/qwidget.h>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QGroupBox;
|
||||||
|
class QTextEdit;
|
||||||
|
class QLineEdit;
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
class ExpressionQueryWidget : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Mode {
|
||||||
|
SeparateEntryMode,
|
||||||
|
ShellMode
|
||||||
|
};
|
||||||
|
|
||||||
|
ExpressionQueryWidget(Mode mode = SeparateEntryMode, QmlEngineDebug *client = 0, QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setEngineDebug(QmlEngineDebug *client);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *event);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setCurrentObject(const QmlDebugObjectReference &obj);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void executeExpression();
|
||||||
|
void showResult();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void appendPrompt();
|
||||||
|
void checkCurrentContext();
|
||||||
|
void showCurrentContext();
|
||||||
|
void updateTitle();
|
||||||
|
|
||||||
|
Mode m_mode;
|
||||||
|
|
||||||
|
QmlEngineDebug *m_client;
|
||||||
|
QmlDebugExpressionQuery *m_query;
|
||||||
|
QTextEdit *m_textEdit;
|
||||||
|
QLineEdit *m_lineEdit;
|
||||||
|
QPushButton *m_button;
|
||||||
|
QString m_prompt;
|
||||||
|
QString m_expr;
|
||||||
|
QString m_lastExpr;
|
||||||
|
|
||||||
|
QString m_title;
|
||||||
|
|
||||||
|
QmlDebugObjectReference m_currObject;
|
||||||
|
QmlDebugObjectReference m_objectAtLastFocus;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
263
src/plugins/qmlinspector/components/objectpropertiesview.cpp
Normal file
263
src/plugins/qmlinspector/components/objectpropertiesview.cpp
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "objectpropertiesview.h"
|
||||||
|
|
||||||
|
#include <private/qmldebugservice_p.h>
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
|
||||||
|
#include <QtGui/qtreewidget.h>
|
||||||
|
#include <QtGui/qlayout.h>
|
||||||
|
#include <QtGui/qheaderview.h>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class PropertiesViewItem : public QObject, public QTreeWidgetItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
BindingType,
|
||||||
|
OtherType
|
||||||
|
};
|
||||||
|
|
||||||
|
PropertiesViewItem(QTreeWidget *widget, Type type = OtherType);
|
||||||
|
PropertiesViewItem(QTreeWidgetItem *parent, Type type = OtherType);
|
||||||
|
|
||||||
|
QmlDebugPropertyReference property;
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
PropertiesViewItem::PropertiesViewItem(QTreeWidget *widget, Type type)
|
||||||
|
: QTreeWidgetItem(widget), type(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertiesViewItem::PropertiesViewItem(QTreeWidgetItem *parent, Type type)
|
||||||
|
: QTreeWidgetItem(parent), type(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectPropertiesView::ObjectPropertiesView(QmlEngineDebug *client, QWidget *parent)
|
||||||
|
: QWidget(parent),
|
||||||
|
m_client(client),
|
||||||
|
m_query(0),
|
||||||
|
m_watch(0)
|
||||||
|
{
|
||||||
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
|
layout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
layout->setSpacing(0);
|
||||||
|
setLayout(layout);
|
||||||
|
|
||||||
|
m_tree = new QTreeWidget(this);
|
||||||
|
m_tree->setAlternatingRowColors(true);
|
||||||
|
m_tree->setExpandsOnDoubleClick(false);
|
||||||
|
m_tree->setHeaderLabels(QStringList()
|
||||||
|
<< tr("Name") << tr("Value") << tr("Type"));
|
||||||
|
QObject::connect(m_tree, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
|
||||||
|
this, SLOT(itemActivated(QTreeWidgetItem *)));
|
||||||
|
|
||||||
|
m_tree->setColumnCount(3);
|
||||||
|
m_tree->header()->setDefaultSectionSize(150);
|
||||||
|
|
||||||
|
layout->addWidget(m_tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::setEngineDebug(QmlEngineDebug *client)
|
||||||
|
{
|
||||||
|
m_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::clear()
|
||||||
|
{
|
||||||
|
setObject(QmlDebugObjectReference());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::reload(const QmlDebugObjectReference &obj)
|
||||||
|
{
|
||||||
|
if (!m_client)
|
||||||
|
return;
|
||||||
|
if (m_query)
|
||||||
|
delete m_query;
|
||||||
|
|
||||||
|
m_query = m_client->queryObjectRecursive(obj, this);
|
||||||
|
if (!m_query->isWaiting())
|
||||||
|
queryFinished();
|
||||||
|
else
|
||||||
|
QObject::connect(m_query, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(queryFinished()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::queryFinished()
|
||||||
|
{
|
||||||
|
if (!m_client || !m_query)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlDebugObjectReference obj = m_query->object();
|
||||||
|
|
||||||
|
QmlDebugWatch *watch = m_client->addWatch(obj, this);
|
||||||
|
if (watch->state() == QmlDebugWatch::Dead) {
|
||||||
|
delete watch;
|
||||||
|
watch = 0;
|
||||||
|
} else {
|
||||||
|
if (m_watch) {
|
||||||
|
m_client->removeWatch(m_watch);
|
||||||
|
delete m_watch;
|
||||||
|
}
|
||||||
|
m_watch = watch;
|
||||||
|
QObject::connect(watch, SIGNAL(valueChanged(QByteArray,QVariant)),
|
||||||
|
this, SLOT(valueChanged(QByteArray,QVariant)));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_query;
|
||||||
|
m_query = 0;
|
||||||
|
|
||||||
|
setObject(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::setPropertyValue(PropertiesViewItem *item, const QVariant &value, bool makeGray)
|
||||||
|
{
|
||||||
|
if (value.type() == QVariant::List || value.type() == QVariant::StringList) {
|
||||||
|
PropertiesViewItem *bindingItem = static_cast<PropertiesViewItem*>(item->takeChild(item->childCount() - 1));
|
||||||
|
if (bindingItem && bindingItem->type != PropertiesViewItem::BindingType) {
|
||||||
|
delete bindingItem;
|
||||||
|
bindingItem = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDeleteAll(item->takeChildren());
|
||||||
|
|
||||||
|
QVariantList variants = value.toList();
|
||||||
|
item->setText(1, tr("<%1 items>", "%1 = number of items").arg(variants.count()));
|
||||||
|
item->setText(2, QString::fromUtf8(value.typeName()));
|
||||||
|
|
||||||
|
PropertiesViewItem *child;
|
||||||
|
for (int i=0; i<variants.count(); ++i) {
|
||||||
|
child = new PropertiesViewItem(item);
|
||||||
|
setPropertyValue(child, variants[i], makeGray);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindingItem)
|
||||||
|
item->addChild(bindingItem);
|
||||||
|
|
||||||
|
item->setExpanded(false);
|
||||||
|
} else {
|
||||||
|
item->setText(1, (value.isNull() ? QLatin1String("<no value>") : value.toString()));
|
||||||
|
item->setExpanded(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (makeGray) {
|
||||||
|
for (int i=0; i<m_tree->columnCount(); ++i)
|
||||||
|
item->setForeground(i, Qt::gray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::setObject(const QmlDebugObjectReference &object)
|
||||||
|
{
|
||||||
|
m_object = object;
|
||||||
|
m_tree->clear();
|
||||||
|
|
||||||
|
QList<QmlDebugPropertyReference> properties = object.properties();
|
||||||
|
for (int i=0; i<properties.count(); ++i) {
|
||||||
|
const QmlDebugPropertyReference &p = properties[i];
|
||||||
|
|
||||||
|
PropertiesViewItem *item = new PropertiesViewItem(m_tree);
|
||||||
|
item->property = p;
|
||||||
|
|
||||||
|
item->setText(0, p.name());
|
||||||
|
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||||
|
|
||||||
|
setPropertyValue(item, p.value(), !p.hasNotifySignal());
|
||||||
|
item->setText(2, p.valueTypeName());
|
||||||
|
|
||||||
|
// binding is set after property value to ensure it is added to the end of the
|
||||||
|
// list, if the value is a list
|
||||||
|
if (!p.binding().isEmpty()) {
|
||||||
|
PropertiesViewItem *binding = new PropertiesViewItem(item, PropertiesViewItem::BindingType);
|
||||||
|
binding->setText(1, p.binding());
|
||||||
|
binding->setForeground(1, Qt::darkGreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::watchCreated(QmlDebugWatch *watch)
|
||||||
|
{
|
||||||
|
if (watch->objectDebugId() == m_object.debugId()
|
||||||
|
&& qobject_cast<QmlDebugPropertyWatch*>(watch)) {
|
||||||
|
connect(watch, SIGNAL(stateChanged(QmlDebugWatch::State)), SLOT(watchStateChanged()));
|
||||||
|
setWatched(qobject_cast<QmlDebugPropertyWatch*>(watch)->name(), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::watchStateChanged()
|
||||||
|
{
|
||||||
|
QmlDebugWatch *watch = qobject_cast<QmlDebugWatch*>(sender());
|
||||||
|
|
||||||
|
if (watch->objectDebugId() == m_object.debugId()
|
||||||
|
&& qobject_cast<QmlDebugPropertyWatch*>(watch)
|
||||||
|
&& watch->state() == QmlDebugWatch::Inactive) {
|
||||||
|
setWatched(qobject_cast<QmlDebugPropertyWatch*>(watch)->name(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::setWatched(const QString &property, bool watched)
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_tree->topLevelItemCount(); ++i) {
|
||||||
|
PropertiesViewItem *item = static_cast<PropertiesViewItem *>(m_tree->topLevelItem(i));
|
||||||
|
if (item->property.name() == property && item->property.hasNotifySignal()) {
|
||||||
|
QFont font = m_tree->font();
|
||||||
|
font.setBold(watched);
|
||||||
|
item->setFont(0, font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::valueChanged(const QByteArray &name, const QVariant &value)
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_tree->topLevelItemCount(); ++i) {
|
||||||
|
PropertiesViewItem *item = static_cast<PropertiesViewItem *>(m_tree->topLevelItem(i));
|
||||||
|
if (item->property.name() == name) {
|
||||||
|
setPropertyValue(item, value, !item->property.hasNotifySignal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectPropertiesView::itemActivated(QTreeWidgetItem *i)
|
||||||
|
{
|
||||||
|
PropertiesViewItem *item = static_cast<PropertiesViewItem *>(i);
|
||||||
|
if (!item->property.name().isEmpty())
|
||||||
|
emit activated(m_object, item->property);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#include "objectpropertiesview.moc"
|
||||||
81
src/plugins/qmlinspector/components/objectpropertiesview.h
Normal file
81
src/plugins/qmlinspector/components/objectpropertiesview.h
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef PROPERTIESTABLEMODEL_H
|
||||||
|
#define PROPERTIESTABLEMODEL_H
|
||||||
|
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
|
||||||
|
#include <QtGui/qwidget.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QTreeWidget;
|
||||||
|
class QTreeWidgetItem;
|
||||||
|
class QmlDebugConnection;
|
||||||
|
class PropertiesViewItem;
|
||||||
|
|
||||||
|
class ObjectPropertiesView : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ObjectPropertiesView(QmlEngineDebug *client = 0, QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setEngineDebug(QmlEngineDebug *client);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void activated(const QmlDebugObjectReference &, const QmlDebugPropertyReference &);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void reload(const QmlDebugObjectReference &);
|
||||||
|
void watchCreated(QmlDebugWatch *);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void queryFinished();
|
||||||
|
void watchStateChanged();
|
||||||
|
void valueChanged(const QByteArray &name, const QVariant &value);
|
||||||
|
void itemActivated(QTreeWidgetItem *i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setObject(const QmlDebugObjectReference &object);
|
||||||
|
void setWatched(const QString &property, bool watched);
|
||||||
|
void setPropertyValue(PropertiesViewItem *item, const QVariant &value, bool makeGray);
|
||||||
|
|
||||||
|
QmlEngineDebug *m_client;
|
||||||
|
QmlDebugObjectQuery *m_query;
|
||||||
|
QmlDebugWatch *m_watch;
|
||||||
|
|
||||||
|
QTreeWidget *m_tree;
|
||||||
|
QmlDebugObjectReference m_object;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
||||||
219
src/plugins/qmlinspector/components/objecttree.cpp
Normal file
219
src/plugins/qmlinspector/components/objecttree.cpp
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include <QtGui/qevent.h>
|
||||||
|
#include <QtGui/qmenu.h>
|
||||||
|
#include <QtGui/qaction.h>
|
||||||
|
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
|
#include <private/qmldebugservice_p.h>
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
|
||||||
|
#include "objecttree.h"
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QmlDebugObjectReference)
|
||||||
|
|
||||||
|
ObjectTree::ObjectTree(QmlEngineDebug *client, QWidget *parent)
|
||||||
|
: QTreeWidget(parent),
|
||||||
|
m_client(client),
|
||||||
|
m_query(0)
|
||||||
|
{
|
||||||
|
setHeaderHidden(true);
|
||||||
|
setMinimumWidth(250);
|
||||||
|
setExpandsOnDoubleClick(false);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
|
||||||
|
SLOT(currentItemChanged(QTreeWidgetItem *)));
|
||||||
|
connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
|
||||||
|
SLOT(activated(QTreeWidgetItem *)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::setEngineDebug(QmlEngineDebug *client)
|
||||||
|
{
|
||||||
|
m_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::reload(int objectDebugId)
|
||||||
|
{
|
||||||
|
if (!m_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_query) {
|
||||||
|
delete m_query;
|
||||||
|
m_query = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_query = m_client->queryObjectRecursive(QmlDebugObjectReference(objectDebugId), this);
|
||||||
|
if (!m_query->isWaiting())
|
||||||
|
objectFetched();
|
||||||
|
else
|
||||||
|
QObject::connect(m_query, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(objectFetched()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::setCurrentObject(int debugId)
|
||||||
|
{
|
||||||
|
QTreeWidgetItem *item = findItemByObjectId(debugId);
|
||||||
|
if (item) {
|
||||||
|
setCurrentItem(item);
|
||||||
|
scrollToItem(item);
|
||||||
|
item->setExpanded(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::objectFetched()
|
||||||
|
{
|
||||||
|
dump(m_query->object(), 0);
|
||||||
|
buildTree(m_query->object(), 0);
|
||||||
|
setCurrentItem(topLevelItem(0));
|
||||||
|
|
||||||
|
delete m_query;
|
||||||
|
m_query = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::currentItemChanged(QTreeWidgetItem *item)
|
||||||
|
{
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlDebugObjectReference obj = item->data(0, Qt::UserRole).value<QmlDebugObjectReference>();
|
||||||
|
if (obj.debugId() >= 0)
|
||||||
|
emit currentObjectChanged(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::activated(QTreeWidgetItem *item)
|
||||||
|
{
|
||||||
|
if (!item)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlDebugObjectReference obj = item->data(0, Qt::UserRole).value<QmlDebugObjectReference>();
|
||||||
|
if (obj.debugId() >= 0)
|
||||||
|
emit activated(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::buildTree(const QmlDebugObjectReference &obj, QTreeWidgetItem *parent)
|
||||||
|
{
|
||||||
|
if (!parent)
|
||||||
|
clear();
|
||||||
|
|
||||||
|
QTreeWidgetItem *item = parent ? new QTreeWidgetItem(parent) : new QTreeWidgetItem(this);
|
||||||
|
item->setText(0, obj.className());
|
||||||
|
item->setData(0, Qt::UserRole, qVariantFromValue(obj));
|
||||||
|
|
||||||
|
if (parent && obj.contextDebugId() >= 0
|
||||||
|
&& obj.contextDebugId() != parent->data(0, Qt::UserRole
|
||||||
|
).value<QmlDebugObjectReference>().contextDebugId()) {
|
||||||
|
QmlDebugFileReference source = obj.source();
|
||||||
|
if (!source.url().isEmpty()) {
|
||||||
|
QString toolTipString = QLatin1String("URL: ") + source.url().toString();
|
||||||
|
item->setToolTip(0, toolTipString);
|
||||||
|
}
|
||||||
|
item->setForeground(0, QColor("orange"));
|
||||||
|
} else {
|
||||||
|
item->setExpanded(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.contextDebugId() < 0)
|
||||||
|
item->setForeground(0, Qt::lightGray);
|
||||||
|
|
||||||
|
for (int ii = 0; ii < obj.children().count(); ++ii)
|
||||||
|
buildTree(obj.children().at(ii), item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::dump(const QmlDebugContextReference &ctxt, int ind)
|
||||||
|
{
|
||||||
|
QByteArray indent(ind * 4, ' ');
|
||||||
|
qWarning().nospace() << indent.constData() << ctxt.debugId() << " "
|
||||||
|
<< qPrintable(ctxt.name());
|
||||||
|
|
||||||
|
for (int ii = 0; ii < ctxt.contexts().count(); ++ii)
|
||||||
|
dump(ctxt.contexts().at(ii), ind + 1);
|
||||||
|
|
||||||
|
for (int ii = 0; ii < ctxt.objects().count(); ++ii)
|
||||||
|
dump(ctxt.objects().at(ii), ind);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::dump(const QmlDebugObjectReference &obj, int ind)
|
||||||
|
{
|
||||||
|
QByteArray indent(ind * 4, ' ');
|
||||||
|
qWarning().nospace() << indent.constData() << qPrintable(obj.className())
|
||||||
|
<< " " << qPrintable(obj.name()) << " "
|
||||||
|
<< obj.debugId();
|
||||||
|
|
||||||
|
for (int ii = 0; ii < obj.children().count(); ++ii)
|
||||||
|
dump(obj.children().at(ii), ind + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeWidgetItem *ObjectTree::findItemByObjectId(int debugId) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<topLevelItemCount(); ++i) {
|
||||||
|
QTreeWidgetItem *item = findItem(topLevelItem(i), debugId);
|
||||||
|
if (item)
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTreeWidgetItem *ObjectTree::findItem(QTreeWidgetItem *item, int debugId) const
|
||||||
|
{
|
||||||
|
if (item->data(0, Qt::UserRole).value<QmlDebugObjectReference>().debugId() == debugId)
|
||||||
|
return item;
|
||||||
|
|
||||||
|
QTreeWidgetItem *child;
|
||||||
|
for (int i=0; i<item->childCount(); ++i) {
|
||||||
|
child = findItem(item->child(i), debugId);
|
||||||
|
if (child)
|
||||||
|
return child;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectTree::mousePressEvent(QMouseEvent *me)
|
||||||
|
{
|
||||||
|
QTreeWidget::mousePressEvent(me);
|
||||||
|
if (!currentItem())
|
||||||
|
return;
|
||||||
|
if(me->button() == Qt::RightButton && me->type() == QEvent::MouseButtonPress) {
|
||||||
|
QAction action(tr("Add watch..."), 0);
|
||||||
|
QList<QAction *> actions;
|
||||||
|
actions << &action;
|
||||||
|
QmlDebugObjectReference obj =
|
||||||
|
currentItem()->data(0, Qt::UserRole).value<QmlDebugObjectReference>();
|
||||||
|
if (QMenu::exec(actions, me->globalPos())) {
|
||||||
|
bool ok = false;
|
||||||
|
QString watch = QInputDialog::getText(this, tr("Watch expression"),
|
||||||
|
tr("Expression:"), QLineEdit::Normal, QString(), &ok);
|
||||||
|
if (ok && !watch.isEmpty())
|
||||||
|
emit expressionWatchRequested(obj, watch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
src/plugins/qmlinspector/components/objecttree.h
Normal file
84
src/plugins/qmlinspector/components/objecttree.h
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef OBJECTTREE_H
|
||||||
|
#define OBJECTTREE_H
|
||||||
|
|
||||||
|
#include <QtGui/qtreewidget.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QTreeWidgetItem;
|
||||||
|
|
||||||
|
class QmlEngineDebug;
|
||||||
|
class QmlDebugObjectReference;
|
||||||
|
class QmlDebugObjectQuery;
|
||||||
|
class QmlDebugContextReference;
|
||||||
|
class QmlDebugConnection;
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectTree : public QTreeWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ObjectTree(QmlEngineDebug *client = 0, QWidget *parent = 0);
|
||||||
|
|
||||||
|
void setEngineDebug(QmlEngineDebug *client);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void currentObjectChanged(const QmlDebugObjectReference &);
|
||||||
|
void activated(const QmlDebugObjectReference &);
|
||||||
|
void expressionWatchRequested(const QmlDebugObjectReference &, const QString &);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void reload(int objectDebugId); // set the root object
|
||||||
|
void setCurrentObject(int debugId); // select an object in the tree
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void mousePressEvent(QMouseEvent *);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void objectFetched();
|
||||||
|
void currentItemChanged(QTreeWidgetItem *);
|
||||||
|
void activated(QTreeWidgetItem *);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTreeWidgetItem *findItemByObjectId(int debugId) const;
|
||||||
|
QTreeWidgetItem *findItem(QTreeWidgetItem *item, int debugId) const;
|
||||||
|
void dump(const QmlDebugContextReference &, int);
|
||||||
|
void dump(const QmlDebugObjectReference &, int);
|
||||||
|
void buildTree(const QmlDebugObjectReference &, QTreeWidgetItem *parent);
|
||||||
|
|
||||||
|
QmlEngineDebug *m_client;
|
||||||
|
QmlDebugObjectQuery *m_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
16
src/plugins/qmlinspector/components/qmldebugger.pri
Normal file
16
src/plugins/qmlinspector/components/qmldebugger.pri
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
QT += network declarative
|
||||||
|
contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, opengles1): QT += opengl
|
||||||
|
|
||||||
|
# Input
|
||||||
|
HEADERS += $$PWD/canvasframerate.h \
|
||||||
|
$$PWD/watchtable.h \
|
||||||
|
$$PWD/objecttree.h \
|
||||||
|
$$PWD/objectpropertiesview.h \
|
||||||
|
$$PWD/expressionquerywidget.h
|
||||||
|
|
||||||
|
SOURCES += $$PWD/canvasframerate.cpp \
|
||||||
|
$$PWD/watchtable.cpp \
|
||||||
|
$$PWD/objecttree.cpp \
|
||||||
|
$$PWD/objectpropertiesview.cpp \
|
||||||
|
$$PWD/expressionquerywidget.cpp
|
||||||
|
|
||||||
7
src/plugins/qmlinspector/components/qmldebugger.qrc
Normal file
7
src/plugins/qmlinspector/components/qmldebugger.qrc
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/">
|
||||||
|
<file>engines.qml</file>
|
||||||
|
<file>engine.png</file>
|
||||||
|
<file>refresh.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
BIN
src/plugins/qmlinspector/components/refresh.png
Normal file
BIN
src/plugins/qmlinspector/components/refresh.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
19
src/plugins/qmlinspector/components/standalone.pro
Normal file
19
src/plugins/qmlinspector/components/standalone.pro
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
DESTDIR = ../../../bin
|
||||||
|
TARGET = qmldebugger
|
||||||
|
|
||||||
|
include(qmldebugger.pri)
|
||||||
|
|
||||||
|
HEADERS += $$PWD/qmldebugger.h \
|
||||||
|
$$PWD/engine.h
|
||||||
|
|
||||||
|
SOURCES += $$PWD/qmldebugger.cpp \
|
||||||
|
$$PWD/engine.cpp \
|
||||||
|
$$PWD/main.cpp
|
||||||
|
|
||||||
|
RESOURCES += $$PWD/qmldebugger.qrc
|
||||||
|
OTHER_FILES += $$PWD/engines.qml
|
||||||
|
|
||||||
|
target.path=$$[QT_INSTALL_BINS]
|
||||||
|
INSTALLS += target
|
||||||
|
|
||||||
|
CONFIG += console
|
||||||
354
src/plugins/qmlinspector/components/watchtable.cpp
Normal file
354
src/plugins/qmlinspector/components/watchtable.cpp
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "watchtable.h"
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtGui/qevent.h>
|
||||||
|
#include <QtGui/qaction.h>
|
||||||
|
#include <QtGui/qmenu.h>
|
||||||
|
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
#include <QtDeclarative/qmlmetatype.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
WatchTableModel::WatchTableModel(QmlEngineDebug *client, QObject *parent)
|
||||||
|
: QAbstractTableModel(parent),
|
||||||
|
m_client(client)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchTableModel::~WatchTableModel()
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_columns.count(); ++i)
|
||||||
|
delete m_columns[i].watch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::setEngineDebug(QmlEngineDebug *client)
|
||||||
|
{
|
||||||
|
m_client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::addWatch(QmlDebugWatch *watch, const QString &title)
|
||||||
|
{
|
||||||
|
QString property;
|
||||||
|
if (qobject_cast<QmlDebugPropertyWatch *>(watch))
|
||||||
|
property = qobject_cast<QmlDebugPropertyWatch *>(watch)->name();
|
||||||
|
|
||||||
|
connect(watch, SIGNAL(valueChanged(QByteArray,QVariant)),
|
||||||
|
SLOT(watchedValueChanged(QByteArray,QVariant)));
|
||||||
|
|
||||||
|
connect(watch, SIGNAL(stateChanged(QmlDebugWatch::State)), SLOT(watchStateChanged()));
|
||||||
|
|
||||||
|
int col = columnCount(QModelIndex());
|
||||||
|
beginInsertColumns(QModelIndex(), col, col);
|
||||||
|
|
||||||
|
WatchedEntity e;
|
||||||
|
e.title = title;
|
||||||
|
e.hasFirstValue = false;
|
||||||
|
e.property = property;
|
||||||
|
e.watch = watch;
|
||||||
|
m_columns.append(e);
|
||||||
|
|
||||||
|
endInsertColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::removeWatch(QmlDebugWatch *watch)
|
||||||
|
{
|
||||||
|
int column = columnForWatch(watch);
|
||||||
|
if (column == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
WatchedEntity entity = m_columns.takeAt(column);
|
||||||
|
|
||||||
|
for (QList<Value>::Iterator iter = m_values.begin(); iter != m_values.end();) {
|
||||||
|
if (iter->column == column) {
|
||||||
|
iter = m_values.erase(iter);
|
||||||
|
} else {
|
||||||
|
if(iter->column > column)
|
||||||
|
--iter->column;
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::updateWatch(QmlDebugWatch *watch, const QVariant &value)
|
||||||
|
{
|
||||||
|
int column = columnForWatch(watch);
|
||||||
|
if (column == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
addValue(column, value);
|
||||||
|
|
||||||
|
if (!m_columns[column].hasFirstValue) {
|
||||||
|
m_columns[column].hasFirstValue = true;
|
||||||
|
m_values[m_values.count() - 1].first = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlDebugWatch *WatchTableModel::findWatch(int column) const
|
||||||
|
{
|
||||||
|
if (column < m_columns.count())
|
||||||
|
return m_columns.at(column).watch;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlDebugWatch *WatchTableModel::findWatch(int objectDebugId, const QString &property) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_columns.count(); ++i) {
|
||||||
|
if (m_columns[i].watch->objectDebugId() == objectDebugId
|
||||||
|
&& m_columns[i].property == property) {
|
||||||
|
return m_columns[i].watch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int WatchTableModel::rowCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return m_values.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int WatchTableModel::columnCount(const QModelIndex &) const
|
||||||
|
{
|
||||||
|
return m_columns.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant WatchTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
if (section < m_columns.count() && role == Qt::DisplayRole)
|
||||||
|
return m_columns.at(section).title;
|
||||||
|
} else {
|
||||||
|
if (role == Qt::DisplayRole)
|
||||||
|
return section + 1;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant WatchTableModel::data(const QModelIndex &idx, int role) const
|
||||||
|
{
|
||||||
|
if (m_values.at(idx.row()).column == idx.column()) {
|
||||||
|
if (role == Qt::DisplayRole) {
|
||||||
|
const QVariant &value = m_values.at(idx.row()).variant;
|
||||||
|
QString str = value.toString();
|
||||||
|
|
||||||
|
if (str.isEmpty() && QmlMetaType::isObject(value.userType())) {
|
||||||
|
QObject *o = QmlMetaType::toQObject(value);
|
||||||
|
if(o) {
|
||||||
|
QString objectName = o->objectName();
|
||||||
|
if(objectName.isEmpty())
|
||||||
|
objectName = QLatin1String("<unnamed>");
|
||||||
|
str = QLatin1String(o->metaObject()->className()) +
|
||||||
|
QLatin1String(": ") + objectName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(str.isEmpty()) {
|
||||||
|
QDebug d(&str);
|
||||||
|
d << value;
|
||||||
|
}
|
||||||
|
return QVariant(str);
|
||||||
|
} else if(role == Qt::BackgroundRole) {
|
||||||
|
if(m_values.at(idx.row()).first)
|
||||||
|
return QColor(Qt::green);
|
||||||
|
else
|
||||||
|
return QVariant();
|
||||||
|
} else {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::watchStateChanged()
|
||||||
|
{
|
||||||
|
QmlDebugWatch *watch = qobject_cast<QmlDebugWatch*>(sender());
|
||||||
|
|
||||||
|
if (watch && watch->state() == QmlDebugWatch::Inactive) {
|
||||||
|
removeWatch(watch);
|
||||||
|
watch->deleteLater();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int WatchTableModel::columnForWatch(QmlDebugWatch *watch) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_columns.count(); ++i) {
|
||||||
|
if (m_columns.at(i).watch == watch)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::addValue(int column, const QVariant &value)
|
||||||
|
{
|
||||||
|
int row = columnCount(QModelIndex());
|
||||||
|
beginInsertRows(QModelIndex(), row, row);
|
||||||
|
|
||||||
|
Value v;
|
||||||
|
v.column = column;
|
||||||
|
v.variant = value;
|
||||||
|
v.first = false;
|
||||||
|
m_values.append(v);
|
||||||
|
|
||||||
|
endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::togglePropertyWatch(const QmlDebugObjectReference &object, const QmlDebugPropertyReference &property)
|
||||||
|
{
|
||||||
|
if (!m_client || !property.hasNotifySignal())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlDebugWatch *watch = findWatch(object.debugId(), property.name());
|
||||||
|
if (watch) {
|
||||||
|
// watch will be deleted in watchStateChanged()
|
||||||
|
m_client->removeWatch(watch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
watch = m_client->addWatch(property, this);
|
||||||
|
if (watch->state() == QmlDebugWatch::Dead) {
|
||||||
|
delete watch;
|
||||||
|
watch = 0;
|
||||||
|
} else {
|
||||||
|
QString desc = property.name()
|
||||||
|
+ QLatin1String(" on\n")
|
||||||
|
+ object.className()
|
||||||
|
+ QLatin1String(":\n")
|
||||||
|
+ (object.name().isEmpty() ? QLatin1String("<unnamed object>") : object.name());
|
||||||
|
addWatch(watch, desc);
|
||||||
|
emit watchCreated(watch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::watchedValueChanged(const QByteArray &propertyName, const QVariant &value)
|
||||||
|
{
|
||||||
|
Q_UNUSED(propertyName);
|
||||||
|
QmlDebugWatch *watch = qobject_cast<QmlDebugWatch*>(sender());
|
||||||
|
if (watch)
|
||||||
|
updateWatch(watch, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::expressionWatchRequested(const QmlDebugObjectReference &obj, const QString &expr)
|
||||||
|
{
|
||||||
|
if (!m_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlDebugWatch *watch = m_client->addWatch(obj, expr, this);
|
||||||
|
|
||||||
|
if (watch->state() == QmlDebugWatch::Dead) {
|
||||||
|
delete watch;
|
||||||
|
watch = 0;
|
||||||
|
} else {
|
||||||
|
addWatch(watch, expr);
|
||||||
|
emit watchCreated(watch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::removeWatchAt(int column)
|
||||||
|
{
|
||||||
|
if (!m_client)
|
||||||
|
return;
|
||||||
|
|
||||||
|
QmlDebugWatch *watch = findWatch(column);
|
||||||
|
if (watch) {
|
||||||
|
m_client->removeWatch(watch);
|
||||||
|
delete watch;
|
||||||
|
watch = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableModel::removeAllWatches()
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_columns.count(); ++i) {
|
||||||
|
if (m_client)
|
||||||
|
m_client->removeWatch(m_columns[i].watch);
|
||||||
|
else
|
||||||
|
delete m_columns[i].watch;
|
||||||
|
}
|
||||||
|
m_columns.clear();
|
||||||
|
m_values.clear();
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
|
||||||
|
WatchTableHeaderView::WatchTableHeaderView(WatchTableModel *model, QWidget *parent)
|
||||||
|
: QHeaderView(Qt::Horizontal, parent),
|
||||||
|
m_model(model)
|
||||||
|
{
|
||||||
|
setClickable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableHeaderView::mousePressEvent(QMouseEvent *me)
|
||||||
|
{
|
||||||
|
QHeaderView::mousePressEvent(me);
|
||||||
|
|
||||||
|
if (me->button() == Qt::RightButton && me->type() == QEvent::MouseButtonPress) {
|
||||||
|
int col = logicalIndexAt(me->pos());
|
||||||
|
if (col >= 0) {
|
||||||
|
QAction action(tr("Stop watching"), 0);
|
||||||
|
QList<QAction *> actions;
|
||||||
|
actions << &action;
|
||||||
|
if (QMenu::exec(actions, me->globalPos()))
|
||||||
|
m_model->removeWatchAt(col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
|
||||||
|
WatchTableView::WatchTableView(WatchTableModel *model, QWidget *parent)
|
||||||
|
: QTableView(parent),
|
||||||
|
m_model(model)
|
||||||
|
{
|
||||||
|
setAlternatingRowColors(true);
|
||||||
|
connect(model, SIGNAL(watchCreated(QmlDebugWatch*)), SLOT(watchCreated(QmlDebugWatch*)));
|
||||||
|
connect(this, SIGNAL(activated(QModelIndex)), SLOT(indexActivated(QModelIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableView::indexActivated(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
QmlDebugWatch *watch = m_model->findWatch(index.column());
|
||||||
|
if (watch)
|
||||||
|
emit objectActivated(watch->objectDebugId());
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTableView::watchCreated(QmlDebugWatch *watch)
|
||||||
|
{
|
||||||
|
int column = m_model->columnForWatch(watch);
|
||||||
|
resizeColumnToContents(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
142
src/plugins/qmlinspector/components/watchtable.h
Normal file
142
src/plugins/qmlinspector/components/watchtable.h
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef WATCHTABLEMODEL_H
|
||||||
|
#define WATCHTABLEMODEL_H
|
||||||
|
|
||||||
|
#include <QtCore/qpointer.h>
|
||||||
|
#include <QtCore/qlist.h>
|
||||||
|
#include <QtCore/qabstractitemmodel.h>
|
||||||
|
|
||||||
|
#include <QtGui/qwidget.h>
|
||||||
|
#include <QtGui/qheaderview.h>
|
||||||
|
#include <QtGui/qtableview.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QmlDebugWatch;
|
||||||
|
class QmlEngineDebug;
|
||||||
|
class QmlDebugConnection;
|
||||||
|
class QmlDebugPropertyReference;
|
||||||
|
class QmlDebugObjectReference;
|
||||||
|
|
||||||
|
class WatchTableModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WatchTableModel(QmlEngineDebug *client = 0, QObject *parent = 0);
|
||||||
|
~WatchTableModel();
|
||||||
|
|
||||||
|
void setEngineDebug(QmlEngineDebug *client);
|
||||||
|
|
||||||
|
QmlDebugWatch *findWatch(int column) const;
|
||||||
|
int columnForWatch(QmlDebugWatch *watch) const;
|
||||||
|
|
||||||
|
void removeWatchAt(int column);
|
||||||
|
void removeAllWatches();
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void watchCreated(QmlDebugWatch *watch);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void togglePropertyWatch(const QmlDebugObjectReference &obj, const QmlDebugPropertyReference &prop);
|
||||||
|
void expressionWatchRequested(const QmlDebugObjectReference &, const QString &);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void watchStateChanged();
|
||||||
|
void watchedValueChanged(const QByteArray &propertyName, const QVariant &value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addWatch(QmlDebugWatch *watch, const QString &title);
|
||||||
|
void removeWatch(QmlDebugWatch *watch);
|
||||||
|
void updateWatch(QmlDebugWatch *watch, const QVariant &value);
|
||||||
|
|
||||||
|
QmlDebugWatch *findWatch(int objectDebugId, const QString &property) const;
|
||||||
|
|
||||||
|
void addValue(int column, const QVariant &value);
|
||||||
|
|
||||||
|
struct WatchedEntity
|
||||||
|
{
|
||||||
|
QString title;
|
||||||
|
bool hasFirstValue;
|
||||||
|
QString property;
|
||||||
|
QPointer<QmlDebugWatch> watch;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Value {
|
||||||
|
int column;
|
||||||
|
QVariant variant;
|
||||||
|
bool first;
|
||||||
|
};
|
||||||
|
|
||||||
|
QmlEngineDebug *m_client;
|
||||||
|
QList<WatchedEntity> m_columns;
|
||||||
|
QList<Value> m_values;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class WatchTableHeaderView : public QHeaderView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WatchTableHeaderView(WatchTableModel *model, QWidget *parent = 0);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void mousePressEvent(QMouseEvent *me);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WatchTableModel *m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class WatchTableView : public QTableView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WatchTableView(WatchTableModel *model, QWidget *parent = 0);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void objectActivated(int objectDebugId);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void indexActivated(const QModelIndex &index);
|
||||||
|
void watchCreated(QmlDebugWatch *watch);
|
||||||
|
|
||||||
|
private:
|
||||||
|
WatchTableModel *m_model;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // WATCHTABLEMODEL_H
|
||||||
BIN
src/plugins/qmlinspector/images/logo.png
Normal file
BIN
src/plugins/qmlinspector/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
138
src/plugins/qmlinspector/inspectoroutputpane.cpp
Normal file
138
src/plugins/qmlinspector/inspectoroutputpane.cpp
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "inspectoroutputpane.h"
|
||||||
|
|
||||||
|
#include <QtGui/qtextedit.h>
|
||||||
|
|
||||||
|
InspectorOutputPane::InspectorOutputPane(QObject *parent)
|
||||||
|
: Core::IOutputPane(parent),
|
||||||
|
m_textEdit(new QTextEdit)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
InspectorOutputPane::~InspectorOutputPane()
|
||||||
|
{
|
||||||
|
delete m_textEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *InspectorOutputPane::outputWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
Q_UNUSED(parent);
|
||||||
|
return m_textEdit;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QWidget*> InspectorOutputPane::toolBarWidgets() const
|
||||||
|
{
|
||||||
|
return QList<QWidget *>();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString InspectorOutputPane::name() const
|
||||||
|
{
|
||||||
|
return tr("Inspector Output");
|
||||||
|
}
|
||||||
|
|
||||||
|
int InspectorOutputPane::priorityInStatusBar() const
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::clearContents()
|
||||||
|
{
|
||||||
|
m_textEdit->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::visibilityChanged(bool visible)
|
||||||
|
{
|
||||||
|
Q_UNUSED(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::setFocus()
|
||||||
|
{
|
||||||
|
m_textEdit->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InspectorOutputPane::hasFocus()
|
||||||
|
{
|
||||||
|
return m_textEdit->hasFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InspectorOutputPane::canFocus()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InspectorOutputPane::canNavigate()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InspectorOutputPane::canNext()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InspectorOutputPane::canPrevious()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::goToNext()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::goToPrev()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::addOutput(RunControl *, const QString &text)
|
||||||
|
{
|
||||||
|
m_textEdit->insertPlainText(text);
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::addOutputInline(RunControl *, const QString &text)
|
||||||
|
{
|
||||||
|
m_textEdit->insertPlainText(text);
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::addErrorOutput(RunControl *, const QString &text)
|
||||||
|
{
|
||||||
|
m_textEdit->append(text);
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
}
|
||||||
|
|
||||||
|
void InspectorOutputPane::addInspectorStatus(const QString &text)
|
||||||
|
{
|
||||||
|
m_textEdit->setTextColor(Qt::darkGreen);
|
||||||
|
m_textEdit->append(text);
|
||||||
|
m_textEdit->moveCursor(QTextCursor::End);
|
||||||
|
m_textEdit->setTextColor(Qt::black);
|
||||||
|
}
|
||||||
|
|
||||||
82
src/plugins/qmlinspector/inspectoroutputpane.h
Normal file
82
src/plugins/qmlinspector/inspectoroutputpane.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef INSPECTOROUTPUTPANE_H
|
||||||
|
#define INSPECTOROUTPUTPANE_H
|
||||||
|
|
||||||
|
#include <coreplugin/ioutputpane.h>
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QTextEdit;
|
||||||
|
|
||||||
|
class RunControl;
|
||||||
|
|
||||||
|
class InspectorOutputPane : public Core::IOutputPane
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
InspectorOutputPane(QObject *parent = 0);
|
||||||
|
virtual ~InspectorOutputPane();
|
||||||
|
|
||||||
|
virtual QWidget *outputWidget(QWidget *parent);
|
||||||
|
virtual QList<QWidget*> toolBarWidgets() const;
|
||||||
|
virtual QString name() const;
|
||||||
|
|
||||||
|
virtual int priorityInStatusBar() const;
|
||||||
|
|
||||||
|
virtual void clearContents();
|
||||||
|
virtual void visibilityChanged(bool visible);
|
||||||
|
|
||||||
|
virtual void setFocus();
|
||||||
|
virtual bool hasFocus();
|
||||||
|
virtual bool canFocus();
|
||||||
|
|
||||||
|
virtual bool canNavigate();
|
||||||
|
virtual bool canNext();
|
||||||
|
virtual bool canPrevious();
|
||||||
|
virtual void goToNext();
|
||||||
|
virtual void goToPrev();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void addOutput(RunControl *, const QString &text);
|
||||||
|
void addOutputInline(RunControl *, const QString &text);
|
||||||
|
|
||||||
|
void addErrorOutput(RunControl *, const QString &text);
|
||||||
|
void addInspectorStatus(const QString &text);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTextEdit *m_textEdit;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
53
src/plugins/qmlinspector/qmlinspector.h
Normal file
53
src/plugins/qmlinspector/qmlinspector.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef QMLINSPECTOR_H
|
||||||
|
#define QMLINSPECTOR_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace QmlInspector {
|
||||||
|
namespace Constants {
|
||||||
|
const char * const RUN = "QmlInspector.Run";
|
||||||
|
const char * const STOP = "QmlInspector.Stop";
|
||||||
|
|
||||||
|
const char * const C_INSPECTOR = "QmlInspector";
|
||||||
|
};
|
||||||
|
|
||||||
|
class StartParameters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
StartParameters() : port(0) {}
|
||||||
|
~StartParameters() {}
|
||||||
|
|
||||||
|
QString address;
|
||||||
|
quint16 port;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
27
src/plugins/qmlinspector/qmlinspector.pro
Normal file
27
src/plugins/qmlinspector/qmlinspector.pro
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
TEMPLATE = lib
|
||||||
|
TARGET = QmlInspector
|
||||||
|
|
||||||
|
INCLUDEPATH += .
|
||||||
|
DEPENDPATH += .
|
||||||
|
|
||||||
|
include(components/qmldebugger.pri)
|
||||||
|
|
||||||
|
HEADERS += qmlinspectorplugin.h \
|
||||||
|
qmlinspector.h \
|
||||||
|
qmlinspectormode.h \
|
||||||
|
inspectoroutputpane.h \
|
||||||
|
runcontrol.h
|
||||||
|
|
||||||
|
SOURCES += qmlinspectorplugin.cpp \
|
||||||
|
qmlinspectormode.cpp \
|
||||||
|
inspectoroutputpane.cpp \
|
||||||
|
runcontrol.cpp
|
||||||
|
|
||||||
|
OTHER_FILES += QmlInspector.pluginspec
|
||||||
|
RESOURCES += qmlinspector.qrc
|
||||||
|
|
||||||
|
include(../../qtcreatorplugin.pri)
|
||||||
|
include(../../plugins/projectexplorer/projectexplorer.pri)
|
||||||
|
include(../../plugins/coreplugin/coreplugin.pri)
|
||||||
|
include(../../plugins/texteditor/texteditor.pri)
|
||||||
|
|
||||||
6
src/plugins/qmlinspector/qmlinspector.qrc
Normal file
6
src/plugins/qmlinspector/qmlinspector.qrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="/qmlinspector" >
|
||||||
|
<file>images/logo.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
||||||
|
|
||||||
555
src/plugins/qmlinspector/qmlinspectormode.cpp
Normal file
555
src/plugins/qmlinspector/qmlinspectormode.cpp
Normal file
@@ -0,0 +1,555 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "qmlinspector.h"
|
||||||
|
#include "qmlinspectormode.h"
|
||||||
|
|
||||||
|
#include "components/objectpropertiesview.h"
|
||||||
|
#include "components/objecttree.h"
|
||||||
|
#include "components/watchtable.h"
|
||||||
|
#include "components/canvasframerate.h"
|
||||||
|
#include "components/expressionquerywidget.h"
|
||||||
|
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
|
||||||
|
#include <utils/styledbar.h>
|
||||||
|
#include <utils/fancymainwindow.h>
|
||||||
|
|
||||||
|
#include <coreplugin/basemode.h>
|
||||||
|
#include <coreplugin/findplaceholder.h>
|
||||||
|
#include <coreplugin/minisplitter.h>
|
||||||
|
#include <coreplugin/outputpane.h>
|
||||||
|
#include <coreplugin/rightpane.h>
|
||||||
|
#include <coreplugin/navigationwidget.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/coreconstants.h>
|
||||||
|
#include <coreplugin/uniqueidmanager.h>
|
||||||
|
|
||||||
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
|
||||||
|
#include <texteditor/itexteditor.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QtPlugin>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
#include <QtGui/qtoolbutton.h>
|
||||||
|
#include <QtGui/qtoolbar.h>
|
||||||
|
#include <QtGui/qboxlayout.h>
|
||||||
|
#include <QtGui/qlabel.h>
|
||||||
|
#include <QtGui/qdockwidget.h>
|
||||||
|
#include <QtGui/qaction.h>
|
||||||
|
#include <QtGui/qlineedit.h>
|
||||||
|
#include <QtGui/qlabel.h>
|
||||||
|
#include <QtGui/qspinbox.h>
|
||||||
|
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
class EngineSpinBox : public QSpinBox
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
struct EngineInfo
|
||||||
|
{
|
||||||
|
QString name;
|
||||||
|
int id;
|
||||||
|
};
|
||||||
|
|
||||||
|
EngineSpinBox(QWidget *parent = 0);
|
||||||
|
|
||||||
|
void addEngine(int engine, const QString &name);
|
||||||
|
void clearEngines();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QString textFromValue(int value) const;
|
||||||
|
virtual int valueFromText(const QString &text) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<EngineInfo> m_engines;
|
||||||
|
};
|
||||||
|
|
||||||
|
EngineSpinBox::EngineSpinBox(QWidget *parent)
|
||||||
|
: QSpinBox(parent)
|
||||||
|
{
|
||||||
|
setEnabled(false);
|
||||||
|
setReadOnly(true);
|
||||||
|
setRange(0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EngineSpinBox::addEngine(int engine, const QString &name)
|
||||||
|
{
|
||||||
|
EngineInfo info;
|
||||||
|
info.id = engine;
|
||||||
|
if (name.isEmpty())
|
||||||
|
info.name = tr("Engine %1", "engine number").arg(engine);
|
||||||
|
else
|
||||||
|
info.name = name;
|
||||||
|
m_engines << info;
|
||||||
|
|
||||||
|
setRange(0, m_engines.count()-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EngineSpinBox::clearEngines()
|
||||||
|
{
|
||||||
|
m_engines.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EngineSpinBox::textFromValue(int value) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_engines.count(); ++i) {
|
||||||
|
if (m_engines[i].id == value)
|
||||||
|
return m_engines[i].name;
|
||||||
|
}
|
||||||
|
return QLatin1String("<None>");
|
||||||
|
}
|
||||||
|
|
||||||
|
int EngineSpinBox::valueFromText(const QString &text) const
|
||||||
|
{
|
||||||
|
for (int i=0; i<m_engines.count(); ++i) {
|
||||||
|
if (m_engines[i].name == text)
|
||||||
|
return m_engines[i].id;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QmlInspectorMode::QmlInspectorMode(QObject *parent)
|
||||||
|
: Core::BaseMode(parent),
|
||||||
|
m_conn(0),
|
||||||
|
m_client(0),
|
||||||
|
m_engineQuery(0),
|
||||||
|
m_contextQuery(0)
|
||||||
|
{
|
||||||
|
m_watchTableModel = new WatchTableModel(0, this);
|
||||||
|
|
||||||
|
initActions();
|
||||||
|
setWidget(createModeWindow());
|
||||||
|
|
||||||
|
setName(tr("QML Inspect"));
|
||||||
|
setIcon(QIcon(":/qmlinspector/images/logo.png"));
|
||||||
|
setUniqueModeName("QML_INSPECT_MODE");
|
||||||
|
}
|
||||||
|
|
||||||
|
quint16 QmlInspectorMode::viewerPort() const
|
||||||
|
{
|
||||||
|
return m_portSpinBox->value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::connectToViewer()
|
||||||
|
{
|
||||||
|
if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState)
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete m_client; m_client = 0;
|
||||||
|
|
||||||
|
if (m_conn) {
|
||||||
|
m_conn->disconnectFromHost();
|
||||||
|
delete m_conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_conn = new QmlDebugConnection(this);
|
||||||
|
connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||||
|
SLOT(connectionStateChanged()));
|
||||||
|
connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||||
|
SLOT(connectionError()));
|
||||||
|
m_conn->connectToHost(m_addressEdit->text(), m_portSpinBox->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::disconnectFromViewer()
|
||||||
|
{
|
||||||
|
m_conn->disconnectFromHost();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::connectionStateChanged()
|
||||||
|
{
|
||||||
|
switch (m_conn->state()) {
|
||||||
|
default:
|
||||||
|
case QAbstractSocket::UnconnectedState:
|
||||||
|
{
|
||||||
|
emit statusMessage(tr("[Inspector] disconnected.\n\n"));
|
||||||
|
m_addressEdit->setEnabled(true);
|
||||||
|
m_portSpinBox->setEnabled(true);
|
||||||
|
|
||||||
|
delete m_engineQuery;
|
||||||
|
m_engineQuery = 0;
|
||||||
|
delete m_contextQuery;
|
||||||
|
m_contextQuery = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QAbstractSocket::HostLookupState:
|
||||||
|
emit statusMessage(tr("[Inspector] resolving host..."));
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ConnectingState:
|
||||||
|
emit statusMessage(tr("[Inspector] connecting to debug server..."));
|
||||||
|
break;
|
||||||
|
case QAbstractSocket::ConnectedState:
|
||||||
|
{
|
||||||
|
emit statusMessage(tr("[Inspector] connected.\n"));
|
||||||
|
m_addressEdit->setEnabled(false);
|
||||||
|
m_portSpinBox->setEnabled(false);
|
||||||
|
|
||||||
|
if (!m_client) {
|
||||||
|
m_client = new QmlEngineDebug(m_conn, this);
|
||||||
|
m_objectTreeWidget->setEngineDebug(m_client);
|
||||||
|
m_propertiesWidget->setEngineDebug(m_client);
|
||||||
|
m_watchTableModel->setEngineDebug(m_client);
|
||||||
|
m_expressionWidget->setEngineDebug(m_client);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_objectTreeWidget->clear();
|
||||||
|
m_propertiesWidget->clear();
|
||||||
|
m_expressionWidget->clear();
|
||||||
|
m_watchTableModel->removeAllWatches();
|
||||||
|
m_frameRateWidget->reset(m_conn);
|
||||||
|
|
||||||
|
reloadEngines();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QAbstractSocket::ClosingState:
|
||||||
|
emit statusMessage(tr("[Inspector] closing..."));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::connectionError()
|
||||||
|
{
|
||||||
|
emit statusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message")
|
||||||
|
.arg(m_conn->error()).arg(m_conn->errorString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::initActions()
|
||||||
|
{
|
||||||
|
m_actions.startAction = new QAction(tr("Start Inspector"), this);
|
||||||
|
m_actions.startAction->setIcon(QIcon(ProjectExplorer::Constants::ICON_RUN));
|
||||||
|
|
||||||
|
m_actions.stopAction = new QAction(tr("Stop Inspector"), this);
|
||||||
|
m_actions.stopAction->setIcon(QIcon(ProjectExplorer::Constants::ICON_STOP));
|
||||||
|
|
||||||
|
Core::ICore *core = Core::ICore::instance();
|
||||||
|
Core::ActionManager *am = core->actionManager();
|
||||||
|
Core::UniqueIDManager *uidm = core->uniqueIDManager();
|
||||||
|
|
||||||
|
QList<int> context;
|
||||||
|
context << uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR);
|
||||||
|
|
||||||
|
am->registerAction(m_actions.startAction, QmlInspector::Constants::RUN, context);
|
||||||
|
connect(m_actions.startAction, SIGNAL(triggered()), SIGNAL(startViewer()));
|
||||||
|
|
||||||
|
am->registerAction(m_actions.stopAction, QmlInspector::Constants::STOP, context);
|
||||||
|
connect(m_actions.stopAction, SIGNAL(triggered()), SIGNAL(stopViewer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QToolButton *QmlInspectorMode::createToolButton(QAction *action)
|
||||||
|
{
|
||||||
|
QToolButton *button = new QToolButton;
|
||||||
|
button->setDefaultAction(action);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *QmlInspectorMode::createMainView()
|
||||||
|
{
|
||||||
|
initWidgets();
|
||||||
|
|
||||||
|
Utils::FancyMainWindow *mainWindow = new Utils::FancyMainWindow;
|
||||||
|
mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
|
||||||
|
mainWindow->setDocumentMode(true);
|
||||||
|
|
||||||
|
QBoxLayout *editorHolderLayout = new QVBoxLayout;
|
||||||
|
editorHolderLayout->setMargin(0);
|
||||||
|
editorHolderLayout->setSpacing(0);
|
||||||
|
|
||||||
|
QWidget *editorAndFindWidget = new QWidget;
|
||||||
|
editorAndFindWidget->setLayout(editorHolderLayout);
|
||||||
|
editorHolderLayout->addWidget(new Core::EditorManagerPlaceHolder(this));
|
||||||
|
editorHolderLayout->addWidget(new Core::FindToolBarPlaceHolder(editorAndFindWidget));
|
||||||
|
|
||||||
|
Utils::StyledBar *treeOptionBar = new Utils::StyledBar;
|
||||||
|
QHBoxLayout *treeOptionBarLayout = new QHBoxLayout(treeOptionBar);
|
||||||
|
treeOptionBarLayout->setContentsMargins(5, 0, 5, 0);
|
||||||
|
treeOptionBarLayout->setSpacing(5);
|
||||||
|
treeOptionBarLayout->addWidget(new QLabel(tr("QML engine:")));
|
||||||
|
treeOptionBarLayout->addWidget(m_engineSpinBox);
|
||||||
|
|
||||||
|
QWidget *treeWindow = new QWidget;
|
||||||
|
QVBoxLayout *treeWindowLayout = new QVBoxLayout(treeWindow);
|
||||||
|
treeWindowLayout->setMargin(0);
|
||||||
|
treeWindowLayout->setSpacing(0);
|
||||||
|
treeWindowLayout->addWidget(treeOptionBar);
|
||||||
|
treeWindowLayout->addWidget(m_objectTreeWidget);
|
||||||
|
|
||||||
|
Core::MiniSplitter *documentAndTree = new Core::MiniSplitter;
|
||||||
|
documentAndTree->addWidget(editorAndFindWidget);
|
||||||
|
documentAndTree->addWidget(new Core::RightPanePlaceHolder(this));
|
||||||
|
documentAndTree->addWidget(treeWindow);
|
||||||
|
documentAndTree->setStretchFactor(0, 2);
|
||||||
|
documentAndTree->setStretchFactor(1, 0);
|
||||||
|
documentAndTree->setStretchFactor(2, 0);
|
||||||
|
|
||||||
|
Utils::StyledBar *configBar = new Utils::StyledBar;
|
||||||
|
configBar->setProperty("topBorder", true);
|
||||||
|
|
||||||
|
QHBoxLayout *configBarLayout = new QHBoxLayout(configBar);
|
||||||
|
configBarLayout->setMargin(0);
|
||||||
|
configBarLayout->setSpacing(5);
|
||||||
|
|
||||||
|
Core::ICore *core = Core::ICore::instance();
|
||||||
|
Core::ActionManager *am = core->actionManager();
|
||||||
|
configBarLayout->addWidget(createToolButton(am->command(QmlInspector::Constants::RUN)->action()));
|
||||||
|
configBarLayout->addWidget(createToolButton(am->command(QmlInspector::Constants::STOP)->action()));
|
||||||
|
configBarLayout->addWidget(m_addressEdit);
|
||||||
|
configBarLayout->addWidget(m_portSpinBox);
|
||||||
|
configBarLayout->addStretch();
|
||||||
|
|
||||||
|
QWidget *widgetAboveTabs = new QWidget;
|
||||||
|
QVBoxLayout *widgetAboveTabsLayout = new QVBoxLayout(widgetAboveTabs);
|
||||||
|
widgetAboveTabsLayout->setMargin(0);
|
||||||
|
widgetAboveTabsLayout->setSpacing(0);
|
||||||
|
widgetAboveTabsLayout->addWidget(documentAndTree);
|
||||||
|
widgetAboveTabsLayout->addWidget(configBar);
|
||||||
|
|
||||||
|
Core::MiniSplitter *mainSplitter = new Core::MiniSplitter(Qt::Vertical);
|
||||||
|
mainSplitter->addWidget(widgetAboveTabs);
|
||||||
|
mainSplitter->addWidget(createBottomWindow());
|
||||||
|
mainSplitter->setStretchFactor(0, 3);
|
||||||
|
mainSplitter->setStretchFactor(1, 1);
|
||||||
|
|
||||||
|
QWidget *centralWidget = new QWidget;
|
||||||
|
QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget);
|
||||||
|
centralLayout->setMargin(0);
|
||||||
|
centralLayout->setSpacing(0);
|
||||||
|
centralLayout->addWidget(mainSplitter);
|
||||||
|
|
||||||
|
mainWindow->setCentralWidget(centralWidget);
|
||||||
|
|
||||||
|
return mainWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *QmlInspectorMode::createBottomWindow()
|
||||||
|
{
|
||||||
|
Utils::FancyMainWindow *win = new Utils::FancyMainWindow;
|
||||||
|
win->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
|
||||||
|
win->setDocumentMode(true);
|
||||||
|
win->setTrackingEnabled(true);
|
||||||
|
|
||||||
|
Core::MiniSplitter *leftSplitter = new Core::MiniSplitter(Qt::Vertical);
|
||||||
|
leftSplitter->addWidget(m_propertiesWidget);
|
||||||
|
leftSplitter->addWidget(m_expressionWidget);
|
||||||
|
leftSplitter->setStretchFactor(0, 2);
|
||||||
|
leftSplitter->setStretchFactor(1, 1);
|
||||||
|
|
||||||
|
Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal);
|
||||||
|
propSplitter->addWidget(leftSplitter);
|
||||||
|
propSplitter->addWidget(m_watchTableView);
|
||||||
|
propSplitter->setStretchFactor(0, 2);
|
||||||
|
propSplitter->setStretchFactor(1, 1);
|
||||||
|
propSplitter->setWindowTitle(tr("Properties and Watchers"));
|
||||||
|
|
||||||
|
QDockWidget *propertiesDock = win->addDockForWidget(propSplitter);
|
||||||
|
win->addDockWidget(Qt::TopDockWidgetArea, propertiesDock);
|
||||||
|
|
||||||
|
QDockWidget *frameRateDock = win->addDockForWidget(m_frameRateWidget);
|
||||||
|
win->addDockWidget(Qt::TopDockWidgetArea, frameRateDock);
|
||||||
|
|
||||||
|
// stack the dock widgets as tabs
|
||||||
|
win->tabifyDockWidget(frameRateDock, propertiesDock);
|
||||||
|
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *QmlInspectorMode::createModeWindow()
|
||||||
|
{
|
||||||
|
// right-side window with editor, output etc.
|
||||||
|
Core::MiniSplitter *mainWindowSplitter = new Core::MiniSplitter;
|
||||||
|
mainWindowSplitter->addWidget(createMainView());
|
||||||
|
mainWindowSplitter->addWidget(new Core::OutputPanePlaceHolder(this));
|
||||||
|
mainWindowSplitter->setStretchFactor(0, 10);
|
||||||
|
mainWindowSplitter->setStretchFactor(1, 0);
|
||||||
|
mainWindowSplitter->setOrientation(Qt::Vertical);
|
||||||
|
|
||||||
|
// navigation + right-side window
|
||||||
|
Core::MiniSplitter *splitter = new Core::MiniSplitter;
|
||||||
|
splitter->addWidget(new Core::NavigationWidgetPlaceHolder(this));
|
||||||
|
splitter->addWidget(mainWindowSplitter);
|
||||||
|
splitter->setStretchFactor(0, 0);
|
||||||
|
splitter->setStretchFactor(1, 1);
|
||||||
|
return splitter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::initWidgets()
|
||||||
|
{
|
||||||
|
m_objectTreeWidget = new ObjectTree;
|
||||||
|
m_propertiesWidget = new ObjectPropertiesView;
|
||||||
|
m_watchTableView = new WatchTableView(m_watchTableModel);
|
||||||
|
m_frameRateWidget = new CanvasFrameRate;
|
||||||
|
m_expressionWidget = new ExpressionQueryWidget(ExpressionQueryWidget::ShellMode);
|
||||||
|
|
||||||
|
// FancyMainWindow uses widgets' window titles for tab labels
|
||||||
|
m_objectTreeWidget->setWindowTitle(tr("Object Tree"));
|
||||||
|
m_frameRateWidget->setWindowTitle(tr("Frame rate"));
|
||||||
|
|
||||||
|
m_watchTableView->setModel(m_watchTableModel);
|
||||||
|
WatchTableHeaderView *header = new WatchTableHeaderView(m_watchTableModel);
|
||||||
|
m_watchTableView->setHorizontalHeader(header);
|
||||||
|
|
||||||
|
connect(m_objectTreeWidget, SIGNAL(activated(QmlDebugObjectReference)),
|
||||||
|
this, SLOT(treeObjectActivated(QmlDebugObjectReference)));
|
||||||
|
|
||||||
|
connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)),
|
||||||
|
m_propertiesWidget, SLOT(reload(QmlDebugObjectReference)));
|
||||||
|
|
||||||
|
connect(m_objectTreeWidget, SIGNAL(expressionWatchRequested(QmlDebugObjectReference,QString)),
|
||||||
|
m_watchTableModel, SLOT(expressionWatchRequested(QmlDebugObjectReference,QString)));
|
||||||
|
|
||||||
|
connect(m_propertiesWidget, SIGNAL(activated(QmlDebugObjectReference,QmlDebugPropertyReference)),
|
||||||
|
m_watchTableModel, SLOT(togglePropertyWatch(QmlDebugObjectReference,QmlDebugPropertyReference)));
|
||||||
|
|
||||||
|
connect(m_watchTableModel, SIGNAL(watchCreated(QmlDebugWatch*)),
|
||||||
|
m_propertiesWidget, SLOT(watchCreated(QmlDebugWatch*)));
|
||||||
|
|
||||||
|
connect(m_watchTableModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||||
|
m_watchTableView, SLOT(scrollToBottom()));
|
||||||
|
|
||||||
|
connect(m_watchTableView, SIGNAL(objectActivated(int)),
|
||||||
|
m_objectTreeWidget, SLOT(setCurrentObject(int)));
|
||||||
|
|
||||||
|
connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)),
|
||||||
|
m_expressionWidget, SLOT(setCurrentObject(QmlDebugObjectReference)));
|
||||||
|
|
||||||
|
m_addressEdit = new QLineEdit;
|
||||||
|
m_addressEdit->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
|
||||||
|
m_addressEdit->setText("127.0.0.1");
|
||||||
|
|
||||||
|
m_portSpinBox = new QSpinBox;
|
||||||
|
m_portSpinBox->setMinimum(1024);
|
||||||
|
m_portSpinBox->setMaximum(20000);
|
||||||
|
m_portSpinBox->setValue(3768);
|
||||||
|
|
||||||
|
m_engineSpinBox = new EngineSpinBox;
|
||||||
|
m_engineSpinBox->setEnabled(false);
|
||||||
|
connect(m_engineSpinBox, SIGNAL(valueChanged(int)),
|
||||||
|
SLOT(queryEngineContext(int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::reloadEngines()
|
||||||
|
{
|
||||||
|
if (m_engineQuery) {
|
||||||
|
emit statusMessage("[Inspector] Waiting for response to previous engine query");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_engineSpinBox->setEnabled(false);
|
||||||
|
|
||||||
|
m_engineQuery = m_client->queryAvailableEngines(this);
|
||||||
|
if (!m_engineQuery->isWaiting())
|
||||||
|
enginesChanged();
|
||||||
|
else
|
||||||
|
QObject::connect(m_engineQuery, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(enginesChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::enginesChanged()
|
||||||
|
{
|
||||||
|
m_engineSpinBox->clearEngines();
|
||||||
|
|
||||||
|
QList<QmlDebugEngineReference> engines = m_engineQuery->engines();
|
||||||
|
delete m_engineQuery; m_engineQuery = 0;
|
||||||
|
|
||||||
|
if (engines.isEmpty())
|
||||||
|
qWarning("qmldebugger: no engines found!");
|
||||||
|
|
||||||
|
m_engineSpinBox->setEnabled(true);
|
||||||
|
|
||||||
|
for (int i=0; i<engines.count(); ++i)
|
||||||
|
m_engineSpinBox->addEngine(engines.at(i).debugId(), engines.at(i).name());
|
||||||
|
|
||||||
|
if (engines.count() > 0) {
|
||||||
|
m_engineSpinBox->setValue(engines.at(0).debugId());
|
||||||
|
queryEngineContext(engines.at(0).debugId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::queryEngineContext(int id)
|
||||||
|
{
|
||||||
|
if (id < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_contextQuery) {
|
||||||
|
delete m_contextQuery;
|
||||||
|
m_contextQuery = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_contextQuery = m_client->queryRootContexts(QmlDebugEngineReference(id), this);
|
||||||
|
if (!m_contextQuery->isWaiting())
|
||||||
|
contextChanged();
|
||||||
|
else
|
||||||
|
QObject::connect(m_contextQuery, SIGNAL(stateChanged(QmlDebugQuery::State)),
|
||||||
|
this, SLOT(contextChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::contextChanged()
|
||||||
|
{
|
||||||
|
//dump(m_contextQuery->rootContext(), 0);
|
||||||
|
|
||||||
|
foreach (const QmlDebugObjectReference &object, m_contextQuery->rootContext().objects())
|
||||||
|
m_objectTreeWidget->reload(object.debugId());
|
||||||
|
|
||||||
|
delete m_contextQuery; m_contextQuery = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorMode::treeObjectActivated(const QmlDebugObjectReference &obj)
|
||||||
|
{
|
||||||
|
QmlDebugFileReference source = obj.source();
|
||||||
|
QString fileName = source.url().toLocalFile();
|
||||||
|
|
||||||
|
if (source.lineNumber() < 0 || !QFile::exists(fileName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
|
TextEditor::ITextEditor *editor = qobject_cast<TextEditor::ITextEditor*>(editorManager->openEditor(fileName));
|
||||||
|
if (editor) {
|
||||||
|
editorManager->ensureEditorManagerVisible();
|
||||||
|
editorManager->addCurrentPositionToNavigationHistory();
|
||||||
|
editor->gotoLine(source.lineNumber());
|
||||||
|
editor->widget()->setFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#include "qmlinspectormode.moc"
|
||||||
|
|
||||||
121
src/plugins/qmlinspector/qmlinspectormode.h
Normal file
121
src/plugins/qmlinspector/qmlinspectormode.h
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef QMLINSPECTORMODE_H
|
||||||
|
#define QMLINSPECTORMODE_H
|
||||||
|
|
||||||
|
#include <coreplugin/basemode.h>
|
||||||
|
|
||||||
|
#include <QtGui/QAction>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QToolButton;
|
||||||
|
class QLineEdit;
|
||||||
|
class QSpinBox;
|
||||||
|
class QLabel;
|
||||||
|
|
||||||
|
class QmlEngineDebug;
|
||||||
|
class QmlDebugConnection;
|
||||||
|
class QmlDebugEnginesQuery;
|
||||||
|
class QmlDebugRootContextQuery;
|
||||||
|
class QmlDebugObjectReference;
|
||||||
|
class ObjectTree;
|
||||||
|
class WatchTableModel;
|
||||||
|
class WatchTableView;
|
||||||
|
class ObjectPropertiesView;
|
||||||
|
class CanvasFrameRate;
|
||||||
|
class ExpressionQueryWidget;
|
||||||
|
class EngineSpinBox;
|
||||||
|
|
||||||
|
|
||||||
|
class QmlInspectorMode : public Core::BaseMode
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QmlInspectorMode(QObject *parent = 0);
|
||||||
|
|
||||||
|
|
||||||
|
quint16 viewerPort() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void startViewer();
|
||||||
|
void stopViewer();
|
||||||
|
void statusMessage(const QString &text);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void connectToViewer(); // using host, port from widgets
|
||||||
|
void disconnectFromViewer();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void connectionStateChanged();
|
||||||
|
void connectionError();
|
||||||
|
void reloadEngines();
|
||||||
|
void enginesChanged();
|
||||||
|
void queryEngineContext(int);
|
||||||
|
void contextChanged();
|
||||||
|
void treeObjectActivated(const QmlDebugObjectReference &obj);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Actions {
|
||||||
|
QAction *startAction;
|
||||||
|
QAction *stopAction;
|
||||||
|
};
|
||||||
|
|
||||||
|
void initActions();
|
||||||
|
QWidget *createModeWindow();
|
||||||
|
QWidget *createMainView();
|
||||||
|
void initWidgets();
|
||||||
|
QWidget *createBottomWindow();
|
||||||
|
QToolButton *createToolButton(QAction *action);
|
||||||
|
|
||||||
|
Actions m_actions;
|
||||||
|
|
||||||
|
QmlDebugConnection *m_conn;
|
||||||
|
QmlEngineDebug *m_client;
|
||||||
|
|
||||||
|
QmlDebugEnginesQuery *m_engineQuery;
|
||||||
|
QmlDebugRootContextQuery *m_contextQuery;
|
||||||
|
|
||||||
|
ObjectTree *m_objectTreeWidget;
|
||||||
|
ObjectPropertiesView *m_propertiesWidget;
|
||||||
|
WatchTableModel *m_watchTableModel;
|
||||||
|
WatchTableView *m_watchTableView;
|
||||||
|
CanvasFrameRate *m_frameRateWidget;
|
||||||
|
ExpressionQueryWidget *m_expressionWidget;
|
||||||
|
|
||||||
|
QLineEdit *m_addressEdit;
|
||||||
|
QSpinBox *m_portSpinBox;
|
||||||
|
EngineSpinBox *m_engineSpinBox;
|
||||||
|
};
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif
|
||||||
163
src/plugins/qmlinspector/qmlinspectorplugin.cpp
Normal file
163
src/plugins/qmlinspector/qmlinspectorplugin.cpp
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "runcontrol.h"
|
||||||
|
#include "qmlinspector.h"
|
||||||
|
#include "qmlinspectormode.h"
|
||||||
|
#include "inspectoroutputpane.h"
|
||||||
|
#include "qmlinspectorplugin.h"
|
||||||
|
|
||||||
|
#include <private/qmldebug_p.h>
|
||||||
|
#include <private/qmldebugclient_p.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/project.h>
|
||||||
|
|
||||||
|
#include <coreplugin/coreconstants.h>
|
||||||
|
#include <coreplugin/uniqueidmanager.h>
|
||||||
|
|
||||||
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QtPlugin>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
QmlInspectorPlugin::QmlInspectorPlugin()
|
||||||
|
: m_inspectMode(0),
|
||||||
|
m_runControl(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlInspectorPlugin::~QmlInspectorPlugin()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorPlugin::shutdown()
|
||||||
|
{
|
||||||
|
removeObject(m_inspectMode);
|
||||||
|
delete m_inspectMode;
|
||||||
|
m_inspectMode = 0;
|
||||||
|
|
||||||
|
removeObject(m_outputPane);
|
||||||
|
delete m_outputPane;
|
||||||
|
m_outputPane = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *errorString)
|
||||||
|
{
|
||||||
|
Q_UNUSED(arguments);
|
||||||
|
Q_UNUSED(errorString);
|
||||||
|
|
||||||
|
Core::ICore *core = Core::ICore::instance();
|
||||||
|
Core::UniqueIDManager *uidm = core->uniqueIDManager();
|
||||||
|
|
||||||
|
QList<int> context;
|
||||||
|
context.append(uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR));
|
||||||
|
context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER));
|
||||||
|
context.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE));
|
||||||
|
|
||||||
|
m_inspectMode = new QmlInspectorMode(this);
|
||||||
|
connect(m_inspectMode, SIGNAL(startViewer()), SLOT(startViewer()));
|
||||||
|
connect(m_inspectMode, SIGNAL(stopViewer()), SLOT(stopViewer()));
|
||||||
|
m_inspectMode->setContext(context);
|
||||||
|
addObject(m_inspectMode);
|
||||||
|
|
||||||
|
m_outputPane = new InspectorOutputPane;
|
||||||
|
addObject(m_outputPane);
|
||||||
|
|
||||||
|
connect(m_inspectMode, SIGNAL(statusMessage(QString)),
|
||||||
|
m_outputPane, SLOT(addInspectorStatus(QString)));
|
||||||
|
|
||||||
|
m_runControlFactory = new QmlInspectorRunControlFactory(this);
|
||||||
|
addAutoReleasedObject(m_runControlFactory);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorPlugin::extensionsInitialized()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorPlugin::startViewer()
|
||||||
|
{
|
||||||
|
stopViewer();
|
||||||
|
|
||||||
|
ProjectExplorer::Project *project = 0;
|
||||||
|
ProjectExplorer::ProjectExplorerPlugin *plugin = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||||
|
if (plugin)
|
||||||
|
project = plugin->currentProject();
|
||||||
|
if (!project) {
|
||||||
|
qDebug() << "No project loaded"; // TODO should this just run the debugger without a viewer?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectExplorer::RunConfiguration *rc = project->activeRunConfiguration();
|
||||||
|
|
||||||
|
QmlInspector::StartParameters sp;
|
||||||
|
sp.port = m_inspectMode->viewerPort();
|
||||||
|
|
||||||
|
m_runControl = m_runControlFactory->create(rc, ProjectExplorer::Constants::RUNMODE, sp);
|
||||||
|
|
||||||
|
if (m_runControl) {
|
||||||
|
connect(m_runControl, SIGNAL(started()), m_inspectMode, SLOT(connectToViewer()));
|
||||||
|
connect(m_runControl, SIGNAL(finished()), m_inspectMode, SLOT(disconnectFromViewer()));
|
||||||
|
|
||||||
|
connect(m_runControl, SIGNAL(addToOutputWindow(RunControl*,QString)),
|
||||||
|
m_outputPane, SLOT(addOutput(RunControl*,QString)));
|
||||||
|
connect(m_runControl, SIGNAL(addToOutputWindowInline(RunControl*,QString)),
|
||||||
|
m_outputPane, SLOT(addOutputInline(RunControl*,QString)));
|
||||||
|
connect(m_runControl, SIGNAL(error(RunControl*,QString)),
|
||||||
|
m_outputPane, SLOT(addErrorOutput(RunControl*,QString)));
|
||||||
|
|
||||||
|
m_runControl->start();
|
||||||
|
m_outputPane->popup(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorPlugin::stopViewer()
|
||||||
|
{
|
||||||
|
if (m_runControl) {
|
||||||
|
m_runControl->stop();
|
||||||
|
m_runControl->deleteLater();
|
||||||
|
m_runControl = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Q_EXPORT_PLUGIN(QmlInspectorPlugin)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
78
src/plugins/qmlinspector/qmlinspectorplugin.h
Normal file
78
src/plugins/qmlinspector/qmlinspectorplugin.h
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef QMLINSPECTORPLUGIN_H
|
||||||
|
#define QMLINSPECTORPLUGIN_H
|
||||||
|
|
||||||
|
#include <extensionsystem/iplugin.h>
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QPointer>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QStringList;
|
||||||
|
|
||||||
|
|
||||||
|
class QmlInspectorRunControlFactory;
|
||||||
|
class QmlInspectorMode;
|
||||||
|
class InspectorOutputPane;
|
||||||
|
|
||||||
|
namespace ProjectExplorer
|
||||||
|
{
|
||||||
|
class RunControl;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QmlInspectorPlugin : public ExtensionSystem::IPlugin
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
QmlInspectorPlugin();
|
||||||
|
~QmlInspectorPlugin();
|
||||||
|
|
||||||
|
virtual bool initialize(const QStringList &arguments, QString *errorString);
|
||||||
|
virtual void extensionsInitialized();
|
||||||
|
virtual void shutdown();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void startViewer();
|
||||||
|
void stopViewer();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QmlInspectorMode *m_inspectMode;
|
||||||
|
InspectorOutputPane *m_outputPane;
|
||||||
|
|
||||||
|
QmlInspectorRunControlFactory *m_runControlFactory;
|
||||||
|
QPointer<ProjectExplorer::RunControl> m_runControl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // QMLINSPECTORPLUGIN_H
|
||||||
162
src/plugins/qmlinspector/runcontrol.cpp
Normal file
162
src/plugins/qmlinspector/runcontrol.cpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#include "runcontrol.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/applicationlauncher.h>
|
||||||
|
#include <projectexplorer/applicationrunconfiguration.h>
|
||||||
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
|
||||||
|
#include <QtCore/qdebug.h>
|
||||||
|
#include <QtCore/qtimer.h>
|
||||||
|
|
||||||
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
|
|
||||||
|
QmlInspectorRunControlFactory::QmlInspectorRunControlFactory(QObject *parent)
|
||||||
|
: ProjectExplorer::IRunControlFactory(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlInspectorRunControlFactory::canRun(RunConfiguration *runConfiguration, const QString &mode) const
|
||||||
|
{
|
||||||
|
Q_UNUSED(runConfiguration);
|
||||||
|
if (mode != ProjectExplorer::Constants::RUNMODE)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectExplorer::RunControl *QmlInspectorRunControlFactory::create(RunConfiguration *runConfiguration, const QString &mode)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mode);
|
||||||
|
return new QmlInspectorRunControl(runConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProjectExplorer::RunControl *QmlInspectorRunControlFactory::create(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
|
const QString &mode, const QmlInspector::StartParameters &sp)
|
||||||
|
{
|
||||||
|
Q_UNUSED(mode);
|
||||||
|
return new QmlInspectorRunControl(runConfiguration, sp);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlInspectorRunControlFactory::displayName() const
|
||||||
|
{
|
||||||
|
return tr("Qml Inspector");
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *QmlInspectorRunControlFactory::configurationWidget(RunConfiguration *runConfiguration)
|
||||||
|
{
|
||||||
|
Q_UNUSED(runConfiguration);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QmlInspectorRunControl::QmlInspectorRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
|
const QmlInspector::StartParameters &sp)
|
||||||
|
: ProjectExplorer::RunControl(runConfiguration),
|
||||||
|
m_configuration(runConfiguration),
|
||||||
|
m_running(false),
|
||||||
|
m_viewerLauncher(0),
|
||||||
|
m_startParams(sp)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlInspectorRunControl::~QmlInspectorRunControl()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::start()
|
||||||
|
{
|
||||||
|
if (m_running || m_viewerLauncher)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_viewerLauncher = new ProjectExplorer::ApplicationLauncher(this);
|
||||||
|
connect(m_viewerLauncher, SIGNAL(applicationError(QString)), SLOT(applicationError(QString)));
|
||||||
|
connect(m_viewerLauncher, SIGNAL(processExited(int)), SLOT(viewerExited()));
|
||||||
|
connect(m_viewerLauncher, SIGNAL(appendOutput(QString)), SLOT(appendOutput(QString)));
|
||||||
|
connect(m_viewerLauncher, SIGNAL(bringToForegroundRequested(qint64)),
|
||||||
|
this, SLOT(appStarted()));
|
||||||
|
|
||||||
|
LocalApplicationRunConfiguration *rc = qobject_cast<LocalApplicationRunConfiguration *>(m_configuration);
|
||||||
|
if (!rc)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ProjectExplorer::Environment env = rc->environment();
|
||||||
|
env.set("QML_DEBUG_SERVER_PORT", QString::number(m_startParams.port));
|
||||||
|
|
||||||
|
QStringList arguments = rc->commandLineArguments();
|
||||||
|
arguments << QLatin1String("-stayontop");
|
||||||
|
|
||||||
|
m_viewerLauncher->setEnvironment(env.toStringList());
|
||||||
|
m_viewerLauncher->setWorkingDirectory(rc->workingDirectory());
|
||||||
|
|
||||||
|
m_running = true;
|
||||||
|
|
||||||
|
m_viewerLauncher->start(static_cast<ApplicationLauncher::Mode>(rc->runMode()),
|
||||||
|
rc->executable(), arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::stop()
|
||||||
|
{
|
||||||
|
if (m_viewerLauncher->isRunning())
|
||||||
|
m_viewerLauncher->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlInspectorRunControl::isRunning() const
|
||||||
|
{
|
||||||
|
return m_running;
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::appStarted()
|
||||||
|
{
|
||||||
|
QTimer::singleShot(500, this, SLOT(delayedStart()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::appendOutput(const QString &s)
|
||||||
|
{
|
||||||
|
emit addToOutputWindow(this, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::delayedStart()
|
||||||
|
{
|
||||||
|
emit started();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::viewerExited()
|
||||||
|
{
|
||||||
|
m_running = false;
|
||||||
|
emit finished();
|
||||||
|
|
||||||
|
deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlInspectorRunControl::applicationError(const QString &s)
|
||||||
|
{
|
||||||
|
emit error(this, s);
|
||||||
|
}
|
||||||
94
src/plugins/qmlinspector/runcontrol.h
Normal file
94
src/plugins/qmlinspector/runcontrol.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** Commercial Usage
|
||||||
|
**
|
||||||
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||||
|
** accordance with the Qt Commercial License Agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and Nokia.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** If you are unsure which license is appropriate for your use, please
|
||||||
|
** contact the sales department at http://qt.nokia.com/contact.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
#ifndef QMLINSPECTORRUNCONTROL_H
|
||||||
|
#define QMLINSPECTORRUNCONTROL_H
|
||||||
|
|
||||||
|
#include "qmlinspector.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
|
#include <QtCore/qobject.h>
|
||||||
|
|
||||||
|
namespace ProjectExplorer {
|
||||||
|
class ApplicationLauncher;
|
||||||
|
}
|
||||||
|
|
||||||
|
class QmlInspectorRunControlFactory : public ProjectExplorer::IRunControlFactory
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QmlInspectorRunControlFactory(QObject *parent);
|
||||||
|
|
||||||
|
virtual bool canRun(
|
||||||
|
ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
|
const QString &mode) const;
|
||||||
|
|
||||||
|
virtual ProjectExplorer::RunControl *create(
|
||||||
|
ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
|
const QString &mode);
|
||||||
|
|
||||||
|
ProjectExplorer::RunControl *create(
|
||||||
|
ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
|
const QString &mode,
|
||||||
|
const QmlInspector::StartParameters &sp);
|
||||||
|
|
||||||
|
virtual QString displayName() const;
|
||||||
|
|
||||||
|
virtual QWidget *configurationWidget(ProjectExplorer::RunConfiguration *runConfiguration);
|
||||||
|
};
|
||||||
|
|
||||||
|
class QmlInspectorRunControl : public ProjectExplorer::RunControl
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit QmlInspectorRunControl(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||||
|
const QmlInspector::StartParameters &sp = QmlInspector::StartParameters());
|
||||||
|
~QmlInspectorRunControl();
|
||||||
|
|
||||||
|
virtual void start();
|
||||||
|
virtual void stop();
|
||||||
|
virtual bool isRunning() const;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void appendOutput(const QString &s);
|
||||||
|
void appStarted();
|
||||||
|
void delayedStart();
|
||||||
|
void viewerExited();
|
||||||
|
void applicationError(const QString &error);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ProjectExplorer::RunConfiguration *m_configuration;
|
||||||
|
bool m_running;
|
||||||
|
ProjectExplorer::ApplicationLauncher *m_viewerLauncher;
|
||||||
|
QmlInspector::StartParameters m_startParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user