diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-05-08 04:27:10 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-05-08 04:27:10 (GMT) |
commit | 225b30555b34885c028fc7a5f79a805cf5167669 (patch) | |
tree | c2a7fc73f53943f13217483e5e989aecbe85cf1a /src/declarative | |
parent | 674f6502671e969264bb7450a507ca04ab149b6a (diff) | |
download | Qt-225b30555b34885c028fc7a5f79a805cf5167669.zip Qt-225b30555b34885c028fc7a5f79a805cf5167669.tar.gz Qt-225b30555b34885c028fc7a5f79a805cf5167669.tar.bz2 |
Add expression watcher support
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/debugger/debugger.pri | 6 | ||||
-rw-r--r-- | src/declarative/debugger/qmldebugger.cpp | 33 | ||||
-rw-r--r-- | src/declarative/debugger/qmldebugger.h | 5 | ||||
-rw-r--r-- | src/declarative/debugger/qmlobjecttree.cpp | 75 | ||||
-rw-r--r-- | src/declarative/debugger/qmlobjecttree_p.h | 86 | ||||
-rw-r--r-- | src/declarative/debugger/qmlpropertyview.cpp | 16 | ||||
-rw-r--r-- | src/declarative/debugger/qmlwatches.cpp | 93 | ||||
-rw-r--r-- | src/declarative/debugger/qmlwatches_p.h | 8 |
8 files changed, 252 insertions, 70 deletions
diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri index bf693d9..4df7e51 100644 --- a/src/declarative/debugger/debugger.pri +++ b/src/declarative/debugger/debugger.pri @@ -1,9 +1,11 @@ SOURCES += debugger/qmldebugger.cpp \ debugger/qmldebuggerstatus.cpp \ debugger/qmlpropertyview.cpp \ - debugger/qmlwatches.cpp + debugger/qmlwatches.cpp \ + debugger/qmlobjecttree.cpp HEADERS += debugger/qmldebugger.h \ debugger/qmldebuggerstatus.h \ debugger/qmlpropertyview_p.h \ - debugger/qmlwatches_p.h + debugger/qmlwatches_p.h \ + debugger/qmlobjecttree_p.h diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp index 907b91b..76d6b10 100644 --- a/src/declarative/debugger/qmldebugger.cpp +++ b/src/declarative/debugger/qmldebugger.cpp @@ -50,6 +50,7 @@ #include <private/qmlboundsignal_p.h> #include <private/qmlcontext_p.h> #include <private/qmlengine_p.h> +#include <private/qmlobjecttree_p.h> #include <QtCore/qdebug.h> #include <QtCore/qfile.h> #include <QtCore/qurl.h> @@ -57,6 +58,7 @@ #include <QtGui/qpushbutton.h> #include <QtGui/qtablewidget.h> #include <QtGui/qevent.h> +#include <QtDeclarative/qmlexpression.h> #include <private/qmlpropertyview_p.h> #include <private/qmlwatches_p.h> @@ -75,10 +77,11 @@ QmlDebugger::QmlDebugger(QWidget *parent) treeWid->setLayout(vlayout); splitter->addWidget(treeWid); - m_tree = new QTreeWidget(treeWid); + m_tree = new QmlObjectTree(treeWid); m_tree->setHeaderHidden(true); QObject::connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *))); QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); + QObject::connect(m_tree, SIGNAL(addWatch(QObject*,QString)), this, SLOT(addWatch(QObject*,QString))); vlayout->addWidget(m_tree); QPushButton *pb = new QPushButton("Refresh", treeWid); @@ -113,29 +116,17 @@ QmlDebugger::QmlDebugger(QWidget *parent) setGeometry(0, 100, 800, 600); } -class QmlDebuggerItem : public QTreeWidgetItem +void QmlDebugger::itemDoubleClicked(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; - - QPointer<QObject> object; - QPointer<QmlBindableValue> bindableValue; -}; +} -void QmlDebugger::itemDoubleClicked(QTreeWidgetItem *i) +void QmlDebugger::addWatch(QObject *obj, const QString &expr) { + QmlContext *ctxt = qmlContext(obj); + if(ctxt) { + QmlExpressionObject *e= new QmlExpressionObject(ctxt, expr, obj, m_watches); + m_watches->addWatch(e); + } } void QmlDebugger::highlightObject(quint32 id) diff --git a/src/declarative/debugger/qmldebugger.h b/src/declarative/debugger/qmldebugger.h index 6495a49..ddb846b 100644 --- a/src/declarative/debugger/qmldebugger.h +++ b/src/declarative/debugger/qmldebugger.h @@ -59,6 +59,8 @@ class QmlDebuggerItem; class QTableView; class QmlPropertyView; class QmlWatches; +class QmlObjectTree; +class QmlContext; class QmlDebugger : public QWidget { Q_OBJECT @@ -74,11 +76,12 @@ private slots: void itemClicked(QTreeWidgetItem *); void itemDoubleClicked(QTreeWidgetItem *); void highlightObject(quint32); + void addWatch(QObject *, const QString &); private: void buildTree(QObject *obj, QmlDebuggerItem *parent); bool makeItem(QObject *obj, QmlDebuggerItem *item); - QTreeWidget *m_tree; + QmlObjectTree *m_tree; QTreeWidget *m_warnings; QTableView *m_watchTable; QmlWatches *m_watches; diff --git a/src/declarative/debugger/qmlobjecttree.cpp b/src/declarative/debugger/qmlobjecttree.cpp new file mode 100644 index 0000000..fb6825a --- /dev/null +++ b/src/declarative/debugger/qmlobjecttree.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** 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 <private/qmlobjecttree_p.h> +#include <QtDeclarative/qml.h> +#include <QtGui/qevent.h> +#include <QtGui/qmenu.h> +#include <QtCore/qlist.h> +#include <QtGui/qaction.h> +#include <QtGui/qinputdialog.h> +#include <QtGui/qboxlayout.h> + +QmlObjectTree::QmlObjectTree(QWidget *parent) +: QTreeWidget(parent) +{ +} + +void QmlObjectTree::mousePressEvent(QMouseEvent *me) +{ + QTreeWidget::mousePressEvent(me); + if(me->button() == Qt::RightButton && me->type() == QEvent::MouseButtonPress) { + QAction action("Add watch...", 0); + QList<QAction *> actions; + actions << &action; + QmlDebuggerItem *item = static_cast<QmlDebuggerItem *>(currentItem()); + if(item && qmlContext(item->object) && + QMenu::exec(actions, me->globalPos())) { + + bool ok = false; + QString watch = QInputDialog::getText(this, "Watch expression", "Expression:", QLineEdit::Normal, QString(), &ok); + + if(ok && !watch.isEmpty()) + emit addWatch(item->object, watch); + } + } +} + diff --git a/src/declarative/debugger/qmlobjecttree_p.h b/src/declarative/debugger/qmlobjecttree_p.h new file mode 100644 index 0000000..4e6d484 --- /dev/null +++ b/src/declarative/debugger/qmlobjecttree_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 QMLOBJECTTREE_P_H +#define QMLOBJECTTREE_P_H + +#include <QtGui/qtreewidget.h> +#include <QtCore/qurl.h> +#include <QtCore/qpointer.h> + +class QmlBindableValue; +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; + + QPointer<QObject> object; + QPointer<QmlBindableValue> bindableValue; +}; + +class QmlContext; +class QmlObjectTree : public QTreeWidget +{ + Q_OBJECT +public: + QmlObjectTree(QWidget *parent = 0); + +signals: + void addWatch(QObject *, const QString &); + +protected: + virtual void mousePressEvent(QMouseEvent *); +}; + +#endif // QMLOBJECTTREE_P_H + diff --git a/src/declarative/debugger/qmlpropertyview.cpp b/src/declarative/debugger/qmlpropertyview.cpp index eda97b7..e32393c 100644 --- a/src/declarative/debugger/qmlpropertyview.cpp +++ b/src/declarative/debugger/qmlpropertyview.cpp @@ -136,17 +136,8 @@ void QmlPropertyView::itemDoubleClicked(QTreeWidgetItem *i) m_watches->addWatch(objectId, item->property.name()); item->setForeground(0, Qt::red); } - } else if(item->exprId) { - - if(m_watches->hasWatch(item->exprId)) { - m_watches->remWatch(item->exprId); - item->setForeground(1, Qt::green); - } else { - m_watches->addWatch(item->exprId); - item->setForeground(1, Qt::darkGreen); - } - } + } void QmlPropertyView::setObject(QObject *object) @@ -206,10 +197,7 @@ void QmlPropertyView::setObject(QObject *object) QmlPropertyViewItem *binding = new QmlPropertyViewItem(item); binding->exprId = iter.value().second; binding->setText(1, iter.value().first); - if (m_watches->hasWatch(binding->exprId)) - binding->setForeground(1, Qt::darkGreen); - else - binding->setForeground(1, Qt::green); + binding->setForeground(1, Qt::green); ++iter; } diff --git a/src/declarative/debugger/qmlwatches.cpp b/src/declarative/debugger/qmlwatches.cpp index 1cc9469..bac4cbd 100644 --- a/src/declarative/debugger/qmlwatches.cpp +++ b/src/declarative/debugger/qmlwatches.cpp @@ -44,6 +44,7 @@ #include <QtCore/qdebug.h> #include <QtGui/qcolor.h> #include <QtDeclarative/qmlmetatype.h> +#include <QtDeclarative/qmlexpression.h> QString QmlWatches::objectToString(QObject *obj) { @@ -69,6 +70,10 @@ public: int column, QmlWatches *parent = 0); + QmlWatchesProxy(QmlExpressionObject *object, + int column, + QmlWatches *parent = 0); + public slots: void refresh(); @@ -76,15 +81,25 @@ private: QmlWatches *m_watches; QObject *m_object; QMetaProperty m_property; + + QmlExpressionObject *m_expr; int m_column; }; +QmlWatchesProxy::QmlWatchesProxy(QmlExpressionObject *object, + int column, + QmlWatches *parent) +: QObject(parent), m_watches(parent), m_object(0), m_expr(object), m_column(column) +{ + QObject::connect(m_expr, SIGNAL(valueChanged()), this, SLOT(refresh())); +} + QmlWatchesProxy::QmlWatchesProxy(QObject *object, const QMetaProperty &prop, int column, QmlWatches *parent) : QObject(parent), m_watches(parent), m_object(object), m_property(prop), - m_column(column) + m_expr(0), m_column(column) { static int refreshIdx = -1; if(refreshIdx == -1) @@ -96,7 +111,10 @@ QmlWatchesProxy::QmlWatchesProxy(QObject *object, void QmlWatchesProxy::refresh() { - QVariant v = m_property.read(m_object); + QVariant v; + if(m_expr) v = m_expr->value(); + else v= m_property.read(m_object); + m_watches->addValue(m_column, v); } @@ -110,6 +128,24 @@ bool QmlWatches::hasWatch(quint32 objectId, const QByteArray &property) return m_watches.contains(qMakePair(objectId, property)); } +void QmlWatches::addWatch(QmlExpressionObject *expr) +{ + int oldColumn = columnCount(QModelIndex()); + + m_watches.append(qMakePair(quint32(0), QByteArray())); + + beginInsertColumns(QModelIndex(), oldColumn, oldColumn); + endInsertColumns(); + + m_columnNames.append(expr->expression()); + + QmlWatchesProxy *proxy = new QmlWatchesProxy(expr, oldColumn, this); + m_proxies.append(proxy); + + proxy->refresh(); + m_values[m_values.count() - 1].first = true; +} + void QmlWatches::addWatch(quint32 objectId, const QByteArray &property) { if(hasWatch(objectId, property)) @@ -117,7 +153,6 @@ void QmlWatches::addWatch(quint32 objectId, const QByteArray &property) int oldColumn = columnCount(QModelIndex()); - m_watches.append(qMakePair(objectId, property)); beginInsertColumns(QModelIndex(), oldColumn, oldColumn); @@ -128,36 +163,38 @@ void QmlWatches::addWatch(quint32 objectId, const QByteArray &property) QMetaProperty prop = obj->metaObject()->property(obj->metaObject()->indexOfProperty(property.constData())); QmlWatchesProxy *proxy = new QmlWatchesProxy(obj, prop, oldColumn, this); + m_proxies.append(proxy); proxy->refresh(); m_values[m_values.count() - 1].first = true; } void QmlWatches::remWatch(quint32 objectId, const QByteArray &property) { - m_watches.removeAll(qMakePair(objectId, property)); -} - -bool QmlWatches::hasWatch(quint32 exprId) -{ - return m_exprWatches.contains(exprId); -} - -void QmlWatches::remWatch(quint32 exprId) -{ - m_exprWatches.removeAll(exprId); -} - -void QmlWatches::addWatch(quint32 exprId) -{ - if (hasWatch(exprId)) - return; - - int oldColumn = columnCount(QModelIndex()); - - m_exprWatches.append(exprId); - - beginInsertColumns(QModelIndex(), oldColumn, oldColumn); - endInsertColumns(); + QPair<quint32, QByteArray> watch = qMakePair(objectId, property); + for(int ii = 0; ii < m_watches.count(); ++ii) { + if(m_watches.at(ii) == watch) { + m_watches.removeAt(ii); + m_columnNames.removeAt(ii); + if(m_proxies.at(ii)) + delete m_proxies.at(ii); + m_proxies.removeAt(ii); + + + for(QList<Value>::Iterator iter = m_values.begin(); + iter != m_values.end(); + ) { + if(iter->column == ii) { + iter = m_values.erase(iter); + } else { + if(iter->column > ii) + --iter->column; + ++iter; + } + } + reset(); + return; + } + } } quint32 QmlWatches::objectId(QObject *object) @@ -210,7 +247,7 @@ void QmlWatches::addValue(int column, const QVariant &value) int QmlWatches::columnCount(const QModelIndex &) const { - return m_watches.count() + m_exprWatches.count(); + return m_watches.count(); } int QmlWatches::rowCount(const QModelIndex &) const diff --git a/src/declarative/debugger/qmlwatches_p.h b/src/declarative/debugger/qmlwatches_p.h index 4570a4f..6c383a1 100644 --- a/src/declarative/debugger/qmlwatches_p.h +++ b/src/declarative/debugger/qmlwatches_p.h @@ -52,6 +52,8 @@ QT_BEGIN_NAMESPACE class QmlWatchesProxy; +class QmlExpressionObject; + class QmlWatches : public QAbstractTableModel { Q_OBJECT @@ -62,9 +64,7 @@ public: void addWatch(quint32 objectId, const QByteArray &property); void remWatch(quint32 objectId, const QByteArray &property); - bool hasWatch(quint32 exprId); - void remWatch(quint32 exprId); - void addWatch(quint32 exprId); + void addWatch(QmlExpressionObject *); quint32 objectId(QObject *); QObject *object(quint32); @@ -79,7 +79,6 @@ protected: private: friend class QmlWatchesProxy; QList<QPair<quint32, QByteArray> > m_watches; - QList<quint32> m_exprWatches; void addValue(int, const QVariant &); struct Value { @@ -89,6 +88,7 @@ private: }; QList<Value> m_values; QStringList m_columnNames; + QList<QPointer<QmlWatchesProxy> > m_proxies; quint32 m_uniqueId; QHash<QObject *, QPair<QPointer<QObject>, quint32> *> m_objects; |