Commit 1bf34183 authored by Bea Lam's avatar Bea Lam

Add qmlinspector plugin.

parent 046dd5d9
......@@ -37,6 +37,10 @@ SUBDIRS = plugin_coreplugin \
plugin_mercurial \
debugger/dumper.pro
contains(QT_CONFIG, declarative) {
SUBDIRS += plugin_qmlinspector
}
plugin_coreplugin.subdir = coreplugin
plugin_welcome.subdir = welcome
......@@ -180,6 +184,11 @@ plugin_qmlprojectmanager.depends += plugin_projectexplorer
plugin_qmlprojectmanager.depends += plugin_help
plugin_qmlprojectmanager.depends += plugin_qmleditor
plugin_qmlinspector.subdir = qmlinspector
plugin_qmlinspector.depends += plugin_projectexplorer
plugin_qmlinspector.depends += plugin_coreplugin
plugin_qmlinspector.depends += plugin_texteditor
plugin_mercurial.subdir = mercurial
plugin_mercurial.depends = plugin_texteditor
plugin_mercurial.depends = plugin_vcsbase
......
<plugin name="QmlInspector" version="1.3.80" compatVersion="1.3.80">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2008-2009 Nokia Corporation</copyright>
<license>
Commercial Usage
Licensees holding valid Qt Commercial licenses may use this plugin in
accordance with the Qt Commercial License Agreement provided with the
Software or, alternatively, in accordance with the terms contained in
a written agreement between you and Nokia.
GNU Lesser General Public License Usage
Alternatively, this plugin may be used under the terms of the GNU Lesser
General Public License version 2.1 as published by the Free Software
Foundation. Please review the following information to
ensure the GNU Lesser General Public License version 2.1 requirements
will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license>
<description>Qml support</description>
<url>http://qt.nokia.com</url>
<dependencyList>
<dependency name="QmlProjectManager" version="1.3.80"/>
<dependency name="ProjectExplorer" version="1.3.80"/>
<dependency name="CppTools" version="1.3.80"/>
<dependency name="CppEditor" version="1.3.80"/>
<dependency name="Help" version="1.3.80"/>
</dependencyList>
</plugin>
This diff is collapsed.
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef CANVASFRAMERATE_H
#define CANVASFRAMERATE_H
#include <private/qmldebugclient_p.h>
#include <QtCore/qpointer.h>
#include <QtGui/qwidget.h>
QT_BEGIN_NAMESPACE
class QTabWidget;
class QSlider;
class QGroupBox;
class QLabel;
class QSpinBox;
class QPushButton;
class CanvasFrameRatePlugin;
class CanvasFrameRate : public QWidget
{
Q_OBJECT
public:
CanvasFrameRate(QWidget *parent = 0);
void reset(QmlDebugConnection *conn);
void setSizeHint(const QSize &);
virtual QSize sizeHint() const;
private slots:
void clearGraph();
void newTab();
void enabledToggled(bool);
void connectionStateChanged(QAbstractSocket::SocketState state);
private:
void handleConnected(QmlDebugConnection *conn);
QGroupBox *m_group;
QTabWidget *m_tabs;
QSpinBox *m_res;
QPushButton *m_clearButton;
CanvasFrameRatePlugin *m_plugin;
QSize m_sizeHint;
};
QT_END_NAMESPACE
#endif // CANVASFRAMERATE_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "engine.h"
#include "objectpropertiesview.h"
#include "expressionquerywidget.h"
#include "objecttree.h"
#include "watchtable.h"
#include <private/qmlenginedebug_p.h>
#include <private/qmldebugclient_p.h>
#include <private/qmldebugservice_p.h>
#include <QtDeclarative/qmlcomponent.h>
#include <QtDeclarative/qmlgraphicsitem.h>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QSplitter>
#include <QTabWidget>
#include <QFile>
QT_BEGIN_NAMESPACE
class DebuggerEngineItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name CONSTANT);
Q_PROPERTY(int engineId READ engineId CONSTANT);
public:
DebuggerEngineItem(const QString &name, int id)
: m_name(name), m_engineId(id) {}
QString name() const { return m_name; }
int engineId() const { return m_engineId; }
private:
QString m_name;
int m_engineId;
};
EnginePane::EnginePane(QmlDebugConnection *conn, QWidget *parent)
: QWidget(parent), m_client(new QmlEngineDebug(conn, this)), m_engines(0), m_context(0), m_watchTableModel(0), m_exprQueryWidget(0)
{
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setContentsMargins(0, 0, 0, 0);
QFile enginesFile(":/engines.qml");
enginesFile.open(QFile::ReadOnly);
Q_ASSERT(enginesFile.isOpen());
m_engineView = new QmlView(this);
m_engineView->rootContext()->setContextProperty("engines", qVariantFromValue(&m_engineItems));
m_engineView->setContentResizable(true);
m_engineView->setQml(enginesFile.readAll());
m_engineView->execute();
m_engineView->setFixedHeight(100);
QObject::connect(m_engineView->root(), SIGNAL(engineClicked(int)),
this, SLOT(engineSelected(int)));
QObject::connect(m_engineView->root(), SIGNAL(refreshEngines()),
this, SLOT(refreshEngines()));
m_engineView->setVisible(false);
layout->addWidget(m_engineView);
QSplitter *splitter = new QSplitter;
m_objTree = new ObjectTree(m_client, this);
m_propertiesView = new ObjectPropertiesView(m_client);
m_watchTableModel = new WatchTableModel(m_client, this);
m_watchTableView = new WatchTableView(m_watchTableModel);
m_watchTableView->setModel(m_watchTableModel);
WatchTableHeaderView *header = new WatchTableHeaderView(m_watchTableModel);
m_watchTableView->setHorizontalHeader(header);
connect(m_objTree, SIGNAL(currentObjectChanged(QmlDebugObjectReference)),
m_propertiesView, SLOT(reload(QmlDebugObjectReference)));
connect(m_objTree, SIGNAL(expressionWatchRequested(QmlDebugObjectReference,QString)),
m_watchTableModel, SLOT(expressionWatchRequested(QmlDebugObjectReference,QString)));
connect(m_propertiesView, SIGNAL(activated(QmlDebugObjectReference,QmlDebugPropertyReference)),
m_watchTableModel, SLOT(togglePropertyWatch(QmlDebugObjectReference,QmlDebugPropertyReference)));
connect(m_watchTableModel, SIGNAL(watchCreated(QmlDebugWatch*)),
m_propertiesView, SLOT(watchCreated(QmlDebugWatch*)));
connect(m_watchTableView, SIGNAL(objectActivated(int)),
m_objTree, SLOT(setCurrentObject(int)));
m_exprQueryWidget = new ExpressionQueryWidget(ExpressionQueryWidget::SeparateEntryMode, m_client);
connect(m_objTree, SIGNAL(currentObjectChanged(QmlDebugObjectReference)),
m_exprQueryWidget, SLOT(setCurrentObject(QmlDebugObjectReference)));
QSplitter *propertiesTab = new QSplitter(Qt::Vertical);
propertiesTab->addWidget(m_propertiesView);
propertiesTab->addWidget(m_exprQueryWidget);
propertiesTab->setStretchFactor(0, 2);
propertiesTab->setStretchFactor(1, 1);
m_tabs = new QTabWidget(this);
m_tabs->addTab(propertiesTab, tr("Properties"));
m_tabs->addTab(m_watchTableView, tr("Watched"));
splitter->addWidget(m_objTree);
splitter->addWidget(m_tabs);
splitter->setStretchFactor(1, 2);
layout->addWidget(splitter);
}
void EnginePane::engineSelected(int id)
{
qWarning() << "Engine selected" << id;
queryContext(id);
}
void EnginePane::queryContext(int id)
{
if (m_context) {
delete m_context;
m_context = 0;
}
m_context = m_client->queryRootContexts(QmlDebugEngineReference(id), this);
if (!m_context->isWaiting())
contextChanged();
else
QObject::connect(m_context, SIGNAL(stateChanged(QmlDebugQuery::State)),
this, SLOT(contextChanged()));
}
void EnginePane::contextChanged()
{
//dump(m_context->rootContext(), 0);
foreach (const QmlDebugObjectReference &object, m_context->rootContext().objects())
m_objTree->reload(object.debugId());
delete m_context; m_context = 0;
}
void EnginePane::refreshEngines()
{
if (m_engines)
return;
m_engines = m_client->queryAvailableEngines(this);
if (!m_engines->isWaiting())
enginesChanged();
else
QObject::connect(m_engines, SIGNAL(stateChanged(QmlDebugQuery::State)),
this, SLOT(enginesChanged()));
}
void EnginePane::enginesChanged()
{
qDeleteAll(m_engineItems);
m_engineItems.clear();
QList<QmlDebugEngineReference> engines = m_engines->engines();
delete m_engines; m_engines = 0;
if (engines.isEmpty())
qWarning("qmldebugger: no engines found!");
for (int ii = 0; ii < engines.count(); ++ii)
m_engineItems << new DebuggerEngineItem(engines.at(ii).name(),
engines.at(ii).debugId());
m_engineView->rootContext()->setContextProperty("engines", qVariantFromValue(&m_engineItems));
m_engineView->setVisible(m_engineItems.count() > 1);
if (m_engineItems.count() == 1)
engineSelected(qobject_cast<DebuggerEngineItem*>(m_engineItems.at(0))->engineId());
}
#include "engine.moc"
QT_END_NAMESPACE
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef ENGINE_H
#define ENGINE_H
#include <private/qmldebug_p.h>
#include <QtDeclarative/qmlengine.h>
#include <QtDeclarative/qmlcontext.h>
#include <QtDeclarative/qmlview.h>
#include <QtCore/qpointer.h>
#include <QtGui/qwidget.h>
QT_BEGIN_NAMESPACE
class ObjectPropertiesView;
class QmlDebugConnection;
class QmlDebugPropertyReference;
class QmlDebugWatch;
class ObjectTree;
class WatchTableModel;
class WatchTableView;
class ExpressionQueryWidget;
class QTabWidget;
class EnginePane : public QWidget
{
Q_OBJECT
public:
EnginePane(QmlDebugConnection *, QWidget *parent = 0);
public slots:
void refreshEngines();
private slots:
void enginesChanged();
void queryContext(int);
void contextChanged();
void engineSelected(int);
private:
QmlEngineDebug *m_client;
QmlDebugEnginesQuery *m_engines;
QmlDebugRootContextQuery *m_context;
ObjectTree *m_objTree;
QTabWidget *m_tabs;
WatchTableView *m_watchTableView;
WatchTableModel *m_watchTableModel;
ExpressionQueryWidget *m_exprQueryWidget;
QmlView *m_engineView;
QList<QObject *> m_engineItems;
ObjectPropertiesView *m_propertiesView;
};
QT_END_NAMESPACE
#endif // ENGINE_H
import Qt 4.6
Item {
height: 100
id: Root
signal engineClicked(int id)
signal refreshEngines()
Row {
anchors.fill: parent
Repeater {
model: engines
Item {
width: 100; height: 100;
Image {
id: EngineIcon;
source: "qrc:/engine.png"
anchors.horizontalCenter: parent.horizontalCenter
}
Text {
anchors.top: EngineIcon.bottom;
text: modelData.name + "(" + modelData.engineId + ")"
anchors.horizontalCenter: parent.horizontalCenter
}
MouseRegion {
anchors.fill: parent
onClicked: Root.engineClicked(modelData.engineId);
}
}
}
}
Image {
y: 15
source: "qrc:/refresh.png";
width: 75;
height: 63;
smooth: true
anchors.right: parent.right
MouseRegion {
anchors.fill: parent
onClicked: Root.refreshEngines()
}
}
}
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "expressionquerywidget.h"
#include <QtCore/qdebug.h>
#include <QtGui/qlabel.h>
#include <QtGui/qtextedit.h>
#include <QtGui/qlineedit.h>
#include <QtGui/qpushbutton.h>
#include <QtGui/qevent.h>
#include <QtGui/qgroupbox.h>
#include <QtGui/qtextobject.h>
#include <QtGui/qlayout.h>
ExpressionQueryWidget::ExpressionQueryWidget(Mode mode, QmlEngineDebug *client, QWidget *parent)
: QWidget(parent),
m_mode(mode),
m_client(client),
m_query(0),
m_textEdit(new QTextEdit),
m_lineEdit(0)
{
m_prompt = QLatin1String(">> ");
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(m_textEdit);
updateTitle();
if (m_mode == SeparateEntryMode) {
m_lineEdit = new QLineEdit;
connect(m_lineEdit, SIGNAL(returnPressed()), SLOT(executeExpression()));
QHBoxLayout *hbox = new QHBoxLayout;
hbox->setMargin(5);
hbox->setSpacing(5);
hbox->addWidget(new QLabel(tr("Expression:")));
hbox->addWidget(m_lineEdit);
layout->addLayout(hbox);
m_textEdit->setReadOnly(true);
m_lineEdit->installEventFilter(this);
} else {
m_textEdit->installEventFilter(this);
appendPrompt();
}
}
void ExpressionQueryWidget::setEngineDebug(QmlEngineDebug *client)
{
m_client = client;
}
void ExpressionQueryWidget::clear()
{
m_textEdit->clear();
if (m_lineEdit)
m_lineEdit->clear();
if (m_mode == ShellMode)
appendPrompt();
}
void ExpressionQueryWidget::updateTitle()
{
if (m_currObject.debugId() < 0) {
m_title = tr("Expression queries");
} else {
QString desc = QLatin1String("<")
+ m_currObject.className() + QLatin1String(": ")
+ (m_currObject.name().isEmpty() ? QLatin1String("<unnamed>") : m_currObject.name())
+ QLatin1String(">");
m_title = tr("Expression queries (using context for %1)" , "Selected object").arg(desc);
}
}
void ExpressionQueryWidget::appendPrompt()
{
m_textEdit->moveCursor(QTextCursor::End);
if (m_mode == SeparateEntryMode) {
m_textEdit->insertPlainText("\n");
} else {
m_textEdit->setTextColor(Qt::gray);
m_textEdit->append(m_prompt);
}
}
void ExpressionQueryWidget::setCurrentObject(const QmlDebugObjectReference &obj)
{
m_currObject = obj;
updateTitle();
}
void ExpressionQueryWidget::checkCurrentContext()
{
m_textEdit->moveCursor(QTextCursor::End);
if (m_currObject.debugId() != -1 && m_currObject.debugId() != m_objectAtLastFocus.debugId())
showCurrentContext();
m_objectAtLastFocus = m_currObject;
}
void ExpressionQueryWidget::showCurrentContext()
{
if (m_mode == ShellMode) {
// clear the initial prompt