diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-05-08 03:34:11 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-05-08 03:34:11 (GMT) |
commit | d3b4366dd383400e5804eff07c4d226abf06c977 (patch) | |
tree | 2631aa82079ec491a5fea1009e2e68c0e48436d1 /src/declarative | |
parent | 2ce79831de76b32ef2b0b96aef7301a83cdcf73a (diff) | |
parent | 674f6502671e969264bb7450a507ca04ab149b6a (diff) | |
download | Qt-d3b4366dd383400e5804eff07c4d226abf06c977.zip Qt-d3b4366dd383400e5804eff07c4d226abf06c977.tar.gz Qt-d3b4366dd383400e5804eff07c4d226abf06c977.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative')
29 files changed, 639 insertions, 164 deletions
diff --git a/src/declarative/canvas/qsimplecanvas_graphicsview.cpp b/src/declarative/canvas/qsimplecanvas_graphicsview.cpp index dd4012b..5c6f2f5 100644 --- a/src/declarative/canvas/qsimplecanvas_graphicsview.cpp +++ b/src/declarative/canvas/qsimplecanvas_graphicsview.cpp @@ -110,7 +110,6 @@ void QSimpleGraphicsItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) p = p->parent(); } owner->mouseReleaseEvent(event); - ungrabMouse(); } void QSimpleGraphicsItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri index 31a1d5b..bf693d9 100644 --- a/src/declarative/debugger/debugger.pri +++ b/src/declarative/debugger/debugger.pri @@ -1,7 +1,9 @@ SOURCES += debugger/qmldebugger.cpp \ debugger/qmldebuggerstatus.cpp \ - debugger/qmlpropertyview.cpp + debugger/qmlpropertyview.cpp \ + debugger/qmlwatches.cpp HEADERS += debugger/qmldebugger.h \ debugger/qmldebuggerstatus.h \ - debugger/qmlpropertyview_p.h + debugger/qmlpropertyview_p.h \ + debugger/qmlwatches_p.h diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp index 634385b..907b91b 100644 --- a/src/declarative/debugger/qmldebugger.cpp +++ b/src/declarative/debugger/qmldebugger.cpp @@ -58,10 +58,11 @@ #include <QtGui/qtablewidget.h> #include <QtGui/qevent.h> #include <private/qmlpropertyview_p.h> +#include <private/qmlwatches_p.h> QmlDebugger::QmlDebugger(QWidget *parent) -: QWidget(parent), m_tree(0), m_warnings(0), m_watchers(0), m_properties(0), - m_text(0) +: QWidget(parent), m_tree(0), m_warnings(0), m_watchTable(0), m_watches(0), + m_properties(0), m_text(0), m_highlightedItem(0) { QHBoxLayout *layout = new QHBoxLayout; setLayout(layout); @@ -75,7 +76,6 @@ 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(itemClicked(QTreeWidgetItem *, int)), this, SLOT(itemClicked(QTreeWidgetItem *))); QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); @@ -95,12 +95,17 @@ QmlDebugger::QmlDebugger(QWidget *parent) 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_watches = new QmlWatches(this); + m_watchTable = new QTableView(this); + m_watchTable->setSelectionMode(QTableWidget::NoSelection); + m_watchTable->setModel(m_watches); + tabs->addTab(m_watchTable, "Watches"); - m_properties = new QmlPropertyView(this); + m_properties = new QmlPropertyView(m_watches, this); + QObject::connect(m_properties, SIGNAL(objectClicked(quint32)), + this, SLOT(highlightObject(quint32))); tabs->addTab(m_properties, "Properties"); + tabs->setCurrentWidget(m_properties); splitter->addWidget(tabs); splitter->setStretchFactor(1, 2); @@ -131,21 +136,22 @@ public: void QmlDebugger::itemDoubleClicked(QTreeWidgetItem *i) { - QmlDebuggerItem *item = static_cast<QmlDebuggerItem *>(i); - - if(item->bindableValue) { - - QmlExpressionPrivate *p = item->bindableValue->d; - - if(m_watchedIds.contains(p->id)) { - m_watchedIds.remove(p->id); - item->setForeground(0, Qt::green); - } else { - m_watchedIds.insert(p->id); - item->setForeground(0, QColor("purple")); - } +} +void QmlDebugger::highlightObject(quint32 id) +{ + QHash<quint32, QTreeWidgetItem *>::ConstIterator iter = m_items.find(id); + if (m_highlightedItem) { + m_highlightedItem->setBackground(0, QPalette().base()); + m_highlightedItem = 0; } + + if (iter != m_items.end()) { + m_highlightedItem = *iter; + m_highlightedItem->setBackground(0, QColor("cyan")); + m_tree->expandItem(m_highlightedItem); + m_tree->scrollToItem(m_highlightedItem); + } } void QmlDebugger::itemClicked(QTreeWidgetItem *i) @@ -227,36 +233,16 @@ bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) QmlExpressionPrivate *p = bv->d; text = bv->property().name() + ": " + bv->expression(); - bool watched = m_watchedIds.contains(p->id); - if(watched) - item->setForeground(0, QColor("purple")); - else - item->setForeground(0, Qt::green); + 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()) { @@ -280,14 +266,12 @@ bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) } + delete item; + return false; + } 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; + delete item; + return false; } else { QmlContext *context = qmlContext(obj); QmlContext *parentContext = qmlContext(obj->parent()); @@ -328,6 +312,7 @@ bool QmlDebugger::makeItem(QObject *obj, QmlDebuggerItem *item) item->setForeground(0, Qt::lightGray); } + m_items.insert(m_watches->objectId(obj), item); item->setText(0, text); return rv; @@ -359,10 +344,8 @@ 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_items.clear(); + m_highlightedItem = 0; m_object = obj; if(!obj) @@ -372,20 +355,5 @@ void QmlDebugger::setDebugObject(QObject *obj) makeItem(obj, item); buildTree(obj, item); item->setExpanded(true); - - 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 35ff92c..6495a49 100644 --- a/src/declarative/debugger/qmldebugger.h +++ b/src/declarative/debugger/qmldebugger.h @@ -56,8 +56,9 @@ class QTreeWidget; class QTreeWidgetItem; class QPlainTextEdit; class QmlDebuggerItem; -class QTableWidget; +class QTableView; class QmlPropertyView; +class QmlWatches; class QmlDebugger : public QWidget { Q_OBJECT @@ -72,19 +73,22 @@ public slots: private slots: void itemClicked(QTreeWidgetItem *); void itemDoubleClicked(QTreeWidgetItem *); + void highlightObject(quint32); private: void buildTree(QObject *obj, QmlDebuggerItem *parent); bool makeItem(QObject *obj, QmlDebuggerItem *item); QTreeWidget *m_tree; QTreeWidget *m_warnings; - QTableWidget *m_watchers; + QTableView *m_watchTable; + QmlWatches *m_watches; 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; + + QTreeWidgetItem *m_highlightedItem; + QHash<quint32, QTreeWidgetItem *> m_items; }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qmlpropertyview.cpp b/src/declarative/debugger/qmlpropertyview.cpp index 2434c58..eda97b7 100644 --- a/src/declarative/debugger/qmlpropertyview.cpp +++ b/src/declarative/debugger/qmlpropertyview.cpp @@ -43,9 +43,12 @@ #include <QtGui/qboxlayout.h> #include <QtGui/qtreewidget.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qdebug.h> +#include <QtDeclarative/qmlbindablevalue.h> +#include <private/qmlboundsignal_p.h> -QmlPropertyView::QmlPropertyView(QWidget *parent) -: QWidget(parent), m_tree(0) +QmlPropertyView::QmlPropertyView(QmlWatches *watches, QWidget *parent) +: QWidget(parent), m_tree(0), m_watches(watches) { QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); @@ -54,6 +57,10 @@ QmlPropertyView::QmlPropertyView(QWidget *parent) m_tree = new QTreeWidget(this); m_tree->setHeaderLabels(QStringList() << "Property" << "Value"); + QObject::connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), + this, SLOT(itemDoubleClicked(QTreeWidgetItem *))); + QObject::connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem *, int)), + this, SLOT(itemClicked(QTreeWidgetItem *))); m_tree->setColumnCount(2); @@ -65,22 +72,81 @@ class QmlPropertyViewItem : public QObject, public QTreeWidgetItem Q_OBJECT public: QmlPropertyViewItem(QTreeWidget *widget); + QmlPropertyViewItem(QTreeWidgetItem *parent); QObject *object; QMetaProperty property; + quint32 exprId; + public slots: void refresh(); }; QmlPropertyViewItem::QmlPropertyViewItem(QTreeWidget *widget) -: QTreeWidgetItem(widget) +: QTreeWidgetItem(widget), object(0), exprId(0) +{ +} + +QmlPropertyViewItem::QmlPropertyViewItem(QTreeWidgetItem *parent) +: QTreeWidgetItem(parent), object(0), exprId(0) { } void QmlPropertyViewItem::refresh() { - setText(1, property.read(object).toString()); + QVariant v = property.read(object); + QString str = v.toString(); + + if (QmlMetaType::isObject(v.userType())) + str = QmlWatches::objectToString(QmlMetaType::toQObject(v)); + + setText(1, str); +} + +void QmlPropertyView::itemClicked(QTreeWidgetItem *i) +{ + QmlPropertyViewItem *item = static_cast<QmlPropertyViewItem *>(i); + + if(item->object) { + QVariant v = item->property.read(item->object); + if (QmlMetaType::isObject(v.userType())) { + QObject *obj = QmlMetaType::toQObject(v); + + if(obj) { + quint32 id = m_watches->objectId(obj); + emit objectClicked(id); + } + } + } + +} + +void QmlPropertyView::itemDoubleClicked(QTreeWidgetItem *i) +{ + QmlPropertyViewItem *item = static_cast<QmlPropertyViewItem *>(i); + + if(item->object) { + quint32 objectId = m_watches->objectId(item->object); + + if(m_watches->hasWatch(objectId, item->property.name())) { + m_watches->remWatch(objectId, item->property.name()); + item->setForeground(0, Qt::black); + } else { + 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) @@ -91,15 +157,38 @@ void QmlPropertyView::setObject(QObject *object) if(!m_object) return; + QMultiHash<QByteArray, QPair<QString, quint32> > bindings; + QHash<QByteArray, QString> sigs; + QObjectList children = object->children(); + + foreach(QObject *child, children) { + if(QmlBindableValue *value = qobject_cast<QmlBindableValue *>(child)) { + bindings.insert(value->property().name().toUtf8(), qMakePair(value->expression(), value->id())); + } else if(QmlBoundSignal *signal = qobject_cast<QmlBoundSignal *>(child)) { + QMetaMethod method = object->metaObject()->method(signal->index()); + QByteArray sig = method.signature(); + sigs.insert(sig, signal->expression()); + } + } + + quint32 objectId = m_watches->objectId(object); + const QMetaObject *mo = object->metaObject(); for(int ii = 0; ii < mo->propertyCount(); ++ii) { + QMetaProperty p = mo->property(ii); + + if(QmlMetaType::isList(p.userType()) || + QmlMetaType::isQmlList(p.userType())) + continue; + QmlPropertyViewItem *item = new QmlPropertyViewItem(m_tree); - QMetaProperty p = mo->property(ii); item->object = object; item->property = p; item->setText(0, QLatin1String(p.name())); + if(m_watches->hasWatch(objectId, p.name())) + item->setForeground(0, Qt::red); static int refreshIdx = -1; if(refreshIdx == -1) @@ -109,8 +198,34 @@ void QmlPropertyView::setObject(QObject *object) QMetaObject::connect(object, p.notifySignalIndex(), item, refreshIdx); + + QMultiHash<QByteArray, QPair<QString, quint32> >::Iterator iter = + bindings.find(p.name()); + + while(iter != bindings.end() && iter.key() == p.name()) { + 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); + ++iter; + } + + item->setExpanded(true); item->refresh(); } + + for(QHash<QByteArray, QString>::ConstIterator iter = sigs.begin(); + iter != sigs.end(); + ++iter) { + + QTreeWidgetItem *item = new QTreeWidgetItem(m_tree); + item->setText(0, iter.key()); + item->setForeground(0, Qt::blue); + item->setText(1, iter.value()); + } } void QmlPropertyView::refresh() diff --git a/src/declarative/debugger/qmlpropertyview_p.h b/src/declarative/debugger/qmlpropertyview_p.h index fce9941..469a08d 100644 --- a/src/declarative/debugger/qmlpropertyview_p.h +++ b/src/declarative/debugger/qmlpropertyview_p.h @@ -44,24 +44,32 @@ #include <QtGui/qwidget.h> #include <QtCore/qpointer.h> +#include <private/qmlwatches_p.h> QT_BEGIN_NAMESPACE class QTreeWidget; +class QTreeWidgetItem; class QmlPropertyView : public QWidget { Q_OBJECT public: - QmlPropertyView(QWidget *parent = 0); + QmlPropertyView(QmlWatches *watches, QWidget *parent = 0); void setObject(QObject *); +signals: + void objectClicked(quint32); + public slots: void refresh(); + void itemDoubleClicked(QTreeWidgetItem *); + void itemClicked(QTreeWidgetItem *); private: QPointer<QObject> m_object; QTreeWidget *m_tree; + QmlWatches *m_watches; }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qmlwatches.cpp b/src/declarative/debugger/qmlwatches.cpp new file mode 100644 index 0000000..1cc9469 --- /dev/null +++ b/src/declarative/debugger/qmlwatches.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** 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 "qmlwatches_p.h" +#include <QtCore/qmetaobject.h> +#include <QtCore/qdebug.h> +#include <QtGui/qcolor.h> +#include <QtDeclarative/qmlmetatype.h> + +QString QmlWatches::objectToString(QObject *obj) +{ + if(!obj) + return QLatin1String("NULL"); + + QString objectName = obj->objectName(); + if(objectName.isEmpty()) + objectName = QLatin1String("<unnamed>"); + + QString rv = QLatin1String(obj->metaObject()->className()) + + QLatin1String(": ") + objectName; + + return rv; +} + +class QmlWatchesProxy : public QObject +{ + Q_OBJECT +public: + QmlWatchesProxy(QObject *object, + const QMetaProperty &prop, + int column, + QmlWatches *parent = 0); + +public slots: + void refresh(); + +private: + QmlWatches *m_watches; + QObject *m_object; + QMetaProperty m_property; + int m_column; +}; + +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) +{ + static int refreshIdx = -1; + if(refreshIdx == -1) + refreshIdx = QmlWatchesProxy::staticMetaObject.indexOfMethod("refresh()"); + + QMetaObject::connect(m_object, prop.notifySignalIndex(), + this, refreshIdx); +} + +void QmlWatchesProxy::refresh() +{ + QVariant v = m_property.read(m_object); + m_watches->addValue(m_column, v); +} + +QmlWatches::QmlWatches(QObject *parent) +: QAbstractTableModel(parent), m_uniqueId(0) +{ +} + +bool QmlWatches::hasWatch(quint32 objectId, const QByteArray &property) +{ + return m_watches.contains(qMakePair(objectId, property)); +} + +void QmlWatches::addWatch(quint32 objectId, const QByteArray &property) +{ + if(hasWatch(objectId, property)) + return; + + int oldColumn = columnCount(QModelIndex()); + + + m_watches.append(qMakePair(objectId, property)); + + beginInsertColumns(QModelIndex(), oldColumn, oldColumn); + endInsertColumns(); + + QObject *obj = object(objectId); + m_columnNames.append(QLatin1String(property) + QLatin1String(" on ") + objectToString(obj)); + QMetaProperty prop = + obj->metaObject()->property(obj->metaObject()->indexOfProperty(property.constData())); + QmlWatchesProxy *proxy = new QmlWatchesProxy(obj, prop, oldColumn, this); + 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(); +} + +quint32 QmlWatches::objectId(QObject *object) +{ + Q_ASSERT(object); + + QHash<QObject *, QPair<QPointer<QObject>, quint32> *>::Iterator iter = + m_objects.find(object); + if(iter == m_objects.end()) { + iter = m_objects.insert(object, new QPair<QPointer<QObject>, quint32>(QPointer<QObject>(object), m_uniqueId++)); + m_objectIds.insert(iter.value()->second, iter.value()); + } + + if(iter.value()->first != object) { + iter.value()->first = object; + iter.value()->second = m_uniqueId++; + + m_objectIds.insert(iter.value()->second, iter.value()); + } + return iter.value()->second; +} + +QObject *QmlWatches::object(quint32 id) +{ + QHash<quint32, QPair<QPointer<QObject>, quint32> *>::Iterator iter = + m_objectIds.find(id); + if(iter == m_objectIds.end()) + return 0; + + if(!iter.value()->first) { + m_objectIds.erase(iter); + return 0; + } + + return iter.value()->first; +} + +void QmlWatches::addValue(int column, const QVariant &value) +{ + int row = m_values.count(); + + beginInsertRows(QModelIndex(), row, row); + Value v; + v.column = column; + v.variant = value; + v.first = false; + m_values.append(v); + endInsertRows(); +} + +int QmlWatches::columnCount(const QModelIndex &) const +{ + return m_watches.count() + m_exprWatches.count(); +} + +int QmlWatches::rowCount(const QModelIndex &) const +{ + return m_values.count(); +} + +QVariant QmlWatches::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && section < m_columnNames.count() && + role == Qt::DisplayRole) + return m_columnNames.at(section); + else + return QVariant(); +} + +QVariant QmlWatches::data(const QModelIndex &idx, int role) const +{ + if(m_values.at(idx.row()).column == idx.column()) { + if(role == Qt::DisplayRole) { + const QVariant &value = m_values.at(idx.row()).variant; + + QString str = value.toString(); + + if(str.isEmpty() && QmlMetaType::isObject(value.userType())) { + QObject *o = QmlMetaType::toQObject(value); + if(o) { + QString objectName = o->objectName(); + if(objectName.isEmpty()) + objectName = QLatin1String("<unnamed>"); + str = QLatin1String(o->metaObject()->className()) + + QLatin1String(": ") + objectName; + } + } + + if(str.isEmpty()) { + QDebug d(&str); + d << value; + } + return QVariant(str); + } else if(role == Qt::BackgroundRole) { + if(m_values.at(idx.row()).first) + return QColor(Qt::green); + else + return QVariant(); + } else { + return QVariant(); + } + } else { + return QVariant(); + } +} + +#include "qmlwatches.moc" diff --git a/src/declarative/debugger/qmlwatches_p.h b/src/declarative/debugger/qmlwatches_p.h new file mode 100644 index 0000000..4570a4f --- /dev/null +++ b/src/declarative/debugger/qmlwatches_p.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** 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 QMLWATCHES_P_H +#define QMLWATCHES_P_H + +#include <QtCore/qbytearray.h> +#include <QtCore/qobject.h> +#include <QtCore/qpointer.h> +#include <QtCore/qset.h> +#include <QtCore/qstringlist.h> +#include <QtCore/qabstractitemmodel.h> + +QT_BEGIN_NAMESPACE + +class QmlWatchesProxy; +class QmlWatches : public QAbstractTableModel +{ + Q_OBJECT +public: + QmlWatches(QObject *parent = 0); + + bool hasWatch(quint32 objectId, const QByteArray &property); + 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); + + quint32 objectId(QObject *); + QObject *object(quint32); + + static QString objectToString(QObject *obj); +protected: + int columnCount(const QModelIndex &) const; + int rowCount(const QModelIndex &) const; + QVariant data(const QModelIndex &, int) const; + QVariant headerData(int, Qt::Orientation, int) const; + +private: + friend class QmlWatchesProxy; + QList<QPair<quint32, QByteArray> > m_watches; + QList<quint32> m_exprWatches; + + void addValue(int, const QVariant &); + struct Value { + int column; + QVariant variant; + bool first; + }; + QList<Value> m_values; + QStringList m_columnNames; + + quint32 m_uniqueId; + QHash<QObject *, QPair<QPointer<QObject>, quint32> *> m_objects; + QHash<quint32, QPair<QPointer<QObject>, quint32> *> m_objectIds; +}; + +QT_END_NAMESPACE + +#endif // QMLWATCHES_P_H diff --git a/src/declarative/fx/qfxblendedimage.cpp b/src/declarative/fx/qfxblendedimage.cpp index 3326ea8..79b8e41 100644 --- a/src/declarative/fx/qfxblendedimage.cpp +++ b/src/declarative/fx/qfxblendedimage.cpp @@ -101,7 +101,7 @@ void QFxBlendedImage::setPrimaryUrl(const QString &url) if (primSrc == url) return; if (!primSrc.isEmpty()) - QFxPixmap::cancelGet(primUrl,this,SLOT(primaryLoaded())); + QFxPixmap::cancelGet(primUrl,this); primSrc = url; primUrl = qmlContext(this)->resolvedUrl(url); if (!primSrc.isEmpty()) @@ -129,7 +129,7 @@ void QFxBlendedImage::setSecondaryUrl(const QString &url) if (secSrc == url) return; if (!secSrc.isEmpty()) - QFxPixmap::cancelGet(secUrl,this,SLOT(secondaryLoaded())); + QFxPixmap::cancelGet(secUrl,this); secSrc = url; secUrl = qmlContext(this)->resolvedUrl(url); if (!secSrc.isEmpty()) diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 52b142b..890bb31 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -116,6 +116,8 @@ void QFxFlickablePrivate::init() QObject::connect(_flick, SIGNAL(topChanged()), q, SIGNAL(positionChanged())); QObject::connect(&elasticX, SIGNAL(updated()), q, SLOT(ticked())); QObject::connect(&elasticY, SIGNAL(updated()), q, SLOT(ticked())); + QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(heightChange())); + QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(widthChange())); } void QFxFlickablePrivate::fixupX() @@ -914,23 +916,21 @@ void QFxFlickable::setViewportWidth(int w) d->updateBeginningEnd(); } -void QFxFlickable::setWidth(int w) +void QFxFlickable::widthChange() { Q_D(QFxFlickable); - QFxItem::setWidth(w); if (d->vWidth < 0) { - d->_flick->setWidth(w); + d->_flick->setWidth(width()); emit viewportWidthChanged(); d->updateBeginningEnd(); } } -void QFxFlickable::setHeight(int h) +void QFxFlickable::heightChange() { Q_D(QFxFlickable); - QFxItem::setHeight(h); if (d->vHeight < 0) { - d->_flick->setHeight(h); + d->_flick->setHeight(height()); emit viewportHeightChanged(); d->updateBeginningEnd(); } diff --git a/src/declarative/fx/qfxflickable.h b/src/declarative/fx/qfxflickable.h index 1281788..c5a0593 100644 --- a/src/declarative/fx/qfxflickable.h +++ b/src/declarative/fx/qfxflickable.h @@ -133,8 +133,6 @@ public: qreal pageYPosition() const; qreal pageHeight() const; - virtual void setWidth(int); - virtual void setHeight(int); QFxItem *viewport(); Q_SIGNALS: @@ -165,6 +163,8 @@ protected Q_SLOTS: virtual void ticked(); void movementStarting(); void movementEnding(); + void heightChange(); + void widthChange(); protected: virtual qreal minXExtent() const; diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index acfb57e..9e6f2c9 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -319,6 +319,8 @@ void QFxGridViewPrivate::init() { Q_Q(QFxGridView); q->setOptions(QFxGridView::IsFocusRealm); + QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(sizeChange())); + QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(sizeChange())); } void QFxGridViewPrivate::clear() @@ -996,26 +998,9 @@ void QFxGridView::setCellHeight(int cellHeight) } } -/*! - \reimp -*/ -void QFxGridView::setHeight(int height) -{ - Q_D(QFxGridView); - QFxFlickable::setHeight(height); - if (isComponentComplete()) { - d->updateGrid(); - d->layout(); - } -} - -/*! - \reimp -*/ -void QFxGridView::setWidth(int width) +void QFxGridView::sizeChange() { Q_D(QFxGridView); - QFxFlickable::setWidth(width); if (isComponentComplete()) { d->updateGrid(); d->layout(); diff --git a/src/declarative/fx/qfxgridview.h b/src/declarative/fx/qfxgridview.h index c612804..2bbfc40 100644 --- a/src/declarative/fx/qfxgridview.h +++ b/src/declarative/fx/qfxgridview.h @@ -109,9 +109,6 @@ public: int cellHeight() const; void setCellHeight(int); - virtual void setHeight(int height); - virtual void setWidth(int width); - static QObject *qmlAttachedProperties(QObject *); Q_SIGNALS: @@ -134,6 +131,7 @@ private Q_SLOTS: void itemsInserted(int index, int count); void itemsRemoved(int index, int count); void destroyRemoved(); + void sizeChange(); private: void refill(); diff --git a/src/declarative/fx/qfxhighlightfilter.cpp b/src/declarative/fx/qfxhighlightfilter.cpp index 862a698..a22ad98 100644 --- a/src/declarative/fx/qfxhighlightfilter.cpp +++ b/src/declarative/fx/qfxhighlightfilter.cpp @@ -149,7 +149,7 @@ void QFxHighlightFilter::setSource(const QString &f) if (d->source == f) return; if (!d->source.isEmpty()) - QFxPixmap::cancelGet(d->url, this, SLOT(imageLoaded())); + QFxPixmap::cancelGet(d->url, this); d->source = f; d->url = qmlContext(this)->resolvedUrl(f); #if defined(QFX_RENDER_OPENGL2) diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index d66846d..e1ac2c7 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -865,9 +865,9 @@ void QFxImage::setSource(const QString &url) } if (!d->url.isEmpty()) - QFxPixmap::cancelGet(d->url, this, SLOT(requestFinished())); + QFxPixmap::cancelGet(d->url, this); if (!d->sciurl.isEmpty()) - QFxPixmap::cancelGet(d->sciurl, this, SLOT(requestFinished())); + QFxPixmap::cancelGet(d->sciurl, this); d->source = url; d->url = qmlContext(this)->resolvedUrl(url); diff --git a/src/declarative/fx/qfxkeyproxy.cpp b/src/declarative/fx/qfxkeyproxy.cpp index 1bb54ec..848b2d9 100644 --- a/src/declarative/fx/qfxkeyproxy.cpp +++ b/src/declarative/fx/qfxkeyproxy.cpp @@ -94,9 +94,9 @@ QList<QFxItem *> *QFxKeyProxy::targets() const void QFxKeyProxy::keyPressEvent(QKeyEvent *e) { for (int ii = 0; ii < d->targets.count(); ++ii) { - QSimpleCanvasItem *i = d->targets.at(ii); + QSimpleCanvasItem *i = canvas()->focusItem(d->targets.at(ii)); if (i) - canvas()->focusItem(i)->keyPressEvent(e); + i->keyPressEvent(e); if (e->isAccepted()) return; } @@ -105,9 +105,9 @@ void QFxKeyProxy::keyPressEvent(QKeyEvent *e) void QFxKeyProxy::keyReleaseEvent(QKeyEvent *e) { for (int ii = 0; ii < d->targets.count(); ++ii) { - QSimpleCanvasItem *i = d->targets.at(ii); + QSimpleCanvasItem *i = canvas()->focusItem(d->targets.at(ii)); if (i) - canvas()->focusItem(i)->keyReleaseEvent(e); + i->keyReleaseEvent(e); if (e->isAccepted()) return; } diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index b256c4a..ad752a7 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -356,6 +356,8 @@ void QFxListViewPrivate::init() { Q_Q(QFxListView); q->setOptions(QFxListView::IsFocusRealm); + QObject::connect(q, SIGNAL(heightChanged()), q, SLOT(refill())); + QObject::connect(q, SIGNAL(widthChanged()), q, SLOT(refill())); } void QFxListViewPrivate::clear() @@ -1190,28 +1192,6 @@ QString QFxListView::currentSection() const return d->currentSection; } -/*! - \reimp -*/ -void QFxListView::setHeight(int height) -{ - Q_D(QFxListView); - QFxFlickable::setHeight(height); - if (d->orient == Qt::Vertical && isComponentComplete()) - refill(); -} - -/*! - \reimp -*/ -void QFxListView::setWidth(int width) -{ - Q_D(QFxListView); - QFxFlickable::setWidth(width); - if (d->orient == Qt::Horizontal && isComponentComplete()) - refill(); -} - void QFxListView::viewportMoved() { Q_D(QFxListView); diff --git a/src/declarative/fx/qfxlistview.h b/src/declarative/fx/qfxlistview.h index f15db0c..40c2496 100644 --- a/src/declarative/fx/qfxlistview.h +++ b/src/declarative/fx/qfxlistview.h @@ -116,9 +116,6 @@ public: void setSectionExpression(const QString &); QString currentSection() const; - virtual void setHeight(int height); - virtual void setWidth(int width); - static QObject *qmlAttachedProperties(QObject *); Q_SIGNALS: @@ -137,10 +134,8 @@ protected: virtual void keyReleaseEvent(QKeyEvent *); virtual void componentComplete(); -private: - void refill(); - private Q_SLOTS: + void refill(); void trackedPositionChanged(); void itemResized(); void itemsInserted(int index, int count); diff --git a/src/declarative/fx/qfxparticles.cpp b/src/declarative/fx/qfxparticles.cpp index 8535a73..1aaf256 100644 --- a/src/declarative/fx/qfxparticles.cpp +++ b/src/declarative/fx/qfxparticles.cpp @@ -635,7 +635,7 @@ void QFxParticles::setSource(const QString &name) return; if (!d->source.isEmpty()) - QFxPixmap::cancelGet(d->url, this, SLOT(imageLoaded())); + QFxPixmap::cancelGet(d->url, this); if (name.isEmpty()) { d->source = name; d->url = QUrl(); diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index 2b39d6e..77d5fa2 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -157,7 +157,6 @@ void QFxPathView::setModel(const QVariant &model) disconnect(d->model, SIGNAL(itemCreated(int, QFxItem*)), this, SLOT(itemCreated(int,QFxItem*))); for (int i=0; i<d->items.count(); i++){ QFxItem *p = d->items[i]; - attachedProperties.remove(p); d->model->release(p); } d->items.clear(); @@ -557,7 +556,6 @@ void QFxPathViewPrivate::regenerate() Q_Q(QFxPathView); for (int i=0; i<items.count(); i++){ QFxItem *p = items[i]; - q->attachedProperties.remove(p); model->release(p); } items.clear(); @@ -631,7 +629,6 @@ void QFxPathView::refill() while(wrapIndex-- >= 0){ QFxItem* p = d->items.takeFirst(); d->updateItem(p, 0.0); - attachedProperties.remove(p); d->model->release(p); d->firstIndex++; d->firstIndex %= d->model->count(); @@ -645,7 +642,6 @@ void QFxPathView::refill() while(wrapIndex++ < d->items.count()-1){ QFxItem* p = d->items.takeLast(); d->updateItem(p, 1.0); - attachedProperties.remove(p); d->model->release(p); d->firstIndex--; if (d->firstIndex < 0) @@ -704,7 +700,6 @@ void QFxPathView::itemsRemoved(int modelIndex, int count) if (d->pathItems == -1) { for (int i = 0; i < count; ++i) { QFxItem* p = d->items.takeAt(modelIndex); - attachedProperties.remove(p); d->model->release(p); } d->snapToCurrent(); @@ -876,8 +871,11 @@ void QFxPathViewPrivate::snapToCurrent() QHash<QObject*, QObject*> QFxPathView::attachedProperties; QObject *QFxPathView::qmlAttachedProperties(QObject *obj) { - QFxPathViewAttached *rv = new QFxPathViewAttached(obj); - attachedProperties.insert(obj, rv); + QObject *rv = attachedProperties.value(obj); + if (!rv) { + rv = new QFxPathViewAttached(obj); + attachedProperties.insert(obj, rv); + } return rv; } diff --git a/src/declarative/fx/qfxpixmap.cpp b/src/declarative/fx/qfxpixmap.cpp index 3fdd8e5..0e5a10f 100644 --- a/src/declarative/fx/qfxpixmap.cpp +++ b/src/declarative/fx/qfxpixmap.cpp @@ -275,15 +275,18 @@ QNetworkReply *QFxPixmap::get(QmlEngine *engine, const QUrl& url, QObject* obj, /*! Stops the given slot being invoked if the given url finishes loading. May also cancel loading (eg. if no other pending request). + + Any connections to the QNetworkReply returned by get() will be + disconnected. */ -void QFxPixmap::cancelGet(const QUrl& url, QObject* obj, const char* slot) +void QFxPixmap::cancelGet(const QUrl& url, QObject* obj) { QString key = url.toString(); QFxPixmapCache::Iterator iter = qfxPixmapCache.find(key); if (iter == qfxPixmapCache.end()) return; if ((*iter)->reply) - QObject::disconnect((*iter)->reply, SIGNAL(finished()), obj, slot); + QObject::disconnect((*iter)->reply, 0, obj, 0); // XXX - loading not cancelled. Need to revisit caching } diff --git a/src/declarative/fx/qfxpixmap.h b/src/declarative/fx/qfxpixmap.h index 748991e..297dba7 100644 --- a/src/declarative/fx/qfxpixmap.h +++ b/src/declarative/fx/qfxpixmap.h @@ -67,7 +67,7 @@ public: QFxPixmap &operator=(const QFxPixmap &); static QNetworkReply *get(QmlEngine *, const QUrl& url, QObject*, const char* slot); - static void cancelGet(const QUrl& url, QObject* obj, const char* slot); + static void cancelGet(const QUrl& url, QObject* obj); bool isNull() const; diff --git a/src/declarative/fx/qfxtextedit.cpp b/src/declarative/fx/qfxtextedit.cpp index bf7a16d..3bc9696 100644 --- a/src/declarative/fx/qfxtextedit.cpp +++ b/src/declarative/fx/qfxtextedit.cpp @@ -377,6 +377,28 @@ void QFxTextEdit::setWrap(bool w) updateSize(); } +/*! + \property QFxTextEdit::cursorVisible + \brief If true the text edit shows a cursor. + + This property is set and unset when the text edit gets focus, but it can also + be set directly (useful, for example, if a KeyProxy might forward keys to it). +*/ +bool QFxTextEdit::isCursorVisible() const +{ + Q_D(const QFxTextEdit); + return d->cursorVisible; +} + +void QFxTextEdit::setCursorVisible(bool on) +{ + Q_D(QFxTextEdit); + if (d->cursorVisible == on) + return; + d->cursorVisible = on; + QFocusEvent focusEvent(on ? QEvent::FocusIn : QEvent::FocusOut); + d->control->processEvent(&focusEvent, QPointF(0, 0)); +} void QFxTextEdit::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) @@ -591,8 +613,15 @@ void QFxTextEdit::keyReleaseEvent(QKeyEvent *event) void QFxTextEdit::focusChanged(bool hasFocus) { Q_D(QFxTextEdit); - QFocusEvent focusEvent(hasFocus ? QEvent::FocusIn : QEvent::FocusOut); - d->control->processEvent(&focusEvent, QPointF(0, 0)); +} + +/*! + Causes all text to be selected. +*/ +void QFxTextEdit::selectAll() +{ + Q_D(QFxTextEdit); + d->control->selectAll(); } static QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e) @@ -737,6 +766,7 @@ void QFxTextEditPrivate::init() document->setDocumentMargin(0); document->setUndoRedoEnabled(false); // flush undo buffer. document->setUndoRedoEnabled(true); + updateDefaultTextOption(); } void QFxTextEdit::q_textChanged() @@ -785,14 +815,13 @@ void QFxTextEdit::updateSize() void QFxTextEditPrivate::updateDefaultTextOption() { - QTextDocument *doc = control->document(); - - QTextOption opt = doc->defaultTextOption(); + QTextOption opt = document->defaultTextOption(); int oldAlignment = opt.alignment(); opt.setAlignment((Qt::Alignment)(int)(hAlign | vAlign)); QTextOption::WrapMode oldWrapMode = opt.wrapMode(); +qDebug() << "wrap mode is" << opt.wrapMode(); if (wrap) opt.setWrapMode(QTextOption::WordWrap); else @@ -800,7 +829,8 @@ void QFxTextEditPrivate::updateDefaultTextOption() if (oldWrapMode == opt.wrapMode() && oldAlignment == opt.alignment()) return; - doc->setDefaultTextOption(opt); +qDebug() << "wrap mode set to" << opt.wrapMode(); + document->setDefaultTextOption(opt); } QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxtextedit.h b/src/declarative/fx/qfxtextedit.h index e5e9421..068a25a 100644 --- a/src/declarative/fx/qfxtextedit.h +++ b/src/declarative/fx/qfxtextedit.h @@ -75,7 +75,9 @@ class Q_DECLARATIVE_EXPORT QFxTextEdit : public QFxPaintedItem Q_PROPERTY(bool wrap READ wrap WRITE setWrap) Q_PROPERTY(TextFormat textFormat READ textFormat WRITE setTextFormat) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) + Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible) Q_CLASSINFO("DefaultProperty", "text") + public: QFxTextEdit(QFxItem *parent=0); @@ -118,6 +120,9 @@ public: bool wrap() const; void setWrap(bool w); + bool isCursorVisible() const; + void setCursorVisible(bool on); + virtual void dump(int depth); virtual QString propertyInfo() const; @@ -145,6 +150,9 @@ Q_SIGNALS: void textChanged(const QString &); void cursorPositionChanged(); +public Q_SLOTS: + void selectAll(); + private Q_SLOTS: void fontChanged(); void updateImgCache(const QRectF &rect); diff --git a/src/declarative/fx/qfxtextedit_p.h b/src/declarative/fx/qfxtextedit_p.h index b583dbe..f4591f5 100644 --- a/src/declarative/fx/qfxtextedit_p.h +++ b/src/declarative/fx/qfxtextedit_p.h @@ -68,7 +68,7 @@ class QFxTextEditPrivate : public QFxPaintedItemPrivate public: QFxTextEditPrivate() - : font(0), color("black"), imgDirty(true), hAlign(QFxTextEdit::AlignLeft), vAlign(QFxTextEdit::AlignTop), dirty(false), wrap(false), richText(false), format(QFxTextEdit::AutoText), document(0) + : font(0), color("black"), imgDirty(true), hAlign(QFxTextEdit::AlignLeft), vAlign(QFxTextEdit::AlignTop), dirty(false), wrap(false), richText(false), cursorVisible(false), format(QFxTextEdit::AutoText), document(0) { } @@ -93,6 +93,7 @@ public: bool dirty; bool wrap; bool richText; + bool cursorVisible; QFxTextEdit::TextFormat format; QTextDocument *document; QTextControl *control; diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 15b5879..50c0981 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -597,6 +597,9 @@ QNetworkAccessManager *QmlEngine::networkAccessManager() const */ QmlContext *QmlEngine::contextForObject(const QObject *object) { + if(!object) + return 0; + QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object)); QmlSimpleDeclarativeData *data = @@ -1093,6 +1096,14 @@ QObject *QmlExpression::scopeObject() const } /*! + \internal +*/ +quint32 QmlExpression::id() const +{ + return d->id; +} + +/*! \class QmlExpression \brief The QmlExpression class evaluates ECMAScript in a QML context. */ diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h index 0ab5d9c..bb6980a 100644 --- a/src/declarative/qml/qmlexpression.h +++ b/src/declarative/qml/qmlexpression.h @@ -80,6 +80,7 @@ public: QObject *scopeObject() const; + quint32 id() const; protected: virtual void valueChanged(); diff --git a/src/declarative/qml/script/qmlbasicscript.cpp b/src/declarative/qml/script/qmlbasicscript.cpp index 603e6ba..ee537e4 100644 --- a/src/declarative/qml/script/qmlbasicscript.cpp +++ b/src/declarative/qml/script/qmlbasicscript.cpp @@ -789,6 +789,7 @@ QVariant QmlBasicScript::run(QmlContext *context, void *voidCache, CacheState *c state = Incremental; } + qWarning("ReferenceError: %s is not defined", id); } else { // instr.type == ScriptInstruction::Fetch QVariant o = stack.pop(); diff --git a/src/declarative/qml/script/qmlbasicscript_p.h b/src/declarative/qml/script/qmlbasicscript_p.h index bcb7d00..fb9951e 100644 --- a/src/declarative/qml/script/qmlbasicscript_p.h +++ b/src/declarative/qml/script/qmlbasicscript_p.h @@ -39,6 +39,7 @@ public: }; int coreType; + bool isValid() const { return type != Invalid; } bool isCore() const { return type == Core; } bool isExplicit() const { return type == Explicit; } void clear(); |