summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/debugger/debugger.pri3
-rw-r--r--src/declarative/debugger/qmldebugger.cpp243
-rw-r--r--src/declarative/debugger/qmldebugger.h82
-rw-r--r--src/declarative/declarative.pro1
-rw-r--r--src/declarative/qml/qmlboundsignal.cpp1
-rw-r--r--src/declarative/qml/qmlcompiler.cpp9
-rw-r--r--src/declarative/qml/qmlcomponent.cpp5
-rw-r--r--src/declarative/qml/qmlcontext.cpp2
-rw-r--r--src/declarative/qml/qmlcontext_p.h3
-rw-r--r--src/declarative/qml/qmlinstruction_p.h1
-rw-r--r--src/declarative/qml/qmlparser.cpp2
-rw-r--r--src/declarative/qml/qmlparser_p.h3
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp5
-rw-r--r--src/declarative/util/qfxview.cpp10
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp1
15 files changed, 368 insertions, 3 deletions
diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri
new file mode 100644
index 0000000..ea5219a
--- /dev/null
+++ b/src/declarative/debugger/debugger.pri
@@ -0,0 +1,3 @@
+SOURCES += debugger/qmldebugger.cpp
+
+HEADERS += debugger/qmldebugger.h
diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp
new file mode 100644
index 0000000..1f7fd68
--- /dev/null
+++ b/src/declarative/debugger/qmldebugger.cpp
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmldebugger.h"
+#include <QtGui/qtreewidget.h>
+#include <QtGui/qboxlayout.h>
+#include <QtGui/qplaintextedit.h>
+#include <QtDeclarative/qmlbindablevalue.h>
+#include <private/qmlboundsignal_p.h>
+#include <private/qmlcontext_p.h>
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qurl.h>
+#include <QtGui/qsplitter.h>
+#include <QtGui/qpushbutton.h>
+#include <QtGui/qevent.h>
+
+QmlDebugger::QmlDebugger(QWidget *parent)
+: QWidget(parent), m_tree(0)
+{
+ QHBoxLayout *layout = new QHBoxLayout;
+ setLayout(layout);
+ QSplitter *splitter = new QSplitter(this);
+ layout->addWidget(splitter);
+
+ QWidget *treeWid = new QWidget(this);
+ QVBoxLayout *vlayout = new QVBoxLayout;
+ vlayout->setContentsMargins(0, 0, 0, 0);
+ treeWid->setLayout(vlayout);
+ splitter->addWidget(treeWid);
+
+ m_tree = new QTreeWidget(treeWid);
+ m_tree->setHeaderHidden(true);
+ QObject::connect(m_tree, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this, SLOT(itemPressed(QTreeWidgetItem *)));
+ vlayout->addWidget(m_tree);
+
+ QPushButton *pb = new QPushButton("Refresh", treeWid);
+ QObject::connect(pb, SIGNAL(clicked()), this, SLOT(refresh()));
+ vlayout->addWidget(pb);
+
+ m_text = new QPlainTextEdit(this);
+ m_text->setReadOnly(true);
+ splitter->addWidget(m_text);
+ splitter->setStretchFactor(1, 2);
+}
+
+class QmlDebuggerItem : public QTreeWidgetItem
+{
+public:
+ QmlDebuggerItem(QTreeWidget *wid)
+ : QTreeWidgetItem(wid), startLine(-1), endLine(-1)
+ {
+ }
+
+ QmlDebuggerItem(QTreeWidgetItem *item)
+ : QTreeWidgetItem(item), startLine(-1), endLine(-1)
+ {
+ }
+
+ int startLine;
+ int endLine;
+ QUrl url;
+};
+
+void QmlDebugger::itemPressed(QTreeWidgetItem *i)
+{
+ QmlDebuggerItem *item = static_cast<QmlDebuggerItem *>(i);
+
+ if(item->url.scheme() == QLatin1String("file")) {
+ QString f = item->url.toLocalFile();
+ QFile file(f);
+ file.open(QIODevice::ReadOnly);
+ QByteArray ba = file.readAll();
+ QTextStream stream(ba, QIODevice::ReadOnly);
+ const QString code = stream.readAll();
+
+ m_text->setPlainText(code);
+
+ if(item->startLine != -1) {
+ QTextDocument *document = m_text->document();
+ QTextCharFormat format;
+ format.setForeground(Qt::lightGray);
+ {
+ QTextCursor cursor(document);
+ cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
+ cursor.movePosition(QTextCursor::Down, QTextCursor::KeepAnchor, item->startLine - 1);
+ cursor.setCharFormat(format);
+ }
+
+ {
+ QTextCursor cursor(document);
+ cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
+ cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, item->endLine);
+ cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
+ cursor.setCharFormat(format);
+ }
+
+ {
+ QTextCursor cursor(document);
+ cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
+ cursor.setCharFormat(QTextCharFormat());
+ }
+
+ {
+ QTextCursor cursor(document);
+ cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
+ cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, item->startLine - 1);
+ m_text->setTextCursor(cursor);
+ m_text->centerCursor();
+ }
+ }
+
+ }
+}
+
+static bool makeItem(QObject *obj, QmlDebuggerItem *item)
+{
+ bool rv = true;
+
+ QString text;
+
+ if(QmlBindableValue *bv = qobject_cast<QmlBindableValue *>(obj)) {
+ text = bv->property().name() + ": " + bv->expression();
+ item->setForeground(0, Qt::green);
+ } else if(QmlBoundSignal *bs = qobject_cast<QmlBoundSignal *>(obj)) {
+ QMetaMethod method = obj->parent()->metaObject()->method(bs->index());
+ QByteArray sig = method.signature();
+ if(!sig.isEmpty())
+ text = sig + ": ";
+ text += bs->expression();
+ item->setForeground(0, Qt::blue);
+ rv = false;
+ } else {
+ QmlContext *context = qmlContext(obj);
+ QmlContext *parentContext = qmlContext(obj->parent());
+
+ text = QLatin1String(obj->metaObject()->className());
+
+ if(context && context != parentContext) {
+ QmlContextPrivate *p = static_cast<QmlContextPrivate *>(QObjectPrivate::get(context));
+
+ QString toolTipString;
+ if(!p->url.toString().isEmpty()) {
+ item->url = p->url;
+ toolTipString = "URL: " + p->url.toString();
+ }
+
+ if(!p->typeName.isEmpty()) {
+ if(!toolTipString.isEmpty())
+ toolTipString.prepend("\n");
+ toolTipString.prepend("Root type: " + text);
+ text = p->typeName;
+ }
+
+ if(!toolTipString.isEmpty())
+ item->setToolTip(0, toolTipString);
+
+ item->setForeground(0, QColor("orange"));
+
+ if(p->startLine != -1) {
+ item->startLine = p->startLine;
+ item->endLine = p->endLine;
+ }
+
+ } else {
+ item->setExpanded(true);
+ }
+ }
+
+ item->setText(0, text);
+
+ return rv;
+}
+
+static void buildTree(QObject *obj, QmlDebuggerItem *parent)
+{
+ QObjectList children = obj->children();
+
+ for (int ii = 0; ii < children.count(); ++ii) {
+ QmlDebuggerItem *item = new QmlDebuggerItem(parent);
+ if(makeItem(children.at(ii), item))
+ buildTree(children.at(ii), item);
+ }
+}
+
+void QmlDebugger::refresh()
+{
+ setDebugObject(m_object);
+}
+
+void QmlDebugger::setDebugObject(QObject *obj)
+{
+ m_tree->clear();
+
+ m_object = obj;
+ if(!obj)
+ return;
+
+ QmlDebuggerItem *item = new QmlDebuggerItem(m_tree);
+ makeItem(obj, item);
+ buildTree(obj, item);
+ item->setExpanded(true);
+ setGeometry(0, 100, 800, 600);
+}
+
diff --git a/src/declarative/debugger/qmldebugger.h b/src/declarative/debugger/qmldebugger.h
new file mode 100644
index 0000000..943abef
--- /dev/null
+++ b/src/declarative/debugger/qmldebugger.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** 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.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMLDEBUGGER_H
+#define QMLDEBUGGER_H
+
+#include <QtCore/qpointer.h>
+#include <QtGui/qwidget.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QTreeWidget;
+class QTreeWidgetItem;
+class QPlainTextEdit;
+class QmlDebugger : public QWidget
+{
+Q_OBJECT
+public:
+ QmlDebugger(QWidget *parent = 0);
+
+ void setDebugObject(QObject *);
+
+public slots:
+ void refresh();
+
+private slots:
+ void itemPressed(QTreeWidgetItem *);
+
+private:
+ QTreeWidget *m_tree;
+ QPlainTextEdit *m_text;
+ QPointer<QObject> m_object;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMLDEBUGGER_H
+
diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro
index 30704d0..1e8e82b 100644
--- a/src/declarative/declarative.pro
+++ b/src/declarative/declarative.pro
@@ -21,5 +21,6 @@ include(timeline/timeline.pri)
include(extra/extra.pri)
include(widgets/widgets.pri)
include(test/test.pri)
+include(debugger/debugger.pri)
contains(QT_CONFIG, opengles2)|contains(QT_CONFIG, opengles1):include(opengl/opengl.pri)
diff --git a/src/declarative/qml/qmlboundsignal.cpp b/src/declarative/qml/qmlboundsignal.cpp
index 67e3dcf..5815dc6 100644
--- a/src/declarative/qml/qmlboundsignal.cpp
+++ b/src/declarative/qml/qmlboundsignal.cpp
@@ -99,6 +99,7 @@ QmlBoundSignalParameters::QmlBoundSignalParameters(const QMetaMethod &method,
// ### Ensure only supported types are allowed, otherwise it might crash
QMetaObjectBuilder mob;
mob.setSuperClass(&QmlBoundSignalParameters::staticMetaObject);
+ mob.setClassName("QmlBoundSignalParameters");
QList<QByteArray> paramTypes = method.parameterTypes();
QList<QByteArray> paramNames = method.parameterNames();
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 67a0a04..9ae1278 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -60,6 +60,7 @@
#include <qmlmetatype.h>
#include <QtCore/qdebug.h>
#include "private/qmlcustomparser_p_p.h"
+#include <private/qmlcontext_p.h>
#include "qmlscriptparser_p.h"
@@ -675,6 +676,7 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
QmlInstruction &create = output->bytecode.last();
create.type = QmlInstruction::CreateComponent;
create.line = obj->line;
+ create.createComponent.endLine = obj->endLine;
int count = output->bytecode.count();
QmlInstruction init;
@@ -1468,7 +1470,12 @@ QObject *QmlCompiledData::TypeReference::createInstance(QmlContext *ctxt) const
QmlEngine::setContextForObject(rv, ctxt);
return rv;
} else if (component) {
- return component->create(ctxt);
+ QObject *rv = component->create(ctxt);
+ QmlContext *ctxt = qmlContext(rv);
+ if(ctxt) {
+ static_cast<QmlContextPrivate *>(QObjectPrivate::get(ctxt))->typeName = className;
+ }
+ return rv;
} else {
return 0;
}
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index b257d5f..027c2a8 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -462,6 +462,11 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
QmlContext *ctxt =
new QmlContext(context, 0);
static_cast<QmlContextPrivate*>(ctxt->d_ptr)->url = d->cc->url;
+ if(d->start != -1) {
+ // ### FIXME
+ static_cast<QmlContextPrivate*>(ctxt->d_ptr)->startLine = d->cc->bytecode.at(d->start - 1).line;
+ static_cast<QmlContextPrivate*>(ctxt->d_ptr)->endLine = d->cc->bytecode.at(d->start - 1).createComponent.endLine;
+ }
ctxt->activate();
QmlVME vme;
diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp
index 68453c3..7187c4c 100644
--- a/src/declarative/qml/qmlcontext.cpp
+++ b/src/declarative/qml/qmlcontext.cpp
@@ -53,7 +53,7 @@
QT_BEGIN_NAMESPACE
QmlContextPrivate::QmlContextPrivate()
- : parent(0), engine(0), highPriorityCount(0)
+ : parent(0), engine(0), highPriorityCount(0), startLine(-1), endLine(-1)
{
}
diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h
index 40848fb..d7c6d29 100644
--- a/src/declarative/qml/qmlcontext_p.h
+++ b/src/declarative/qml/qmlcontext_p.h
@@ -70,6 +70,9 @@ public:
QScriptValueList scopeChain;
QUrl url;
+ QByteArray typeName;
+ int startLine;
+ int endLine;
void init();
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 01bdfdd..e9c81d6 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -275,6 +275,7 @@ public:
} assignSignalObject;
struct {
int count;
+ int endLine;
} createComponent;
struct {
int id;
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index d68eb68..a6cb2ca 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
using namespace QmlParser;
QmlParser::Object::Object()
-: type(-1), metatype(0), extObjectData(0), defaultProperty(0), line(-1), column(-1)
+: type(-1), metatype(0), extObjectData(0), defaultProperty(0), line(-1), column(-1), endLine(-1), endColumn(-1)
{
}
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index 2c9b0f1..aa22928 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -106,6 +106,9 @@ namespace QmlParser
qint64 line;
qint64 column;
+ qint64 endLine;
+ qint64 endColumn;
+
struct DynamicProperty {
DynamicProperty();
DynamicProperty(const DynamicProperty &);
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index aed17d6..8be0e5a 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -235,6 +235,11 @@ Object *ProcessAST::defineObjectBinding_helper(int line,
_scope.removeLast();
obj->line = line;
+ if(initializer) {
+ obj->endLine = initializer->rbraceToken.startLine;
+ obj->endColumn = initializer->rbraceToken.startColumn;
+ }
+
if (propertyCount) {
Property *prop = currentProperty();
Value *v = new Value;
diff --git a/src/declarative/util/qfxview.cpp b/src/declarative/util/qfxview.cpp
index 1315f19..ea2719d 100644
--- a/src/declarative/util/qfxview.cpp
+++ b/src/declarative/util/qfxview.cpp
@@ -60,10 +60,12 @@
#include "qfxview.h"
#include <QtDeclarative/qmlengine.h>
#include <QtDeclarative/qmlcontext.h>
+#include <QtDeclarative/qmldebugger.h>
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(itemTreeDump, ITEMTREE_DUMP);
+DEFINE_BOOL_CONFIG_OPTION(qmlDebugger, QML_DEBUGGER);
static QVariant stringToPixmap(const QString &str)
{
@@ -324,6 +326,14 @@ void QFxView::continueExecute()
if (itemTreeDump())
item->dump();
+ if(qmlDebugger()) {
+ QmlDebugger *debugger = new QmlDebugger;
+ debugger->setDebugObject(item);
+ debugger->show();
+ raise();
+ debugger->raise();
+ }
+
QPerformanceLog::displayData();
QPerformanceLog::clear();
d->root = item;
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp
index 87d8f4d..fc20fa9 100644
--- a/src/declarative/util/qmlopenmetaobject.cpp
+++ b/src/declarative/util/qmlopenmetaobject.cpp
@@ -48,6 +48,7 @@ QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic)
: autoCreate(automatic), parent(0), mem(0), _object(obj)
{
mob.setSuperClass(obj->metaObject());
+ mob.setClassName(obj->metaObject()->className());
mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
QObjectPrivate *op = QObjectPrivate::get(obj);