forked from qt-creator/qt-creator
Get rid of the old the QML inspector code.
This commit is contained in:
@@ -1,569 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 <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>
|
||||
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
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 QDeclarativeDebugClient
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CanvasFrameRatePlugin(QDeclarativeDebugConnection *client);
|
||||
|
||||
signals:
|
||||
void sample(int, int, int, bool);
|
||||
|
||||
protected:
|
||||
virtual void messageReceived(const QByteArray &);
|
||||
|
||||
private:
|
||||
int lb;
|
||||
int ld;
|
||||
};
|
||||
|
||||
CanvasFrameRatePlugin::CanvasFrameRatePlugin(QDeclarativeDebugConnection *client)
|
||||
: QDeclarativeDebugClient(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(QDeclarativeDebugConnection *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<QDeclarativeDebugConnection*>(sender()));
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasFrameRate::handleConnected(QDeclarativeDebugConnection *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<QDeclarativeDebugClient *>(m_plugin)->setEnabled(checked);
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#include "canvasframerate.moc"
|
||||
@@ -1,88 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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/qdeclarativedebugclient_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;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
class CanvasFrameRatePlugin;
|
||||
|
||||
class CanvasFrameRate : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CanvasFrameRate(QWidget *parent = 0);
|
||||
|
||||
void reset(QDeclarativeDebugConnection *conn);
|
||||
|
||||
void setSizeHint(const QSize &);
|
||||
virtual QSize sizeHint() const;
|
||||
|
||||
signals:
|
||||
void contextHelpIdChanged(const QString &helpId);
|
||||
|
||||
private slots:
|
||||
void clearGraph();
|
||||
void newTab();
|
||||
void enabledToggled(bool);
|
||||
void connectionStateChanged(QAbstractSocket::SocketState state);
|
||||
|
||||
private:
|
||||
void handleConnected(QDeclarativeDebugConnection *conn);
|
||||
|
||||
QGroupBox *m_group;
|
||||
QTabWidget *m_tabs;
|
||||
QSpinBox *m_res;
|
||||
QPushButton *m_clearButton;
|
||||
CanvasFrameRatePlugin *m_plugin;
|
||||
QSize m_sizeHint;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif // CANVASFRAMERATE_H
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.2 KiB |
@@ -1,46 +0,0 @@
|
||||
import Qt 4.7
|
||||
|
||||
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
|
||||
}
|
||||
MouseArea {
|
||||
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
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: Root.refreshEngines()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,330 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "qmlinspectorconstants.h"
|
||||
#include "inspectorcontext.h"
|
||||
|
||||
#include <utils/styledbar.h>
|
||||
#include <utils/filterlineedit.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <texteditor/texteditorsettings.h>
|
||||
#include <texteditor/fontsettings.h>
|
||||
#include <qmljseditor/qmljshighlighter.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtGui/QTextCharFormat>
|
||||
#include <QtGui/QKeySequence>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QGroupBox>
|
||||
#include <QtGui/QTextObject>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QShortcut>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
ExpressionQueryWidget::ExpressionQueryWidget(Mode mode, QDeclarativeEngineDebug *client, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_mode(mode),
|
||||
m_client(client),
|
||||
m_query(0),
|
||||
m_textEdit(new QPlainTextEdit),
|
||||
m_lineEdit(0)
|
||||
{
|
||||
m_prompt = QLatin1String(">");
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setMargin(0);
|
||||
layout->setSpacing(0);
|
||||
layout->addWidget(m_textEdit);
|
||||
m_textEdit->setFrameStyle(QFrame::NoFrame);
|
||||
|
||||
updateTitle();
|
||||
|
||||
m_highlighter = new QmlJSEditor::Highlighter(m_textEdit->document());
|
||||
m_highlighter->setParent(m_textEdit->document());
|
||||
|
||||
if (m_mode == SeparateEntryMode) {
|
||||
Utils::StyledBar *bar = new Utils::StyledBar;
|
||||
m_lineEdit = new Utils::FilterLineEdit;
|
||||
|
||||
m_lineEdit->setPlaceholderText(tr("<Type expression to evaluate>"));
|
||||
m_lineEdit->setToolTip(tr("Write and evaluate QtScript expressions."));
|
||||
|
||||
m_clearButton = new QToolButton();
|
||||
m_clearButton->setToolTip(tr("Clear Output"));
|
||||
m_clearButton->setIcon(QIcon(Core::Constants::ICON_CLEAN_PANE));
|
||||
connect(m_clearButton, SIGNAL(clicked()), this, SLOT(clearTextEditor()));
|
||||
connect(m_lineEdit, SIGNAL(textChanged(QString)), SLOT(changeContextHelpId(QString)));
|
||||
|
||||
connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(executeExpression()));
|
||||
QHBoxLayout *hbox = new QHBoxLayout(bar);
|
||||
hbox->setMargin(1);
|
||||
hbox->setSpacing(1);
|
||||
hbox->addWidget(m_lineEdit);
|
||||
hbox->addWidget(m_clearButton);
|
||||
layout->addWidget(bar);
|
||||
|
||||
m_textEdit->setReadOnly(true);
|
||||
m_lineEdit->installEventFilter(this);
|
||||
} else {
|
||||
m_textEdit->installEventFilter(this);
|
||||
appendPrompt();
|
||||
}
|
||||
setFontSettings();
|
||||
clear();
|
||||
}
|
||||
|
||||
void ExpressionQueryWidget::changeContextHelpId(const QString &)
|
||||
{
|
||||
emit contextHelpIdChanged(InspectorContext::contextHelpIdForItem(m_lineEdit->text()));
|
||||
}
|
||||
|
||||
void ExpressionQueryWidget::clearTextEditor()
|
||||
{
|
||||
m_textEdit->clear();
|
||||
m_textEdit->appendPlainText(tr("Script Console\n"));
|
||||
}
|
||||
|
||||
void ExpressionQueryWidget::setFontSettings()
|
||||
{
|
||||
const TextEditor::FontSettings &fs = TextEditor::TextEditorSettings::instance()->fontSettings();
|
||||
static QVector<QString> categories;
|
||||
if (categories.isEmpty()) {
|
||||
categories << QLatin1String(TextEditor::Constants::C_NUMBER)
|
||||
<< QLatin1String(TextEditor::Constants::C_STRING)
|
||||
<< QLatin1String(TextEditor::Constants::C_TYPE)
|
||||
<< QLatin1String(TextEditor::Constants::C_KEYWORD)
|
||||
<< QLatin1String(TextEditor::Constants::C_LABEL)
|
||||
<< QLatin1String(TextEditor::Constants::C_COMMENT)
|
||||
<< QLatin1String(TextEditor::Constants::C_VISUAL_WHITESPACE);
|
||||
}
|
||||
|
||||
const QVector<QTextCharFormat> formats = fs.toTextCharFormats(categories);
|
||||
m_highlighter->setFormats(formats);
|
||||
m_highlighter->rehighlight();
|
||||
m_textEdit->setFont(fs.font());
|
||||
if (m_mode == SeparateEntryMode)
|
||||
m_lineEdit->setFont(fs.font());
|
||||
}
|
||||
|
||||
void ExpressionQueryWidget::setEngineDebug(QDeclarativeEngineDebug *client)
|
||||
{
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
void ExpressionQueryWidget::clear()
|
||||
{
|
||||
clearTextEditor();
|
||||
|
||||
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->appendPlainText(m_prompt);
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionQueryWidget::setCurrentObject(const QDeclarativeDebugObjectReference &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->appendPlainText(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(QDeclarativeDebugQuery::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("<%n items>", 0, value.toList().count());
|
||||
} else if (value.isNull()) {
|
||||
result = QLatin1String("<no value>");
|
||||
} else {
|
||||
result = value.toString();
|
||||
}
|
||||
|
||||
if (m_mode == SeparateEntryMode) {
|
||||
m_textEdit->insertPlainText(m_expr + " : ");
|
||||
m_textEdit->insertPlainText(result);
|
||||
} else {
|
||||
m_textEdit->insertPlainText(" => ");
|
||||
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.positionInBlock() <= 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_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);
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,119 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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/qdeclarativedebug_p.h>
|
||||
|
||||
#include <QtGui/qwidget.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QGroupBox;
|
||||
class QPlainTextEdit;
|
||||
class QLineEdit;
|
||||
class QToolButton;
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Utils {
|
||||
class FancyLineEdit;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class IContext;
|
||||
}
|
||||
|
||||
namespace QmlJSEditor {
|
||||
class Highlighter;
|
||||
}
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
class ExpressionQueryWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Mode {
|
||||
SeparateEntryMode,
|
||||
ShellMode
|
||||
};
|
||||
|
||||
ExpressionQueryWidget(Mode mode = SeparateEntryMode, QDeclarativeEngineDebug *client = 0, QWidget *parent = 0);
|
||||
|
||||
void setEngineDebug(QDeclarativeEngineDebug *client);
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void contextHelpIdChanged(const QString &contextHelpId);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
public slots:
|
||||
void setCurrentObject(const QDeclarativeDebugObjectReference &obj);
|
||||
|
||||
private slots:
|
||||
void clearTextEditor();
|
||||
void executeExpression();
|
||||
void showResult();
|
||||
void changeContextHelpId(const QString &text);
|
||||
|
||||
private:
|
||||
void setFontSettings();
|
||||
void appendPrompt();
|
||||
void checkCurrentContext();
|
||||
void showCurrentContext();
|
||||
void updateTitle();
|
||||
|
||||
Mode m_mode;
|
||||
|
||||
QDeclarativeEngineDebug *m_client;
|
||||
QDeclarativeDebugExpressionQuery *m_query;
|
||||
QPlainTextEdit *m_textEdit;
|
||||
Utils::FancyLineEdit *m_lineEdit;
|
||||
|
||||
QToolButton *m_clearButton;
|
||||
QString m_prompt;
|
||||
QString m_expr;
|
||||
QString m_lastExpr;
|
||||
|
||||
QString m_title;
|
||||
QmlJSEditor::Highlighter *m_highlighter;
|
||||
|
||||
QDeclarativeDebugObjectReference m_currObject;
|
||||
QDeclarativeDebugObjectReference m_objectAtLastFocus;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
#include "inspectortreeitems.h"
|
||||
#include "qmlinspector.h"
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
// *************************************************************************
|
||||
// ObjectTreeItem
|
||||
// *************************************************************************
|
||||
|
||||
ObjectTreeItem::ObjectTreeItem(QTreeWidget *widget, int type) :
|
||||
QTreeWidgetItem(widget, type), m_hasValidDebugId(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ObjectTreeItem::ObjectTreeItem(QTreeWidgetItem *parentItem, int type) :
|
||||
QTreeWidgetItem(parentItem, type), m_hasValidDebugId(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QVariant ObjectTreeItem::data (int column, int role) const
|
||||
{
|
||||
if (role == Qt::ForegroundRole)
|
||||
return m_hasValidDebugId ? qApp->palette().color(QPalette::Foreground) : qApp->palette().color(QPalette::Disabled, QPalette::Foreground);
|
||||
|
||||
return QTreeWidgetItem::data(column, role);
|
||||
}
|
||||
|
||||
void ObjectTreeItem::setData (int column, int role, const QVariant & value)
|
||||
{
|
||||
QTreeWidgetItem::setData(column, role, value);
|
||||
}
|
||||
|
||||
void ObjectTreeItem::setHasValidDebugId(bool value)
|
||||
{
|
||||
m_hasValidDebugId = value;
|
||||
}
|
||||
|
||||
// *************************************************************************
|
||||
// PropertiesViewItem
|
||||
// *************************************************************************
|
||||
PropertiesViewItem::PropertiesViewItem(QTreeWidget *widget, int type)
|
||||
: QTreeWidgetItem(widget, type), m_disabled(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PropertiesViewItem::PropertiesViewItem(QTreeWidgetItem *parent, int type)
|
||||
: QTreeWidgetItem(parent, type), m_disabled(false)
|
||||
{
|
||||
}
|
||||
|
||||
QVariant PropertiesViewItem::data (int column, int role) const
|
||||
{
|
||||
if (role == Qt::ForegroundRole) {
|
||||
bool makeDisabledColor = m_disabled;
|
||||
if (column == 1 && !data(0, CanEditRole).toBool())
|
||||
makeDisabledColor = true;
|
||||
return makeDisabledColor ? qApp->palette().color(QPalette::Disabled, QPalette::Foreground) : qApp->palette().color(QPalette::Foreground);
|
||||
}
|
||||
|
||||
|
||||
return QTreeWidgetItem::data(column, role);
|
||||
}
|
||||
|
||||
void PropertiesViewItem::setData (int column, int role, const QVariant & value)
|
||||
{
|
||||
if (role == Qt::EditRole) {
|
||||
if (column == 1)
|
||||
QmlInspector::instance()->executeExpression(property.objectDebugId(), objectIdString(), property.name(), value);
|
||||
}
|
||||
|
||||
QTreeWidgetItem::setData(column, role, value);
|
||||
}
|
||||
|
||||
QString PropertiesViewItem::objectIdString() const
|
||||
{
|
||||
return data(0, ObjectIdStringRole).toString();
|
||||
}
|
||||
void PropertiesViewItem::setWatchingDisabled(bool disabled)
|
||||
{
|
||||
m_disabled = disabled;
|
||||
}
|
||||
|
||||
bool PropertiesViewItem::isWatchingDisabled() const
|
||||
{
|
||||
return m_disabled;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,58 +0,0 @@
|
||||
#ifndef INSPECTORTREEITEMS_H
|
||||
#define INSPECTORTREEITEMS_H
|
||||
|
||||
#include <QTreeWidgetItem>
|
||||
#include <QObject>
|
||||
#include <private/qdeclarativedebug_p.h>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
class ObjectTreeItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
explicit ObjectTreeItem(QTreeWidget *widget, int type = 0);
|
||||
ObjectTreeItem(QTreeWidgetItem *parentItem, int type = 0);
|
||||
QVariant data (int column, int role) const;
|
||||
void setData (int column, int role, const QVariant & value);
|
||||
|
||||
void setHasValidDebugId(bool value);
|
||||
|
||||
|
||||
private:
|
||||
bool m_hasValidDebugId;
|
||||
};
|
||||
|
||||
class PropertiesViewItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
BindingType = QTreeWidgetItem::UserType,
|
||||
OtherType = QTreeWidgetItem::UserType + 1,
|
||||
ClassType = QTreeWidgetItem::UserType + 2
|
||||
};
|
||||
enum DataRoles {
|
||||
CanEditRole = Qt::UserRole,
|
||||
ObjectIdStringRole = Qt::UserRole + 1,
|
||||
ClassDepthRole = Qt::UserRole + 2
|
||||
};
|
||||
|
||||
PropertiesViewItem(QTreeWidget *widget, int type = OtherType);
|
||||
PropertiesViewItem(QTreeWidgetItem *parent, int type = OtherType);
|
||||
QVariant data (int column, int role) const;
|
||||
void setData (int column, int role, const QVariant & value);
|
||||
void setWatchingDisabled(bool disabled);
|
||||
bool isWatchingDisabled() const;
|
||||
QDeclarativeDebugPropertyReference property;
|
||||
|
||||
private:
|
||||
QString objectIdString() const;
|
||||
bool m_disabled;
|
||||
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif // INSPECTORTREEITEMS_H
|
||||
@@ -1,519 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "inspectortreeitems.h"
|
||||
#include "inspectorcontext.h"
|
||||
#include "watchtable.h"
|
||||
#include "qmlinspector.h"
|
||||
#include "propertytypefinder.h"
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <qmljs/qmljsmodelmanagerinterface.h>
|
||||
#include <qmljs/qmljsdocument.h>
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QTreeWidget>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QHeaderView>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
ObjectPropertiesView::ObjectPropertiesView(WatchTableModel *watchTableModel,
|
||||
QDeclarativeEngineDebug *client, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_client(client),
|
||||
m_query(0),
|
||||
m_watch(0), m_clickedItem(0),
|
||||
m_groupByItemType(true), m_showUnwatchableProperties(false),
|
||||
m_watchTableModel(watchTableModel)
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout;
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->setSpacing(0);
|
||||
setLayout(layout);
|
||||
|
||||
m_tree = new QTreeWidget(this);
|
||||
m_tree->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
m_tree->setFrameStyle(QFrame::NoFrame);
|
||||
m_tree->setAlternatingRowColors(true);
|
||||
m_tree->setExpandsOnDoubleClick(false);
|
||||
m_tree->setRootIsDecorated(m_groupByItemType);
|
||||
m_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||
|
||||
m_tree->setHeaderLabels(QStringList()
|
||||
<< tr("Name") << tr("Value") << tr("Type"));
|
||||
QObject::connect(m_tree, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
|
||||
this, SLOT(itemDoubleClicked(QTreeWidgetItem *, int)));
|
||||
connect(m_tree, SIGNAL(itemSelectionChanged()), SLOT(changeItemSelection()));
|
||||
|
||||
m_addWatchAction = new QAction(tr("&Watch expression"), this);
|
||||
m_removeWatchAction = new QAction(tr("&Remove watch"), this);
|
||||
m_toggleUnwatchablePropertiesAction = new QAction(tr("Show &unwatchable properties"), this);
|
||||
|
||||
|
||||
m_toggleGroupByItemTypeAction = new QAction(tr("&Group by item type"), this);
|
||||
m_toggleGroupByItemTypeAction->setCheckable(true);
|
||||
m_toggleGroupByItemTypeAction->setChecked(m_groupByItemType);
|
||||
connect(m_addWatchAction, SIGNAL(triggered()), SLOT(addWatch()));
|
||||
connect(m_removeWatchAction, SIGNAL(triggered()), SLOT(removeWatch()));
|
||||
connect(m_toggleUnwatchablePropertiesAction, SIGNAL(triggered()), SLOT(toggleUnwatchableProperties()));
|
||||
connect(m_toggleGroupByItemTypeAction, SIGNAL(triggered()), SLOT(toggleGroupingByItemType()));
|
||||
|
||||
m_tree->setColumnCount(3);
|
||||
m_tree->header()->setDefaultSectionSize(150);
|
||||
|
||||
layout->addWidget(m_tree);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::readSettings(const InspectorSettings &settings)
|
||||
{
|
||||
if (settings.showUnwatchableProperties() != m_showUnwatchableProperties)
|
||||
toggleUnwatchableProperties();
|
||||
if (settings.groupPropertiesByItemType() != m_groupByItemType)
|
||||
toggleGroupingByItemType();
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::saveSettings(InspectorSettings &settings)
|
||||
{
|
||||
settings.setShowUnwatchableProperties(m_showUnwatchableProperties);
|
||||
settings.setGroupPropertiesByItemType(m_groupByItemType);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::toggleUnwatchableProperties()
|
||||
{
|
||||
m_showUnwatchableProperties = !m_showUnwatchableProperties;
|
||||
setObject(m_object);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::toggleGroupingByItemType()
|
||||
{
|
||||
m_groupByItemType = !m_groupByItemType;
|
||||
m_tree->setRootIsDecorated(m_groupByItemType);
|
||||
m_toggleGroupByItemTypeAction->setChecked(m_groupByItemType);
|
||||
setObject(m_object);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::changeItemSelection()
|
||||
{
|
||||
if (m_tree->selectedItems().isEmpty())
|
||||
return;
|
||||
|
||||
QString item = m_object.className();
|
||||
QString prop = m_tree->selectedItems().first()->text(0);
|
||||
emit contextHelpIdChanged(InspectorContext::contextHelpIdForProperty(item, prop));
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::setEngineDebug(QDeclarativeEngineDebug *client)
|
||||
{
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::clear()
|
||||
{
|
||||
setObject(QDeclarativeDebugObjectReference());
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::reload(const QDeclarativeDebugObjectReference &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(QDeclarativeDebugQuery::State)),
|
||||
this, SLOT(queryFinished()));
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::queryFinished()
|
||||
{
|
||||
if (!m_client || !m_query)
|
||||
return;
|
||||
|
||||
QDeclarativeDebugObjectReference obj = m_query->object();
|
||||
|
||||
QDeclarativeDebugWatch *watch = m_client->addWatch(obj, this);
|
||||
if (watch->state() == QDeclarativeDebugWatch::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 isDisabled)
|
||||
{
|
||||
item->setWatchingDisabled(isDisabled);
|
||||
|
||||
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("<%n items>", 0, 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], isDisabled);
|
||||
}
|
||||
|
||||
if (bindingItem)
|
||||
item->addChild(bindingItem);
|
||||
|
||||
item->setExpanded(false);
|
||||
} else {
|
||||
item->setText(1, (value.isNull() ? QLatin1String("<no value>") : value.toString()));
|
||||
item->setExpanded(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QString ObjectPropertiesView::propertyBaseClass(const QDeclarativeDebugObjectReference &object, const QDeclarativeDebugPropertyReference &property, int &depth)
|
||||
{
|
||||
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
|
||||
QmlJS::ModelManagerInterface *modelManager = pluginManager->getObject<QmlJS::ModelManagerInterface>();
|
||||
QmlJS::Snapshot snapshot = modelManager->snapshot();
|
||||
|
||||
QmlJS::Document::Ptr document = snapshot.document(object.source().url().path());
|
||||
if (document.isNull()) {
|
||||
|
||||
QFile inFile(object.source().url().path());
|
||||
QString contents;
|
||||
if (inFile.open(QIODevice::ReadOnly)) {
|
||||
QTextStream ins(&inFile);
|
||||
contents = ins.readAll();
|
||||
inFile.close();
|
||||
}
|
||||
|
||||
document = QmlJS::Document::create(object.source().url().path());
|
||||
document->setSource(contents);
|
||||
if (!document->parse())
|
||||
return QString();
|
||||
|
||||
snapshot.insert(document);
|
||||
}
|
||||
|
||||
PropertyTypeFinder find(document, snapshot, modelManager->importPaths());
|
||||
QString baseClassName = find(object.source().lineNumber(), object.source().columnNumber(), property.name());
|
||||
|
||||
if (baseClassName.isEmpty()) {
|
||||
if (!object.idString().isEmpty())
|
||||
baseClassName = object.idString();
|
||||
else
|
||||
baseClassName = QString("<%1>").arg(object.className());
|
||||
}
|
||||
|
||||
depth = find.depth();
|
||||
|
||||
return baseClassName;
|
||||
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::setObject(const QDeclarativeDebugObjectReference &object)
|
||||
{
|
||||
m_object = object;
|
||||
m_tree->clear();
|
||||
|
||||
QHash<QString, PropertiesViewItem*> baseClassItems;
|
||||
PropertiesViewItem* currentParentItem = 0;
|
||||
|
||||
QList<QString> insertedPropertyNames;
|
||||
|
||||
QList<QDeclarativeDebugPropertyReference> properties = object.properties();
|
||||
for (int i=0; i<properties.count(); ++i) {
|
||||
const QDeclarativeDebugPropertyReference &p = properties[i];
|
||||
|
||||
// ignore overridden/redefined/shadowed properties; and do special ignore for QGraphicsObject* parent,
|
||||
// which is useless while debugging.
|
||||
if (insertedPropertyNames.contains(p.name())
|
||||
|| (p.name() == "parent" && p.valueTypeName() == "QGraphicsObject*"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
insertedPropertyNames.append(p.name());
|
||||
|
||||
if (m_showUnwatchableProperties || p.hasNotifySignal()) {
|
||||
|
||||
PropertiesViewItem *item = 0;
|
||||
|
||||
if (m_groupByItemType) {
|
||||
int depth = 0;
|
||||
QString baseClassName = propertyBaseClass(object, p, depth);
|
||||
if (!baseClassItems.contains(baseClassName)) {
|
||||
PropertiesViewItem *baseClassItem = new PropertiesViewItem(m_tree, PropertiesViewItem::ClassType);
|
||||
baseClassItem->setData(0, PropertiesViewItem::CanEditRole, false);
|
||||
baseClassItem->setData(0, PropertiesViewItem::ClassDepthRole, depth);
|
||||
baseClassItem->setText(0, baseClassName);
|
||||
|
||||
QFont font = m_tree->font();
|
||||
font.setBold(true);
|
||||
baseClassItem->setFont(0, font);
|
||||
|
||||
baseClassItems.insert(baseClassName, baseClassItem);
|
||||
|
||||
}
|
||||
currentParentItem = baseClassItems.value(baseClassName);
|
||||
item = new PropertiesViewItem(currentParentItem);
|
||||
} else
|
||||
item = new PropertiesViewItem(m_tree);
|
||||
|
||||
item->property = p;
|
||||
item->setData(0, PropertiesViewItem::ObjectIdStringRole, object.idString());
|
||||
item->setText(0, p.name());
|
||||
Qt::ItemFlags itemFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
|
||||
bool canEdit = object.idString().length() && QmlInspector::instance()->canEditProperty(item->property.valueTypeName());
|
||||
item->setData(0, PropertiesViewItem::CanEditRole, canEdit);
|
||||
|
||||
if (canEdit)
|
||||
itemFlags |= Qt::ItemIsEditable;
|
||||
|
||||
item->setFlags(itemFlags);
|
||||
if (m_watchTableModel.data() && m_watchTableModel.data()->isWatchingProperty(p)) {
|
||||
QFont font = m_tree->font();
|
||||
font.setBold(true);
|
||||
item->setFont(0, font);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (m_groupByItemType)
|
||||
sortBaseClassItems();
|
||||
m_tree->expandAll();
|
||||
|
||||
}
|
||||
|
||||
static bool baseClassItemsDepthLessThan(const PropertiesViewItem *item1, const PropertiesViewItem *item2)
|
||||
{
|
||||
int depth1 = item1->data(0, PropertiesViewItem::ClassDepthRole).toInt();
|
||||
int depth2 = item2->data(0, PropertiesViewItem::ClassDepthRole).toInt();
|
||||
|
||||
// reversed order
|
||||
return !(depth1 < depth2);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::sortBaseClassItems()
|
||||
{
|
||||
QList<PropertiesViewItem*> topLevelItems;
|
||||
while(m_tree->topLevelItemCount())
|
||||
topLevelItems.append(static_cast<PropertiesViewItem*>(m_tree->takeTopLevelItem(0)));
|
||||
|
||||
qSort(topLevelItems.begin(), topLevelItems.end(), baseClassItemsDepthLessThan);
|
||||
foreach(PropertiesViewItem *item, topLevelItems)
|
||||
m_tree->addTopLevelItem(item);
|
||||
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::watchCreated(QDeclarativeDebugWatch *watch)
|
||||
{
|
||||
|
||||
if (watch->objectDebugId() == m_object.debugId()
|
||||
&& qobject_cast<QDeclarativeDebugPropertyWatch*>(watch)) {
|
||||
connect(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)), SLOT(watchStateChanged()));
|
||||
setWatched(qobject_cast<QDeclarativeDebugPropertyWatch*>(watch)->name(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::watchStateChanged()
|
||||
{
|
||||
QDeclarativeDebugWatch *watch = qobject_cast<QDeclarativeDebugWatch*>(sender());
|
||||
|
||||
if (watch->objectDebugId() == m_object.debugId()
|
||||
&& qobject_cast<QDeclarativeDebugPropertyWatch*>(watch)
|
||||
&& watch->state() == QDeclarativeDebugWatch::Inactive) {
|
||||
setWatched(qobject_cast<QDeclarativeDebugPropertyWatch*>(watch)->name(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::setWatched(const QString &property, bool watched)
|
||||
{
|
||||
for (int i = 0; i < m_tree->topLevelItemCount(); ++i) {
|
||||
PropertiesViewItem *topLevelItem = static_cast<PropertiesViewItem *>(m_tree->topLevelItem(i));
|
||||
if (m_groupByItemType) {
|
||||
for(int j = 0; j < topLevelItem->childCount(); ++j) {
|
||||
PropertiesViewItem *item = static_cast<PropertiesViewItem*>(topLevelItem->child(j));
|
||||
if (styleWatchedItem(item, property, watched))
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (styleWatchedItem(topLevelItem, property, watched))
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ObjectPropertiesView::styleWatchedItem(PropertiesViewItem *item, const QString &property, bool isWatched) const
|
||||
{
|
||||
if (item->property.name() == property && item->property.hasNotifySignal()) {
|
||||
QFont font = m_tree->font();
|
||||
font.setBold(isWatched);
|
||||
item->setFont(0, font);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ObjectPropertiesView::isWatched(QTreeWidgetItem *item)
|
||||
{
|
||||
return item->font(0).bold();
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::valueChanged(const QByteArray &name, const QVariant &value)
|
||||
{
|
||||
for (int i=0; i<m_tree->topLevelItemCount(); ++i) {
|
||||
PropertiesViewItem *topLevelItem = static_cast<PropertiesViewItem *>(m_tree->topLevelItem(i));
|
||||
|
||||
if (m_groupByItemType) {
|
||||
for(int j = 0; j < topLevelItem->childCount(); ++j) {
|
||||
PropertiesViewItem *item = static_cast<PropertiesViewItem*>(topLevelItem->child(j));
|
||||
if (item->property.name() == name) {
|
||||
setPropertyValue(item, value, !item->property.hasNotifySignal());
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (topLevelItem->property.name() == name) {
|
||||
setPropertyValue(topLevelItem, value, !topLevelItem->property.hasNotifySignal());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::itemDoubleClicked(QTreeWidgetItem *item, int column)
|
||||
{
|
||||
if (item->type() == PropertiesViewItem::ClassType)
|
||||
return;
|
||||
|
||||
if (column == 0)
|
||||
toggleWatch(item);
|
||||
else if (column == 1)
|
||||
m_tree->editItem(item, column);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::addWatch()
|
||||
{
|
||||
toggleWatch(m_clickedItem);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::removeWatch()
|
||||
{
|
||||
toggleWatch(m_clickedItem);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::toggleWatch(QTreeWidgetItem *item)
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
PropertiesViewItem *propItem = static_cast<PropertiesViewItem *>(item);
|
||||
if (!propItem->property.name().isEmpty())
|
||||
emit watchToggleRequested(m_object, propItem->property);
|
||||
}
|
||||
|
||||
void ObjectPropertiesView::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
m_clickedItem = m_tree->itemAt(QPoint(event->pos().x(),
|
||||
event->pos().y() - m_tree->header()->height()));
|
||||
|
||||
if (!m_clickedItem)
|
||||
return;
|
||||
|
||||
PropertiesViewItem *propItem = static_cast<PropertiesViewItem *>(m_clickedItem);
|
||||
|
||||
bool isWatchableItem = propItem->type() != PropertiesViewItem::ClassType &&
|
||||
propItem->type() != PropertiesViewItem::BindingType;
|
||||
|
||||
QMenu menu;
|
||||
if (isWatchableItem) {
|
||||
if (!isWatched(m_clickedItem)) {
|
||||
m_addWatchAction->setText(tr("Watch expression '%1'").arg(propItem->property.name()));
|
||||
m_addWatchAction->setDisabled(propItem->isWatchingDisabled());
|
||||
menu.addAction(m_addWatchAction);
|
||||
} else {
|
||||
menu.addAction(m_removeWatchAction);
|
||||
m_addWatchAction->setDisabled(propItem->isWatchingDisabled());
|
||||
}
|
||||
}
|
||||
menu.addSeparator();
|
||||
|
||||
|
||||
if (m_showUnwatchableProperties)
|
||||
m_toggleUnwatchablePropertiesAction->setText(tr("Hide unwatchable properties"));
|
||||
else
|
||||
m_toggleUnwatchablePropertiesAction->setText(tr("Show unwatchable properties"));
|
||||
|
||||
menu.addAction(m_toggleGroupByItemTypeAction);
|
||||
menu.addAction(m_toggleUnwatchablePropertiesAction);
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,117 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "inspectorsettings.h"
|
||||
|
||||
#include <private/qdeclarativedebug_p.h>
|
||||
#include <QtGui/qwidget.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
class QDeclarativeDebugConnection;
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
class PropertiesViewItem;
|
||||
class WatchTableModel;
|
||||
|
||||
class ObjectPropertiesView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ObjectPropertiesView(WatchTableModel *watchTableModel, QDeclarativeEngineDebug *client = 0, QWidget *parent = 0);
|
||||
void readSettings(const InspectorSettings &settings);
|
||||
void saveSettings(InspectorSettings &settings);
|
||||
|
||||
void setEngineDebug(QDeclarativeEngineDebug *client);
|
||||
void clear();
|
||||
|
||||
signals:
|
||||
void watchToggleRequested(const QDeclarativeDebugObjectReference &, const QDeclarativeDebugPropertyReference &);
|
||||
void contextHelpIdChanged(const QString &contextHelpId);
|
||||
|
||||
public slots:
|
||||
void reload(const QDeclarativeDebugObjectReference &);
|
||||
void watchCreated(QDeclarativeDebugWatch *);
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent *);
|
||||
|
||||
private slots:
|
||||
void changeItemSelection();
|
||||
void queryFinished();
|
||||
void watchStateChanged();
|
||||
void valueChanged(const QByteArray &name, const QVariant &value);
|
||||
void itemDoubleClicked(QTreeWidgetItem *i, int column);
|
||||
|
||||
void addWatch();
|
||||
void removeWatch();
|
||||
void toggleUnwatchableProperties();
|
||||
void toggleGroupingByItemType();
|
||||
|
||||
private:
|
||||
void sortBaseClassItems();
|
||||
bool styleWatchedItem(PropertiesViewItem *item, const QString &property, bool isWatched) const;
|
||||
QString propertyBaseClass(const QDeclarativeDebugObjectReference &object, const QDeclarativeDebugPropertyReference &property, int &depth);
|
||||
void toggleWatch(QTreeWidgetItem *item);
|
||||
void setObject(const QDeclarativeDebugObjectReference &object);
|
||||
bool isWatched(QTreeWidgetItem *item);
|
||||
void setWatched(const QString &property, bool watched);
|
||||
void setPropertyValue(PropertiesViewItem *item, const QVariant &value, bool isDisabled);
|
||||
|
||||
QDeclarativeEngineDebug *m_client;
|
||||
QDeclarativeDebugObjectQuery *m_query;
|
||||
QDeclarativeDebugWatch *m_watch;
|
||||
|
||||
QAction *m_addWatchAction;
|
||||
QAction *m_removeWatchAction;
|
||||
QAction *m_toggleUnwatchablePropertiesAction;
|
||||
QAction *m_toggleGroupByItemTypeAction;
|
||||
QTreeWidgetItem *m_clickedItem;
|
||||
|
||||
bool m_groupByItemType;
|
||||
bool m_showUnwatchableProperties;
|
||||
QTreeWidget *m_tree;
|
||||
QWeakPointer<WatchTableModel> m_watchTableModel;
|
||||
|
||||
QDeclarativeDebugObjectReference m_object;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,311 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 <QDebug>
|
||||
|
||||
#include <private/qdeclarativedebug_p.h>
|
||||
|
||||
#include "objecttree.h"
|
||||
#include "inspectortreeitems.h"
|
||||
#include "inspectorcontext.h"
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
ObjectTree::ObjectTree(QDeclarativeEngineDebug *client, QWidget *parent)
|
||||
: QTreeWidget(parent),
|
||||
m_client(client),
|
||||
m_query(0), m_clickedItem(0), m_showUninspectableItems(false),
|
||||
m_currentObjectDebugId(0), m_showUninspectableOnInitDone(false)
|
||||
{
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setHeaderHidden(true);
|
||||
setExpandsOnDoubleClick(false);
|
||||
|
||||
m_addWatchAction = new QAction(tr("Add watch expression..."), this);
|
||||
m_toggleUninspectableItemsAction = new QAction(tr("Show uninspectable items"), this);
|
||||
m_toggleUninspectableItemsAction->setCheckable(true);
|
||||
m_goToFileAction = new QAction(tr("Go to file"), this);
|
||||
connect(m_toggleUninspectableItemsAction, SIGNAL(triggered()), SLOT(toggleUninspectableItems()));
|
||||
connect(m_addWatchAction, SIGNAL(triggered()), SLOT(addWatch()));
|
||||
connect(m_goToFileAction, SIGNAL(triggered()), SLOT(goToFile()));
|
||||
|
||||
connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)),
|
||||
SLOT(currentItemChanged(QTreeWidgetItem *)));
|
||||
connect(this, SIGNAL(itemActivated(QTreeWidgetItem *, int)),
|
||||
SLOT(activated(QTreeWidgetItem *)));
|
||||
connect(this, SIGNAL(itemSelectionChanged()), SLOT(selectionChanged()));
|
||||
}
|
||||
|
||||
void ObjectTree::readSettings(const InspectorSettings &settings)
|
||||
{
|
||||
if (settings.showUninspectableItems() != m_showUninspectableItems)
|
||||
toggleUninspectableItems();
|
||||
}
|
||||
void ObjectTree::saveSettings(InspectorSettings &settings)
|
||||
{
|
||||
settings.setShowUninspectableItems(m_showUninspectableItems);
|
||||
}
|
||||
|
||||
void ObjectTree::setEngineDebug(QDeclarativeEngineDebug *client)
|
||||
{
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
void ObjectTree::toggleUninspectableItems()
|
||||
{
|
||||
m_showUninspectableItems = !m_showUninspectableItems;
|
||||
m_toggleUninspectableItemsAction->setChecked(m_showUninspectableItems);
|
||||
reload(m_currentObjectDebugId);
|
||||
}
|
||||
|
||||
void ObjectTree::selectionChanged()
|
||||
{
|
||||
if (selectedItems().isEmpty())
|
||||
return;
|
||||
|
||||
QTreeWidgetItem *item = selectedItems().first();
|
||||
if (item)
|
||||
emit contextHelpIdChanged(InspectorContext::contextHelpIdForItem(item->text(0)));
|
||||
}
|
||||
|
||||
void ObjectTree::reload(int objectDebugId)
|
||||
{
|
||||
if (!m_client)
|
||||
return;
|
||||
|
||||
if (m_query) {
|
||||
delete m_query;
|
||||
m_query = 0;
|
||||
}
|
||||
m_currentObjectDebugId = objectDebugId;
|
||||
|
||||
m_query = m_client->queryObjectRecursive(QDeclarativeDebugObjectReference(objectDebugId), this);
|
||||
if (!m_query->isWaiting())
|
||||
objectFetched();
|
||||
else
|
||||
QObject::connect(m_query, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
|
||||
this, SLOT(objectFetched(QDeclarativeDebugQuery::State)));
|
||||
}
|
||||
|
||||
void ObjectTree::setCurrentObject(int debugId)
|
||||
{
|
||||
QTreeWidgetItem *item = findItemByObjectId(debugId);
|
||||
if (item) {
|
||||
setCurrentItem(item);
|
||||
scrollToItem(item);
|
||||
item->setExpanded(true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ObjectTree::objectFetched(QDeclarativeDebugQuery::State state)
|
||||
{
|
||||
if (state == QDeclarativeDebugQuery::Completed) {
|
||||
//dump(m_query->object(), 0);
|
||||
buildTree(m_query->object(), 0);
|
||||
setCurrentItem(topLevelItem(0));
|
||||
|
||||
delete m_query;
|
||||
m_query = 0;
|
||||
|
||||
// this ugly hack is needed if user wants to see internal structs
|
||||
// on startup - debugger does not load them until towards the end,
|
||||
// so essentially loading twice gives us the full list as everything
|
||||
// is already loaded.
|
||||
if (m_showUninspectableItems && !m_showUninspectableOnInitDone) {
|
||||
m_showUninspectableOnInitDone = true;
|
||||
reload(m_currentObjectDebugId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectTree::currentItemChanged(QTreeWidgetItem *item)
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
|
||||
if (obj.debugId() >= 0)
|
||||
emit currentObjectChanged(obj);
|
||||
}
|
||||
|
||||
void ObjectTree::activated(QTreeWidgetItem *item)
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
QDeclarativeDebugObjectReference obj = item->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
|
||||
if (obj.debugId() >= 0)
|
||||
emit activated(obj);
|
||||
}
|
||||
|
||||
void ObjectTree::cleanup()
|
||||
{
|
||||
m_showUninspectableOnInitDone = false;
|
||||
clear();
|
||||
}
|
||||
|
||||
void ObjectTree::buildTree(const QDeclarativeDebugObjectReference &obj, QTreeWidgetItem *parent)
|
||||
{
|
||||
if (!parent)
|
||||
clear();
|
||||
|
||||
if (obj.contextDebugId() < 0 && !m_showUninspectableItems)
|
||||
return;
|
||||
|
||||
ObjectTreeItem *item = parent ? new ObjectTreeItem(parent) : new ObjectTreeItem(this);
|
||||
if (obj.idString().isEmpty())
|
||||
item->setText(0, QString("<%1>").arg(obj.className()));
|
||||
else
|
||||
item->setText(0, obj.idString());
|
||||
item->setData(0, Qt::UserRole, qVariantFromValue(obj));
|
||||
|
||||
if (parent && obj.contextDebugId() >= 0
|
||||
&& obj.contextDebugId() != parent->data(0, Qt::UserRole
|
||||
).value<QDeclarativeDebugObjectReference>().contextDebugId())
|
||||
{
|
||||
|
||||
QDeclarativeDebugFileReference source = obj.source();
|
||||
if (!source.url().isEmpty()) {
|
||||
QString toolTipString = QLatin1String("URL: ") + source.url().toString();
|
||||
item->setToolTip(0, toolTipString);
|
||||
}
|
||||
|
||||
} else {
|
||||
item->setExpanded(true);
|
||||
}
|
||||
|
||||
if (obj.contextDebugId() < 0)
|
||||
item->setHasValidDebugId(false);
|
||||
|
||||
for (int ii = 0; ii < obj.children().count(); ++ii)
|
||||
buildTree(obj.children().at(ii), item);
|
||||
}
|
||||
|
||||
void ObjectTree::dump(const QDeclarativeDebugContextReference &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 QDeclarativeDebugObjectReference &obj, int ind)
|
||||
{
|
||||
QByteArray indent(ind * 4, ' ');
|
||||
qWarning().nospace() << indent.constData() << qPrintable(obj.className())
|
||||
<< " " << qPrintable(obj.idString()) << " "
|
||||
<< 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<QDeclarativeDebugObjectReference>().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::addWatch()
|
||||
{
|
||||
QDeclarativeDebugObjectReference obj =
|
||||
currentItem()->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
void ObjectTree::goToFile()
|
||||
{
|
||||
QDeclarativeDebugObjectReference obj =
|
||||
currentItem()->data(0, Qt::UserRole).value<QDeclarativeDebugObjectReference>();
|
||||
|
||||
if (obj.debugId() >= 0)
|
||||
emit activated(obj);
|
||||
}
|
||||
|
||||
void ObjectTree::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
|
||||
m_clickedItem = itemAt(QPoint(event->pos().x(),
|
||||
event->pos().y() ));
|
||||
if (!m_clickedItem)
|
||||
return;
|
||||
|
||||
QMenu menu;
|
||||
menu.addAction(m_addWatchAction);
|
||||
menu.addAction(m_goToFileAction);
|
||||
if (m_currentObjectDebugId) {
|
||||
menu.addSeparator();
|
||||
menu.addAction(m_toggleUninspectableItemsAction);
|
||||
}
|
||||
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,107 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "inspectorsettings.h"
|
||||
#include <private/qdeclarativedebug_p.h>
|
||||
#include <QtGui/qtreewidget.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTreeWidgetItem;
|
||||
|
||||
class QDeclarativeEngineDebug;
|
||||
class QDeclarativeDebugObjectReference;
|
||||
class QDeclarativeDebugObjectQuery;
|
||||
class QDeclarativeDebugContextReference;
|
||||
class QDeclarativeDebugConnection;
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
class ObjectTree : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ObjectTree(QDeclarativeEngineDebug *client = 0, QWidget *parent = 0);
|
||||
|
||||
void setEngineDebug(QDeclarativeEngineDebug *client);
|
||||
void readSettings(const InspectorSettings &settings);
|
||||
void saveSettings(InspectorSettings &settings);
|
||||
|
||||
signals:
|
||||
void currentObjectChanged(const QDeclarativeDebugObjectReference &);
|
||||
void activated(const QDeclarativeDebugObjectReference &);
|
||||
void expressionWatchRequested(const QDeclarativeDebugObjectReference &, const QString &);
|
||||
void contextHelpIdChanged(const QString &contextHelpId);
|
||||
|
||||
public slots:
|
||||
void cleanup();
|
||||
void reload(int objectDebugId); // set the root object
|
||||
void setCurrentObject(int debugId); // select an object in the tree
|
||||
|
||||
protected:
|
||||
virtual void contextMenuEvent(QContextMenuEvent *);
|
||||
|
||||
private slots:
|
||||
void addWatch();
|
||||
void toggleUninspectableItems();
|
||||
void objectFetched(QDeclarativeDebugQuery::State = QDeclarativeDebugQuery::Completed);
|
||||
void currentItemChanged(QTreeWidgetItem *);
|
||||
void activated(QTreeWidgetItem *);
|
||||
void selectionChanged();
|
||||
void goToFile();
|
||||
|
||||
private:
|
||||
QTreeWidgetItem *findItemByObjectId(int debugId) const;
|
||||
QTreeWidgetItem *findItem(QTreeWidgetItem *item, int debugId) const;
|
||||
void dump(const QDeclarativeDebugContextReference &, int);
|
||||
void dump(const QDeclarativeDebugObjectReference &, int);
|
||||
void buildTree(const QDeclarativeDebugObjectReference &, QTreeWidgetItem *parent);
|
||||
|
||||
QDeclarativeEngineDebug *m_client;
|
||||
QDeclarativeDebugObjectQuery *m_query;
|
||||
|
||||
QTreeWidgetItem *m_clickedItem;
|
||||
QAction *m_toggleUninspectableItemsAction;
|
||||
QAction *m_addWatchAction;
|
||||
QAction *m_goToFileAction;
|
||||
bool m_showUninspectableItems;
|
||||
int m_currentObjectDebugId;
|
||||
bool m_showUninspectableOnInitDone;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif
|
||||
@@ -1,83 +0,0 @@
|
||||
#include "propertytypefinder.h"
|
||||
|
||||
#include <qmljs/parser/qmljsast_p.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace QmlJS;
|
||||
using namespace QmlJS::AST;
|
||||
using namespace QmlJS::Interpreter;
|
||||
using namespace Qml::Internal;
|
||||
|
||||
PropertyTypeFinder::PropertyTypeFinder(QmlJS::Document::Ptr doc, QmlJS::Snapshot snapshot, const QStringList &importPaths)
|
||||
: m_doc(doc)
|
||||
, m_snapshot(snapshot)
|
||||
, m_engine()
|
||||
, m_context(&m_engine)
|
||||
, m_link(&m_context, doc, snapshot, importPaths)
|
||||
, m_scopeBuilder(doc, &m_context)
|
||||
, m_depth(0)
|
||||
{
|
||||
}
|
||||
|
||||
QString PropertyTypeFinder::operator()(int objectLine, int objectColumn, const QString &propertyName)
|
||||
{
|
||||
m_objectLine = objectLine;
|
||||
m_objectColumn = objectColumn;
|
||||
m_propertyName = propertyName;
|
||||
m_definingClass.clear();
|
||||
|
||||
Node::accept(m_doc->ast(), this);
|
||||
return m_definingClass;
|
||||
}
|
||||
|
||||
int PropertyTypeFinder::depth() const
|
||||
{
|
||||
return m_depth;
|
||||
}
|
||||
|
||||
bool PropertyTypeFinder::visit(QmlJS::AST::UiObjectBinding *ast)
|
||||
{
|
||||
m_scopeBuilder.push(ast);
|
||||
|
||||
return check(ast->qualifiedTypeNameId);
|
||||
}
|
||||
|
||||
bool PropertyTypeFinder::visit(QmlJS::AST::UiObjectDefinition *ast)
|
||||
{
|
||||
m_scopeBuilder.push(ast);
|
||||
|
||||
return check(ast->qualifiedTypeNameId);
|
||||
}
|
||||
|
||||
void PropertyTypeFinder::endVisit(QmlJS::AST::UiObjectBinding * /*ast*/)
|
||||
{
|
||||
m_scopeBuilder.pop();
|
||||
}
|
||||
|
||||
void PropertyTypeFinder::endVisit(QmlJS::AST::UiObjectDefinition * /*ast*/)
|
||||
{
|
||||
m_scopeBuilder.pop();
|
||||
}
|
||||
|
||||
bool PropertyTypeFinder::check(QmlJS::AST::UiQualifiedId *qId)
|
||||
{
|
||||
if (!qId)
|
||||
return true;
|
||||
|
||||
if (qId->identifierToken.startLine == m_objectLine
|
||||
&& qId->identifierToken.startColumn == m_objectColumn) {
|
||||
// got it!
|
||||
for (const ObjectValue *iter = m_context.scopeChain().qmlScopeObjects.last(); iter; iter = iter->prototype(&m_context)) {
|
||||
|
||||
if (iter->lookupMember(m_propertyName, &m_context, false)) {
|
||||
m_definingClass = iter->className();
|
||||
return true;
|
||||
}
|
||||
++m_depth;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#ifndef PROPERTYTYPEFINDER_H
|
||||
#define PROPERTYTYPEFINDER_H
|
||||
|
||||
#include <qmljs/qmljsdocument.h>
|
||||
#include <qmljs/parser/qmljsastvisitor_p.h>
|
||||
#include <qmljs/qmljsinterpreter.h>
|
||||
#include <qmljs/qmljslink.h>
|
||||
#include <qmljs/qmljsscopebuilder.h>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
class PropertyTypeFinder: protected QmlJS::AST::Visitor
|
||||
{
|
||||
public:
|
||||
PropertyTypeFinder(QmlJS::Document::Ptr doc, QmlJS::Snapshot snapshot, const QStringList &importPaths);
|
||||
|
||||
QString operator()(int objectLine, int objectColumn, const QString &propertyName);
|
||||
int depth() const;
|
||||
protected:
|
||||
using QmlJS::AST::Visitor::visit;
|
||||
using QmlJS::AST::Visitor::endVisit;
|
||||
|
||||
virtual bool visit(QmlJS::AST::UiObjectBinding *ast);
|
||||
virtual bool visit(QmlJS::AST::UiObjectDefinition *ast);
|
||||
|
||||
virtual void endVisit(QmlJS::AST::UiObjectBinding *ast);
|
||||
virtual void endVisit(QmlJS::AST::UiObjectDefinition *ast);
|
||||
|
||||
private:
|
||||
bool check(QmlJS::AST::UiQualifiedId *qId);
|
||||
|
||||
private:
|
||||
QmlJS::Document::Ptr m_doc;
|
||||
QmlJS::Snapshot m_snapshot;
|
||||
QmlJS::Interpreter::Engine m_engine;
|
||||
QmlJS::Interpreter::Context m_context;
|
||||
QmlJS::Link m_link;
|
||||
QmlJS::ScopeBuilder m_scopeBuilder;
|
||||
|
||||
quint32 m_objectLine;
|
||||
quint32 m_objectColumn;
|
||||
QString m_definingClass;
|
||||
QString m_propertyName;
|
||||
quint8 m_depth;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Qml
|
||||
|
||||
#endif // PROPERTYTYPEFINDER_H
|
||||
@@ -1,19 +0,0 @@
|
||||
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 \
|
||||
components/inspectortreeitems.h \
|
||||
components/propertytypefinder.h
|
||||
|
||||
SOURCES += $$PWD/canvasframerate.cpp \
|
||||
$$PWD/watchtable.cpp \
|
||||
$$PWD/objecttree.cpp \
|
||||
$$PWD/objectpropertiesview.cpp \
|
||||
$$PWD/expressionquerywidget.cpp \
|
||||
components/inspectortreeitems.cpp \
|
||||
components/propertytypefinder.cpp
|
||||
@@ -1,7 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>engines.qml</file>
|
||||
<file>engine.png</file>
|
||||
<file>refresh.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 6.0 KiB |
@@ -1,400 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "qmlinspector.h"
|
||||
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QApplication>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <private/qdeclarativedebug_p.h>
|
||||
#include <private/qdeclarativemetatype_p.h>
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
const int C_NAME = 0;
|
||||
const int C_VALUE = 1;
|
||||
const int C_COLUMNS = 2;
|
||||
|
||||
WatchTableModel::WatchTableModel(QDeclarativeEngineDebug *client, QObject *parent)
|
||||
: QAbstractTableModel(parent),
|
||||
m_client(client)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
WatchTableModel::~WatchTableModel()
|
||||
{
|
||||
for (int i=0; i < m_entities.count(); ++i)
|
||||
delete m_entities[i].watch;
|
||||
}
|
||||
|
||||
void WatchTableModel::setEngineDebug(QDeclarativeEngineDebug *client)
|
||||
{
|
||||
m_client = client;
|
||||
}
|
||||
|
||||
void WatchTableModel::addWatch(const QDeclarativeDebugObjectReference &object, const QString &propertyType,
|
||||
QDeclarativeDebugWatch *watch, const QString &title)
|
||||
{
|
||||
QString property;
|
||||
if (qobject_cast<QDeclarativeDebugPropertyWatch *>(watch))
|
||||
property = qobject_cast<QDeclarativeDebugPropertyWatch *>(watch)->name();
|
||||
|
||||
connect(watch, SIGNAL(valueChanged(QByteArray,QVariant)),
|
||||
SLOT(watchedValueChanged(QByteArray,QVariant)));
|
||||
|
||||
connect(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)), SLOT(watchStateChanged()));
|
||||
|
||||
int row = rowCount(QModelIndex());
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
||||
WatchedEntity e;
|
||||
e.title = title;
|
||||
e.property = property;
|
||||
e.watch = watch;
|
||||
e.objectId = object.idString();
|
||||
e.objectDebugId = object.debugId();
|
||||
e.objectPropertyType = propertyType;
|
||||
|
||||
m_entities.append(e);
|
||||
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
void WatchTableModel::removeWatch(QDeclarativeDebugWatch *watch)
|
||||
{
|
||||
int column = rowForWatch(watch);
|
||||
if (column == -1)
|
||||
return;
|
||||
|
||||
m_entities.takeAt(column);
|
||||
|
||||
reset();
|
||||
emit watchRemoved();
|
||||
}
|
||||
|
||||
void WatchTableModel::updateWatch(QDeclarativeDebugWatch *watch, const QVariant &value)
|
||||
{
|
||||
int row = rowForWatch(watch);
|
||||
if (row == -1)
|
||||
return;
|
||||
|
||||
m_entities[row].value = value;
|
||||
const QModelIndex &idx = index(row, C_VALUE);
|
||||
emit dataChanged(idx, idx);
|
||||
|
||||
}
|
||||
|
||||
QDeclarativeDebugWatch *WatchTableModel::findWatch(int row) const
|
||||
{
|
||||
if (row < m_entities.count())
|
||||
return m_entities.at(row).watch;
|
||||
return 0;
|
||||
}
|
||||
|
||||
QDeclarativeDebugWatch *WatchTableModel::findWatch(int objectDebugId, const QString &property) const
|
||||
{
|
||||
for (int i=0; i < m_entities.count(); ++i) {
|
||||
if (m_entities[i].watch->objectDebugId() == objectDebugId
|
||||
&& m_entities[i].property == property) {
|
||||
return m_entities[i].watch;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WatchTableModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return m_entities.count();
|
||||
}
|
||||
|
||||
int WatchTableModel::columnCount(const QModelIndex &) const
|
||||
{
|
||||
return C_COLUMNS;
|
||||
}
|
||||
|
||||
QVariant WatchTableModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
{
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||
if (section == C_NAME)
|
||||
return tr("Name");
|
||||
else if (section == C_VALUE)
|
||||
return tr("Value");
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant WatchTableModel::data(const QModelIndex &idx, int role) const
|
||||
{
|
||||
if (idx.column() == C_NAME) {
|
||||
if (role == Qt::DisplayRole)
|
||||
return QVariant(m_entities.at(idx.row()).title);
|
||||
} else if (idx.column() == C_VALUE) {
|
||||
|
||||
if (role == Qt::DisplayRole || role == Qt::EditRole) {
|
||||
return QVariant(m_entities.at(idx.row()).value);
|
||||
} else if (role == CanEditRole || role == Qt::ForegroundRole) {
|
||||
const WatchedEntity &entity = m_entities.at(idx.row());
|
||||
bool canEdit = entity.objectId.length() > 0 && QmlInspector::instance()->canEditProperty(entity.objectPropertyType);
|
||||
|
||||
if (role == Qt::ForegroundRole)
|
||||
return canEdit ? qApp->palette().color(QPalette::Foreground) : qApp->palette().color(QPalette::Disabled, QPalette::Foreground);
|
||||
|
||||
return canEdit;
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
bool WatchTableModel::isWatchingProperty(const QDeclarativeDebugPropertyReference &prop) const
|
||||
{
|
||||
foreach (const WatchedEntity &entity, m_entities) {
|
||||
if (entity.objectDebugId == prop.objectDebugId() && entity.property == prop.name())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool WatchTableModel::setData ( const QModelIndex & index, const QVariant & value, int role)
|
||||
{
|
||||
Q_UNUSED(index);
|
||||
Q_UNUSED(value);
|
||||
if (role == Qt::EditRole) {
|
||||
|
||||
if (index.row() >= 0 && index.row() < m_entities.length()) {
|
||||
WatchedEntity &entity = m_entities[index.row()];
|
||||
|
||||
QmlInspector::instance()->executeExpression(entity.objectDebugId, entity.objectId, entity.property, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Qt::ItemFlags WatchTableModel::flags ( const QModelIndex & index ) const
|
||||
{
|
||||
Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
|
||||
if (index.column() == C_VALUE && index.data(CanEditRole).toBool())
|
||||
{
|
||||
flags |= Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void WatchTableModel::watchStateChanged()
|
||||
{
|
||||
QDeclarativeDebugWatch *watch = qobject_cast<QDeclarativeDebugWatch*>(sender());
|
||||
|
||||
if (watch && watch->state() == QDeclarativeDebugWatch::Inactive) {
|
||||
removeWatch(watch);
|
||||
watch->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
int WatchTableModel::rowForWatch(QDeclarativeDebugWatch *watch) const
|
||||
{
|
||||
for (int i=0; i < m_entities.count(); ++i) {
|
||||
if (m_entities.at(i).watch == watch)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void WatchTableModel::togglePropertyWatch(const QDeclarativeDebugObjectReference &object, const QDeclarativeDebugPropertyReference &property)
|
||||
{
|
||||
if (!m_client || !property.hasNotifySignal())
|
||||
return;
|
||||
|
||||
QDeclarativeDebugWatch *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() == QDeclarativeDebugWatch::Dead) {
|
||||
delete watch;
|
||||
watch = 0;
|
||||
} else {
|
||||
|
||||
QString desc = (object.idString().isEmpty() ? QLatin1String("<") + object.className() + QLatin1String(">") : object.idString())
|
||||
+ QLatin1String(".") + property.name();
|
||||
|
||||
addWatch(object, property.valueTypeName(), watch, desc);
|
||||
emit watchCreated(watch);
|
||||
}
|
||||
}
|
||||
|
||||
void WatchTableModel::watchedValueChanged(const QByteArray &propertyName, const QVariant &value)
|
||||
{
|
||||
Q_UNUSED(propertyName);
|
||||
QDeclarativeDebugWatch *watch = qobject_cast<QDeclarativeDebugWatch*>(sender());
|
||||
if (watch)
|
||||
updateWatch(watch, value);
|
||||
}
|
||||
|
||||
void WatchTableModel::expressionWatchRequested(const QDeclarativeDebugObjectReference &obj, const QString &expr)
|
||||
{
|
||||
if (!m_client)
|
||||
return;
|
||||
|
||||
QDeclarativeDebugWatch *watch = m_client->addWatch(obj, expr, this);
|
||||
|
||||
if (watch->state() == QDeclarativeDebugWatch::Dead) {
|
||||
delete watch;
|
||||
watch = 0;
|
||||
} else {
|
||||
addWatch(obj, "<expression>", watch, expr);
|
||||
emit watchCreated(watch);
|
||||
}
|
||||
}
|
||||
|
||||
void WatchTableModel::removeWatchAt(int row)
|
||||
{
|
||||
if (!m_client)
|
||||
return;
|
||||
|
||||
QDeclarativeDebugWatch *watch = findWatch(row);
|
||||
if (watch) {
|
||||
m_client->removeWatch(watch);
|
||||
delete watch;
|
||||
watch = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void WatchTableModel::removeAllWatches()
|
||||
{
|
||||
for (int i=0; i<m_entities.count(); ++i) {
|
||||
if (m_client)
|
||||
m_client->removeWatch(m_entities[i].watch);
|
||||
else
|
||||
delete m_entities[i].watch;
|
||||
}
|
||||
m_entities.clear();
|
||||
reset();
|
||||
emit watchRemoved();
|
||||
}
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
WatchTableHeaderView::WatchTableHeaderView(WatchTableModel *model, QWidget *parent)
|
||||
: QHeaderView(Qt::Horizontal, parent),
|
||||
m_model(model)
|
||||
{
|
||||
setClickable(true);
|
||||
setResizeMode(QHeaderView::ResizeToContents);
|
||||
setMinimumSectionSize(100);
|
||||
setStretchLastSection(true);
|
||||
}
|
||||
|
||||
//----------------------------------------------
|
||||
|
||||
WatchTableView::WatchTableView(WatchTableModel *model, QWidget *parent)
|
||||
: QTableView(parent),
|
||||
m_model(model)
|
||||
{
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
setAlternatingRowColors(true);
|
||||
setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
setSelectionBehavior(QAbstractItemView::SelectItems);
|
||||
setShowGrid(false);
|
||||
setVerticalHeader(0);
|
||||
|
||||
setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
|
||||
connect(model, SIGNAL(watchRemoved()), SLOT(watchRemoved()));
|
||||
connect(model, SIGNAL(watchCreated(QDeclarativeDebugWatch*)), SLOT(watchCreated(QDeclarativeDebugWatch*)));
|
||||
connect(this, SIGNAL(activated(QModelIndex)), SLOT(indexActivated(QModelIndex)));
|
||||
}
|
||||
|
||||
void WatchTableView::indexActivated(const QModelIndex &index)
|
||||
{
|
||||
QDeclarativeDebugWatch *watch = m_model->findWatch(index.column());
|
||||
if (watch)
|
||||
emit objectActivated(watch->objectDebugId());
|
||||
}
|
||||
|
||||
void WatchTableView::watchCreated(QDeclarativeDebugWatch *watch)
|
||||
{
|
||||
int row = m_model->rowForWatch(watch);
|
||||
resizeRowToContents(row);
|
||||
resizeColumnToContents(C_NAME);
|
||||
|
||||
if (!isVisible())
|
||||
show();
|
||||
}
|
||||
|
||||
void WatchTableView::mousePressEvent(QMouseEvent *me)
|
||||
{
|
||||
QTableView::mousePressEvent(me);
|
||||
|
||||
if (me->button() == Qt::RightButton && me->type() == QEvent::MouseButtonPress) {
|
||||
int row = rowAt(me->pos().y());
|
||||
if (row >= 0) {
|
||||
QAction action(tr("Stop watching"), 0);
|
||||
QList<QAction *> actions;
|
||||
actions << &action;
|
||||
if (QMenu::exec(actions, me->globalPos())) {
|
||||
m_model->removeWatchAt(row);
|
||||
hideIfEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WatchTableView::hideIfEmpty()
|
||||
{
|
||||
if (m_model->rowCount() == 0) {
|
||||
hide();
|
||||
} else if (!isVisible())
|
||||
show();
|
||||
}
|
||||
|
||||
void WatchTableView::watchRemoved()
|
||||
{
|
||||
hideIfEmpty();
|
||||
}
|
||||
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,157 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 QDeclarativeDebugWatch;
|
||||
class QDeclarativeEngineDebug;
|
||||
class QDeclarativeDebugConnection;
|
||||
class QDeclarativeDebugPropertyReference;
|
||||
class QDeclarativeDebugObjectReference;
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
class WatchTableModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WatchTableModel(QDeclarativeEngineDebug *client = 0, QObject *parent = 0);
|
||||
~WatchTableModel();
|
||||
|
||||
void setEngineDebug(QDeclarativeEngineDebug *client);
|
||||
|
||||
QDeclarativeDebugWatch *findWatch(int column) const;
|
||||
int rowForWatch(QDeclarativeDebugWatch *watch) const;
|
||||
|
||||
void removeWatchAt(int row);
|
||||
void removeAllWatches();
|
||||
|
||||
Qt::ItemFlags flags (const QModelIndex & index) const;
|
||||
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;
|
||||
bool setData (const QModelIndex & index, const QVariant & value, int role = Qt::EditRole);
|
||||
|
||||
bool isWatchingProperty(const QDeclarativeDebugPropertyReference &prop) const;
|
||||
|
||||
signals:
|
||||
void watchCreated(QDeclarativeDebugWatch *watch);
|
||||
void watchRemoved();
|
||||
|
||||
public slots:
|
||||
void togglePropertyWatch(const QDeclarativeDebugObjectReference &obj, const QDeclarativeDebugPropertyReference &prop);
|
||||
void expressionWatchRequested(const QDeclarativeDebugObjectReference &, const QString &);
|
||||
|
||||
private slots:
|
||||
void watchStateChanged();
|
||||
void watchedValueChanged(const QByteArray &propertyName, const QVariant &value);
|
||||
|
||||
private:
|
||||
void addWatch(const QDeclarativeDebugObjectReference &object, const QString &propertyType,
|
||||
QDeclarativeDebugWatch *watch, const QString &title);
|
||||
|
||||
void removeWatch(QDeclarativeDebugWatch *watch);
|
||||
void updateWatch(QDeclarativeDebugWatch *watch, const QVariant &value);
|
||||
|
||||
QDeclarativeDebugWatch *findWatch(int objectDebugId, const QString &property) const;
|
||||
|
||||
struct WatchedEntity
|
||||
{
|
||||
int objectDebugId;
|
||||
QString objectId;
|
||||
QString title;
|
||||
QString property;
|
||||
QString objectPropertyType;
|
||||
QPointer<QDeclarativeDebugWatch> watch;
|
||||
QVariant value;
|
||||
};
|
||||
|
||||
enum DataRoles {
|
||||
CanEditRole = Qt::UserRole + 1
|
||||
|
||||
};
|
||||
|
||||
QDeclarativeEngineDebug *m_client;
|
||||
QList<WatchedEntity> m_entities;
|
||||
};
|
||||
|
||||
|
||||
class WatchTableHeaderView : public QHeaderView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WatchTableHeaderView(WatchTableModel *model, QWidget *parent = 0);
|
||||
|
||||
private:
|
||||
WatchTableModel *m_model;
|
||||
};
|
||||
|
||||
|
||||
class WatchTableView : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WatchTableView(WatchTableModel *model, QWidget *parent = 0);
|
||||
|
||||
signals:
|
||||
void objectActivated(int objectDebugId);
|
||||
void contextHelpIdChanged(const QString &contextHelpId);
|
||||
|
||||
protected:
|
||||
void mousePressEvent(QMouseEvent *me);
|
||||
|
||||
private slots:
|
||||
void indexActivated(const QModelIndex &index);
|
||||
void watchCreated(QDeclarativeDebugWatch *watch);
|
||||
void watchRemoved();
|
||||
private:
|
||||
void hideIfEmpty();
|
||||
private:
|
||||
WatchTableModel *m_model;
|
||||
};
|
||||
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif // WATCHTABLEMODEL_H
|
||||
@@ -30,27 +30,22 @@
|
||||
#include "inspectorcontext.h"
|
||||
#include "qmlinspectorconstants.h"
|
||||
|
||||
#include "components/objectpropertiesview.h"
|
||||
#include "components/objecttree.h"
|
||||
#include <coreplugin/icore.h>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
using namespace QmlInspector::Internal;
|
||||
using namespace QmlInspector::Constants;
|
||||
|
||||
InspectorContext::InspectorContext(QWidget *widget)
|
||||
: IContext(widget),
|
||||
m_widget(widget),
|
||||
m_context(Constants::C_INSPECTOR)
|
||||
m_context(C_INSPECTOR)
|
||||
{
|
||||
}
|
||||
|
||||
InspectorContext::~InspectorContext()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Core::Context InspectorContext::context() const
|
||||
@@ -85,6 +80,3 @@ QString InspectorContext::contextHelpIdForItem(const QString &itemName)
|
||||
return QString("QML.").append(itemName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,28 +37,25 @@ QT_BEGIN_NAMESPACE
|
||||
class QWidget;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Qml {
|
||||
namespace QmlInspector {
|
||||
namespace Internal {
|
||||
|
||||
class ObjectPropertiesView;
|
||||
class ObjectTree;
|
||||
class DesignModeWidget;
|
||||
|
||||
/**
|
||||
* Bauhaus Design mode context object
|
||||
*/
|
||||
class InspectorContext : public Core::IContext
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InspectorContext(QWidget *widget);
|
||||
~InspectorContext();
|
||||
virtual ~InspectorContext();
|
||||
|
||||
Core::Context context() const;
|
||||
QWidget *widget();
|
||||
|
||||
QString contextHelpId() const;
|
||||
// Core::IContext interface
|
||||
virtual Core::Context context() const;
|
||||
virtual QWidget *widget();
|
||||
virtual QString contextHelpId() const;
|
||||
|
||||
static QString contextHelpIdForProperty(const QString &itemName, const QString &propName);
|
||||
static QString contextHelpIdForItem(const QString &itemName);
|
||||
@@ -67,13 +64,12 @@ public slots:
|
||||
void setContextHelpId(const QString &helpId);
|
||||
|
||||
private:
|
||||
Core::Context m_context;
|
||||
QWidget *m_widget;
|
||||
Core::Context m_context;
|
||||
QString m_contextHelpId;
|
||||
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
} // QmlInspector
|
||||
|
||||
#endif // DESIGNMODECONTEXT_H
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "inspectoroutputwidget.h"
|
||||
#include <coreplugin/coreconstants.h>
|
||||
|
||||
#include <QtGui/QTextEdit>
|
||||
#include <QtGui/QContextMenuEvent>
|
||||
#include <QtGui/QMenu>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QIcon>
|
||||
|
||||
using namespace Qml;
|
||||
|
||||
InspectorOutputWidget::InspectorOutputWidget(QWidget *parent)
|
||||
: QTextEdit(parent)
|
||||
{
|
||||
setWindowTitle(tr("Output"));
|
||||
setFrameStyle(QFrame::NoFrame);
|
||||
m_clearContents = new QAction(QString(tr("Clear")), this);
|
||||
m_clearContents->setIcon(QIcon(Core::Constants::ICON_CLEAR));
|
||||
connect(m_clearContents, SIGNAL(triggered()), SLOT(clear()));
|
||||
}
|
||||
|
||||
InspectorOutputWidget::~InspectorOutputWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void InspectorOutputWidget::contextMenuEvent(QContextMenuEvent *e)
|
||||
{
|
||||
QMenu *menu = createStandardContextMenu(e->globalPos());
|
||||
|
||||
menu->addSeparator();
|
||||
menu->addAction(m_clearContents);
|
||||
menu->exec(e->globalPos());
|
||||
}
|
||||
|
||||
void InspectorOutputWidget::addOutput(RunControl *, const QString &text)
|
||||
{
|
||||
insertPlainText(text);
|
||||
moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
void InspectorOutputWidget::addOutputInline(RunControl *, const QString &text)
|
||||
{
|
||||
insertPlainText(text);
|
||||
moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
void InspectorOutputWidget::addErrorOutput(RunControl *, const QString &text)
|
||||
{
|
||||
append(text);
|
||||
moveCursor(QTextCursor::End);
|
||||
}
|
||||
|
||||
void InspectorOutputWidget::addInspectorStatus(const QString &text)
|
||||
{
|
||||
setTextColor(Qt::darkGreen);
|
||||
append(text);
|
||||
moveCursor(QTextCursor::End);
|
||||
setTextColor(Qt::black);
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 INSPECTOROUTPUTWIDGET_H
|
||||
#define INSPECTOROUTPUTWIDGET_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/QTextEdit>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QAction;
|
||||
class QContextMenuEvent;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(RunControl);
|
||||
|
||||
namespace Qml {
|
||||
|
||||
class InspectorOutputWidget : public QTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
InspectorOutputWidget(QWidget *parent = 0);
|
||||
virtual ~InspectorOutputWidget();
|
||||
|
||||
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);
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
private:
|
||||
QAction *m_clearContents;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // INSPECTOROUTPUTWIDGET_H
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
#include "inspectorsettings.h"
|
||||
#include "qmlinspectorconstants.h"
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
InspectorSettings::InspectorSettings() : m_externalPort(3768), m_externalUrl("127.0.0.1"),
|
||||
m_showUninspectableItems(false), m_showUnwatchableProperties(false), m_groupPropertiesByItemType(true)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void InspectorSettings::readSettings(QSettings *settings)
|
||||
{
|
||||
settings->beginGroup(QLatin1String(Qml::Constants::S_QML_INSPECTOR));
|
||||
m_externalPort= settings->value(QLatin1String(Qml::Constants::S_EXTERNALPORT_KEY), 3768).toUInt();
|
||||
m_externalUrl = settings->value(QLatin1String(Qml::Constants::S_EXTERNALURL_KEY), "127.0.0.1").toString();
|
||||
m_showUninspectableItems = settings->value(QLatin1String(Qml::Constants::S_SHOW_UNINSPECTABLE_ITEMS), false).toBool();
|
||||
m_showUnwatchableProperties = settings->value(QLatin1String(Qml::Constants::S_SHOW_UNWATCHABLE_PROPERTIES), false).toBool();
|
||||
m_groupPropertiesByItemType = settings->value(QLatin1String(Qml::Constants::S_GROUP_PROPERTIES_BY_ITEM_TYPE), true).toBool();
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
void InspectorSettings::saveSettings(QSettings *settings) const
|
||||
{
|
||||
settings->beginGroup(QLatin1String(Qml::Constants::S_QML_INSPECTOR));
|
||||
settings->setValue(QLatin1String(Qml::Constants::S_EXTERNALPORT_KEY), m_externalPort);
|
||||
settings->setValue(QLatin1String(Qml::Constants::S_EXTERNALURL_KEY), m_externalUrl);
|
||||
settings->setValue(QLatin1String(Qml::Constants::S_SHOW_UNINSPECTABLE_ITEMS), m_showUninspectableItems);
|
||||
settings->setValue(QLatin1String(Qml::Constants::S_SHOW_UNWATCHABLE_PROPERTIES), m_showUnwatchableProperties);
|
||||
settings->setValue(QLatin1String(Qml::Constants::S_GROUP_PROPERTIES_BY_ITEM_TYPE), m_groupPropertiesByItemType);
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
quint16 InspectorSettings::externalPort() const
|
||||
{
|
||||
return m_externalPort;
|
||||
}
|
||||
|
||||
QString InspectorSettings::externalUrl() const
|
||||
{
|
||||
return m_externalUrl;
|
||||
}
|
||||
|
||||
void InspectorSettings::setExternalPort(quint16 port)
|
||||
{
|
||||
m_externalPort = port;
|
||||
}
|
||||
|
||||
void InspectorSettings::setExternalUrl(const QString &url)
|
||||
{
|
||||
m_externalUrl = url;
|
||||
}
|
||||
|
||||
bool InspectorSettings::showUninspectableItems() const
|
||||
{
|
||||
return m_showUninspectableItems;
|
||||
}
|
||||
|
||||
bool InspectorSettings::showUnwatchableProperties() const
|
||||
{
|
||||
return m_showUnwatchableProperties;
|
||||
}
|
||||
|
||||
bool InspectorSettings::groupPropertiesByItemType() const
|
||||
{
|
||||
return m_groupPropertiesByItemType;
|
||||
}
|
||||
|
||||
void InspectorSettings::setShowUninspectableItems(bool value)
|
||||
{
|
||||
m_showUninspectableItems = value;
|
||||
}
|
||||
|
||||
void InspectorSettings::setShowUnwatchableProperties(bool value)
|
||||
{
|
||||
m_showUnwatchableProperties = value;
|
||||
}
|
||||
|
||||
void InspectorSettings::setGroupPropertiesByItemType(bool value)
|
||||
{
|
||||
m_groupPropertiesByItemType = value;
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,44 +0,0 @@
|
||||
#ifndef INSPECTORSETTINGS_H
|
||||
#define INSPECTORSETTINGS_H
|
||||
|
||||
#include <QString>
|
||||
#include "inspectorsettings.h"
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QSettings)
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
class InspectorSettings
|
||||
{
|
||||
public:
|
||||
InspectorSettings();
|
||||
|
||||
void readSettings(QSettings *settings);
|
||||
void saveSettings(QSettings *settings) const;
|
||||
|
||||
bool groupPropertiesByItemType() const;
|
||||
bool showUninspectableItems() const;
|
||||
bool showUnwatchableProperties() const;
|
||||
void setShowUninspectableItems(bool value);
|
||||
void setShowUnwatchableProperties(bool value);
|
||||
void setGroupPropertiesByItemType(bool value);
|
||||
|
||||
void setExternalPort(quint16 port);
|
||||
void setExternalUrl(const QString &url);
|
||||
quint16 externalPort() const;
|
||||
QString externalUrl() const;
|
||||
|
||||
private:
|
||||
quint16 m_externalPort;
|
||||
QString m_externalUrl;
|
||||
bool m_showUninspectableItems;
|
||||
bool m_showUnwatchableProperties;
|
||||
bool m_groupPropertiesByItemType;
|
||||
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif // INSPECTORSETTINGS_H
|
||||
@@ -1,913 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "qmlinspectorconstants.h"
|
||||
#include "qmlinspector.h"
|
||||
#include "inspectoroutputwidget.h"
|
||||
#include "inspectorcontext.h"
|
||||
#include "startexternalqmldialog.h"
|
||||
#include "components/objecttree.h"
|
||||
#include "components/watchtable.h"
|
||||
#include "components/canvasframerate.h"
|
||||
#include "components/expressionquerywidget.h"
|
||||
#include "components/objectpropertiesview.h"
|
||||
|
||||
#include <debugger/debuggerconstants.h>
|
||||
#include <debugger/debuggerengine.h>
|
||||
#include <debugger/debuggermainwindow.h>
|
||||
#include <debugger/debuggerplugin.h>
|
||||
#include <debugger/debuggerrunner.h>
|
||||
#include <debugger/debuggeruiswitcher.h>
|
||||
#include <debugger/watchdata.h>
|
||||
#include <debugger/watchhandler.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/styledbar.h>
|
||||
#include <utils/fancymainwindow.h>
|
||||
|
||||
#include <coreplugin/icontext.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/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
|
||||
#include <texteditor/itexteditor.h>
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/applicationrunconfiguration.h>
|
||||
#include <qmlprojectmanager/qmlprojectconstants.h>
|
||||
#include <qmlprojectmanager/qmlprojectrunconfiguration.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
|
||||
#include <private/qdeclarativedebug_p.h>
|
||||
#include <private/qdeclarativedebugclient_p.h>
|
||||
|
||||
#include "debugger/qml/qmlengine.h"
|
||||
//#include "debugger/debuggermanager.h"
|
||||
#include "debugger/stackframe.h"
|
||||
#include "debugger/stackhandler.h"
|
||||
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtCore/QtPlugin>
|
||||
#include <QtCore/QDateTime>
|
||||
|
||||
#include <QtGui/QToolButton>
|
||||
#include <QtGui/QToolBar>
|
||||
#include <QtGui/QBoxLayout>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QDockWidget>
|
||||
#include <QtGui/QAction>
|
||||
#include <QtGui/QLineEdit>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QSpinBox>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
#include <QtNetwork/QHostAddress>
|
||||
|
||||
using namespace Qml;
|
||||
|
||||
using namespace Debugger;
|
||||
using namespace Debugger::Internal;
|
||||
|
||||
class DebuggerClient : public QDeclarativeDebugClient
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DebuggerClient(QDeclarativeDebugConnection *client, QmlEngine *engine)
|
||||
: QDeclarativeDebugClient(QLatin1String("Debugger"), client)
|
||||
, connection(client), engine(engine)
|
||||
{
|
||||
QObject::connect(engine, SIGNAL(sendMessage(QByteArray)),
|
||||
this, SLOT(slotSendMessage(QByteArray)));
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
void messageReceived(const QByteArray &data)
|
||||
{
|
||||
engine->messageReceived(data);
|
||||
}
|
||||
|
||||
|
||||
QDeclarativeDebugConnection *connection;
|
||||
QmlEngine *engine;
|
||||
|
||||
public slots:
|
||||
void slotSendMessage(const QByteArray &message)
|
||||
{
|
||||
QDeclarativeDebugClient::sendMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
namespace Qml {
|
||||
|
||||
namespace Internal {
|
||||
class EngineComboBox : public QComboBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct EngineInfo
|
||||
{
|
||||
QString name;
|
||||
int id;
|
||||
};
|
||||
|
||||
EngineComboBox(QWidget *parent = 0);
|
||||
|
||||
void addEngine(int engine, const QString &name);
|
||||
void clearEngines();
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
QList<EngineInfo> m_engines;
|
||||
};
|
||||
|
||||
EngineComboBox::EngineComboBox(QWidget *parent)
|
||||
: QComboBox(parent)
|
||||
{
|
||||
setEnabled(false);
|
||||
setEditable(false);
|
||||
}
|
||||
|
||||
void EngineComboBox::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;
|
||||
|
||||
addItem(info.name);
|
||||
}
|
||||
|
||||
void EngineComboBox::clearEngines()
|
||||
{
|
||||
m_engines.clear();
|
||||
clear();
|
||||
}
|
||||
|
||||
} // Internal
|
||||
|
||||
QmlInspector *QmlInspector::m_instance = 0;
|
||||
|
||||
QmlInspector::QmlInspector(QObject *parent)
|
||||
: QObject(parent),
|
||||
m_conn(0),
|
||||
m_client(0),
|
||||
m_engineQuery(0),
|
||||
m_contextQuery(0),
|
||||
m_objectTreeDock(0),
|
||||
m_frameRateDock(0),
|
||||
m_propertyWatcherDock(0),
|
||||
m_inspectorOutputDock(0),
|
||||
m_connectionTimer(new QTimer(this)),
|
||||
m_connectionAttempts(0),
|
||||
m_simultaneousCppAndQmlDebugMode(false),
|
||||
m_debugMode(StandaloneMode)
|
||||
{
|
||||
m_instance = this;
|
||||
m_watchTableModel = new Internal::WatchTableModel(0, this);
|
||||
|
||||
m_objectTreeWidget = new Internal::ObjectTree;
|
||||
m_propertiesWidget = new Internal::ObjectPropertiesView(m_watchTableModel);
|
||||
m_watchTableView = new Internal::WatchTableView(m_watchTableModel);
|
||||
m_expressionWidget = new Internal::ExpressionQueryWidget(Internal::ExpressionQueryWidget::SeparateEntryMode);
|
||||
// m_frameRateWidget = new Internal::CanvasFrameRate;
|
||||
// m_frameRateWidget->setObjectName(QLatin1String("QmlDebugFrameRate"));
|
||||
|
||||
connect(Debugger::DebuggerPlugin::instance(),
|
||||
SIGNAL(stateChanged(int)), this, SLOT(debuggerStateChanged(int)));
|
||||
|
||||
m_editablePropertyTypes = QStringList() << "qreal" << "bool" << "QString"
|
||||
<< "int" << "QVariant" << "QUrl" << "QColor";
|
||||
|
||||
connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector()));
|
||||
}
|
||||
|
||||
QmlInspector::~QmlInspector()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void QmlInspector::shutdown()
|
||||
{
|
||||
m_objectTreeWidget->saveSettings(m_settings);
|
||||
m_propertiesWidget->saveSettings(m_settings);
|
||||
m_settings.saveSettings(Core::ICore::instance()->settings());
|
||||
}
|
||||
|
||||
void QmlInspector::pollInspector()
|
||||
{
|
||||
++m_connectionAttempts;
|
||||
if (connectToViewer()) {
|
||||
m_connectionTimer->stop();
|
||||
m_connectionAttempts = 0;
|
||||
} else if (m_connectionAttempts == MaxConnectionAttempts) {
|
||||
m_connectionTimer->stop();
|
||||
m_connectionAttempts = 0;
|
||||
|
||||
QMessageBox::critical(0,
|
||||
tr("Failed to connect to debugger"),
|
||||
tr("Could not connect to debugger server.") );
|
||||
}
|
||||
updateMenuActions();
|
||||
}
|
||||
|
||||
bool QmlInspector::setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug)
|
||||
{
|
||||
if (!projectToDebug) {
|
||||
emit statusMessage(tr("Invalid project, debugging canceled."));
|
||||
return false;
|
||||
}
|
||||
|
||||
QmlProjectManager::QmlProjectRunConfiguration* config =
|
||||
qobject_cast<QmlProjectManager::QmlProjectRunConfiguration*>(projectToDebug->activeTarget()->activeRunConfiguration());
|
||||
if (!config) {
|
||||
emit statusMessage(tr("Cannot find project run configuration, debugging canceled."));
|
||||
return false;
|
||||
}
|
||||
m_runConfigurationDebugData.serverAddress = config->debugServerAddress();
|
||||
m_runConfigurationDebugData.serverPort = config->debugServerPort();
|
||||
m_connectionTimer->setInterval(ConnectionAttemptDefaultInterval);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlInspector::startQmlProjectDebugger()
|
||||
{
|
||||
m_simultaneousCppAndQmlDebugMode = false;
|
||||
m_connectionTimer->start();
|
||||
}
|
||||
|
||||
bool QmlInspector::connectToViewer()
|
||||
{
|
||||
if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState)
|
||||
return false;
|
||||
|
||||
delete m_client; m_client = 0;
|
||||
|
||||
if (m_conn) {
|
||||
m_conn->disconnectFromHost();
|
||||
delete m_conn;
|
||||
m_conn = 0;
|
||||
}
|
||||
|
||||
QString host = m_runConfigurationDebugData.serverAddress;
|
||||
quint16 port = quint16(m_runConfigurationDebugData.serverPort);
|
||||
|
||||
m_conn = new QDeclarativeDebugConnection(this);
|
||||
connect(m_conn, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
|
||||
SLOT(connectionStateChanged()));
|
||||
connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)),
|
||||
SLOT(connectionError()));
|
||||
|
||||
emit statusMessage(tr("[Inspector] set to connect to debug server %1:%2").arg(host).arg(port));
|
||||
m_conn->connectToHost(host, port);
|
||||
// blocks until connected; if no connection is available, will fail immediately
|
||||
|
||||
if (!m_conn->waitForConnected())
|
||||
return false;
|
||||
|
||||
QTC_ASSERT(m_debuggerRunControl, return false);
|
||||
QmlEngine *engine = qobject_cast<QmlEngine *>(m_debuggerRunControl->engine());
|
||||
QTC_ASSERT(engine, return false);
|
||||
|
||||
(void) new DebuggerClient(m_conn, engine);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlInspector::disconnectFromViewer()
|
||||
{
|
||||
m_conn->disconnectFromHost();
|
||||
updateMenuActions();
|
||||
}
|
||||
|
||||
void QmlInspector::connectionStateChanged()
|
||||
{
|
||||
switch (m_conn->state()) {
|
||||
case QAbstractSocket::UnconnectedState:
|
||||
{
|
||||
emit statusMessage(tr("[Inspector] disconnected.\n\n"));
|
||||
|
||||
delete m_engineQuery;
|
||||
m_engineQuery = 0;
|
||||
delete m_contextQuery;
|
||||
m_contextQuery = 0;
|
||||
|
||||
resetViews();
|
||||
|
||||
updateMenuActions();
|
||||
|
||||
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"));
|
||||
|
||||
if (!m_client) {
|
||||
m_client = new QDeclarativeEngineDebug(m_conn, this);
|
||||
m_objectTreeWidget->setEngineDebug(m_client);
|
||||
m_propertiesWidget->setEngineDebug(m_client);
|
||||
m_watchTableModel->setEngineDebug(m_client);
|
||||
m_expressionWidget->setEngineDebug(m_client);
|
||||
}
|
||||
|
||||
resetViews();
|
||||
// m_frameRateWidget->reset(m_conn);
|
||||
|
||||
reloadEngines();
|
||||
break;
|
||||
}
|
||||
case QAbstractSocket::ClosingState:
|
||||
emit statusMessage(tr("[Inspector] closing..."));
|
||||
break;
|
||||
case QAbstractSocket::BoundState:
|
||||
case QAbstractSocket::ListeningState:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void QmlInspector::resetViews()
|
||||
{
|
||||
m_objectTreeWidget->cleanup();
|
||||
m_propertiesWidget->clear();
|
||||
m_expressionWidget->clear();
|
||||
m_watchTableModel->removeAllWatches();
|
||||
}
|
||||
|
||||
Core::IContext *QmlInspector::context() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
void QmlInspector::connectionError()
|
||||
{
|
||||
emit statusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message")
|
||||
.arg(m_conn->error()).arg(m_conn->errorString()));
|
||||
}
|
||||
|
||||
void QmlInspector::createDockWidgets()
|
||||
{
|
||||
|
||||
m_engineComboBox = new Internal::EngineComboBox;
|
||||
m_engineComboBox->setEnabled(false);
|
||||
connect(m_engineComboBox, SIGNAL(currentIndexChanged(int)),
|
||||
SLOT(queryEngineContext(int)));
|
||||
|
||||
// FancyMainWindow uses widgets' window titles for tab labels
|
||||
// m_frameRateWidget->setWindowTitle(tr("Frame rate"));
|
||||
|
||||
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_engineComboBox);
|
||||
|
||||
QWidget *treeWindow = new QWidget;
|
||||
treeWindow->setObjectName(QLatin1String("QmlDebugTree"));
|
||||
treeWindow->setWindowTitle(tr("Object Tree"));
|
||||
QVBoxLayout *treeWindowLayout = new QVBoxLayout(treeWindow);
|
||||
treeWindowLayout->setMargin(0);
|
||||
treeWindowLayout->setSpacing(0);
|
||||
treeWindowLayout->setContentsMargins(0,0,0,0);
|
||||
treeWindowLayout->addWidget(treeOptionBar);
|
||||
treeWindowLayout->addWidget(m_objectTreeWidget);
|
||||
|
||||
|
||||
m_watchTableView->setModel(m_watchTableModel);
|
||||
Internal::WatchTableHeaderView *header = new Internal::WatchTableHeaderView(m_watchTableModel);
|
||||
m_watchTableView->setHorizontalHeader(header);
|
||||
|
||||
connect(m_objectTreeWidget, SIGNAL(activated(QDeclarativeDebugObjectReference)),
|
||||
this, SLOT(treeObjectActivated(QDeclarativeDebugObjectReference)));
|
||||
|
||||
connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QDeclarativeDebugObjectReference)),
|
||||
m_propertiesWidget, SLOT(reload(QDeclarativeDebugObjectReference)));
|
||||
|
||||
connect(m_objectTreeWidget, SIGNAL(expressionWatchRequested(QDeclarativeDebugObjectReference,QString)),
|
||||
m_watchTableModel, SLOT(expressionWatchRequested(QDeclarativeDebugObjectReference,QString)));
|
||||
|
||||
connect(m_propertiesWidget, SIGNAL(watchToggleRequested(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)),
|
||||
m_watchTableModel, SLOT(togglePropertyWatch(QDeclarativeDebugObjectReference,QDeclarativeDebugPropertyReference)));
|
||||
|
||||
connect(m_watchTableModel, SIGNAL(watchCreated(QDeclarativeDebugWatch*)),
|
||||
m_propertiesWidget, SLOT(watchCreated(QDeclarativeDebugWatch*)));
|
||||
|
||||
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(QDeclarativeDebugObjectReference)),
|
||||
m_expressionWidget, SLOT(setCurrentObject(QDeclarativeDebugObjectReference)));
|
||||
|
||||
|
||||
Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal);
|
||||
Core::MiniSplitter *propWatcherSplitter = new Core::MiniSplitter(Qt::Vertical);
|
||||
propWatcherSplitter->addWidget(m_propertiesWidget);
|
||||
propWatcherSplitter->addWidget(m_watchTableView);
|
||||
propWatcherSplitter->setStretchFactor(0, 2);
|
||||
propWatcherSplitter->setStretchFactor(1, 1);
|
||||
propWatcherSplitter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
|
||||
|
||||
propSplitter->setWindowTitle(tr("Properties and Watchers"));
|
||||
propSplitter->setObjectName(QLatin1String("QmlDebugProperties"));
|
||||
propSplitter->addWidget(m_objectTreeWidget);
|
||||
propSplitter->addWidget(propWatcherSplitter);
|
||||
propSplitter->setStretchFactor(0, 1);
|
||||
propSplitter->setStretchFactor(1, 3);
|
||||
|
||||
InspectorOutputWidget *inspectorOutput = new InspectorOutputWidget();
|
||||
inspectorOutput->setObjectName(QLatin1String("QmlDebugInspectorOutput"));
|
||||
connect(this, SIGNAL(statusMessage(QString)),
|
||||
inspectorOutput, SLOT(addInspectorStatus(QString)));
|
||||
|
||||
Debugger::DebuggerUISwitcher *uiSwitcher = Debugger::DebuggerUISwitcher::instance();
|
||||
|
||||
m_watchTableView->hide();
|
||||
// m_objectTreeDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
|
||||
// treeWindow, Qt::BottomDockWidgetArea);
|
||||
// m_frameRateDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
|
||||
// m_frameRateWidget, Qt::BottomDockWidgetArea);
|
||||
m_propertyWatcherDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
|
||||
propSplitter, Qt::BottomDockWidgetArea);
|
||||
m_inspectorOutputDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
|
||||
inspectorOutput, Qt::BottomDockWidgetArea);
|
||||
|
||||
m_expressionWidget->setWindowTitle(tr("Script Console"));
|
||||
m_expressionQueryDock = uiSwitcher->createDockWidget(Qml::Constants::LANG_QML,
|
||||
m_expressionWidget, Qt::BottomDockWidgetArea);
|
||||
|
||||
m_inspectorOutputDock->setToolTip(tr("Output of the QML inspector, such as information on connecting to the server."));
|
||||
|
||||
m_dockWidgets << /*m_objectTreeDock << *//*m_frameRateDock << */ m_propertyWatcherDock
|
||||
<< m_inspectorOutputDock << m_expressionQueryDock;
|
||||
|
||||
m_context = new Internal::InspectorContext(m_objectTreeWidget);
|
||||
m_propWatcherContext = new Internal::InspectorContext(m_propertyWatcherDock);
|
||||
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
core->addContextObject(m_propWatcherContext);
|
||||
core->addContextObject(m_context);
|
||||
|
||||
m_simultaneousDebugAction = new QAction(this);
|
||||
m_simultaneousDebugAction->setText(tr("Start Debugging C++ and QML Simultaneously..."));
|
||||
connect(m_simultaneousDebugAction, SIGNAL(triggered()),
|
||||
this, SLOT(simultaneouslyDebugQmlCppApplication()));
|
||||
|
||||
Core::ActionManager *am = core->actionManager();
|
||||
Core::ActionContainer *mstart = am->actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING);
|
||||
Core::Command *cmd = am->registerAction(m_simultaneousDebugAction, Constants::M_DEBUG_SIMULTANEOUSLY,
|
||||
m_context->context());
|
||||
cmd->setAttribute(Core::Command::CA_Hide);
|
||||
mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE);
|
||||
|
||||
m_settings.readSettings(core->settings());
|
||||
m_objectTreeWidget->readSettings(m_settings);
|
||||
m_propertiesWidget->readSettings(m_settings);
|
||||
|
||||
connect(m_objectTreeWidget, SIGNAL(contextHelpIdChanged(QString)), m_context,
|
||||
SLOT(setContextHelpId(QString)));
|
||||
connect(m_watchTableView, SIGNAL(contextHelpIdChanged(QString)), m_propWatcherContext,
|
||||
SLOT(setContextHelpId(QString)));
|
||||
connect(m_propertiesWidget, SIGNAL(contextHelpIdChanged(QString)), m_propWatcherContext,
|
||||
SLOT(setContextHelpId(QString)));
|
||||
connect(m_expressionWidget, SIGNAL(contextHelpIdChanged(QString)), m_propWatcherContext,
|
||||
SLOT(setContextHelpId(QString)));
|
||||
}
|
||||
|
||||
void QmlInspector::simultaneouslyDebugQmlCppApplication()
|
||||
{
|
||||
QString errorMessage;
|
||||
ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||
ProjectExplorer::Project *project = pex->startupProject();
|
||||
|
||||
if (!project)
|
||||
errorMessage = QString(tr("No project was found."));
|
||||
else {
|
||||
if (project->id() == "QmlProjectManager.QmlProject")
|
||||
errorMessage = attachToQmlViewerAsExternalApp(project);
|
||||
else {
|
||||
errorMessage = attachToExternalCppAppWithQml(project);
|
||||
}
|
||||
}
|
||||
|
||||
if (!errorMessage.isEmpty())
|
||||
QMessageBox::warning(Core::ICore::instance()->mainWindow(), "Failed to debug C++ and QML", errorMessage);
|
||||
}
|
||||
|
||||
QString QmlInspector::attachToQmlViewerAsExternalApp(ProjectExplorer::Project *project)
|
||||
{
|
||||
m_debugMode = QmlProjectWithCppPlugins;
|
||||
|
||||
QmlProjectManager::QmlProjectRunConfiguration* runConfig =
|
||||
qobject_cast<QmlProjectManager::QmlProjectRunConfiguration*>(project->activeTarget()->activeRunConfiguration());
|
||||
|
||||
if (!runConfig)
|
||||
return QString(tr("No run configurations were found for the project '%1'.").arg(project->displayName()));
|
||||
|
||||
Internal::StartExternalQmlDialog dlg(Debugger::DebuggerUISwitcher::instance()->mainWindow());
|
||||
|
||||
QString importPathArgument = "-I";
|
||||
QString execArgs;
|
||||
if (runConfig->viewerArguments().contains(importPathArgument))
|
||||
execArgs = runConfig->viewerArguments().join(" ");
|
||||
else {
|
||||
QFileInfo qmlFileInfo(runConfig->viewerArguments().last());
|
||||
importPathArgument.append(" " + qmlFileInfo.absolutePath() + " ");
|
||||
execArgs = importPathArgument + runConfig->viewerArguments().join(" ");
|
||||
}
|
||||
|
||||
|
||||
dlg.setPort(runConfig->debugServerPort());
|
||||
dlg.setDebuggerUrl(runConfig->debugServerAddress());
|
||||
dlg.setProjectDisplayName(project->displayName());
|
||||
dlg.setDebugMode(Internal::StartExternalQmlDialog::QmlProjectWithCppPlugins);
|
||||
dlg.setQmlViewerArguments(execArgs);
|
||||
dlg.setQmlViewerPath(runConfig->viewerPath());
|
||||
|
||||
if (dlg.exec() != QDialog::Accepted)
|
||||
return QString();
|
||||
|
||||
m_runConfigurationDebugData.serverAddress = dlg.debuggerUrl();
|
||||
m_runConfigurationDebugData.serverPort = dlg.port();
|
||||
m_settings.setExternalPort(dlg.port());
|
||||
m_settings.setExternalUrl(dlg.debuggerUrl());
|
||||
|
||||
ProjectExplorer::Environment customEnv = ProjectExplorer::Environment::systemEnvironment(); // empty env by default
|
||||
customEnv.set(QmlProjectManager::Constants::E_QML_DEBUG_SERVER_PORT, QString::number(m_settings.externalPort()));
|
||||
|
||||
Debugger::DebuggerRunControl *debuggableRunControl =
|
||||
createDebuggerRunControl(runConfig, dlg.qmlViewerPath(), dlg.qmlViewerArguments());
|
||||
|
||||
return executeDebuggerRunControl(debuggableRunControl, &customEnv);
|
||||
}
|
||||
|
||||
QString QmlInspector::attachToExternalCppAppWithQml(ProjectExplorer::Project *project)
|
||||
{
|
||||
m_debugMode = CppProjectWithQmlEngines;
|
||||
|
||||
ProjectExplorer::LocalApplicationRunConfiguration* runConfig =
|
||||
qobject_cast<ProjectExplorer::LocalApplicationRunConfiguration*>(project->activeTarget()->activeRunConfiguration());
|
||||
|
||||
if (!project->activeTarget() || !project->activeTarget()->activeRunConfiguration())
|
||||
return QString(tr("No run configurations were found for the project '%1'.").arg(project->displayName()));
|
||||
else if (!runConfig)
|
||||
return QString(tr("No valid run configuration was found for the project %1. "
|
||||
"Only locally runnable configurations are supported.\n"
|
||||
"Please check your project settings.").arg(project->displayName()));
|
||||
|
||||
Internal::StartExternalQmlDialog dlg(Debugger::DebuggerUISwitcher::instance()->mainWindow());
|
||||
|
||||
dlg.setPort(m_settings.externalPort());
|
||||
dlg.setDebuggerUrl(m_settings.externalUrl());
|
||||
dlg.setProjectDisplayName(project->displayName());
|
||||
dlg.setDebugMode(Internal::StartExternalQmlDialog::CppProjectWithQmlEngine);
|
||||
if (dlg.exec() != QDialog::Accepted)
|
||||
return QString();
|
||||
|
||||
m_runConfigurationDebugData.serverAddress = dlg.debuggerUrl();
|
||||
m_runConfigurationDebugData.serverPort = dlg.port();
|
||||
m_settings.setExternalPort(dlg.port());
|
||||
m_settings.setExternalUrl(dlg.debuggerUrl());
|
||||
|
||||
ProjectExplorer::Environment customEnv = runConfig->environment();
|
||||
customEnv.set(QmlProjectManager::Constants::E_QML_DEBUG_SERVER_PORT, QString::number(m_settings.externalPort()));
|
||||
Debugger::DebuggerRunControl *debuggableRunControl = createDebuggerRunControl(runConfig);
|
||||
return executeDebuggerRunControl(debuggableRunControl, &customEnv);
|
||||
}
|
||||
|
||||
QString QmlInspector::executeDebuggerRunControl(Debugger::DebuggerRunControl *debuggableRunControl, ProjectExplorer::Environment *environment)
|
||||
{
|
||||
ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||
|
||||
// to make sure we have a valid, debuggable run control, find the correct factory for it
|
||||
if (debuggableRunControl) {
|
||||
|
||||
// modify the env
|
||||
debuggableRunControl->setCustomEnvironment(*environment);
|
||||
|
||||
pex->startRunControl(debuggableRunControl, ProjectExplorer::Constants::DEBUGMODE);
|
||||
m_simultaneousCppAndQmlDebugMode = true;
|
||||
|
||||
return QString();
|
||||
}
|
||||
return QString(tr("A valid run control was not registered in Qt Creator for this project run configuration."));;
|
||||
}
|
||||
|
||||
Debugger::DebuggerRunControl *QmlInspector::createDebuggerRunControl(ProjectExplorer::RunConfiguration *runConfig,
|
||||
const QString &executableFile, const QString &executableArguments)
|
||||
{
|
||||
ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance();
|
||||
const QList<Debugger::DebuggerRunControlFactory *> factories = pm->getObjects<Debugger::DebuggerRunControlFactory>();
|
||||
ProjectExplorer::RunControl *runControl = 0;
|
||||
|
||||
if (m_debugMode == QmlProjectWithCppPlugins) {
|
||||
Debugger::DebuggerStartParameters sp;
|
||||
sp.startMode = Debugger::StartExternal;
|
||||
sp.executable = executableFile;
|
||||
sp.processArgs = executableArguments.split(QLatin1Char(' '));
|
||||
runControl = factories.first()->create(sp);
|
||||
return qobject_cast<Debugger::DebuggerRunControl *>(runControl);
|
||||
}
|
||||
|
||||
if (m_debugMode == CppProjectWithQmlEngines) {
|
||||
if (factories.length() && factories.first()->canRun(runConfig, ProjectExplorer::Constants::DEBUGMODE)) {
|
||||
runControl = factories.first()->create(runConfig, ProjectExplorer::Constants::DEBUGMODE);
|
||||
return qobject_cast<Debugger::DebuggerRunControl *>(runControl);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void QmlInspector::updateMenuActions()
|
||||
{
|
||||
|
||||
bool enabled = true;
|
||||
if (m_simultaneousCppAndQmlDebugMode)
|
||||
enabled = (m_cppDebuggerState == Debugger::DebuggerNotReady && (!m_conn || m_conn->state() == QAbstractSocket::UnconnectedState));
|
||||
else
|
||||
enabled = (!m_conn || m_conn->state() == QAbstractSocket::UnconnectedState);
|
||||
|
||||
m_simultaneousDebugAction->setEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
void QmlInspector::debuggerStateChanged(int newState)
|
||||
{
|
||||
if (m_simultaneousCppAndQmlDebugMode) {
|
||||
|
||||
switch(newState) {
|
||||
case Debugger::EngineStarting:
|
||||
{
|
||||
m_connectionInitialized = false;
|
||||
break;
|
||||
}
|
||||
case Debugger::AdapterStartFailed:
|
||||
case Debugger::InferiorStartFailed:
|
||||
emit statusMessage(QString(tr("Debugging failed: could not start C++ debugger.")));
|
||||
break;
|
||||
case Debugger::InferiorRunningRequested:
|
||||
{
|
||||
if (m_cppDebuggerState == Debugger::InferiorStopped) {
|
||||
// re-enable UI again
|
||||
m_objectTreeWidget->setEnabled(true);
|
||||
m_propertiesWidget->setEnabled(true);
|
||||
m_expressionWidget->setEnabled(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Debugger::InferiorRunning:
|
||||
{
|
||||
if (!m_connectionInitialized) {
|
||||
m_connectionInitialized = true;
|
||||
m_connectionTimer->setInterval(ConnectionAttemptSimultaneousInterval);
|
||||
m_connectionTimer->start();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Debugger::InferiorStopped:
|
||||
{
|
||||
m_objectTreeWidget->setEnabled(false);
|
||||
m_propertiesWidget->setEnabled(false);
|
||||
m_expressionWidget->setEnabled(false);
|
||||
break;
|
||||
}
|
||||
case Debugger::EngineShuttingDown:
|
||||
{
|
||||
m_connectionInitialized = false;
|
||||
// here it's safe to enable the debugger windows again -
|
||||
// disabled ones look ugly.
|
||||
m_objectTreeWidget->setEnabled(true);
|
||||
m_propertiesWidget->setEnabled(true);
|
||||
m_expressionWidget->setEnabled(true);
|
||||
m_simultaneousCppAndQmlDebugMode = false;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_cppDebuggerState = newState;
|
||||
updateMenuActions();
|
||||
}
|
||||
|
||||
|
||||
void QmlInspector::setSimpleDockWidgetArrangement()
|
||||
{
|
||||
Utils::FancyMainWindow *mainWindow = Debugger::DebuggerUISwitcher::instance()->mainWindow();
|
||||
|
||||
mainWindow->setTrackingEnabled(false);
|
||||
QList<QDockWidget *> dockWidgets = mainWindow->dockWidgets();
|
||||
foreach (QDockWidget *dockWidget, dockWidgets) {
|
||||
if (m_dockWidgets.contains(dockWidget)) {
|
||||
dockWidget->setFloating(false);
|
||||
mainWindow->removeDockWidget(dockWidget);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (QDockWidget *dockWidget, dockWidgets) {
|
||||
if (m_dockWidgets.contains(dockWidget)) {
|
||||
mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
|
||||
dockWidget->show();
|
||||
}
|
||||
}
|
||||
//mainWindow->tabifyDockWidget(m_frameRateDock, m_propertyWatcherDock);
|
||||
mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_expressionQueryDock);
|
||||
mainWindow->tabifyDockWidget(m_propertyWatcherDock, m_inspectorOutputDock);
|
||||
m_propertyWatcherDock->raise();
|
||||
|
||||
m_inspectorOutputDock->setVisible(false);
|
||||
|
||||
mainWindow->setTrackingEnabled(true);
|
||||
}
|
||||
|
||||
void QmlInspector::reloadEngines()
|
||||
{
|
||||
if (m_engineQuery) {
|
||||
emit statusMessage("[Inspector] Waiting for response to previous engine query");
|
||||
return;
|
||||
}
|
||||
|
||||
m_engineComboBox->setEnabled(false);
|
||||
|
||||
m_engineQuery = m_client->queryAvailableEngines(this);
|
||||
if (!m_engineQuery->isWaiting())
|
||||
enginesChanged();
|
||||
else
|
||||
QObject::connect(m_engineQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
|
||||
this, SLOT(enginesChanged()));
|
||||
}
|
||||
|
||||
void QmlInspector::enginesChanged()
|
||||
{
|
||||
m_engineComboBox->clearEngines();
|
||||
|
||||
QList<QDeclarativeDebugEngineReference> engines = m_engineQuery->engines();
|
||||
delete m_engineQuery; m_engineQuery = 0;
|
||||
|
||||
if (engines.isEmpty())
|
||||
qWarning("qmldebugger: no engines found!");
|
||||
|
||||
m_engineComboBox->setEnabled(true);
|
||||
|
||||
for (int i = 0; i < engines.count(); ++i)
|
||||
m_engineComboBox->addEngine(engines.at(i).debugId(), engines.at(i).name());
|
||||
|
||||
if (engines.count() > 0) {
|
||||
m_engineComboBox->setCurrentIndex(engines.at(0).debugId());
|
||||
queryEngineContext(engines.at(0).debugId());
|
||||
}
|
||||
}
|
||||
|
||||
void QmlInspector::queryEngineContext(int id)
|
||||
{
|
||||
if (id < 0)
|
||||
return;
|
||||
|
||||
if (m_contextQuery) {
|
||||
delete m_contextQuery;
|
||||
m_contextQuery = 0;
|
||||
}
|
||||
|
||||
m_contextQuery = m_client->queryRootContexts(QDeclarativeDebugEngineReference(id), this);
|
||||
if (!m_contextQuery->isWaiting())
|
||||
contextChanged();
|
||||
else
|
||||
QObject::connect(m_contextQuery, SIGNAL(stateChanged(QDeclarativeDebugQuery::State)),
|
||||
this, SLOT(contextChanged()));
|
||||
}
|
||||
|
||||
void QmlInspector::contextChanged()
|
||||
{
|
||||
//dump(m_contextQuery->rootContext(), 0);
|
||||
|
||||
foreach (const QDeclarativeDebugObjectReference &object, m_contextQuery->rootContext().objects())
|
||||
m_objectTreeWidget->reload(object.debugId());
|
||||
|
||||
delete m_contextQuery; m_contextQuery = 0;
|
||||
}
|
||||
|
||||
void QmlInspector::treeObjectActivated(const QDeclarativeDebugObjectReference &obj)
|
||||
{
|
||||
QDeclarativeDebugFileReference source = obj.source();
|
||||
QString fileName = source.url().toLocalFile();
|
||||
|
||||
if (source.lineNumber() < 0 || !QFile::exists(fileName))
|
||||
return;
|
||||
|
||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||
Core::IEditor *editor = editorManager->openEditor(fileName, QString(), Core::EditorManager::NoModeSwitch);
|
||||
TextEditor::ITextEditor *textEditor = qobject_cast<TextEditor::ITextEditor*>(editor);
|
||||
|
||||
if (textEditor) {
|
||||
editorManager->addCurrentPositionToNavigationHistory();
|
||||
textEditor->gotoLine(source.lineNumber());
|
||||
textEditor->widget()->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
bool QmlInspector::canEditProperty(const QString &propertyType)
|
||||
{
|
||||
return m_editablePropertyTypes.contains(propertyType);
|
||||
}
|
||||
|
||||
QDeclarativeDebugExpressionQuery *QmlInspector::executeExpression(int objectDebugId, const QString &objectId,
|
||||
const QString &propertyName, const QVariant &value)
|
||||
{
|
||||
//qDebug() << entity.property << entity.title << entity.objectId;
|
||||
if (objectId.length()) {
|
||||
|
||||
QString quoteWrappedValue = value.toString();
|
||||
if (addQuotesForData(value))
|
||||
quoteWrappedValue = QString("'%1'").arg(quoteWrappedValue);
|
||||
|
||||
QString constructedExpression = objectId + "." + propertyName + "=" + quoteWrappedValue;
|
||||
//qDebug() << "EXPRESSION:" << constructedExpression;
|
||||
return m_client->queryExpressionResult(objectDebugId, constructedExpression, this);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool QmlInspector::addQuotesForData(const QVariant &value) const
|
||||
{
|
||||
switch (value.type()) {
|
||||
case QVariant::String:
|
||||
case QVariant::Color:
|
||||
case QVariant::Date:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QmlInspector *QmlInspector::instance()
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#include "qmlinspector.moc"
|
||||
@@ -1,197 +0,0 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 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 "qmlinspector_global.h"
|
||||
#include "inspectorsettings.h"
|
||||
#include <coreplugin/basemode.h>
|
||||
#include <qmlprojectmanager/qmlprojectrunconfiguration.h>
|
||||
|
||||
#include <QtGui/QAction>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QDockWidget;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QSpinBox;
|
||||
class QToolButton;
|
||||
|
||||
class QDeclarativeEngineDebug;
|
||||
class QDeclarativeDebugConnection;
|
||||
class QDeclarativeDebugExpressionQuery;
|
||||
class QDeclarativeDebugEnginesQuery;
|
||||
class QDeclarativeDebugRootContextQuery;
|
||||
class QDeclarativeDebugObjectReference;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
||||
namespace ProjectExplorer {
|
||||
class Project;
|
||||
class Environment;
|
||||
}
|
||||
|
||||
namespace Core {
|
||||
class IContext;
|
||||
}
|
||||
|
||||
namespace Debugger {
|
||||
class DebuggerRunControl;
|
||||
}
|
||||
|
||||
namespace Qml {
|
||||
|
||||
namespace Internal {
|
||||
class EngineComboBox;
|
||||
class InspectorContext;
|
||||
class ObjectTree;
|
||||
class ObjectPropertiesView;
|
||||
class WatchTableModel;
|
||||
class WatchTableView;
|
||||
class CanvasFrameRate;
|
||||
class ExpressionQueryWidget;
|
||||
}
|
||||
|
||||
const int MaxConnectionAttempts = 50;
|
||||
const int ConnectionAttemptDefaultInterval = 75;
|
||||
// used when debugging with c++ - connection can take a lot of time
|
||||
const int ConnectionAttemptSimultaneousInterval = 500;
|
||||
|
||||
class QMLINSPECTOR_EXPORT QmlInspector : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum DebugMode {
|
||||
StandaloneMode,
|
||||
CppProjectWithQmlEngines,
|
||||
QmlProjectWithCppPlugins
|
||||
};
|
||||
|
||||
QmlInspector(QObject *parent = 0);
|
||||
~QmlInspector();
|
||||
void shutdown();
|
||||
|
||||
void createDockWidgets();
|
||||
bool connectToViewer(); // using host, port from widgets
|
||||
Core::IContext *context() const;
|
||||
|
||||
// returns false if project is not debuggable.
|
||||
bool setDebugConfigurationDataFromProject(ProjectExplorer::Project *projectToDebug);
|
||||
void startQmlProjectDebugger();
|
||||
|
||||
static QmlInspector *instance();
|
||||
bool canEditProperty(const QString &propertyType);
|
||||
QDeclarativeDebugExpressionQuery *executeExpression(int objectDebugId,
|
||||
const QString &objectId, const QString &propertyName, const QVariant &value);
|
||||
|
||||
signals:
|
||||
void statusMessage(const QString &text);
|
||||
|
||||
public slots:
|
||||
void disconnectFromViewer();
|
||||
void setSimpleDockWidgetArrangement();
|
||||
|
||||
private slots:
|
||||
void connectionStateChanged();
|
||||
void connectionError();
|
||||
void reloadEngines();
|
||||
void enginesChanged();
|
||||
void queryEngineContext(int);
|
||||
void contextChanged();
|
||||
void treeObjectActivated(const QDeclarativeDebugObjectReference &obj);
|
||||
void simultaneouslyDebugQmlCppApplication();
|
||||
|
||||
void debuggerStateChanged(int newState);
|
||||
void pollInspector();
|
||||
|
||||
private:
|
||||
void updateMenuActions();
|
||||
Debugger::DebuggerRunControl *createDebuggerRunControl(
|
||||
ProjectExplorer::RunConfiguration *runConfig,
|
||||
const QString &executableFile = QString(),
|
||||
const QString &executableArguments = QString());
|
||||
QString executeDebuggerRunControl(Debugger::DebuggerRunControl *debuggableRunControl,
|
||||
ProjectExplorer::Environment *environment);
|
||||
QString attachToQmlViewerAsExternalApp(ProjectExplorer::Project *project);
|
||||
QString attachToExternalCppAppWithQml(ProjectExplorer::Project *project);
|
||||
|
||||
bool addQuotesForData(const QVariant &value) const;
|
||||
void resetViews();
|
||||
|
||||
QDeclarativeDebugConnection *m_conn;
|
||||
QDeclarativeEngineDebug *m_client;
|
||||
|
||||
QDeclarativeDebugEnginesQuery *m_engineQuery;
|
||||
QDeclarativeDebugRootContextQuery *m_contextQuery;
|
||||
|
||||
Internal::ObjectTree *m_objectTreeWidget;
|
||||
Internal::ObjectPropertiesView *m_propertiesWidget;
|
||||
Internal::WatchTableModel *m_watchTableModel;
|
||||
Internal::WatchTableView *m_watchTableView;
|
||||
Internal::CanvasFrameRate *m_frameRateWidget;
|
||||
Internal::ExpressionQueryWidget *m_expressionWidget;
|
||||
|
||||
Internal::EngineComboBox *m_engineComboBox;
|
||||
|
||||
QDockWidget *m_objectTreeDock;
|
||||
QDockWidget *m_frameRateDock;
|
||||
QDockWidget *m_expressionQueryDock;
|
||||
QDockWidget *m_propertyWatcherDock;
|
||||
QDockWidget *m_inspectorOutputDock;
|
||||
QList<QDockWidget*> m_dockWidgets;
|
||||
|
||||
Internal::InspectorContext *m_context;
|
||||
Internal::InspectorContext *m_propWatcherContext;
|
||||
|
||||
QAction *m_simultaneousDebugAction;
|
||||
|
||||
QTimer *m_connectionTimer;
|
||||
int m_connectionAttempts;
|
||||
|
||||
Internal::InspectorSettings m_settings;
|
||||
QmlProjectManager::QmlProjectRunConfigurationDebugData m_runConfigurationDebugData;
|
||||
|
||||
QStringList m_editablePropertyTypes;
|
||||
|
||||
// simultaneous debug mode stuff
|
||||
int m_cppDebuggerState;
|
||||
bool m_connectionInitialized;
|
||||
bool m_simultaneousCppAndQmlDebugMode;
|
||||
DebugMode m_debugMode;
|
||||
Debugger::DebuggerRunControl *m_debuggerRunControl;
|
||||
|
||||
static QmlInspector *m_instance;
|
||||
};
|
||||
|
||||
} // Qml
|
||||
|
||||
#endif
|
||||
@@ -5,32 +5,20 @@ INCLUDEPATH += .
|
||||
DEPENDPATH += .
|
||||
|
||||
include(../../private_headers.pri)
|
||||
include(components/qmldebugger.pri)
|
||||
|
||||
DEFINES += QMLINSPECTOR_LIBRARY
|
||||
|
||||
HEADERS += qmlinspectorplugin.h \
|
||||
qmlinspectorconstants.h \
|
||||
qmlinspector.h \
|
||||
inspectoroutputwidget.h \
|
||||
qmlinspector_global.h \
|
||||
inspectorcontext.h \
|
||||
startexternalqmldialog.h \
|
||||
inspectorsettings.h
|
||||
|
||||
SOURCES += qmlinspectorplugin.cpp \
|
||||
qmlinspector.cpp \
|
||||
inspectoroutputwidget.cpp \
|
||||
inspectorcontext.cpp \
|
||||
startexternalqmldialog.cpp \
|
||||
inspectorsettings.cpp
|
||||
inspectorcontext.cpp
|
||||
|
||||
OTHER_FILES += QmlInspector.pluginspec
|
||||
RESOURCES += qmlinspector.qrc
|
||||
|
||||
FORMS += \
|
||||
startexternalqmldialog.ui
|
||||
|
||||
include(../../qtcreatorplugin.pri)
|
||||
include(../../plugins/projectexplorer/projectexplorer.pri)
|
||||
include(../../plugins/qmlprojectmanager/qmlprojectmanager.pri)
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
#ifndef QMLINSPECTORCONSTANTS_H
|
||||
#define QMLINSPECTORCONSTANTS_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace Qml {
|
||||
namespace QmlInspector {
|
||||
namespace Constants {
|
||||
const char * const RUN = "QmlInspector.Run";
|
||||
const char * const STOP = "QmlInspector.Stop";
|
||||
@@ -51,8 +49,7 @@ namespace Qml {
|
||||
const char * const S_SHOW_UNWATCHABLE_PROPERTIES = "ShowUninspectableItem";
|
||||
const char * const S_GROUP_PROPERTIES_BY_ITEM_TYPE = "GroupPropertiesByItemType";
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
**************************************************************************/
|
||||
|
||||
#include "qmlinspectorconstants.h"
|
||||
#include "qmlinspector.h"
|
||||
#include "qmlinspectorplugin.h"
|
||||
|
||||
#include <debugger/debuggeruiswitcher.h>
|
||||
@@ -60,39 +59,41 @@
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
using namespace QmlInspector::Internal;
|
||||
using namespace QmlInspector::Constants;
|
||||
|
||||
using namespace Qml;
|
||||
|
||||
|
||||
static QToolButton *createToolButton(QAction *action)
|
||||
namespace {
|
||||
QToolButton *createToolButton(QAction *action)
|
||||
{
|
||||
QToolButton *button = new QToolButton;
|
||||
button->setDefaultAction(action);
|
||||
return button;
|
||||
}
|
||||
} // end of anonymous namespace
|
||||
|
||||
QmlInspectorPlugin::QmlInspectorPlugin()
|
||||
: m_inspector(0)
|
||||
{
|
||||
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
QmlInspectorPlugin::~QmlInspectorPlugin()
|
||||
{
|
||||
removeObject(m_inspector);
|
||||
delete m_inspector;
|
||||
m_inspector = 0;
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
void QmlInspectorPlugin::aboutToShutdown()
|
||||
{
|
||||
m_inspector->shutdown();
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *errorString)
|
||||
{
|
||||
Q_UNUSED(arguments);
|
||||
Q_UNUSED(errorString);
|
||||
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#if 0
|
||||
Core::ICore *core = Core::ICore::instance();
|
||||
connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
|
||||
SLOT(prepareDebugger(Core::IMode*)));
|
||||
@@ -104,12 +105,16 @@ bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *error
|
||||
m_inspector = new QmlInspector;
|
||||
m_inspector->createDockWidgets();
|
||||
addObject(m_inspector);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QmlInspectorPlugin::extensionsInitialized()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#if 0
|
||||
ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance();
|
||||
Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>();
|
||||
|
||||
@@ -136,10 +141,17 @@ void QmlInspectorPlugin::extensionsInitialized()
|
||||
configBarLayout->addStretch();
|
||||
|
||||
uiSwitcher->setToolbar(Qml::Constants::LANG_QML, configBar);
|
||||
#endif
|
||||
}
|
||||
|
||||
void QmlInspectorPlugin::activateDebuggerForProject(ProjectExplorer::Project *project, const QString &runMode)
|
||||
{
|
||||
Q_UNUSED(project);
|
||||
Q_UNUSED(runMode);
|
||||
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#if 0
|
||||
if (runMode == ProjectExplorer::Constants::DEBUGMODE) {
|
||||
// FIXME we probably want to activate the debugger for other projects than QmlProjects,
|
||||
// if they contain Qml files. Some kind of options should exist for this behavior.
|
||||
@@ -147,11 +159,15 @@ void QmlInspectorPlugin::activateDebuggerForProject(ProjectExplorer::Project *pr
|
||||
if (qmlproj && m_inspector->setDebugConfigurationDataFromProject(qmlproj))
|
||||
m_inspector->startQmlProjectDebugger();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void QmlInspectorPlugin::prepareDebugger(Core::IMode *mode)
|
||||
{
|
||||
Q_UNUSED(mode);
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#if 0
|
||||
if (mode->id() != Debugger::Constants::MODE_DEBUG)
|
||||
return;
|
||||
|
||||
@@ -163,12 +179,19 @@ void QmlInspectorPlugin::prepareDebugger(Core::IMode *mode)
|
||||
Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>();
|
||||
uiSwitcher->setActiveLanguage(Qml::Constants::LANG_QML);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void QmlInspectorPlugin::setDockWidgetArrangement(const QString &activeLanguage)
|
||||
{
|
||||
Q_UNUSED(activeLanguage);
|
||||
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
|
||||
#if 0
|
||||
if (activeLanguage == Qml::Constants::LANG_QML || activeLanguage.isEmpty())
|
||||
m_inspector->setSimpleDockWidgetArrangement();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <QtCore/QPointer>
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QStringList);
|
||||
QT_FORWARD_DECLARE_CLASS(QStringList)
|
||||
|
||||
namespace Core {
|
||||
class IMode;
|
||||
@@ -45,8 +45,8 @@ namespace ProjectExplorer {
|
||||
class Project;
|
||||
}
|
||||
|
||||
namespace Qml {
|
||||
class QmlInspector;
|
||||
namespace QmlInspector {
|
||||
namespace Internal {
|
||||
|
||||
class QmlInspectorPlugin : public ExtensionSystem::IPlugin
|
||||
{
|
||||
@@ -54,7 +54,7 @@ class QmlInspectorPlugin : public ExtensionSystem::IPlugin
|
||||
|
||||
public:
|
||||
QmlInspectorPlugin();
|
||||
~QmlInspectorPlugin();
|
||||
virtual ~QmlInspectorPlugin();
|
||||
|
||||
virtual bool initialize(const QStringList &arguments, QString *errorString);
|
||||
virtual void extensionsInitialized();
|
||||
@@ -66,11 +66,9 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void prepareDebugger(Core::IMode *mode);
|
||||
|
||||
private:
|
||||
QmlInspector *m_inspector;
|
||||
};
|
||||
|
||||
} // Qml
|
||||
} // end of namespace Internal
|
||||
} // end of namespace QmlInspector
|
||||
|
||||
#endif // QMLINSPECTORPLUGIN_H
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
#include "startexternalqmldialog.h"
|
||||
#include "ui_startexternalqmldialog.h"
|
||||
|
||||
#include <utils/pathchooser.h>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
StartExternalQmlDialog::StartExternalQmlDialog(QWidget *parent)
|
||||
: QDialog(parent), m_ui(new Ui::StartExternalQmlDialog), m_debugMode(QmlProjectWithCppPlugins)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
|
||||
m_ui->projectDisplayName->setText(tr("<No project>"));
|
||||
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
StartExternalQmlDialog::~StartExternalQmlDialog()
|
||||
{
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
void StartExternalQmlDialog::setDebuggerUrl(const QString &str)
|
||||
{
|
||||
m_ui->urlLine->setText(str);
|
||||
}
|
||||
|
||||
QString StartExternalQmlDialog::debuggerUrl() const
|
||||
{
|
||||
return m_ui->urlLine->text();
|
||||
}
|
||||
|
||||
void StartExternalQmlDialog::setPort(quint16 str)
|
||||
{
|
||||
m_ui->portSpinBox->setValue(str);
|
||||
}
|
||||
|
||||
quint16 StartExternalQmlDialog::port() const
|
||||
{
|
||||
return m_ui->portSpinBox->value();
|
||||
}
|
||||
|
||||
void StartExternalQmlDialog::setProjectDisplayName(const QString &projectName)
|
||||
{
|
||||
m_ui->projectDisplayName->setText(projectName);
|
||||
}
|
||||
|
||||
void StartExternalQmlDialog::setQmlViewerPath(const QString &path)
|
||||
{
|
||||
m_ui->viewerPathLineEdit->setText(path);
|
||||
}
|
||||
|
||||
QString StartExternalQmlDialog::qmlViewerPath() const
|
||||
{
|
||||
return m_ui->viewerPathLineEdit->text();
|
||||
}
|
||||
|
||||
void StartExternalQmlDialog::setQmlViewerArguments(const QString &arguments)
|
||||
{
|
||||
m_ui->viewerArgumentsLineEdit->setText(arguments);
|
||||
}
|
||||
|
||||
QString StartExternalQmlDialog::qmlViewerArguments() const
|
||||
{
|
||||
return m_ui->viewerArgumentsLineEdit->text();
|
||||
}
|
||||
|
||||
void StartExternalQmlDialog::setDebugMode(DebugMode mode)
|
||||
{
|
||||
m_debugMode = mode;
|
||||
if (m_debugMode == QmlProjectWithCppPlugins) {
|
||||
m_ui->labelViewerPath->show();
|
||||
m_ui->viewerPathLineEdit->show();
|
||||
m_ui->labelViewerArguments->show();
|
||||
m_ui->viewerArgumentsLineEdit->show();
|
||||
setMinimumHeight(270);
|
||||
resize(width(), 270);
|
||||
} else {
|
||||
m_ui->labelViewerPath->hide();
|
||||
m_ui->viewerPathLineEdit->hide();
|
||||
m_ui->labelViewerArguments->hide();
|
||||
m_ui->viewerArgumentsLineEdit->hide();
|
||||
setMinimumHeight(200);
|
||||
resize(width(), 200);
|
||||
}
|
||||
}
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
@@ -1,55 +0,0 @@
|
||||
#ifndef STARTEXTERNALQMLDIALOG_H
|
||||
#define STARTEXTERNALQMLDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui {
|
||||
class StartExternalQmlDialog;
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace Qml {
|
||||
namespace Internal {
|
||||
|
||||
|
||||
class StartExternalQmlDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit StartExternalQmlDialog(QWidget *parent);
|
||||
~StartExternalQmlDialog();
|
||||
|
||||
enum DebugMode {
|
||||
QmlProjectWithCppPlugins,
|
||||
CppProjectWithQmlEngine
|
||||
};
|
||||
|
||||
void setDebugMode(DebugMode mode);
|
||||
|
||||
void setQmlViewerPath(const QString &path);
|
||||
QString qmlViewerPath() const;
|
||||
|
||||
void setQmlViewerArguments(const QString &arguments);
|
||||
QString qmlViewerArguments() const;
|
||||
|
||||
void setDebuggerUrl(const QString &url);
|
||||
QString debuggerUrl() const;
|
||||
|
||||
void setPort(quint16 port);
|
||||
quint16 port() const;
|
||||
|
||||
void setProjectDisplayName(const QString &projectName);
|
||||
|
||||
private slots:
|
||||
|
||||
private:
|
||||
Ui::StartExternalQmlDialog *m_ui;
|
||||
DebugMode m_debugMode;
|
||||
};
|
||||
|
||||
} // Internal
|
||||
} // Qml
|
||||
|
||||
#endif // STARTEXTERNALQMLDIALOG_H
|
||||
@@ -1,148 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>StartExternalQmlDialog</class>
|
||||
<widget class="QDialog" name="StartExternalQmlDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>425</width>
|
||||
<height>278</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>425</width>
|
||||
<height>278</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Start Simultaneous QML and C++ Debugging </string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout">
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="labelBreakAtMain">
|
||||
<property name="text">
|
||||
<string>Debugging address:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Debugging port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSpinBox" name="portSpinBox">
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3768</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="urlLine">
|
||||
<property name="text">
|
||||
<string>127.0.0.1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Project:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="projectDisplayName">
|
||||
<property name="text">
|
||||
<string><No project></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="labelViewerPath">
|
||||
<property name="text">
|
||||
<string>Viewer path:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="viewerPathLineEdit"/>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="labelViewerArguments">
|
||||
<property name="text">
|
||||
<string>Viewer arguments:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="viewerArgumentsLineEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>To switch languages while debugging, go to Debug->Language menu.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>407</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -86,7 +86,7 @@ void QmlRunControl::start()
|
||||
|
||||
// FIXME this line should be refactored out in order to remove the dependency between
|
||||
// debugger and qmlprojectmanager, because debugger also relies on cpptools.
|
||||
Debugger::DebuggerUISwitcher::instance()->setActiveLanguage(Qml::Constants::LANG_QML);
|
||||
Debugger::DebuggerUISwitcher::instance()->setActiveLanguage(QmlInspector::Constants::LANG_QML);
|
||||
|
||||
emit started();
|
||||
emit appendMessage(this, tr("Starting %1 %2").arg(QDir::toNativeSeparators(m_executable),
|
||||
|
||||
Reference in New Issue
Block a user