diff options
Diffstat (limited to 'src')
20 files changed, 601 insertions, 70 deletions
diff --git a/src/declarative/canvas/qsimplecanvas.cpp b/src/declarative/canvas/qsimplecanvas.cpp index ce02a4c..e1dd0e8 100644 --- a/src/declarative/canvas/qsimplecanvas.cpp +++ b/src/declarative/canvas/qsimplecanvas.cpp @@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(fullUpdate, GFX_CANVAS_FULL_UPDATE); DEFINE_BOOL_CONFIG_OPTION(continuousUpdate, GFX_CANVAS_CONTINUOUS_UPDATE); -DEFINE_BOOL_CONFIG_OPTION(useGraphicsView, QFX_USE_GRAPHICSVIEW); +DEFINE_BOOL_CONFIG_OPTION(useSimpleCanvas, QFX_USE_SIMPLECANVAS); template<class T, int s = 60> class CircularList @@ -556,7 +556,7 @@ QSimpleCanvas::QSimpleCanvas(CanvasMode mode, QWidget *parent) QSimpleCanvas::QSimpleCanvas(QWidget *parent) : QWidget(parent), d(new QSimpleCanvasPrivate(this)) { - d->init(useGraphicsView()?SimpleCanvas:GraphicsView); + d->init(useSimpleCanvas()?SimpleCanvas:GraphicsView); } void QSimpleCanvasPrivate::init(QSimpleCanvas::CanvasMode mode) @@ -904,6 +904,13 @@ QSimpleCanvasItem *QSimpleCanvas::activeFocusPanel() const return d->focusPanels.top(); } +QSimpleCanvasItem *QSimpleCanvas::focusItem(QSimpleCanvasItem *item) const +{ + while (item && d->focusPanelData.contains(item)) + item = d->focusPanelData.value(item); + return item; +} + bool QSimpleCanvas::event(QEvent *e) { if (e->type() == QEvent::User && d->isSimpleCanvas()) { diff --git a/src/declarative/canvas/qsimplecanvas.h b/src/declarative/canvas/qsimplecanvas.h index a35cbf5..20dab28 100644 --- a/src/declarative/canvas/qsimplecanvas.h +++ b/src/declarative/canvas/qsimplecanvas.h @@ -141,6 +141,8 @@ public: void checkState(); QSimpleCanvasItem *focusItem() const; + QSimpleCanvasItem *focusItem(QSimpleCanvasItem *item) const; + QSimpleCanvasItem *activeFocusPanel() const; QImage asImage() const; diff --git a/src/declarative/canvas/qsimplecanvas_software.cpp b/src/declarative/canvas/qsimplecanvas_software.cpp index c130a62..194024d 100644 --- a/src/declarative/canvas/qsimplecanvas_software.cpp +++ b/src/declarative/canvas/qsimplecanvas_software.cpp @@ -172,6 +172,11 @@ void QSimpleCanvasItemPrivate::paint(QPainter &p) if (clip) p.restore(); + + if (debuggerStatus && debuggerStatus->selected) { + p.setWorldTransform(data()->transformActive); + p.fillRect(q->boundingRect(), QColor(255, 0, 0, 80)); + } } void QSimpleCanvasItemPrivate::paintChild(QPainter &p, QSimpleCanvasItem *c) diff --git a/src/declarative/canvas/qsimplecanvasitem.cpp b/src/declarative/canvas/qsimplecanvasitem.cpp index 62a44e4..ba33a41 100644 --- a/src/declarative/canvas/qsimplecanvasitem.cpp +++ b/src/declarative/canvas/qsimplecanvasitem.cpp @@ -1380,6 +1380,14 @@ QSimpleCanvasItem::operator QGraphicsItem *() return d->graphicsItem; } +QSimpleCanvasItem::operator QmlDebuggerStatus *() +{ + Q_D(QSimpleCanvasItem); + if(!d->debuggerStatus) + d->debuggerStatus = new QSimpleCanvasItemDebuggerStatus(this); + return d->debuggerStatus; +} + QPointF QSimpleCanvasItemPrivate::transformOrigin() const { Q_Q(const QSimpleCanvasItem); diff --git a/src/declarative/canvas/qsimplecanvasitem.h b/src/declarative/canvas/qsimplecanvasitem.h index 83f19c3..cab8492 100644 --- a/src/declarative/canvas/qsimplecanvasitem.h +++ b/src/declarative/canvas/qsimplecanvasitem.h @@ -42,10 +42,11 @@ #ifndef QSIMPLECANVASITEM_H #define QSIMPLECANVASITEM_H -#include <qfxglobal.h> -#include <qsimplecanvas.h> -#include <QObject> -#include <QGraphicsItem> +#include <QtDeclarative/qfxglobal.h> +#include <QtDeclarative/qmldebuggerstatus.h> +#include <QtDeclarative/qsimplecanvas.h> +#include <QtCore/qobject.h> +#include <QtGui/qgraphicsitem.h> class QPainter; QT_BEGIN_HEADER @@ -70,6 +71,7 @@ class Q_DECLARATIVE_EXPORT QSimpleCanvasItem : public QObject { Q_OBJECT Q_CAST_INTERFACES(QGraphicsItem) + Q_CAST_INTERFACES(QmlDebuggerStatus) Q_DECLARE_PRIVATE(QSimpleCanvasItem) Q_ENUMS(TransformOrigin) Q_PROPERTY(TransformOrigin transformOrigin READ transformOrigin WRITE setTransformOrigin); @@ -94,6 +96,7 @@ public: QSimpleCanvasItem(QSimpleCanvasItem *parent=0); virtual ~QSimpleCanvasItem(); operator QGraphicsItem *(); + operator QmlDebuggerStatus *(); bool clip() const; void setClip(bool); diff --git a/src/declarative/canvas/qsimplecanvasitem_p.h b/src/declarative/canvas/qsimplecanvasitem_p.h index 27a75bd..cfe0bba 100644 --- a/src/declarative/canvas/qsimplecanvasitem_p.h +++ b/src/declarative/canvas/qsimplecanvasitem_p.h @@ -110,6 +110,22 @@ public: #endif }; +class QSimpleCanvasItemDebuggerStatus : public QmlDebuggerStatus +{ +public: + QSimpleCanvasItemDebuggerStatus(QSimpleCanvasItem *i) + : item(i), selected(false) {} + + virtual void setSelectedState(bool state) + { + selected = state; + item->update(); + } + + QSimpleCanvasItem *item; + bool selected; +}; + class QSimpleCanvasFilter; class QGraphicsQSimpleCanvasItem; class QSimpleCanvasItemPrivate : public QObjectPrivate @@ -117,7 +133,8 @@ class QSimpleCanvasItemPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QSimpleCanvasItem); public: QSimpleCanvasItemPrivate() - : parent(0), canvas(0), filter(0), clip(QSimpleCanvasItem::NoClip), + : parent(0), canvas(0), debuggerStatus(0), filter(0), + clip(QSimpleCanvasItem::NoClip), origin(QSimpleCanvasItem::TopLeft), options(QSimpleCanvasItem::NoOption), focusable(false), wantsActiveFocusPanelPendingCanvas(false), hasBeenActiveFocusPanel(false), @@ -127,12 +144,16 @@ public: { } - virtual ~QSimpleCanvasItemPrivate() {} + virtual ~QSimpleCanvasItemPrivate() + { + if(debuggerStatus) delete debuggerStatus; + } QSimpleCanvasItem *parent; QSimpleCanvas *canvas; QList<QSimpleCanvasItem *> children; + QSimpleCanvasItemDebuggerStatus *debuggerStatus; QSimpleCanvasFilter *filter; QSimpleCanvasItem::ClipType clip:3; diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri index ea5219a..31a1d5b 100644 --- a/src/declarative/debugger/debugger.pri +++ b/src/declarative/debugger/debugger.pri @@ -1,3 +1,7 @@ -SOURCES += debugger/qmldebugger.cpp +SOURCES += debugger/qmldebugger.cpp \ + debugger/qmldebuggerstatus.cpp \ + debugger/qmlpropertyview.cpp -HEADERS += debugger/qmldebugger.h +HEADERS += debugger/qmldebugger.h \ + debugger/qmldebuggerstatus.h \ + debugger/qmlpropertyview_p.h diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp index 033a15f..634385b 100644 --- a/src/declarative/debugger/qmldebugger.cpp +++ b/src/declarative/debugger/qmldebugger.cpp @@ -43,7 +43,10 @@ #include <QtGui/qtreewidget.h> #include <QtGui/qboxlayout.h> #include <QtGui/qplaintextedit.h> +#include <QTextBlock> +#include <QtGui/qtabwidget.h> #include <QtDeclarative/qmlbindablevalue.h> +#include <QtDeclarative/qmldebuggerstatus.h> #include <private/qmlboundsignal_p.h> #include <private/qmlcontext_p.h> #include <private/qmlengine_p.h> @@ -52,10 +55,13 @@ #include <QtCore/qurl.h> #include <QtGui/qsplitter.h> #include <QtGui/qpushbutton.h> +#include <QtGui/qtablewidget.h> #include <QtGui/qevent.h> +#include <private/qmlpropertyview_p.h> QmlDebugger::QmlDebugger(QWidget *parent) -: QWidget(parent), m_tree(0) +: QWidget(parent), m_tree(0), m_warnings(0), m_watchers(0), m_properties(0), + m_text(0) { QHBoxLayout *layout = new QHBoxLayout; setLayout(layout); @@ -69,18 +75,37 @@ QmlDebugger::QmlDebugger(QWidget *parent) splitter->addWidget(treeWid); m_tree = new QTreeWidget(treeWid); + m_tree->setSelectionMode(QTreeWidget::NoSelection); m_tree->setHeaderHidden(true); - QObject::connect(m_tree, SIGNAL(itemPressed(QTreeWidgetItem *, int)), this, SLOT(itemPressed(QTreeWidgetItem *))); + QObject::connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *))); + QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); vlayout->addWidget(m_tree); QPushButton *pb = new QPushButton("Refresh", treeWid); QObject::connect(pb, SIGNAL(clicked()), this, SLOT(refresh())); vlayout->addWidget(pb); + QTabWidget *tabs = new QTabWidget(this); + m_text = new QPlainTextEdit(this); m_text->setReadOnly(true); - splitter->addWidget(m_text); + tabs->addTab(m_text, "File"); + + m_warnings = new QTreeWidget(this); + m_warnings->setHeaderHidden(true); + tabs->addTab(m_warnings, "Warnings"); + + m_watchers = new QTableWidget(this); + m_watchers->setSelectionMode(QTableWidget::NoSelection); + tabs->addTab(m_watchers, "Watchers"); + + m_properties = new QmlPropertyView(this); + tabs->addTab(m_properties, "Properties"); + + splitter->addWidget(tabs); splitter->setStretchFactor(1, 2); + + setGeometry(0, 100, 800, 600); } class QmlDebuggerItem : public QTreeWidgetItem @@ -100,34 +125,53 @@ public: int endLine; QUrl url; + QPointer<QObject> object; QPointer<QmlBindableValue> bindableValue; }; -void QmlDebugger::itemPressed(QTreeWidgetItem *i) +void QmlDebugger::itemDoubleClicked(QTreeWidgetItem *i) { QmlDebuggerItem *item = static_cast<QmlDebuggerItem *>(i); if(item->bindableValue) { - QString str; - QmlExpressionPrivate *p = item->bindableValue->d; - if(p->log) { - QString str; - QDebug d(&str); - for(int ii = 0; ii < p->log->count(); ++ii) { - d << p->log->at(ii).result() << "\n"; - QStringList warnings = p->log->at(ii).warnings(); - foreach(const QString &warning, warnings) - d << " " << warning << "\n"; - } - m_text->setPlainText(str); + if(m_watchedIds.contains(p->id)) { + m_watchedIds.remove(p->id); + item->setForeground(0, Qt::green); } else { - m_text->setPlainText("No history"); + m_watchedIds.insert(p->id); + item->setForeground(0, QColor("purple")); } - } else if(item->url.scheme() == QLatin1String("file")) { + } +} + +void QmlDebugger::itemClicked(QTreeWidgetItem *i) +{ + QmlDebuggerItem *item = static_cast<QmlDebuggerItem *>(i); + + if(m_selectedItem) { + QmlDebuggerStatus *debug = + qobject_cast<QmlDebuggerStatus *>(m_selectedItem); + Q_ASSERT(debug); + debug->setSelectedState(false); + m_selectedItem = 0; + } + + if(item->object) { + QmlDebuggerStatus *debug = + qobject_cast<QmlDebuggerStatus *>(item->object); + if(debug) { + debug->setSelectedState(true); + m_selectedItem = item->object; + } + + m_properties->setObject(item->object); + } + + if(item->url.scheme() == QLatin1String("file")) { QString f = item->url.toLocalFile(); QFile file(f); file.open(QIODevice::ReadOnly); @@ -141,17 +185,11 @@ void QmlDebugger::itemPressed(QTreeWidgetItem *i) 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::NextBlock, QTextCursor::MoveAnchor, item->endLine); cursor.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); cursor.setCharFormat(format); } @@ -159,31 +197,89 @@ void QmlDebugger::itemPressed(QTreeWidgetItem *i) { QTextCursor cursor(document); cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - cursor.setCharFormat(QTextCharFormat()); + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor, item->startLine - 1); + cursor.setCharFormat(format); } { QTextCursor cursor(document); cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); - cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, item->startLine - 1); + cursor.movePosition(QTextCursor::NextBlock, QTextCursor::MoveAnchor, item->startLine - 1); m_text->setTextCursor(cursor); m_text->centerCursor(); } + + } } } -static bool makeItem(QObject *obj, QmlDebuggerItem *item) +bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) { bool rv = true; QString text; + item->object = obj; + if(QmlBindableValue *bv = qobject_cast<QmlBindableValue *>(obj)) { + QmlExpressionPrivate *p = bv->d; + text = bv->property().name() + ": " + bv->expression(); - item->setForeground(0, Qt::green); + bool watched = m_watchedIds.contains(p->id); + if(watched) + item->setForeground(0, QColor("purple")); + else + item->setForeground(0, Qt::green); item->bindableValue = bv; + + if(p->log) { + QTreeWidgetItem *warningItem = 0; + + int column = m_watchers->columnCount(); + + if(watched) { + m_watchers->insertColumn(column); + QTableWidgetItem *tableheader = new QTableWidgetItem; + tableheader->setText(bv->expression()); + tableheader->setToolTip(bv->expression()); + m_watchers->setHorizontalHeaderItem(column, tableheader); + } + + for(int ii = 0; ii < p->log->count(); ++ii) { + const QmlExpressionLog &log = p->log->at(ii); + + QString variant; QDebug d(&variant); d << log.result(); + if(watched) { + QString str = log.result().toString(); + if(str.isEmpty()) + str = variant; + m_expressions << qMakePair(log.time(), qMakePair(column, str)); + } + + if(!log.warnings().isEmpty()) { + + if(!warningItem) { + warningItem = new QTreeWidgetItem(m_warnings); + warningItem->setText(0, bv->expression()); + } + + QTreeWidgetItem *entry = new QTreeWidgetItem(warningItem); + entry->setExpanded(true); + + entry->setText(0, variant); + + foreach(const QString &warning, log.warnings()) { + QTreeWidgetItem *w = new QTreeWidgetItem(entry); + w->setText(0, warning); + } + } + + } + + } + } else if(QmlBoundSignal *bs = qobject_cast<QmlBoundSignal *>(obj)) { QMetaMethod method = obj->parent()->metaObject()->method(bs->index()); QByteArray sig = method.signature(); @@ -237,7 +333,7 @@ static bool makeItem(QObject *obj, QmlDebuggerItem *item) return rv; } -static void buildTree(QObject *obj, QmlDebuggerItem *parent) +void QmlDebugger::buildTree(QObject *obj, QmlDebuggerItem *parent) { QObjectList children = obj->children(); @@ -253,9 +349,20 @@ void QmlDebugger::refresh() setDebugObject(m_object); } +bool operator<(const QPair<quint32, QPair<int, QString> > &lhs, + const QPair<quint32, QPair<int, QString> > &rhs) +{ + return lhs.first < rhs.first; +} + void QmlDebugger::setDebugObject(QObject *obj) { m_tree->clear(); + m_warnings->clear(); + m_watchers->clear(); + m_watchers->setColumnCount(0); + m_watchers->setRowCount(0); + m_expressions.clear(); m_object = obj; if(!obj) @@ -265,6 +372,20 @@ void QmlDebugger::setDebugObject(QObject *obj) makeItem(obj, item); buildTree(obj, item); item->setExpanded(true); - setGeometry(0, 100, 800, 600); + + m_watchers->setRowCount(m_expressions.count()); + + qSort(m_expressions.begin(), m_expressions.end()); + + for(int ii = 0; ii < m_expressions.count(); ++ii) { + + const QPair<quint32, QPair<int, QString> > &expr = m_expressions.at(ii); + QTableWidgetItem *item = new QTableWidgetItem; + item->setText(expr.second.second); + m_watchers->setItem(ii, expr.second.first, item); + + } + + } diff --git a/src/declarative/debugger/qmldebugger.h b/src/declarative/debugger/qmldebugger.h index 943abef..35ff92c 100644 --- a/src/declarative/debugger/qmldebugger.h +++ b/src/declarative/debugger/qmldebugger.h @@ -43,6 +43,7 @@ #define QMLDEBUGGER_H #include <QtCore/qpointer.h> +#include <QtCore/qset.h> #include <QtGui/qwidget.h> QT_BEGIN_HEADER @@ -54,6 +55,9 @@ QT_MODULE(Declarative) class QTreeWidget; class QTreeWidgetItem; class QPlainTextEdit; +class QmlDebuggerItem; +class QTableWidget; +class QmlPropertyView; class QmlDebugger : public QWidget { Q_OBJECT @@ -66,12 +70,21 @@ public slots: void refresh(); private slots: - void itemPressed(QTreeWidgetItem *); + void itemClicked(QTreeWidgetItem *); + void itemDoubleClicked(QTreeWidgetItem *); private: + void buildTree(QObject *obj, QmlDebuggerItem *parent); + bool makeItem(QObject *obj, QmlDebuggerItem *item); QTreeWidget *m_tree; + QTreeWidget *m_warnings; + QTableWidget *m_watchers; + QmlPropertyView *m_properties; QPlainTextEdit *m_text; QPointer<QObject> m_object; + QList<QPair<quint32, QPair<int, QString> > > m_expressions; + QSet<quint32> m_watchedIds; + QPointer<QObject> m_selectedItem; }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qmldebuggerstatus.cpp b/src/declarative/debugger/qmldebuggerstatus.cpp new file mode 100644 index 0000000..d46a21d --- /dev/null +++ b/src/declarative/debugger/qmldebuggerstatus.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** 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 "qmldebuggerstatus.h" + +QT_BEGIN_NAMESPACE + +QmlDebuggerStatus::~QmlDebuggerStatus() +{ +} + +void QmlDebuggerStatus::setSelectedState(bool) +{ +} + +QT_END_NAMESPACE diff --git a/src/declarative/debugger/qmldebuggerstatus.h b/src/declarative/debugger/qmldebuggerstatus.h new file mode 100644 index 0000000..8c6355d --- /dev/null +++ b/src/declarative/debugger/qmldebuggerstatus.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** 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 QMLDEBUGGERSTATUS_P_H +#define QMLDEBUGGERSTATUS_P_H + +#include <QtCore/qobject.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class Q_DECLARATIVE_EXPORT QmlDebuggerStatus +{ +public: + virtual ~QmlDebuggerStatus(); + + virtual void setSelectedState(bool); +}; +Q_DECLARE_INTERFACE(QmlDebuggerStatus, "com.trolltech.qml.QmlDebuggerStatus"); + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QLMDEBUGGERSTATUS_P_H + diff --git a/src/declarative/debugger/qmlpropertyview.cpp b/src/declarative/debugger/qmlpropertyview.cpp new file mode 100644 index 0000000..2434c58 --- /dev/null +++ b/src/declarative/debugger/qmlpropertyview.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** 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 "qmlpropertyview_p.h" +#include <QtGui/qboxlayout.h> +#include <QtGui/qtreewidget.h> +#include <QtCore/qmetaobject.h> + +QmlPropertyView::QmlPropertyView(QWidget *parent) +: QWidget(parent), m_tree(0) +{ + QVBoxLayout *layout = new QVBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + setLayout(layout); + + m_tree = new QTreeWidget(this); + m_tree->setHeaderLabels(QStringList() << "Property" << "Value"); + + m_tree->setColumnCount(2); + + layout->addWidget(m_tree); +} + +class QmlPropertyViewItem : public QObject, public QTreeWidgetItem +{ +Q_OBJECT +public: + QmlPropertyViewItem(QTreeWidget *widget); + + QObject *object; + QMetaProperty property; + +public slots: + void refresh(); +}; + +QmlPropertyViewItem::QmlPropertyViewItem(QTreeWidget *widget) +: QTreeWidgetItem(widget) +{ +} + +void QmlPropertyViewItem::refresh() +{ + setText(1, property.read(object).toString()); +} + +void QmlPropertyView::setObject(QObject *object) +{ + m_object = object; + + m_tree->clear(); + if(!m_object) + return; + + const QMetaObject *mo = object->metaObject(); + for(int ii = 0; ii < mo->propertyCount(); ++ii) { + QmlPropertyViewItem *item = new QmlPropertyViewItem(m_tree); + + QMetaProperty p = mo->property(ii); + item->object = object; + item->property = p; + + item->setText(0, QLatin1String(p.name())); + + static int refreshIdx = -1; + if(refreshIdx == -1) + refreshIdx = QmlPropertyViewItem::staticMetaObject.indexOfMethod("refresh()"); + + if(p.hasNotifySignal()) + QMetaObject::connect(object, p.notifySignalIndex(), + item, refreshIdx); + + item->refresh(); + } +} + +void QmlPropertyView::refresh() +{ + setObject(m_object); +} + +#include "qmlpropertyview.moc" diff --git a/src/declarative/debugger/qmlpropertyview_p.h b/src/declarative/debugger/qmlpropertyview_p.h new file mode 100644 index 0000000..fce9941 --- /dev/null +++ b/src/declarative/debugger/qmlpropertyview_p.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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 QMLPROPERTYVIEW_P_H +#define QMLPROPERTYVIEW_P_H + +#include <QtGui/qwidget.h> +#include <QtCore/qpointer.h> + +QT_BEGIN_NAMESPACE + +class QTreeWidget; +class QmlPropertyView : public QWidget +{ + Q_OBJECT +public: + QmlPropertyView(QWidget *parent = 0); + + void setObject(QObject *); + +public slots: + void refresh(); + +private: + QPointer<QObject> m_object; + QTreeWidget *m_tree; +}; + +QT_END_NAMESPACE + +#endif // QMLPROPERTYVIEW_P_H + diff --git a/src/declarative/fx/qfxkeyproxy.cpp b/src/declarative/fx/qfxkeyproxy.cpp index 6d9c6ab..1bb54ec 100644 --- a/src/declarative/fx/qfxkeyproxy.cpp +++ b/src/declarative/fx/qfxkeyproxy.cpp @@ -96,7 +96,7 @@ void QFxKeyProxy::keyPressEvent(QKeyEvent *e) for (int ii = 0; ii < d->targets.count(); ++ii) { QSimpleCanvasItem *i = d->targets.at(ii); if (i) - i->keyPressEvent(e); + canvas()->focusItem(i)->keyPressEvent(e); if (e->isAccepted()) return; } @@ -107,7 +107,7 @@ void QFxKeyProxy::keyReleaseEvent(QKeyEvent *e) for (int ii = 0; ii < d->targets.count(); ++ii) { QSimpleCanvasItem *i = d->targets.at(ii); if (i) - i->keyReleaseEvent(e); + canvas()->focusItem(i)->keyReleaseEvent(e); if (e->isAccepted()) return; } diff --git a/src/declarative/fx/qfxtextedit.cpp b/src/declarative/fx/qfxtextedit.cpp index a1b5484..bf7a16d 100644 --- a/src/declarative/fx/qfxtextedit.cpp +++ b/src/declarative/fx/qfxtextedit.cpp @@ -582,25 +582,17 @@ void QFxTextEdit::keyReleaseEvent(QKeyEvent *event) } /*! -\overload -Handles the given focus \a event. -*/ -void QFxTextEdit::focusInEvent(QFocusEvent *event) -{ - Q_D(QFxTextEdit); - QFxPaintedItem::focusInEvent(event); - d->control->processEvent(event, QPointF(0, 0)); -} - -/*! -\overload -Handles the given focus \a event. + \overload + Handles changing of the focus property. Focus is applied to the control + even if the edit does not have active focus. This is because things + like KeyProxy can give the behavior of focus even when activeFocus isn't + true. */ -void QFxTextEdit::focusOutEvent(QFocusEvent *event) +void QFxTextEdit::focusChanged(bool hasFocus) { Q_D(QFxTextEdit); - QFxPaintedItem::focusOutEvent(event); - d->control->processEvent(event, QPointF(0, 0)); + QFocusEvent focusEvent(hasFocus ? QEvent::FocusIn : QEvent::FocusOut); + d->control->processEvent(&focusEvent, QPointF(0, 0)); } static QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e) diff --git a/src/declarative/fx/qfxtextedit.h b/src/declarative/fx/qfxtextedit.h index b017635..e5e9421 100644 --- a/src/declarative/fx/qfxtextedit.h +++ b/src/declarative/fx/qfxtextedit.h @@ -161,8 +161,7 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); - void focusInEvent(QFocusEvent *); - void focusOutEvent(QFocusEvent *); + void focusChanged(bool); // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index be5226e..15b5879 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -139,7 +139,7 @@ QStack<QmlEngine *> *QmlEngineStack::engines() QmlEnginePrivate::QmlEnginePrivate(QmlEngine *e) : rootContext(0), currentBindContext(0), currentExpression(0), q(e), - rootComponent(0), networkAccessManager(0), typeManager(e) + rootComponent(0), networkAccessManager(0), typeManager(e), uniqueId(1) { QScriptValue proto = scriptEngine.newObject(); proto.setProperty(QLatin1String("emit"), @@ -720,17 +720,17 @@ QmlEngine *QmlEngine::activeEngine() QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b) -: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false), log(0) +: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false), id(0), log(0) { } QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, void *expr, QmlRefCount *rc) -: q(b), ctxt(0), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true), log(0) +: q(b), ctxt(0), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true), id(0), log(0) { } QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, const QString &expr, bool ssecompile) -: q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true), log(0) +: q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true), id(0), log(0) { if (ssecompile) { #ifdef Q_ENABLE_PERFORMANCE_LOG @@ -765,6 +765,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, void *expr, : d(new QmlExpressionPrivate(this, expr, rc)) { d->ctxt = ctxt; + if(ctxt && ctxt->engine()) + d->id = ctxt->engine()->d_func()->getUniqueId(); d->me = me; } @@ -774,6 +776,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expr, : d(new QmlExpressionPrivate(this, expr, ssecompile)) { d->ctxt = ctxt; + if(ctxt && ctxt->engine()) + d->id = ctxt->engine()->d_func()->getUniqueId(); d->me = me; } @@ -789,6 +793,8 @@ QmlExpression::QmlExpression(QmlContext *ctxt, const QString &expression, : d(new QmlExpressionPrivate(this, expression, true)) { d->ctxt = ctxt; + if(ctxt && ctxt->engine()) + d->id = ctxt->engine()->d_func()->getUniqueId(); d->me = scope; } @@ -810,7 +816,7 @@ QmlEngine *QmlExpression::engine() const } /*! - Returns teh QmlContext this expression is associated with, or 0 if there + Returns the QmlContext this expression is associated with, or 0 if there is no association or the QmlContext has been destroyed. */ QmlContext *QmlExpression::context() const @@ -988,6 +994,7 @@ QVariant QmlExpression::value() if(qmlDebugger()) { QmlExpressionLog log; + log.setTime(engine()->d_func()->getUniqueId()); log.setExpression(expression()); log.setResult(rv); @@ -997,8 +1004,8 @@ QVariant QmlExpression::value() if (prop.hasChangedNotifier()) { prop.connectNotifier(d->proxy, changedIndex); - } else { - QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: ") + QLatin1String(prop.object()->metaObject()->className()) + QLatin1String(".") + prop.name(); + } else if (prop.needsChangedNotifier()) { + QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: [") + QLatin1String(prop.object()->metaObject()->className()) + QLatin1String("].") + prop.name(); log.addWarning(warn); } } @@ -1015,6 +1022,7 @@ QVariant QmlExpression::value() } } else { QmlExpressionLog log; + log.setTime(engine()->d_func()->getUniqueId()); log.setExpression(expression()); log.setResult(rv); d->addLog(log); @@ -1023,6 +1031,7 @@ QVariant QmlExpression::value() } else { if(qmlDebugger()) { QmlExpressionLog log; + log.setTime(engine()->d_func()->getUniqueId()); log.setExpression(expression()); log.setResult(rv); d->addLog(log); @@ -1421,7 +1430,8 @@ QmlExpressionLog::QmlExpressionLog() } QmlExpressionLog::QmlExpressionLog(const QmlExpressionLog &o) -: m_expression(o.m_expression), +: m_time(o.m_time), + m_expression(o.m_expression), m_result(o.m_result), m_warnings(o.m_warnings) { @@ -1433,12 +1443,22 @@ QmlExpressionLog::~QmlExpressionLog() QmlExpressionLog &QmlExpressionLog::operator=(const QmlExpressionLog &o) { + m_time = o.m_time; m_expression = o.m_expression; m_result = o.m_result; m_warnings = o.m_warnings; return *this; } +void QmlExpressionLog::setTime(quint32 time) +{ + m_time = time; +} + +quint32 QmlExpressionLog::time() const +{ + return m_time; +} QString QmlExpressionLog::expression() const { diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 7d5176e..63df0ba 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -114,6 +114,11 @@ public: QmlCompositeTypeManager typeManager; QMap<QString,QString> nameSpacePaths; + + mutable quint32 uniqueId; + quint32 getUniqueId() const { + return uniqueId++; + } }; @@ -201,6 +206,9 @@ public: QmlExpressionLog &operator=(const QmlExpressionLog &); + void setTime(quint32); + quint32 time() const; + QString expression() const; void setExpression(const QString &); @@ -211,6 +219,7 @@ public: void setResult(const QVariant &); private: + quint32 m_time; QString m_expression; QVariant m_result; QStringList m_warnings; @@ -233,6 +242,8 @@ public: QObject *me; bool trackChange; + quint32 id; + void addLog(const QmlExpressionLog &); QList<QmlExpressionLog> *log; }; diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 40c9b0e..59d6b38 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -988,6 +988,18 @@ bool QmlMetaProperty::hasChangedNotifier() const } /*! + Returns true if the property needs a change notifier signal for bindings + to remain upto date, false otherwise. + + Some properties, such as attached properties or those whose value never + changes, do not require a change notifier. +*/ +bool QmlMetaProperty::needsChangedNotifier() const +{ + return type() & Property && !(type() & Attached); +} + +/*! Connects the property's change notifier signal to the specified \a method of the \a dest object and returns true. Returns false if this metaproperty does not diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h index 4836038..68b06e5 100644 --- a/src/declarative/qml/qmlmetaproperty.h +++ b/src/declarative/qml/qmlmetaproperty.h @@ -89,6 +89,7 @@ public: void emitSignal(); bool hasChangedNotifier() const; + bool needsChangedNotifier() const; bool connectNotifier(QObject *dest, const char *slot) const; bool connectNotifier(QObject *dest, int method) const; |