diff options
author | Michael Brasser <michael.brasser@nokia.com> | 2009-04-28 04:57:49 (GMT) |
---|---|---|
committer | Michael Brasser <michael.brasser@nokia.com> | 2009-04-28 04:57:49 (GMT) |
commit | c139630bb792e3d0e364c05c7be3e190bfd90b64 (patch) | |
tree | 1e5f16a1b65ef1cab34989ef776a353d94c1dc85 | |
parent | 72dfac4fbe7a45ca84ce233eb68161c685bdc31c (diff) | |
parent | a6ffd7c7c28066f2794579bc40e7b9517e76d1ff (diff) | |
download | Qt-c139630bb792e3d0e364c05c7be3e190bfd90b64.zip Qt-c139630bb792e3d0e364c05c7be3e190bfd90b64.tar.gz Qt-c139630bb792e3d0e364c05c7be3e190bfd90b64.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
56 files changed, 886 insertions, 350 deletions
diff --git a/examples/declarative/connections/connections.qml b/examples/declarative/connections/connections.qml index 3146338..45c0e99 100644 --- a/examples/declarative/connections/connections.qml +++ b/examples/declarative/connections/connections.qml @@ -1,9 +1,9 @@ <Rect id="rect" color="blue" width="40" height="30"> <Rect id="dot" color="red" width="3" height="3" x="{rect.width/2}" y="{rect.height/2}"/> <MouseRegion id="mr" anchors.fill="{rect}"/> - <Connection sender="{mr}" signal="clicked(x,y)"> + <Connection sender="{mr}" signal="clicked(mouse)"> color="green"; - dot.x = x-1; - dot.y = y-1; + dot.x = mouse.x-1; + dot.y = mouse.y-1; </Connection> </Rect> diff --git a/examples/declarative/listview/listview.qml b/examples/declarative/listview/listview.qml index 08c8f18..6cacdd1 100644 --- a/examples/declarative/listview/listview.qml +++ b/examples/declarative/listview/listview.qml @@ -74,7 +74,7 @@ Note that we specify the 'children' property. This is because the default property of a ListView is 'delegate'. --> - <Rect y="{List3.yPosition+125}" width="200" height="50" color="#FFFF88" z="0"/> + <Rect y="125" width="200" height="50" color="#FFFF88" z="-1"/> </children> </ListView> diff --git a/examples/declarative/mouseregion/mouse.qml b/examples/declarative/mouseregion/mouse.qml index f0f22ac..7aaf51a 100644 --- a/examples/declarative/mouseregion/mouse.qml +++ b/examples/declarative/mouseregion/mouse.qml @@ -1,10 +1,10 @@ <Rect color="white" width="200" height="200"> <Rect width="50" height="50" color="red"> <Text text="Click" anchors.centeredIn="{parent}"/> - <MouseRegion onPressed="print('press (x: ' + x + ' y: ' + y + ')')" - onReleased="print('release (x: ' + x + ' y: ' + y + ' isClick: ' + isClick + ' followsPressAndHold: ' + followsPressAndHold + ')')" - onClicked="print('click (x: ' + x + ' y: ' + y + ' followsPressAndHold: ' + followsPressAndHold + ')')" - onDoubleClicked="print('double click (x: ' + x + ' y: ' + y + ')')" + <MouseRegion onPressed="print('press (x: ' + mouse.x + ' y: ' + mouse.y + ' button: ' + (mouse.button == Qt.RightButton ? 'right' : 'left') + ' Shift: ' + (mouse.modifiers & Qt.ShiftModifier ? 'true' : 'false') + ')')" + onReleased="print('release (x: ' + mouse.x + ' y: ' + mouse.y + ' isClick: ' + mouse.isClick + ' wasHeld: ' + mouse.wasHeld + ')')" + onClicked="print('click (x: ' + mouse.x + ' y: ' + mouse.y + ' wasHeld: ' + mouse.wasHeld + ')')" + onDoubleClicked="print('double click (x: ' + mouse.x + ' y: ' + mouse.y + ')')" onPressAndHold="print('press and hold')" onExitedWhilePressed="print('exiting while pressed')" onReenteredWhilePressed="print('reentering while pressed')" anchors.fill="{parent}"/> @@ -14,8 +14,8 @@ <MouseRegion drag.target="{parent}" drag.axis="x" drag.xmin="0" drag.xmax="150" onPressed="print('press')" - onReleased="print('release (isClick: ' + isClick + ') (followsPressAndHold: ' + followsPressAndHold + ')')" - onClicked="print('click' + '(followsPressAndHold: ' + followsPressAndHold + ')')" + onReleased="print('release (isClick: ' + mouse.isClick + ') (wasHeld: ' + mouse.wasHeld + ')')" + onClicked="print('click' + '(wasHeld: ' + mouse.wasHeld + ')')" onDoubleClicked="print('double click')" onPressAndHold="print('press and hold')" onExitedWhilePressed="print('exiting while pressed')" diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 638c7d1..220e132 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -842,6 +842,14 @@ QObject::~QObject() d->eventFilters.clear(); + // As declarativeData is in a union with currentChildBeingDeleted, this must + // be done (and declarativeData set back to 0) before deleting children. + if(d->declarativeData) { + QDeclarativeData *dd = d->declarativeData; + d->declarativeData = 0; + dd->destroyed(this); + } + if (!d->children.isEmpty()) d->deleteChildren(); diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 31b1593..81d3aba 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -85,6 +85,13 @@ inline QObjectData::~QObjectData() {} enum { QObjectPrivateVersion = QT_VERSION }; +class Q_CORE_EXPORT QDeclarativeData +{ +public: + virtual ~QDeclarativeData() {} + virtual void destroyed(QObject *) {} +}; + class Q_CORE_EXPORT QObjectPrivate : public QObjectData { Q_DECLARE_PUBLIC(QObject) @@ -118,7 +125,10 @@ public: // object currently activating the object Sender *currentSender; - QObject *currentChildBeingDeleted; + union { + QObject *currentChildBeingDeleted; + QDeclarativeData *declarativeData; + }; bool isSender(const QObject *receiver, const char *signal) const; QObjectList receiverList(const char *signal) const; diff --git a/src/declarative/canvas/qsimplecanvas.cpp b/src/declarative/canvas/qsimplecanvas.cpp index 4d2cc5b..572bc43 100644 --- a/src/declarative/canvas/qsimplecanvas.cpp +++ b/src/declarative/canvas/qsimplecanvas.cpp @@ -411,6 +411,7 @@ QGraphicsSceneMouseEvent *QSimpleCanvasPrivate::mouseEventToSceneMouseEvent(QMou QGraphicsSceneMouseEvent *me = new QGraphicsSceneMouseEvent(t); me->setButton(e->button()); me->setButtons(e->buttons()); + me->setModifiers(e->modifiers()); me->setPos(item); me->setScreenPos(e->pos()); me->setScenePos(e->pos()); diff --git a/src/declarative/extra/qmlsqlconnection.cpp b/src/declarative/extra/qmlsqlconnection.cpp index 3e2032c..7f1fec2 100644 --- a/src/declarative/extra/qmlsqlconnection.cpp +++ b/src/declarative/extra/qmlsqlconnection.cpp @@ -62,7 +62,6 @@ public: int port; QString name, databaseName, connectionOptions; QString hostName, userName, password, driver; - QmlContext *context; }; /*! @@ -177,8 +176,6 @@ public: QmlSqlConnection::QmlSqlConnection(QObject *parent) : QObject(*(new QmlSqlConnectionPrivate), parent) { - Q_D(QmlSqlConnection); - d->context = QmlContext::activeContext(); } /*! @@ -416,10 +413,11 @@ QSqlDatabase QmlSqlConnection::database() const } if (db.isOpen()) return db; - if ((d->driver.isEmpty() || d->driver == QLatin1String("QSQLITE")) && d->context) { + if ((d->driver.isEmpty() || d->driver == QLatin1String("QSQLITE")) && + qmlContext(this)) { // SQLITE uses files for databases, hence use relative pathing // if possible. - QUrl url = d->context->resolvedUrl(d->databaseName); + QUrl url = qmlContext(this)->resolvedUrl(d->databaseName); if (url.isRelative() || url.scheme() == QLatin1String("file")) db.setDatabaseName(url.toLocalFile()); else diff --git a/src/declarative/extra/qmlxmllistmodel.cpp b/src/declarative/extra/qmlxmllistmodel.cpp index 13faab2..44787b5 100644 --- a/src/declarative/extra/qmlxmllistmodel.cpp +++ b/src/declarative/extra/qmlxmllistmodel.cpp @@ -87,7 +87,7 @@ class QmlXmlListModelPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QmlXmlListModel) public: - QmlXmlListModelPrivate() : size(-1), highestRole(Qt::UserRole), reply(0), context(0), roleObjects(this) {} + QmlXmlListModelPrivate() : size(-1), highestRole(Qt::UserRole), reply(0), roleObjects(this) {} QString src; QString query; @@ -100,7 +100,6 @@ public: QNetworkReply *reply; mutable QByteArray xml; QString prefix; - QmlContext *context; struct RoleList : public QmlConcreteList<XmlListModelRole *> { @@ -144,7 +143,6 @@ QmlXmlListModel::QmlXmlListModel(QObject *parent) : QListModelInterface(*(new QmlXmlListModelPrivate), parent) { Q_D(QmlXmlListModel); - d->context = QmlContext::activeContext(); } QmlXmlListModel::~QmlXmlListModel() @@ -249,7 +247,7 @@ void QmlXmlListModel::fetch() QNetworkRequest req((QUrl(d->src))); req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - d->reply = d->context->engine()->networkAccessManager()->get(req); + d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(requestFinished())); } diff --git a/src/declarative/fx/fx.pri b/src/declarative/fx/fx.pri index fc20371..ef059c7 100644 --- a/src/declarative/fx/fx.pri +++ b/src/declarative/fx/fx.pri @@ -8,6 +8,7 @@ HEADERS += \ fx/qfxcomponentinstance_p.h \ fx/qfxcontentwrapper.h \ fx/qfxcontentwrapper_p.h \ + fx/qfxevents_p.h \ fx/qfxflickable.h \ fx/qfxflickable_p.h \ fx/qfxflipable.h \ @@ -58,6 +59,7 @@ SOURCES += \ fx/qfxblurfilter.cpp \ fx/qfxcomponentinstance.cpp \ fx/qfxcontentwrapper.cpp \ + fx/qfxevents.cpp \ fx/qfxflickable.cpp \ fx/qfxflipable.cpp \ fx/qfxfocuspanel.cpp \ diff --git a/src/declarative/fx/qfxanimatedimageitem.cpp b/src/declarative/fx/qfxanimatedimageitem.cpp index cc11b56..b5f0cc4 100644 --- a/src/declarative/fx/qfxanimatedimageitem.cpp +++ b/src/declarative/fx/qfxanimatedimageitem.cpp @@ -165,7 +165,7 @@ void QFxAnimatedImageItem::setSource(const QString &url) } d->source = url; - d->url = itemContext()->resolvedUrl(url); + d->url = qmlContext(this)->resolvedUrl(url); if(url.isEmpty()) { delete d->_movie; @@ -174,7 +174,7 @@ void QFxAnimatedImageItem::setSource(const QString &url) d->status = Loading; QNetworkRequest req(d->url); req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - d->reply = itemContext()->engine()->networkAccessManager()->get(req); + d->reply = qmlContext(this)->engine()->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(movieRequestFinished())); } diff --git a/src/declarative/fx/qfxblendedimage.cpp b/src/declarative/fx/qfxblendedimage.cpp index b5b7bb3..ec2b9cc 100644 --- a/src/declarative/fx/qfxblendedimage.cpp +++ b/src/declarative/fx/qfxblendedimage.cpp @@ -103,9 +103,9 @@ void QFxBlendedImage::setPrimaryUrl(const QString &url) if (!primSrc.isEmpty()) QFxPixmap::cancelGet(primUrl,this,SLOT(primaryLoaded())); primSrc = url; - primUrl = itemContext()->resolvedUrl(url); + primUrl = qmlContext(this)->resolvedUrl(url); if (!primSrc.isEmpty()) - QFxPixmap::get(itemContext()->engine(), primUrl,this,SLOT(primaryLoaded())); + QFxPixmap::get(qmlEngine(this), primUrl,this,SLOT(primaryLoaded())); } /*! @@ -131,9 +131,9 @@ void QFxBlendedImage::setSecondaryUrl(const QString &url) if (!secSrc.isEmpty()) QFxPixmap::cancelGet(secUrl,this,SLOT(secondaryLoaded())); secSrc = url; - secUrl = itemContext()->resolvedUrl(url); + secUrl = qmlContext(this)->resolvedUrl(url); if (!secSrc.isEmpty()) - QFxPixmap::get(itemContext()->engine(), secUrl,this,SLOT(secondaryLoaded())); + QFxPixmap::get(qmlEngine(this), secUrl,this,SLOT(secondaryLoaded())); } /*! diff --git a/src/declarative/fx/qfxcomponentinstance.cpp b/src/declarative/fx/qfxcomponentinstance.cpp index b456716..02a6c86 100644 --- a/src/declarative/fx/qfxcomponentinstance.cpp +++ b/src/declarative/fx/qfxcomponentinstance.cpp @@ -109,7 +109,7 @@ void QFxComponentInstance::create() { Q_D(QFxComponentInstance); if(d->component) { - QObject *obj= d->component->create(itemContext()); + QObject *obj= d->component->create(qmlContext(this)); if(obj) { QFxItem *objitem = qobject_cast<QFxItem *>(obj); if(objitem) { diff --git a/src/declarative/fx/qfxevents.cpp b/src/declarative/fx/qfxevents.cpp new file mode 100644 index 0000000..804446b --- /dev/null +++ b/src/declarative/fx/qfxevents.cpp @@ -0,0 +1,185 @@ +/**************************************************************************** +** +** 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 "qfxevents_p.h" + +QT_BEGIN_NAMESPACE +/*! + \qmlclass KeyEvent QFxKeyEvent + \brief The KeyEvent element provides information about a key event. + + For example, the following changes the Item's state property when the Enter + key is pressed: + \code + <Item focus="true"> + <onKeyPress>if (event.key == Qt.Key_Enter) state = 'ShowDetails';</onKeyPress> + </Item> + \endcode + + The \l KeyActions element could also be used to achieve the above with + a clearer syntax. + + \sa KeyActions +*/ + +/*! + \internal + \class QFxKeyEvent +*/ + +/*! + \qmlproperty int KeyEvent::key + + This property holds the code of the key that was pressed or released. + + See \l {Qt::Key}{Qt.Key} for the list of keyboard codes. These codes are + independent of the underlying window system. Note that this + function does not distinguish between capital and non-capital + letters, use the text() function (returning the Unicode text the + key generated) for this purpose. + + A value of either 0 or \l {Qt::Key_unknown}{Qt.Key_Unknown} means that the event is not + the result of a known key; for example, it may be the result of + a compose sequence, a keyboard macro, or due to key event + compression. +*/ + +/*! + \qmlproperty string KeyEvent::text + + This property holds the Unicode text that the key generated. + The text returned can be an empty string in cases where modifier keys, + such as Shift, Control, Alt, and Meta, are being pressed or released. + In such cases \c key will contain a valid value +*/ + +/*! + \qmlproperty bool KeyEvent::isAutoRepeat + + This property holds whether this event comes from an auto-repeating key. +*/ + +/*! + \qmlproperty int KeyEvent::count + + This property holds the number of keys involved in this event. If \l KeyEvent::text + is not empty, this is simply the length of the string. +*/ + +/*! + \qmlclass MouseEvent QFxMouseEvent + \brief The MouseEvent element provides information about a mouse event. + + The position of the mouse can be found via the x and y properties. + The button that caused the event is available via the button property. +*/ + +/*! + \internal + \class QFxMouseEvent +*/ + +/*! + \qmlproperty int x + \qmlproperty int y + + These properties hold the position of the mouse event. +*/ + +/*! + \qmlproperty enum MouseEvent::button + + This property holds the button that caused the event. It can be one of: + \list + \o Qt.LeftButton + \o Qt.RightButton + \o Qt.MidButton + \endlist +*/ + +/*! + \qmlproperty int MouseEvent::buttons + + This property holds the mouse buttons pressed when the event was generated. + For mouse move events, this is all buttons that are pressed down. For mouse + press and double click events this includes the button that caused the event. + For mouse release events this excludes the button that caused the event. + + It contains a bitwise combination of: + \list + \o Qt.LeftButton + \o Qt.RightButton + \o Qt.MidButton + \endlist +*/ + +/*! + \qmlproperty int MouseEvent::modifiers + + This property holds the keyboard modifier flags that existed immediately + before the event occurred. + + It contains a bitwise combination of: + \list + \o Qt.NoModifier - No modifier key is pressed. + \o Qt.ShiftModifier - A Shift key on the keyboard is pressed. + \o Qt.ControlModifier - A Ctrl key on the keyboard is pressed. + \o Qt.AltModifier - An Alt key on the keyboard is pressed. + \o Qt.MetaModifier - A Meta key on the keyboard is pressed. + \o Qt.KeypadModifier - A keypad button is pressed. + \endlist + + For example, to react to a Shift key + Left mouse button click: + \code + <MouseRegion> + <onClick> + <![CDATA[ + if (mouse.button == Qt.LeftButton && mouse.modifiers & Qt.ShiftModifier) doSomething(); + ]]> + </onclick> + </MouseRegion> + \endcode +*/ + +QML_DEFINE_NOCREATE_TYPE(QFxKeyEvent); +QML_DEFINE_NOCREATE_TYPE(QFxMouseEvent); + +QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxevents_p.h b/src/declarative/fx/qfxevents_p.h new file mode 100644 index 0000000..30717ef --- /dev/null +++ b/src/declarative/fx/qfxevents_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** 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 QFXEVENTS_P_H +#define QFXEVENTS_P_H + +#include <qfxglobal.h> +#include <qml.h> +#include <QtCore/qobject.h> +#include <QtGui/qevent.h> + +QT_BEGIN_NAMESPACE + +class QFxKeyEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int key READ key) + Q_PROPERTY(QString text READ text) + Q_PROPERTY(int modifiers READ modifiers) + Q_PROPERTY(bool isAutoRepeat READ isAutoRepeat) + Q_PROPERTY(int count READ count) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) + +public: + QFxKeyEvent(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text=QString(), bool autorep=false, ushort count=1) + : event(type, key, modifiers, text, autorep, count) { event.setAccepted(false); } + QFxKeyEvent(const QKeyEvent &ke) + : event(ke) { event.setAccepted(false); } + + int key() const { return event.key(); } + QString text() const { return event.text(); } + int modifiers() const { return event.modifiers(); } + bool isAutoRepeat() const { return event.isAutoRepeat(); } + int count() const { return event.count(); } + + bool isAccepted() { return event.isAccepted(); } + void setAccepted(bool accepted) { event.setAccepted(accepted); } + +private: + QKeyEvent event; +}; + +QML_DECLARE_TYPE(QFxKeyEvent); + +class QFxMouseEvent : public QObject +{ + Q_OBJECT + Q_PROPERTY(int x READ x) + Q_PROPERTY(int y READ y) + Q_PROPERTY(int button READ button) + Q_PROPERTY(int buttons READ buttons) + Q_PROPERTY(int modifiers READ modifiers) + Q_PROPERTY(bool wasHeld READ wasHeld) + Q_PROPERTY(bool isClick READ isClick) + Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted) + +public: + QFxMouseEvent(int x, int y, Qt::MouseButton button, Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers + , bool isClick=false, bool wasHeld=false) + : _x(x), _y(y), _button(button), _buttons(buttons), _modifiers(modifiers) + , _wasHeld(wasHeld), _isClick(isClick), _accepted(false) {} + + int x() const { return _x; } + int y() const { return _y; } + int button() const { return _button; } + int buttons() const { return _buttons; } + int modifiers() const { return _modifiers; } + bool wasHeld() const { return _wasHeld; } + bool isClick() const { return _isClick; } + + bool isAccepted() { return _accepted; } + void setAccepted(bool accepted) { _accepted = accepted; } + +private: + int _x; + int _y; + Qt::MouseButton _button; + Qt::MouseButtons _buttons; + Qt::KeyboardModifiers _modifiers; + bool _wasHeld; + bool _isClick; + bool _accepted; +}; + +QML_DECLARE_TYPE(QFxMouseEvent); + +QT_END_NAMESPACE + +#endif // QFXEVENTS_P_H diff --git a/src/declarative/fx/qfxflickable.cpp b/src/declarative/fx/qfxflickable.cpp index 04b4a3d..b6eaa8e 100644 --- a/src/declarative/fx/qfxflickable.cpp +++ b/src/declarative/fx/qfxflickable.cpp @@ -626,7 +626,7 @@ void QFxFlickablePrivate::handleMouseMoveEvent(QGraphicsSceneMouseEvent *event) lastPos = event->pos(); } -void QFxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *event) +void QFxFlickablePrivate::handleMouseReleaseEvent(QGraphicsSceneMouseEvent *) { Q_Q(QFxFlickable); diff --git a/src/declarative/fx/qfxgridview.cpp b/src/declarative/fx/qfxgridview.cpp index f9a9f8c..25c1565 100644 --- a/src/declarative/fx/qfxgridview.cpp +++ b/src/declarative/fx/qfxgridview.cpp @@ -79,12 +79,9 @@ public: } static QFxGridViewAttached *properties(QObject *obj) { - if(!attachedProperties.contains(obj)) { - QFxGridViewAttached *rv = new QFxGridViewAttached(obj); - attachedProperties.insert(obj, rv); - return rv; - } - return attachedProperties.value(obj); + QFxGridViewAttached *rv = new QFxGridViewAttached(obj); + attachedProperties.insert(obj, rv); + return rv; } void emitAdd() { emit add(); } @@ -558,7 +555,7 @@ void QFxGridViewPrivate::createHighlight() return; if (currentItem) { - QmlContext *highlightContext = new QmlContext(q->itemContext()); + QmlContext *highlightContext = new QmlContext(qmlContext(q)); QObject *nobj = highlightComponent->create(highlightContext); if (nobj) { highlightContext->setParent(nobj); @@ -751,7 +748,7 @@ void QFxGridView::setModel(const QVariant &model) d->model = vim; } else { if (!d->ownModel) { - d->model = new QFxVisualItemModel(itemContext()); + d->model = new QFxVisualItemModel(qmlContext(this)); d->ownModel = true; } d->model->setModel(model); @@ -796,7 +793,7 @@ void QFxGridView::setDelegate(QmlComponent *delegate) { Q_D(QFxGridView); if (!d->ownModel) { - d->model = new QFxVisualItemModel(itemContext()); + d->model = new QFxVisualItemModel(qmlContext(this)); d->ownModel = true; } d->model->setDelegate(delegate); diff --git a/src/declarative/fx/qfxhighlightfilter.cpp b/src/declarative/fx/qfxhighlightfilter.cpp index d1ff3d3..d99b9e5 100644 --- a/src/declarative/fx/qfxhighlightfilter.cpp +++ b/src/declarative/fx/qfxhighlightfilter.cpp @@ -56,10 +56,8 @@ class QFxHighlightFilterPrivate { public: QFxHighlightFilterPrivate() - : ctxt(QmlContext::activeContext()), - xOffset(0), yOffset(0), tiled(false) {} + : xOffset(0), yOffset(0), tiled(false) {} - QmlContext *ctxt; QString source; QUrl url; int xOffset; @@ -147,12 +145,12 @@ void QFxHighlightFilter::setSource(const QString &f) if(!d->source.isEmpty()) QFxPixmap::cancelGet(d->url, this, SLOT(imageLoaded())); d->source = f; - d->url = QmlContext::activeContext()->resolvedUrl(f); + d->url = qmlContext(this)->resolvedUrl(f); #if defined(QFX_RENDER_OPENGL2) d->tex.clear(); #endif if(!f.isEmpty()) - QFxPixmap::get(d->ctxt->engine(), d->url, this, SLOT(imageLoaded())); + QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(imageLoaded())); else emit sourceChanged(d->source); } diff --git a/src/declarative/fx/qfximage.cpp b/src/declarative/fx/qfximage.cpp index 9fe491c..2d0dbc7 100644 --- a/src/declarative/fx/qfximage.cpp +++ b/src/declarative/fx/qfximage.cpp @@ -842,7 +842,7 @@ void QFxImage::setSource(const QString &url) QFxPixmap::cancelGet(d->sciurl, this, SLOT(requestFinished())); d->source = url; - d->url = itemContext()->resolvedUrl(url); + d->url = qmlContext(this)->resolvedUrl(url); d->sciurl = QUrl(); if(url.isEmpty()) { @@ -861,12 +861,12 @@ void QFxImage::setSource(const QString &url) { QNetworkRequest req(d->url); req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - d->reply = itemContext()->engine()->networkAccessManager()->get(req); + d->reply = qmlEngine(this)->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(sciRequestFinished())); } } else { - QFxPixmap::get(itemContext()->engine(), d->url, this, SLOT(requestFinished())); + QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(requestFinished())); } } @@ -921,7 +921,7 @@ void QFxImage::setGridScaledImage(const QFxGridScaledImage& sci) emit statusChanged(d->status); } else { d->sciurl = d->url.resolved(QUrl(sci.pixmapUrl())); - QFxPixmap::get(itemContext()->engine(), d->sciurl, this, SLOT(requestFinished())); + QFxPixmap::get(qmlEngine(this), d->sciurl, this, SLOT(requestFinished())); QFxScaleGrid *sg = scaleGrid(); sg->setTop(sci.gridTop()); sg->setBottom(sci.gridBottom()); diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index 0ee734b..e3568e0 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -60,6 +60,7 @@ #include "qfxitem_p.h" #include "qfxitem.h" +#include "qfxevents_p.h" #include <qsimplecanvasfilter.h> #include <qmlcomponent.h> @@ -242,24 +243,20 @@ void QFxContents::setItem(QFxItem *item) This signal is emitted when the baseline of the item changes. - The baseline may change in response to a call to setBaselineOffset() - or due to the geometry of the item changing. - - \sa baselineOffset(), setBaselineOffset() + The baseline may change in response to a change to the baselineOffset + property or due to the geometry of the item changing. */ /*! \fn void QFxItem::baselineOffsetChanged() This signal is emitted when the baseline of the item is changed - via setBaselineOffset(). + via the baselineOffset property. The baseline corresponds to the baseline of the text contained in the element. It is useful for aligning the text in items placed beside each other. The default baseline is positioned at 2/3 of the height of the item. - - \sa baselineOffset(), setBaselineOffset() */ /*! @@ -325,33 +322,27 @@ void QFxContents::setItem(QFxItem *item) */ /*! - \fn void QFxItem::keyPress(QObject *event) + \qmlsignal Item::onKeyPress(event) - This signal is emitted when a key is pressed. + This handler is called when a key is pressed. - The key event is available in QML via the QFxKeyEvent \c event - property. + The key event is available via the KeyEvent \a event. \qml <Item onKeyPress="if (event.key == Qt.Key_Enter) state='Enter'"/> \endqml - - \sa keyRelease() */ /*! - \fn void QFxItem::keyRelease(QObject *event) + \qmlsignal Item::onKeyRelease(event) - This signal is emitted when a key is released. + This handler is called when a key is released. - The key event is available in QML via the QFxKeyEvent \c event - property. + The key event is available in via the KeyEvent \a event. \qml <Item onKeyRelease="if (event.key == Qt.Key_Enter) state='Enter'"/> \endqml - - \sa keyPress() */ /*! @@ -816,7 +807,7 @@ void QFxItem::setQml(const QString &qml) } d->_qml = qml; - d->_qmlurl = itemContext()->resolvedUri(qml); + d->_qmlurl = qmlContext(this)->resolvedUri(qml); d->qmlItem = 0; if(d->_qml.isEmpty()) { @@ -831,7 +822,7 @@ void QFxItem::setQml(const QString &qml) emit qmlChanged(); } else { d->_qmlcomp = - new QmlComponent(itemContext()->engine(), d->_qmlurl, this); + new QmlComponent(qmlEngine(this), d->_qmlurl, this); if(!d->_qmlcomp->isLoading()) qmlLoaded(); else @@ -852,12 +843,12 @@ void QFxItem::qmlLoaded() if(c->isLoading()) continue; - QmlContext *ctxt = new QmlContext(itemContext()); + QmlContext *ctxt = new QmlContext(qmlContext(this)); QObject* o = c ? c->create(ctxt):0; QFxItem* ret = qobject_cast<QFxItem*>(o); if (ret) { ret->setItemParent(this); - QScriptValue v = itemContext()->engine()->scriptEngine()->newQObject(ret); + QScriptValue v = qmlEngine(this)->scriptEngine()->newQObject(ret); emit newChildCreated(d->_qmlnewloading.at(i).toString(),v); } @@ -870,7 +861,7 @@ void QFxItem::qmlLoaded() // setQml... if (d->_qmlcomp) { - QmlContext *ctxt = new QmlContext(itemContext()); + QmlContext *ctxt = new QmlContext(qmlContext(this)); ctxt->addDefaultObject(this); QObject *obj = d->_qmlcomp->create(ctxt); @@ -1120,34 +1111,13 @@ void QFxItem::setFlipHorizontally(bool v) setFlip((QSimpleCanvasItem::Flip)(flip() & ~HorizontalFlip)); } -class QFxKeyEvent : public QObject -{ - Q_OBJECT - Q_PROPERTY(int key READ key); - Q_PROPERTY(QString text READ text); - Q_PROPERTY(bool accepted READ isAccepted WRITE setAccepted); -public: - QFxKeyEvent(int key, const QString &text=QString()) : _accepted(false), _key(key), _text(text) {} - - bool isAccepted() { return _accepted; } - void setAccepted(bool accepted) { _accepted = accepted; } - - int key() const { return _key; } - - QString text() const { return _text; } - -private: - bool _accepted; - int _key; - QString _text; -}; /*! \reimp */ void QFxItem::keyPressEvent(QKeyEvent *event) { - QFxKeyEvent ke(event->key(), event->text()); + QFxKeyEvent ke(*event); emit keyPress(&ke); event->setAccepted(ke.isAccepted()); if (itemParent() && !ke.isAccepted()) @@ -1159,7 +1129,7 @@ void QFxItem::keyPressEvent(QKeyEvent *event) */ void QFxItem::keyReleaseEvent(QKeyEvent *event) { - QFxKeyEvent ke(event->key(), event->text()); + QFxKeyEvent ke(*event); emit keyRelease(&ke); event->setAccepted(ke.isAccepted()); if (itemParent() && !ke.isAccepted()) @@ -1218,36 +1188,54 @@ void QFxItem::setId(const QString &id) d->_id = id; } +/*! + \internal +*/ QFxAnchorLine QFxItem::left() const { Q_D(const QFxItem); return d->anchorLines()->left; } +/*! + \internal +*/ QFxAnchorLine QFxItem::right() const { Q_D(const QFxItem); return d->anchorLines()->right; } +/*! + \internal +*/ QFxAnchorLine QFxItem::horizontalCenter() const { Q_D(const QFxItem); return d->anchorLines()->hCenter; } +/*! + \internal +*/ QFxAnchorLine QFxItem::top() const { Q_D(const QFxItem); return d->anchorLines()->top; } +/*! + \internal +*/ QFxAnchorLine QFxItem::bottom() const { Q_D(const QFxItem); return d->anchorLines()->bottom; } +/*! + \internal +*/ QFxAnchorLine QFxItem::verticalCenter() const { Q_D(const QFxItem); @@ -1382,7 +1370,6 @@ QFxAnchorLine QFxItem::verticalCenter() const For non-text items, a default baseline offset of two-thirds of the item's height is used to determine the baseline. */ - int QFxItem::baselineOffset() const { Q_D(const QFxItem); @@ -1392,6 +1379,9 @@ int QFxItem::baselineOffset() const return d->_baselineOffset; } +/*! + \internal +*/ void QFxItem::setBaselineOffset(int offset) { Q_D(QFxItem); @@ -1862,7 +1852,6 @@ void QFxItem::setVisible(bool visible) */ void QFxItem::dump(int depth) { - Q_D(QFxItem); QByteArray ba(depth * 4, ' '); qWarning() << ba.constData() << metaObject()->className() << "(" << (void *)static_cast<QFxItem*>(this) << ", " << (void *)static_cast<QSimpleCanvasItem*>(this) << "):" << x() << y() << width() << height() << (void *) itemParent(); } @@ -1885,12 +1874,12 @@ void QFxItem::newChild(const QString &type) { Q_D(QFxItem); - QUrl url = itemContext()->resolvedUri(type); + QUrl url = qmlContext(this)->resolvedUri(type); if (url.isEmpty()) return; d->_qmlnewloading.append(url); - d->_qmlnewcomp.append(new QmlComponent(itemContext()->engine(), url, this)); + d->_qmlnewcomp.append(new QmlComponent(qmlEngine(this), url, this)); if(!d->_qmlnewcomp.last()->isLoading()) qmlLoaded(); @@ -1964,6 +1953,9 @@ void QFxItem::reparentItems() qFatal("EEK"); } +/*! + \internal +*/ void QFxItem::updateTransform() { Q_D(QFxItem); @@ -1978,17 +1970,11 @@ void QFxItem::updateTransform() transformChanged(trans); } -void QFxItem::transformChanged(const QSimpleCanvas::Matrix &) -{ -} - /*! - Returns the current QML context for this item. + \internal */ -QmlContext *QFxItem::itemContext() const +void QFxItem::transformChanged(const QSimpleCanvas::Matrix &) { - Q_D(const QFxItem); - return d->_ctxt; } QmlStateGroup *QFxItemPrivate::states() @@ -2021,5 +2007,4 @@ QFxItemPrivate::AnchorLines::AnchorLines(QFxItem *q) vCenter.anchorLine = QFxAnchorLine::VCenter; } -#include "qfxitem.moc" QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxitem.h b/src/declarative/fx/qfxitem.h index bfd493f..b76235b 100644 --- a/src/declarative/fx/qfxitem.h +++ b/src/declarative/fx/qfxitem.h @@ -94,6 +94,7 @@ class QmlContext; class QmlState; class QmlTransition; class QFxTransform; +class QFxKeyEvent; class QFxItemPrivate; class Q_DECLARATIVE_EXPORT QFxItem : public QSimpleCanvasItem, public QmlParserStatus { @@ -181,13 +182,6 @@ public: int baselineOffset() const; void setBaselineOffset(int); - QFxAnchorLine left() const; - QFxAnchorLine right() const; - QFxAnchorLine horizontalCenter() const; - QFxAnchorLine top() const; - QFxAnchorLine bottom() const; - QFxAnchorLine verticalCenter() const; - qreal rotation() const; void setRotation(qreal); @@ -215,8 +209,6 @@ public: bool keepMouseGrab() const; void setKeepMouseGrab(bool); - QmlContext *itemContext() const; - public Q_SLOTS: void newChild(const QString &url); @@ -235,8 +227,8 @@ Q_SIGNALS: void focusChanged(); void activeFocusChanged(); void parentChanged(); - void keyPress(QObject *event); - void keyRelease(QObject *event); + void keyPress(QFxKeyEvent *event); + void keyRelease(QFxKeyEvent *event); void rotationChanged(); void scaleChanged(); void opacityChanged(); @@ -266,8 +258,16 @@ protected: QFxItem(QFxItemPrivate &dd, QFxItem *parent = 0); private: + QFxAnchorLine left() const; + QFxAnchorLine right() const; + QFxAnchorLine horizontalCenter() const; + QFxAnchorLine top() const; + QFxAnchorLine bottom() const; + QFxAnchorLine verticalCenter() const; + void init(QFxItem *parent); friend class QmlStatePrivate; + friend class QFxAnchors; Q_DISABLE_COPY(QFxItem) Q_DECLARE_PRIVATE(QFxItem) }; diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h index 1266711..71fc912 100644 --- a/src/declarative/fx/qfxitem_p.h +++ b/src/declarative/fx/qfxitem_p.h @@ -84,7 +84,6 @@ public: void init(QFxItem *parent) { Q_Q(QFxItem); - _ctxt = QmlContext::activeContext(); if(parent) q->setItemParent(parent); @@ -92,7 +91,6 @@ public: q->setAcceptedMouseButtons(Qt::NoButton); } - QmlContext *_ctxt; QString _id; // data property diff --git a/src/declarative/fx/qfxkeyactions.cpp b/src/declarative/fx/qfxkeyactions.cpp index c4ae3e3..3bd7d00 100644 --- a/src/declarative/fx/qfxkeyactions.cpp +++ b/src/declarative/fx/qfxkeyactions.cpp @@ -239,12 +239,7 @@ void QFxKeyActions::setEnabled(bool e) } /*! - \qmlproperty string KeyActions::keyA - \qmlproperty string KeyActions::keyB - \qmlproperty string KeyActions::keyC - \qmlproperty ... KeyActions::... - \qmlproperty string KeyActions::keyY - \qmlproperty string KeyActions::keyZ + \qmlproperty string KeyActions::keyA...keyZ The action to take for the given letter. @@ -569,11 +564,7 @@ void QFxKeyActions::setKey_Down(const QString &s) } /*! - \qmlproperty string KeyActions::digit0 - \qmlproperty string KeyActions::digit1 - \qmlproperty string KeyActions::digit2 - \qmlproperty ... KeyActions::... - \qmlproperty string KeyActions::digit9 + \qmlproperty string KeyActions::digit0...digit9 The action to take for the given number key. @@ -908,8 +899,7 @@ void QFxKeyActions::keyPressEvent(QKeyEvent *event) { Qt::Key key = (Qt::Key)event->key(); if(d->enabled && d->key(key)) { - QmlExpression b(itemContext(), d->action(key), - this, false); + QmlExpression b(qmlContext(this), d->action(key), this, false); b.value(); event->accept(); } else { diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index f25470b..c85d8ce 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -98,12 +98,9 @@ public: } static QFxListViewAttached *properties(QObject *obj) { - if(!attachedProperties.contains(obj)) { - QFxListViewAttached *rv = new QFxListViewAttached(obj); - attachedProperties.insert(obj, rv); - return rv; - } - return attachedProperties.value(obj); + QFxListViewAttached *rv = new QFxListViewAttached(obj); + attachedProperties.insert(obj, rv); + return rv; } void emitAdd() { emit add(); } @@ -394,7 +391,7 @@ FxListItem *QFxListViewPrivate::createItem(int modelIndex) listItem->index = modelIndex; // initialise attached properties if (!sectionExpression.isEmpty()) { - QmlExpression e(listItem->item->itemContext(), sectionExpression, q); + QmlExpression e(qmlContext(listItem->item), sectionExpression, q); e.setTrackChange(false); listItem->attached->m_section = e.value().toString(); if (modelIndex > 0) { @@ -580,7 +577,7 @@ void QFxListViewPrivate::createHighlight() if (currentItem) { QFxItem *item = 0; if (highlightComponent) { - QmlContext *highlightContext = new QmlContext(q->itemContext()); + QmlContext *highlightContext = new QmlContext(qmlContext(q)); QObject *nobj = highlightComponent->create(highlightContext); if (nobj) { highlightContext->setParent(nobj); @@ -899,7 +896,7 @@ void QFxListView::setModel(const QVariant &model) d->model = vim; } else { if (!d->ownModel) { - d->model = new QFxVisualItemModel(itemContext()); + d->model = new QFxVisualItemModel(qmlContext(this)); d->ownModel = true; } d->model->setModel(model); @@ -944,7 +941,7 @@ void QFxListView::setDelegate(QmlComponent *delegate) { Q_D(QFxListView); if (!d->ownModel) { - d->model = new QFxVisualItemModel(itemContext()); + d->model = new QFxVisualItemModel(qmlContext(this)); d->ownModel = true; } d->model->setDelegate(delegate); diff --git a/src/declarative/fx/qfxmouseregion.cpp b/src/declarative/fx/qfxmouseregion.cpp index c6a7f96..f7b6c57 100644 --- a/src/declarative/fx/qfxmouseregion.cpp +++ b/src/declarative/fx/qfxmouseregion.cpp @@ -41,6 +41,7 @@ #include "qfxmouseregion.h" #include "qfxmouseregion_p.h" +#include "qfxevents_p.h" #include <QGraphicsSceneMouseEvent> @@ -154,18 +155,23 @@ void QFxDrag::setYmax(int m) </Rect> \endcode - For the mouse handlers the variable mouseButton is set to be one of 'Left', 'Right', 'Middle', - or 'None'. This allows you to distinguish left and right clicking. Below we have the previous + Many MouseRegion signals pass a \l {MouseEvent}{mouse} parameter that contains + additional information about the mouse event, such as the position, button, + and any key modifiers. + + Below we have the previous example extended so as to give a different color when you right click. \code <Rect width="100" height="100"> - <MouseRegion anchors.fill="{parent}" onClick="if(mouseButton=='Right') { parent.color='blue';} else { parent.color = 'red';}"/> + <MouseRegion anchors.fill="{parent}" onClick="if(mouse.button==Qt.RightButton) { parent.color='blue';} else { parent.color = 'red';}"/> </Rect> \endcode For basic key handling, see \l KeyActions. MouseRegion is an invisible element: it is never painted. + + \sa MouseEvent */ /*! @@ -197,46 +203,59 @@ void QFxDrag::setYmax(int m) */ /*! - \qmlsignal MouseRegion::onClicked + \qmlsignal MouseRegion::onPositionChanged(mouse) + + This handler is called when the mouse position changes. + + The \l {MouseEvent}{mouse} parameter provides information about the mouse, including the x and y + position, and any buttons currently pressed. +*/ + +/*! + \qmlsignal MouseRegion::onClicked(mouse) This handler is called when there is a click. A click is defined as a press followed by a release, both inside the MouseRegion (pressing, moving outside the MouseRegion, and then moving back inside and releasing is also considered a click). - The x and y parameters tell you the position of the release of the click. The followsPressAndHold parameter tells - you whether or not the release portion of the click followed a long press. + + The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y + position of the release of the click, and whether the click wasHeld. */ /*! - \qmlsignal MouseRegion::onPressed + \qmlsignal MouseRegion::onPressed(mouse) This handler is called when there is a press. - The x and y parameters tell you the position of the press. + The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y + position and which button was pressed. */ /*! - \qmlsignal MouseRegion::onReleased + \qmlsignal MouseRegion::onReleased(mouse) This handler is called when there is a release. - The x and y parameters tell you the position of the release. The isClick parameter tells you whether - or not the release is part of a click. The followsPressAndHold parameter tells you whether or not the - release followed a long press. + The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y + position of the release of the click, and whether the click wasHeld. */ /*! - \qmlsignal MouseRegion::onPressAndHold + \qmlsignal MouseRegion::onPressAndHold(mouse) This handler is called when there is a long press (currently 800ms). - The x and y parameters tell you the position of the long press. + The \l {MouseEvent}{mouse} parameter provides information about the press, including the x and y + position of the press, and which button is pressed. */ /*! - \qmlsignal MouseRegion::onDoubleClicked + \qmlsignal MouseRegion::onDoubleClicked(mouse) This handler is called when there is a double-click (a press followed by a release followed by a press). - The x and y parameters tell you the position of the double-click. + The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y + position of the release of the click, and whether the click wasHeld. */ QML_DEFINE_TYPE(QFxMouseRegion,MouseRegion); + /*! \internal \class QFxMouseRegion @@ -301,23 +320,6 @@ void QFxMouseRegion::setEnabled(bool a) d->absorb = a; } -void QFxMouseRegionPrivate::bindButtonValue(Qt::MouseButton b) -{ - Q_Q(QFxMouseRegion); - QString bString; - switch(b){ - case Qt::LeftButton: - bString = QLatin1String("Left"); break; - case Qt::RightButton: - bString = QLatin1String("Right"); break; - case Qt::MidButton: - bString = QLatin1String("Middle"); break; - default: - bString = QLatin1String("None"); break; - } - q->itemContext()->setContextProperty(QLatin1String("mouseButton"), bString); -} - void QFxMouseRegion::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QFxMouseRegion); @@ -330,7 +332,7 @@ void QFxMouseRegion::mousePressEvent(QGraphicsSceneMouseEvent *event) emit hoveredChanged(); } d->longPress = false; - d->lastPos = event->pos(); + d->saveEvent(event); d->dragX = drag()->axis().contains(QLatin1String("x")); d->dragY = drag()->axis().contains(QLatin1String("y")); d->dragged = false; @@ -339,9 +341,7 @@ void QFxMouseRegion::mousePressEvent(QGraphicsSceneMouseEvent *event) // ### we should only start timer if pressAndHold is connected to (but connectNotify doesn't work) d->pressAndHoldTimer.start(PressAndHoldDelay, this); setKeepMouseGrab(false); - d->bindButtonValue(event->button()); setPressed(true); - emit positionChanged(); event->accept(); } } @@ -354,7 +354,7 @@ void QFxMouseRegion::mouseMoveEvent(QGraphicsSceneMouseEvent *event) return; } - d->lastPos = event->pos(); + d->saveEvent(event); // ### we should skip this if these signals aren't used const QRect &bounds = itemBoundingRect(); @@ -415,7 +415,8 @@ void QFxMouseRegion::mouseMoveEvent(QGraphicsSceneMouseEvent *event) } } d->moved = true; - emit positionChanged(); + QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); + emit positionChanged(&me); event->accept(); } @@ -426,6 +427,7 @@ void QFxMouseRegion::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) if(!d->absorb) QFxItem::mouseReleaseEvent(event); else { + d->saveEvent(event); setPressed(false); //d->inside = false; //emit hoveredChanged(); @@ -441,8 +443,10 @@ void QFxMouseRegion::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) else { //d->inside = true; //emit hoveredChanged(); + d->saveEvent(event); setPressed(true); - emit this->doubleClicked(d->lastPos.x(), d->lastPos.y()); + QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, true, false); + emit this->doubleClicked(&me); event->accept(); } } @@ -490,7 +494,8 @@ void QFxMouseRegion::timerEvent(QTimerEvent *event) d->pressAndHoldTimer.stop(); if (d->pressed && d->dragged == false && d->inside == true) { d->longPress = true; - emit pressAndHold(d->lastPos.x(), d->lastPos.y()); + QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, false, d->longPress); + emit pressAndHold(&me); } } } @@ -533,12 +538,14 @@ void QFxMouseRegion::setPressed(bool p) if(d->pressed != p) { d->pressed = p; - if(d->pressed) - emit pressed(d->lastPos.x(), d->lastPos.y()); - else { - emit released(d->lastPos.x(), d->lastPos.y(), isclick, d->longPress); + QFxMouseEvent me(d->lastPos.x(), d->lastPos.y(), d->lastButton, d->lastButtons, d->lastModifiers, isclick, d->longPress); + if(d->pressed) { + emit positionChanged(&me); + emit pressed(&me); + } else { + emit released(&me); if (isclick) - emit clicked(d->lastPos.x(), d->lastPos.y(), d->longPress); + emit clicked(&me); } emit pressedChanged(); diff --git a/src/declarative/fx/qfxmouseregion.h b/src/declarative/fx/qfxmouseregion.h index ee8b577..2ba4a50 100644 --- a/src/declarative/fx/qfxmouseregion.h +++ b/src/declarative/fx/qfxmouseregion.h @@ -88,6 +88,7 @@ private: }; QML_DECLARE_TYPE(QFxDrag); +class QFxMouseEvent; class QFxMouseRegionPrivate; class Q_DECLARATIVE_EXPORT QFxMouseRegion : public QFxItem { @@ -120,13 +121,13 @@ public: Q_SIGNALS: void hoveredChanged(); void pressedChanged(); - void positionChanged(); + void positionChanged(QFxMouseEvent *mouse); - void pressed(int x, int y); - void pressAndHold(int x, int y); - void released(int x, int y, bool isClick, bool followsPressAndHold); - void clicked(int x, int y, bool followsPressAndHold); - void doubleClicked(int x, int y); + void pressed(QFxMouseEvent *mouse); + void pressAndHold(QFxMouseEvent *mouse); + void released(QFxMouseEvent *mouse); + void clicked(QFxMouseEvent *mouse); + void doubleClicked(QFxMouseEvent *mouse); void entered(); void exited(); void exitedWhilePressed(); diff --git a/src/declarative/fx/qfxmouseregion_p.h b/src/declarative/fx/qfxmouseregion_p.h index 09e1b98..d72b423 100644 --- a/src/declarative/fx/qfxmouseregion_p.h +++ b/src/declarative/fx/qfxmouseregion_p.h @@ -55,6 +55,7 @@ #include "qdatetime.h" #include "qbasictimer.h" +#include "qgraphicssceneevent.h" #include "qfxitem_p.h" QT_BEGIN_NAMESPACE @@ -65,7 +66,7 @@ class QFxMouseRegionPrivate : public QFxItemPrivate public: QFxMouseRegionPrivate() - : absorb(true), hovered(false), inside(true), pressed(false), longPress(0), drag(0) + : absorb(true), hovered(false), inside(true), pressed(false), longPress(false), drag(0) { } @@ -76,23 +77,32 @@ public: q->setOptions(QSimpleCanvasItem::HoverEvents | QSimpleCanvasItem::MouseEvents); } - void bindButtonValue(Qt::MouseButton); + void saveEvent(QGraphicsSceneMouseEvent *event) { + lastPos = event->pos(); + lastButton = event->button(); + lastButtons = event->buttons(); + lastModifiers = event->modifiers(); + qDebug() << "modifiers" << lastModifiers; + } - bool absorb; - bool hovered; - bool inside; - bool pressed; - bool longPress; + bool absorb : 1; + bool hovered : 1; + bool inside : 1; + bool pressed : 1; + bool longPress : 1; + bool moved : 1; + bool dragX : 1; + bool dragY : 1; + bool dragged : 1; QFxDrag drag; - bool moved; - bool dragX; - bool dragY; - bool dragged; QPointF start; QPointF startScene; int startX; int startY; QPointF lastPos; + Qt::MouseButton lastButton; + Qt::MouseButtons lastButtons; + Qt::KeyboardModifiers lastModifiers; QBasicTimer pressAndHoldTimer; }; diff --git a/src/declarative/fx/qfxparticles.cpp b/src/declarative/fx/qfxparticles.cpp index 54e3778..8b16098 100644 --- a/src/declarative/fx/qfxparticles.cpp +++ b/src/declarative/fx/qfxparticles.cpp @@ -613,8 +613,8 @@ void QFxParticles::setUrl(const QString &name) update(); } else { d->source = name; - d->url = itemContext()->resolvedUrl(name); - QFxPixmap::get(itemContext()->engine(), d->url, this, SLOT(imageLoaded())); + d->url = qmlContext(this)->resolvedUrl(name); + QFxPixmap::get(qmlEngine(this), d->url, this, SLOT(imageLoaded())); } } diff --git a/src/declarative/fx/qfxpathview.cpp b/src/declarative/fx/qfxpathview.cpp index b1cfaa5..59c7cd1 100644 --- a/src/declarative/fx/qfxpathview.cpp +++ b/src/declarative/fx/qfxpathview.cpp @@ -188,7 +188,7 @@ void QFxPathView::setModel(const QVariant &model) d->model = m; } else { if (!d->ownModel) { - d->model = new QFxVisualItemModel; + d->model = new QFxVisualItemModel(qmlContext(this)); d->ownModel = true; } d->model->setModel(model); @@ -368,7 +368,7 @@ void QFxPathView::setDelegate(QmlComponent *c) { Q_D(QFxPathView); if (!d->ownModel) { - d->model = new QFxVisualItemModel; + d->model = new QFxVisualItemModel(qmlContext(this)); d->ownModel = true; } d->model->setDelegate(c); @@ -830,11 +830,9 @@ void QFxPathViewPrivate::snapToCurrent() QHash<QObject*, QObject*> QFxPathView::attachedProperties; QObject *QFxPathView::qmlAttachedProperties(QObject *obj) { - if(!attachedProperties.contains(obj)) { - QFxPathViewAttached *rv = new QFxPathViewAttached(obj); - attachedProperties.insert(obj, rv); - } - return attachedProperties.value(obj); + QFxPathViewAttached *rv = new QFxPathViewAttached(obj); + attachedProperties.insert(obj, rv); + return rv; } QT_END_NAMESPACE diff --git a/src/declarative/fx/qfxrepeater.cpp b/src/declarative/fx/qfxrepeater.cpp index 570d54d..78e9f51 100644 --- a/src/declarative/fx/qfxrepeater.cpp +++ b/src/declarative/fx/qfxrepeater.cpp @@ -235,6 +235,15 @@ void QFxRepeater::setComponent(QmlComponent *_c) /*! \internal */ +void QFxRepeater::componentComplete() +{ + QFxItem::componentComplete(); + regenerate(); +} + +/*! + \internal + */ void QFxRepeater::parentChanged(QSimpleCanvasItem *o, QSimpleCanvasItem *n) { QFxItem::parentChanged(o, n); @@ -250,7 +259,7 @@ void QFxRepeater::regenerate() qDeleteAll(d->deletables); d->deletables.clear(); - if(!d->component || !itemParent()) + if(!d->component || !itemParent() || !isComponentComplete()) return; QFxItem *lastItem = this; @@ -259,7 +268,7 @@ void QFxRepeater::regenerate() QStringList sl = qvariant_cast<QStringList>(d->dataSource); for(int ii = 0; ii < sl.size(); ++ii) { - QmlContext *ctxt = new QmlContext(itemContext(), this); + QmlContext *ctxt = new QmlContext(qmlContext(this), this); d->deletables << ctxt; ctxt->setContextProperty(QLatin1String("index"), ii); @@ -277,7 +286,7 @@ void QFxRepeater::regenerate() QVariant v = QmlMetaType::listAt(d->dataSource, ii); QObject *o = QmlMetaType::toQObject(v); - QmlContext *ctxt = new QmlContext(itemContext(), this); + QmlContext *ctxt = new QmlContext(qmlContext(this), this); d->deletables << ctxt; ctxt->setContextProperty(QLatin1String("index"), ii); @@ -292,7 +301,7 @@ void QFxRepeater::regenerate() return; for(int ii = 0; ii < cnt; ++ii) { - QmlContext *ctxt = new QmlContext(itemContext(), this); + QmlContext *ctxt = new QmlContext(qmlContext(this), this); d->deletables << ctxt; ctxt->setContextProperty(QLatin1String("index"), ii); @@ -313,7 +322,7 @@ void QFxRepeater::regenerate() } else if (QObject *object = d->dataSource.value<QObject*>()) { // A single object (i.e. list of size 1). // Properties are the roles (excluding objectName). - QmlContext *ctxt = new QmlContext(itemContext(), this); + QmlContext *ctxt = new QmlContext(qmlContext(this), this); d->deletables << ctxt; ctxt->setContextProperty(QLatin1String("index"), QVariant(0)); @@ -335,7 +344,7 @@ void QFxRepeater::regenerate() int count = qvariant_cast<int>(d->dataSource); for(int ii = 0; ii < count; ++ii) { - QmlContext *ctxt = new QmlContext(itemContext(), this); + QmlContext *ctxt = new QmlContext(qmlContext(this), this); d->deletables << ctxt; ctxt->setContextProperty(QLatin1String("index"), ii); diff --git a/src/declarative/fx/qfxrepeater.h b/src/declarative/fx/qfxrepeater.h index f6c4584..8efd281 100644 --- a/src/declarative/fx/qfxrepeater.h +++ b/src/declarative/fx/qfxrepeater.h @@ -72,6 +72,7 @@ private: void regenerate(); protected: + virtual void componentComplete(); virtual void parentChanged(QSimpleCanvasItem *, QSimpleCanvasItem *); QFxRepeater(QFxRepeaterPrivate &dd, QFxItem *parent); diff --git a/src/declarative/fx/qfxvisualitemmodel.cpp b/src/declarative/fx/qfxvisualitemmodel.cpp index 145e750..e851bad 100644 --- a/src/declarative/fx/qfxvisualitemmodel.cpp +++ b/src/declarative/fx/qfxvisualitemmodel.cpp @@ -285,7 +285,7 @@ QFxVisualItemModelData *QFxVisualItemModelPrivate::data(QObject *item) } QFxVisualItemModel::QFxVisualItemModel() -: QObject(*(new QFxVisualItemModelPrivate(QmlContext::activeContext()))) +: QObject(*(new QFxVisualItemModelPrivate(0))) { } @@ -489,7 +489,9 @@ QFxItem *QFxVisualItemModel::item(int index, const QByteArray &viewId, bool comp if(d->m_cache.contains(index)) { nobj = d->m_cache[index]; } else { - QmlContext *ctxt = new QmlContext(d->m_context); + QmlContext *ccontext = d->m_context; + if(!ccontext) ccontext = qmlContext(this); + QmlContext *ctxt = new QmlContext(ccontext); QFxVisualItemModelData *data = new QFxVisualItemModelData(index, d); ctxt->setContextProperty(QLatin1String("model"), data); ctxt->addDefaultObject(data); @@ -540,12 +542,14 @@ QVariant QFxVisualItemModel::evaluate(int index, const QString &expression, QObj QObject *nobj = d->m_cache[index]; QFxItem *item = qobject_cast<QFxItem *>(nobj); if (item) { - QmlExpression e(item->itemContext(), expression, objectContext); + QmlExpression e(qmlContext(item), expression, objectContext); e.setTrackChange(false); value = e.value(); } } else { - QmlContext *ctxt = new QmlContext(d->m_context); + QmlContext *ccontext = d->m_context; + if(!ccontext) ccontext = qmlContext(this); + QmlContext *ctxt = new QmlContext(ccontext); QFxVisualItemModelData *data = new QFxVisualItemModelData(index, d); ctxt->addDefaultObject(data); QmlExpression e(ctxt, expression, objectContext); diff --git a/src/declarative/fx/qfxwebview.cpp b/src/declarative/fx/qfxwebview.cpp index 05e2f65..293c72b 100644 --- a/src/declarative/fx/qfxwebview.cpp +++ b/src/declarative/fx/qfxwebview.cpp @@ -199,23 +199,13 @@ QFxWebView::~QFxWebView() void QFxWebView::init() { + Q_D(QFxWebView); + setAcceptedMouseButtons(Qt::LeftButton); setOptions(HasContents | MouseEvents); setFocusable(true); - QWebPage *wp = new QFxWebPage(this); - - // QML elements don't default to having a background, - // even though most we pages will set one anyway. - QPalette pal = QApplication::palette(); - pal.setBrush(QPalette::Base, QColor::fromRgbF(0, 0, 0, 0)); - wp->setPalette(pal); - - wp->setNetworkAccessManager(itemContext()->engine()->networkAccessManager()); - setPage(wp); - - // XXX settable from QML? - settings()->setAttribute(QWebSettings::PluginsEnabled, true); + d->page = 0; } void QFxWebView::componentComplete() @@ -297,26 +287,25 @@ void QFxWebView::doLoadFinished(bool ok) */ QString QFxWebView::url() const { - Q_D(const QFxWebView); - return d->page->mainFrame()->url().toString(); + return page()->mainFrame()->url().toString(); } void QFxWebView::setUrl(const QString &n) { Q_D(QFxWebView); - if(n == d->page->mainFrame()->url().toString()) + if(n == page()->mainFrame()->url().toString()) return; - d->page->setViewportSize(QSize( + page()->setViewportSize(QSize( d->idealwidth>0 ? d->idealwidth : width(), d->idealheight>0 ? d->idealheight : height())); QUrl url(n); if (url.isRelative()) - url = itemContext()->resolvedUrl(n); + url = qmlContext(this)->resolvedUrl(n); if (isComponentComplete()) - d->page->mainFrame()->load(url); + page()->mainFrame()->load(url); else { d->pending = d->PendingUrl; d->pending_url = url; @@ -429,7 +418,7 @@ void QFxWebView::updateCacheForVisibility() void QFxWebView::expandToWebPage() { Q_D(QFxWebView); - QSize cs = d->page->mainFrame()->contentsSize(); + QSize cs = page()->mainFrame()->contentsSize(); if (cs.width() < d->idealwidth) cs.setWidth(d->idealwidth); if (cs.height() < d->idealheight) @@ -438,8 +427,8 @@ void QFxWebView::expandToWebPage() cs.setWidth(width()); if (heightValid() && cs.height() < height()) cs.setHeight(height()); - if (cs != d->page->viewportSize()) { - d->page->setViewportSize(cs); + if (cs != page()->viewportSize()) { + page()->setViewportSize(cs); d->clearCache(); setImplicitWidth(cs.width()); setImplicitHeight(cs.height()); @@ -524,7 +513,7 @@ void QFxWebView::paintGLContents(GLPainter &p) #endif { Q_D(QFxWebView); - QWebFrame *frame = d->page->mainFrame(); + QWebFrame *frame = page()->mainFrame(); const QRect content(QPoint(0,0),frame->contentsSize()); if (content.width() <= 0 || content.height() <= 0) @@ -604,8 +593,7 @@ void QFxWebView::paintGLContents(GLPainter &p) QString QFxWebView::propertyInfo() const { - Q_D(const QFxWebView); - return d->page->mainFrame()->url().toString(); + return page()->mainFrame()->url().toString(); } static QMouseEvent *sceneMouseEventToMouseEvent(QGraphicsSceneMouseEvent *e) @@ -638,12 +626,12 @@ void QFxWebView::timerEvent(QTimerEvent *event) if (event->timerId() ==d->dcTimer.timerId()) { d->dcTimer.stop(); if (d->lastPress) { - d->page->event(d->lastPress); + page()->event(d->lastPress); delete d->lastPress; d->lastPress = 0; } if (d->lastRelease) { - d->page->event(d->lastRelease); + page()->event(d->lastRelease); delete d->lastRelease; d->lastRelease = 0; } @@ -719,7 +707,7 @@ void QFxWebView::mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_D(const QFxWebView); if (d->interactive && !d->dcTimer.isActive()) { QMouseEvent *me = sceneMouseEventToMouseEvent(event); - d->page->event(me); + page()->event(me); event->setAccepted( #if QT_VERSION <= 0x040500 // XXX see bug 230835 true @@ -739,7 +727,7 @@ void QFxWebView::keyPressEvent(QKeyEvent* event) { Q_D(const QFxWebView); if (d->interactive) - d->page->event(event); + page()->event(event); if (!event->isAccepted()) QFxItem::keyPressEvent(event); } @@ -748,7 +736,7 @@ void QFxWebView::keyReleaseEvent(QKeyEvent* event) { Q_D(const QFxWebView); if (d->interactive) - d->page->event(event); + page()->event(event); if (!event->isAccepted()) QFxItem::keyReleaseEvent(event); } @@ -759,8 +747,7 @@ void QFxWebView::keyReleaseEvent(QKeyEvent* event) */ QAction *QFxWebView::backAction() const { - Q_D(const QFxWebView); - return d->page->action(QWebPage::Back); + return page()->action(QWebPage::Back); } /*! @@ -769,8 +756,7 @@ QAction *QFxWebView::backAction() const */ QAction *QFxWebView::forwardAction() const { - Q_D(const QFxWebView); - return d->page->action(QWebPage::Forward); + return page()->action(QWebPage::Forward); } /*! @@ -779,8 +765,7 @@ QAction *QFxWebView::forwardAction() const */ QAction *QFxWebView::reloadAction() const { - Q_D(const QFxWebView); - return d->page->action(QWebPage::Reload); + return page()->action(QWebPage::Reload); } /*! @@ -789,8 +774,7 @@ QAction *QFxWebView::reloadAction() const */ QAction *QFxWebView::stopAction() const { - Q_D(const QFxWebView); - return d->page->action(QWebPage::Stop); + return page()->action(QWebPage::Stop); } /*! @@ -809,10 +793,7 @@ QAction *QFxWebView::stopAction() const */ QString QFxWebView::title() const { - Q_D(const QFxWebView); - if (d->page) - return d->page->mainFrame()->title(); - return QString(); + return page()->mainFrame()->title(); } @@ -831,10 +812,7 @@ QString QFxWebView::title() const */ QPixmap QFxWebView::icon() const { - Q_D(const QFxWebView); - if (d->page) - return d->page->mainFrame()->icon().pixmap(QSize(256,256)); - return QPixmap(); + return page()->mainFrame()->icon().pixmap(QSize(256,256)); } @@ -848,8 +826,7 @@ QPixmap QFxWebView::icon() const */ void QFxWebView::setTextSizeMultiplier(qreal factor) { - Q_D(QFxWebView); - d->page->mainFrame()->setTextSizeMultiplier(factor); + page()->mainFrame()->setTextSizeMultiplier(factor); } /*! @@ -857,8 +834,7 @@ void QFxWebView::setTextSizeMultiplier(qreal factor) */ qreal QFxWebView::textSizeMultiplier() const { - Q_D(const QFxWebView); - return d->page->mainFrame()->textSizeMultiplier(); + return page()->mainFrame()->textSizeMultiplier(); } void QFxWebView::setStatusBarMessage(const QString& s) @@ -877,9 +853,31 @@ QString QFxWebView::status() const QWebPage *QFxWebView::page() const { Q_D(const QFxWebView); + + if (!d->page) { + QFxWebView *self = const_cast<QFxWebView*>(this); + QWebPage *wp = new QFxWebPage(self); + + // QML elements don't default to having a background, + // even though most we pages will set one anyway. + QPalette pal = QApplication::palette(); + pal.setBrush(QPalette::Base, QColor::fromRgbF(0, 0, 0, 0)); + wp->setPalette(pal); + + wp->setNetworkAccessManager(qmlEngine(this)->networkAccessManager()); + + // XXX settable from QML? + wp->settings()->setAttribute(QWebSettings::PluginsEnabled, true); + + self->setPage(wp); + + return wp; + } + return d->page; } + void QFxWebView::setPage(QWebPage *page) { Q_D(QFxWebView); @@ -1030,7 +1028,7 @@ public: propertyValues(paramValues), webview(view) { - QmlEngine *engine = webview->itemContext()->engine(); + QmlEngine *engine = qmlEngine(webview); component = new QmlComponent(engine, url, this); item = 0; connect(engine, SIGNAL(statusChanged(Status)), this, SLOT(qmlLoaded())); @@ -1039,7 +1037,7 @@ public: public Q_SLOTS: void qmlLoaded() { - item = qobject_cast<QFxItem*>(component->create(webview->itemContext())); + item = qobject_cast<QFxItem*>(component->create(qmlContext(webview))); item->setParent(webview); for (int i=0; i<propertyNames.count(); ++i) { if (propertyNames[i] != QLatin1String("type") && propertyNames[i] != QLatin1String("data")) { @@ -1074,7 +1072,7 @@ QFxWebView *QFxWebPage::view() QObject *QFxWebPage::createPlugin(const QString &, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) { - QUrl comp = view()->itemContext()->resolvedUri(url.toString()); + QUrl comp = qmlContext(view())->resolvedUri(url.toString()); return new QWidget_Dummy_Plugin(comp,view(),paramNames,paramValues); } diff --git a/src/declarative/qml/qml.h b/src/declarative/qml/qml.h index bf7b6bc..2d8d83e 100644 --- a/src/declarative/qml/qml.h +++ b/src/declarative/qml/qml.h @@ -88,6 +88,27 @@ QT_MODULE(Declarative) #define QML_DEFINE_NOCREATE_TYPE(TYPE) \ template<> QmlPrivate::InstanceType QmlPrivate::Define<TYPE *>::instance(qmlRegisterType<TYPE>(#TYPE)); +class QmlContext; +class QmlEngine; +Q_DECLARATIVE_EXPORT QmlContext *qmlContext(const QObject *); +Q_DECLARATIVE_EXPORT QmlEngine *qmlEngine(const QObject *); +Q_DECLARATIVE_EXPORT QObject *qmlAttachedPropertiesObjectById(int, const QObject *); + +template<typename T> +QObject *qmlAttachedPropertiesObject(const QObject *obj) +{ + // ### is this threadsafe? + static int idx = -1; + + if(idx == -1) + idx = QmlMetaType::attachedPropertiesFuncId(&T::staticMetaObject); + + if(idx == -1 || !obj) + return 0; + + return qmlAttachedPropertiesObjectById(obj, idx); +} + QML_DECLARE_TYPE(QObject); Q_DECLARE_METATYPE(QVariant); diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri index 65e6763..c44e8c5 100644 --- a/src/declarative/qml/qml.pri +++ b/src/declarative/qml/qml.pri @@ -56,7 +56,8 @@ HEADERS += qml/qmlparser_p.h \ qml/qmlmetaproperty_p.h \ qml/qmlcontext_p.h \ qml/qmlcompositetypemanager_p.h \ - qml/qmllist.h + qml/qmllist.h \ + qml/qmldeclarativedata_p.h # for qtscript debugger QT += scripttools diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index f03ce20..7535bc7 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -909,8 +909,10 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop, QmlInstruction fetch; fetch.type = QmlInstruction::FetchAttached; fetch.line = prop->line; - int ref = output->indexForByteArray(prop->name); - fetch.fetchAttached.idx = ref; + int id = QmlMetaType::attachedPropertiesFuncId(prop->name); + if(id == -1) + COMPILE_EXCEPTION("Non-existant attached property object" << prop->name); + fetch.fetchAttached.id = id; output->bytecode << fetch; COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1)); @@ -1647,12 +1649,15 @@ QmlCompiledData &QmlCompiledData::operator=(const QmlCompiledData &other) return *this; } -QObject *QmlCompiledData::TypeReference::createInstance() const +QObject *QmlCompiledData::TypeReference::createInstance(QmlContext *ctxt) const { if(type) { - return type->create(); + QObject *rv = type->create(); + if(rv) + QmlEngine::setContextForObject(rv, ctxt); + return rv; } else if(component) { - return component->create(QmlContext::activeContext()); + return component->create(ctxt); } else { return 0; } diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 754e284..286cda8 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -54,6 +54,7 @@ class QmlXmlParser; class QmlEngine; class QmlComponent; class QmlCompiledComponent; +class QmlContext; namespace QmlParser { class Object; @@ -83,7 +84,7 @@ public: QmlCustomParser *parser; QmlRefCount *ref; - QObject *createInstance() const; + QObject *createInstance(QmlContext *) const; }; QList<TypeReference> types; struct CustomTypeData diff --git a/src/declarative/qml/qmlcontext.cpp b/src/declarative/qml/qmlcontext.cpp index 104f460..40e33c2 100644 --- a/src/declarative/qml/qmlcontext.cpp +++ b/src/declarative/qml/qmlcontext.cpp @@ -96,6 +96,8 @@ void QmlContextPrivate::init() else scopeChain = parent->d_func()->scopeChain; scopeChain.prepend(scopeObj); + + contextData.context = q; } void QmlContextPrivate::addDefaultObject(QObject *object, Priority priority) diff --git a/src/declarative/qml/qmlcontext_p.h b/src/declarative/qml/qmlcontext_p.h index 8c51a6b..3772885 100644 --- a/src/declarative/qml/qmlcontext_p.h +++ b/src/declarative/qml/qmlcontext_p.h @@ -44,6 +44,7 @@ #include <qmlcontext.h> #include <private/qobject_p.h> +#include <private/qmldeclarativedata_p.h> #include <qhash.h> #include <qscriptvalue.h> @@ -81,6 +82,8 @@ public: NormalPriority }; void addDefaultObject(QObject *, Priority); + + QmlSimpleDeclarativeData contextData; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qmldeclarativedata_p.h b/src/declarative/qml/qmldeclarativedata_p.h new file mode 100644 index 0000000..a934442 --- /dev/null +++ b/src/declarative/qml/qmldeclarativedata_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 QMLDECLARATIVEDATA_P_H +#define QMLDECLARATIVEDATA_P_H + +#include <private/qobject_p.h> + +QT_BEGIN_NAMESPACE + +class QmlSimpleDeclarativeData : public QDeclarativeData +{ +public: + QmlSimpleDeclarativeData() : flags(0), context(0) {} + + enum Flag { Extended = 0x00000001 }; + quint32 flags; + QmlContext *context; +}; + +class QmlExtendedDeclarativeData : public QmlSimpleDeclarativeData +{ +public: + QmlExtendedDeclarativeData() { flags = Extended; } + + virtual void destroyed(QObject *); + QHash<int, QObject *> attachedProperties; +}; + +QT_END_NAMESPACE + +#endif // QMLDECLARATIVEDATA_P_H diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 5cbd02b..ad4a627 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -42,6 +42,7 @@ #include <QMetaProperty> #include <private/qmlengine_p.h> #include <private/qmlcontext_p.h> +#include <private/qobject_p.h> #ifdef QT_SCRIPTTOOLS_LIB #include <QScriptEngineDebugger> @@ -595,6 +596,90 @@ QNetworkAccessManager *QmlEngine::networkAccessManager() const return d->networkAccessManager; } +QmlContext *QmlEngine::contextForObject(const QObject *object) +{ + QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object)); + + QmlSimpleDeclarativeData *data = + static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData); + + return data?data->context:0; +} + +void QmlEngine::setContextForObject(QObject *object, QmlContext *context) +{ + QObjectPrivate *priv = QObjectPrivate::get(object); + + QmlSimpleDeclarativeData *data = + static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData); + + if(data && data->context) { + qWarning("QmlEngine::setContextForObject(): Object already has a QmlContext"); + return; + } + + if(!data) { + priv->declarativeData = &context->d_func()->contextData; + } else { + // ### - Don't have to use extended data here + QmlExtendedDeclarativeData *data = new QmlExtendedDeclarativeData; + data->context = context; + priv->declarativeData = data; + } +} + +QmlContext *qmlContext(const QObject *obj) +{ + return QmlEngine::contextForObject(obj); +} + +QmlEngine *qmlEngine(const QObject *obj) +{ + QmlContext *context = QmlEngine::contextForObject(obj); + return context?context->engine():0; +} + +QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object) +{ + QObjectPrivate *priv = QObjectPrivate::get(const_cast<QObject *>(object)); + + + QmlSimpleDeclarativeData *data = static_cast<QmlSimpleDeclarativeData *>(priv->declarativeData); + + QmlExtendedDeclarativeData *edata = (data && data->flags & QmlSimpleDeclarativeData::Extended)?static_cast<QmlExtendedDeclarativeData *>(data):0; + + if(edata) { + QObject *rv = edata->attachedProperties.value(id); + if(rv) + return rv; + } + + QmlAttachedPropertiesFunc pf = QmlMetaType::attachedPropertiesFuncById(id); + if(!pf) + return 0; + + QObject *rv = pf(const_cast<QObject *>(object)); + + if(rv) { + if(!edata) { + + edata = new QmlExtendedDeclarativeData; + if(data) edata->context = data->context; + priv->declarativeData = edata; + + } + + edata->attachedProperties.insert(id, rv); + } + + return rv; +} + +void QmlExtendedDeclarativeData::destroyed(QObject *) +{ + delete this; +} + /*! \internal */ QScriptEngine *QmlEngine::scriptEngine() { diff --git a/src/declarative/qml/qmlengine.h b/src/declarative/qml/qmlengine.h index 086595a..fde84d4 100644 --- a/src/declarative/qml/qmlengine.h +++ b/src/declarative/qml/qmlengine.h @@ -81,6 +81,8 @@ public: void setNetworkAccessManager(QNetworkAccessManager *); QNetworkAccessManager *networkAccessManager() const; + static QmlContext *contextForObject(const QObject *); + static void setContextForObject(QObject *, QmlContext *); private: // LK: move to the private class QScriptEngine *scriptEngine(); diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp index 9938022..848c8db 100644 --- a/src/declarative/qml/qmlinstruction.cpp +++ b/src/declarative/qml/qmlinstruction.cpp @@ -173,7 +173,7 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx) qWarning() << idx << "\t" << line << "\t" << "ASSIGN_OBJECT_LIST\t" << instr->assignObject.property << "\t" << instr->assignObject.castValue << "\t\t" << ((instr->assignObject.property == -1)?QByteArray("default"):datas.at(instr->assignObject.property)); break; case QmlInstruction::FetchAttached: - qWarning() << idx << "\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.idx << "\t\t\t" << primitives.at(instr->fetchAttached.idx); + qWarning() << idx << "\t" << line << "\t" << "FETCH_ATTACHED\t\t" << instr->fetchAttached.id; break; case QmlInstruction::FetchQmlList: qWarning() << idx << "\t" << line << "\t" << "FETCH_QMLLIST\t\t" << instr->fetchQmlList.property << "\t" << instr->fetchQmlList.type; diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h index 40a0b84..440b54a 100644 --- a/src/declarative/qml/qmlinstruction_p.h +++ b/src/declarative/qml/qmlinstruction_p.h @@ -280,7 +280,7 @@ public: int count; } createComponent; struct { - int idx; + int id; } fetchAttached; struct { int property; diff --git a/src/declarative/qml/qmlmetaproperty.cpp b/src/declarative/qml/qmlmetaproperty.cpp index 1218b99..780f8a8 100644 --- a/src/declarative/qml/qmlmetaproperty.cpp +++ b/src/declarative/qml/qmlmetaproperty.cpp @@ -103,7 +103,18 @@ QmlMetaProperty::~QmlMetaProperty() // ### not thread safe static QHash<const QMetaObject *, QMetaPropertyEx> qmlCacheDefProp; + +/*! + Creates a QmlMetaProperty for the default property of \a obj. If there is no + default property, an invalid QmlMetaProperty will be created. + */ +QmlMetaProperty::QmlMetaProperty(QObject *obj) +{ + initDefault(obj); +} + /*! + \internal Creates a QmlMetaProperty for the default property of \a obj. If there is no default property, an invalid QmlMetaProperty will be created. */ @@ -111,6 +122,11 @@ QmlMetaProperty::QmlMetaProperty(QObject *obj, QmlContext *ctxt) : d(new QmlMetaPropertyPrivate) { d->context = ctxt; + initDefault(obj); +} + +void QmlMetaProperty::initDefault(QObject *obj) +{ if(!obj) return; @@ -162,6 +178,16 @@ static QHash<const QMetaObject *, QHash<QString, QMetaPropertyEx> > qmlCacheProp /*! Creates a QmlMetaProperty for the property \a name of \a obj. */ +QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name) +: d(new QmlMetaPropertyPrivate) +{ + initProperty(obj, name); +} + +/*! + \internal + Creates a QmlMetaProperty for the property \a name of \a obj. + */ QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name, QmlContext *ctxt) : d(new QmlMetaPropertyPrivate) { @@ -170,6 +196,11 @@ QmlMetaProperty::QmlMetaProperty(QObject *obj, const QString &name, QmlContext * #endif d->context = ctxt; + initProperty(obj, name); +} + +void QmlMetaProperty::initProperty(QObject *obj, const QString &name) +{ d->name = name; d->object = obj; if(name.isEmpty() || !obj) @@ -519,7 +550,7 @@ QObject *QmlMetaPropertyPrivate::attachedObject() const if(attachedFunc == -1) return 0; else - return QmlMetaType::attachedPropertiesFuncById(attachedFunc)(object); + return qmlAttachedPropertiesObjectById(attachedFunc, object); } /*! diff --git a/src/declarative/qml/qmlmetaproperty.h b/src/declarative/qml/qmlmetaproperty.h index a2939f9..4836038 100644 --- a/src/declarative/qml/qmlmetaproperty.h +++ b/src/declarative/qml/qmlmetaproperty.h @@ -72,8 +72,10 @@ public: Normal }; QmlMetaProperty(); - QmlMetaProperty(QObject *, QmlContext * = 0); - QmlMetaProperty(QObject *, const QString &, QmlContext * = 0); + QmlMetaProperty(QObject *); + QmlMetaProperty(QObject *, const QString &); + QmlMetaProperty(QObject *, QmlContext *); + QmlMetaProperty(QObject *, const QString &, QmlContext *); QmlMetaProperty(const QmlMetaProperty &); QmlMetaProperty &operator=(const QmlMetaProperty &); QmlMetaProperty(QObject *, int, PropertyCategory = Unknown, QmlContext * = 0); @@ -125,6 +127,8 @@ public: int coreIndex() const; private: + void initDefault(QObject *obj); + void initProperty(QObject *obj, const QString &name); friend class QmlEnginePrivate; QmlMetaPropertyPrivate *d; }; diff --git a/src/declarative/qml/qmlmetatype.cpp b/src/declarative/qml/qmlmetatype.cpp index 51d5607..c12f01a 100644 --- a/src/declarative/qml/qmlmetatype.cpp +++ b/src/declarative/qml/qmlmetatype.cpp @@ -643,6 +643,18 @@ int QmlMetaType::attachedPropertiesFuncId(const QByteArray &name) return -1; } +int QmlMetaType::attachedPropertiesFuncId(const QMetaObject *mo) +{ + QReadLocker lock(metaTypeDataLock()); + QmlMetaTypeData *data = metaTypeData(); + + QmlType *type = data->metaObjectToType.value(mo); + if(type && type->attachedPropertiesFunction()) + return type->index(); + else + return -1; +} + QmlAttachedPropertiesFunc QmlMetaType::attachedPropertiesFuncById(int id) { if(id < 0) diff --git a/src/declarative/qml/qmlmetatype.h b/src/declarative/qml/qmlmetatype.h index 3daa14b..c17d47f 100644 --- a/src/declarative/qml/qmlmetatype.h +++ b/src/declarative/qml/qmlmetatype.h @@ -90,6 +90,7 @@ public: static const QMetaObject *metaObjectForType(const QByteArray &); static const QMetaObject *metaObjectForType(int); static int attachedPropertiesFuncId(const QByteArray &); + static int attachedPropertiesFuncId(const QMetaObject *); static QmlAttachedPropertiesFunc attachedPropertiesFuncById(int); static QmlAttachedPropertiesFunc attachedPropertiesFunc(const QByteArray &); diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp index 966ef8a..62a0864 100644 --- a/src/declarative/qml/qmlvme.cpp +++ b/src/declarative/qml/qmlvme.cpp @@ -253,7 +253,7 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in #ifdef Q_ENABLE_PERFORMANCE_LOG QFxCompilerTimer<QFxCompiler::InstrCreateObject> cc; #endif - QObject *o = types.at(instr.create.type).createInstance(); + QObject *o = types.at(instr.create.type).createInstance(QmlContext::activeContext()); if(!o) VME_EXCEPTION("Unable to create object of type" << types.at(instr.create.type).className); @@ -276,6 +276,7 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in QObject *o = QmlMetaType::toQObject(v); if(!o) VME_EXCEPTION("Unable to create" << types.at(instr.create.type).className); + QmlEngine::setContextForObject(o, QmlContext::activeContext()); if(!stack.isEmpty()) { QObject *parent = stack.top(); @@ -859,14 +860,10 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in #endif QObject *target = stack.top(); - QmlAttachedPropertiesFunc attachFunc = - QmlMetaType::attachedPropertiesFunc(datas.at(instr.fetchAttached.idx)); - if(!attachFunc) - VME_EXCEPTION("No such attached object" << primitives.at(instr.fetchAttached.idx)); + QObject *qmlObject = qmlAttachedPropertiesObjectById(instr.fetchAttached.id, target); - QObject *qmlObject = attachFunc(target); if(!qmlObject) - VME_EXCEPTION("Internal error - unable to create attached object" << primitives.at(instr.fetchAttached.idx)); + VME_EXCEPTION("Unable to create attached object"); stack.push(qmlObject); } diff --git a/src/declarative/util/qmlanimation.cpp b/src/declarative/util/qmlanimation.cpp index f71d203..91a5361 100644 --- a/src/declarative/util/qmlanimation.cpp +++ b/src/declarative/util/qmlanimation.cpp @@ -1004,7 +1004,7 @@ void QmlRunScriptActionPrivate::execute() } if(!scriptStr.isEmpty()) { - QmlExpression expr(ctxt, scriptStr, q); + QmlExpression expr(qmlContext(q), scriptStr, q); expr.setTrackChange(false); expr.value(); } diff --git a/src/declarative/util/qmlanimation_p.h b/src/declarative/util/qmlanimation_p.h index f14df82..80cc7f7 100644 --- a/src/declarative/util/qmlanimation_p.h +++ b/src/declarative/util/qmlanimation_p.h @@ -225,13 +225,12 @@ class QmlRunScriptActionPrivate : public QmlAbstractAnimationPrivate Q_DECLARE_PUBLIC(QmlRunScriptAction); public: QmlRunScriptActionPrivate() - : QmlAbstractAnimationPrivate(), ctxt(QmlContext::activeContext()), proxy(this), rsa(0) {} + : QmlAbstractAnimationPrivate(), proxy(this), rsa(0) {} void init(); QString script; QString file; - QmlContext* ctxt; void execute(); diff --git a/src/declarative/util/qmlbehaviour.cpp b/src/declarative/util/qmlbehaviour.cpp index 3169f63..3fff06c 100644 --- a/src/declarative/util/qmlbehaviour.cpp +++ b/src/declarative/util/qmlbehaviour.cpp @@ -76,14 +76,13 @@ class QmlBehaviourPrivate : public QObjectPrivate { public: QmlBehaviourPrivate() - : context(0), oldContext(0), valueData(0), operations(this) {} + : context(0), valueData(0), operations(this) {} QmlMetaProperty property; QVariant currentValue; QVariant fromValue; QVariant toValue; QmlContext *context; - QmlContext *oldContext; QmlBehaviourData *valueData; class AnimationList : public QmlConcreteList<QmlAbstractAnimation *> { @@ -123,8 +122,6 @@ QmlBehaviour::QmlBehaviour(QObject *parent) { Q_D(QmlBehaviour); d->valueData = new QmlBehaviourData(this); - d->context = new QmlContext(QmlContext::activeContext(), this); - d->context->addDefaultObject(d->valueData); d->group = new QSequentialAnimationGroup(this); } @@ -234,6 +231,10 @@ void QmlBehaviour::setTarget(const QmlMetaProperty &property) void QmlBehaviour::classBegin() { Q_D(QmlBehaviour); + if(!d->context) { + d->context = new QmlContext(qmlContext(this), this); + d->context->addDefaultObject(d->valueData); + } d->context->activate(); } diff --git a/src/declarative/util/qmlconnection.cpp b/src/declarative/util/qmlconnection.cpp index df45a31..b2fd450 100644 --- a/src/declarative/util/qmlconnection.cpp +++ b/src/declarative/util/qmlconnection.cpp @@ -51,9 +51,8 @@ QT_BEGIN_NAMESPACE class QmlConnectionPrivate : public QObjectPrivate { public: - QmlConnectionPrivate() : ctxt(0), boundsignal(0), signalSender(0), componentcomplete(false) {} + QmlConnectionPrivate() : boundsignal(0), signalSender(0), componentcomplete(false) {} - QmlContext *ctxt; QmlBoundSignal *boundsignal; QObject *signalSender; QString script; @@ -112,8 +111,6 @@ public: QmlConnection::QmlConnection(QObject *parent) : QObject(*(new QmlConnectionPrivate), parent) { - Q_D(QmlConnection); - d->ctxt = QmlContext::activeContext(); } QmlConnection::~QmlConnection() @@ -192,9 +189,9 @@ void QmlConnection::connectIfValid() } if (sigparams.isEmpty()) - d->boundsignal = new QmlBoundSignal(d->ctxt, d->script, sender, sigIdx, this); + d->boundsignal = new QmlBoundSignal(qmlContext(this), d->script, sender, sigIdx, this); else - d->boundsignal = new QmlBoundSignalProxy(new QmlContext(d->ctxt,this), d->script, sender, sigIdx, this); + d->boundsignal = new QmlBoundSignalProxy(new QmlContext(qmlContext(this),this), d->script, sender, sigIdx, this); } } diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp index 992185a..24f2d5c 100644 --- a/src/declarative/util/qmllistmodel.cpp +++ b/src/declarative/util/qmllistmodel.cpp @@ -537,7 +537,6 @@ ModelNode::~ModelNode() struct ListModelData { int dataOffset; - int id; int instrCount; ListInstruction *instructions() const { return (ListInstruction *)((char *)this + sizeof(ListModelData)); } }; @@ -546,7 +545,6 @@ QByteArray ListModelParser::compile(QXmlStreamReader& reader, bool *ok) { *ok = true; - QByteArray id; QByteArray data; QList<ListInstruction> instr; int depth=0; @@ -649,10 +647,6 @@ QByteArray ListModelParser::compile(QXmlStreamReader& reader, bool *ok) rv.resize(size); ListModelData *lmd = (ListModelData *)rv.data(); - if(id.count()) - lmd->id = 0; - else - lmd->id = -1; lmd->dataOffset = sizeof(ListModelData) + instr.count() * sizeof(ListInstruction); lmd->instrCount = instr.count(); @@ -709,11 +703,6 @@ QVariant ListModelParser::create(const QByteArray &d) } } - if(lmd->id != -1) { - QmlContext *ctxt = QmlContext::activeContext(); - ctxt->setContextProperty(QLatin1String(data + lmd->id), rv); - } - return QVariant::fromValue(rv); } diff --git a/src/declarative/util/qmlscript.cpp b/src/declarative/util/qmlscript.cpp index 859e21e..73c8c07 100644 --- a/src/declarative/util/qmlscript.cpp +++ b/src/declarative/util/qmlscript.cpp @@ -65,7 +65,7 @@ class QmlScriptPrivate : public QObjectPrivate Q_DECLARE_PUBLIC(QmlScript); public: - QmlScriptPrivate() : reply(0), ctxt(0) {} + QmlScriptPrivate() : reply(0) {} void addScriptToEngine(const QString &, const QString &fileName=QString()); @@ -73,7 +73,6 @@ public: QString source; QNetworkReply *reply; QUrl url; - QmlContext *ctxt; }; /*! @@ -106,8 +105,6 @@ public: QML_DEFINE_TYPE(QmlScript,Script); QmlScript::QmlScript(QObject *parent) : QObject(*(new QmlScriptPrivate), parent) { - Q_D(QmlScript); - d->ctxt = QmlContext::activeContext(); } /*! @@ -154,10 +151,10 @@ void QmlScript::setSource(const QString &source) if (d->source == source) return; d->source = source; - d->url = d->ctxt->resolvedUrl(source); + d->url = qmlContext(this)->resolvedUrl(source); QNetworkRequest req(d->url); req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - d->reply = d->ctxt->engine()->networkAccessManager()->get(req); + d->reply = qmlEngine(this)->networkAccessManager()->get(req); QObject::connect(d->reply, SIGNAL(finished()), this, SLOT(replyFinished())); } @@ -176,7 +173,8 @@ void QmlScript::replyFinished() void QmlScriptPrivate::addScriptToEngine(const QString &script, const QString &fileName) { Q_Q(QmlScript); - QmlEngine *engine = ctxt->engine(); + QmlEngine *engine = qmlEngine(q); + QmlContext *context = qmlContext(q); QScriptEngine *scriptEngine = engine->scriptEngine(); QScriptContext *currentContext = engine->scriptEngine()->currentContext(); @@ -186,11 +184,11 @@ void QmlScriptPrivate::addScriptToEngine(const QString &script, const QString &f for (int i = 0; i < oldScopeChain.size(); ++i) { currentContext->popScope(); } - for (int i = ctxt->d_func()->scopeChain.size() - 1; i > -1; --i) { - currentContext->pushScope(ctxt->d_func()->scopeChain.at(i)); + for (int i = context->d_func()->scopeChain.size() - 1; i > -1; --i) { + currentContext->pushScope(context->d_func()->scopeChain.at(i)); } - currentContext->setActivationObject(ctxt->d_func()->scopeChain.at(0)); + currentContext->setActivationObject(context->d_func()->scopeChain.at(0)); QScriptValue val = scriptEngine->evaluate(script, fileName); if (scriptEngine->hasUncaughtException()) { @@ -209,7 +207,7 @@ void QmlScriptPrivate::addScriptToEngine(const QString &script, const QString &f currentContext->setActivationObject(oldact); - for (int i = 0; i < ctxt->d_func()->scopeChain.size(); ++i) + for (int i = 0; i < context->d_func()->scopeChain.size(); ++i) currentContext->popScope(); for (int i = oldScopeChain.size() - 1; i > -1; --i) diff --git a/src/declarative/util/qmlstateoperations.cpp b/src/declarative/util/qmlstateoperations.cpp index 6836472..c70977a 100644 --- a/src/declarative/util/qmlstateoperations.cpp +++ b/src/declarative/util/qmlstateoperations.cpp @@ -136,9 +136,8 @@ QmlStateOperation::ActionList QmlParentChange::actions() class QmlRunScriptPrivate : public QObjectPrivate { public: - QmlRunScriptPrivate() : ctxt(0) {} + QmlRunScriptPrivate() {} - QmlContext *ctxt; QString script; QString name; }; @@ -151,8 +150,6 @@ QML_DEFINE_TYPE(QmlRunScript,RunScript); QmlRunScript::QmlRunScript(QObject *parent) : QmlStateOperation(*(new QmlRunScriptPrivate), parent) { - Q_D(QmlRunScript); - d->ctxt = QmlContext::activeContext(); } QmlRunScript::~QmlRunScript() @@ -191,7 +188,7 @@ void QmlRunScript::execute() { Q_D(QmlRunScript); if(!d->script.isEmpty()) { - QmlExpression expr(d->ctxt, d->script, this); + QmlExpression expr(qmlContext(this), d->script, this); expr.setTrackChange(false); expr.value(); } diff --git a/src/declarative/widgets/graphicslayouts.cpp b/src/declarative/widgets/graphicslayouts.cpp index 1ecde71..8e0081b 100644 --- a/src/declarative/widgets/graphicslayouts.cpp +++ b/src/declarative/widgets/graphicslayouts.cpp @@ -150,18 +150,17 @@ void QGraphicsLinearLayoutObject::updateAlignment(QGraphicsLayoutItem *item, Qt: QHash<QGraphicsLayoutItem*, QObject*> QGraphicsLinearLayoutObject::attachedProperties; QObject *QGraphicsLinearLayoutObject::qmlAttachedProperties(QObject *obj) { + // ### This is not allowed - you must attach to any object if (!qobject_cast<QGraphicsLayoutItem*>(obj)) return 0; - if(!attachedProperties.contains(qobject_cast<QGraphicsLayoutItem*>(obj))) { - LinearLayoutAttached *rv = new LinearLayoutAttached(obj); - /*if (QGraphicsLinearLayoutObject *lo = qobject_cast<QGraphicsLinearLayoutObject*>(obj->parent())) - QObject::connect(rv, SIGNAL(stretchChanged(QGraphicsLayoutItem*,int)), - lo, SLOT(updateStretch(QGraphicsLayoutItem*,int))); - QObject::connect(rv, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)), - lo, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment)));*/ - attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv); - } - return attachedProperties.value(qobject_cast<QGraphicsLayoutItem*>(obj)); + LinearLayoutAttached *rv = new LinearLayoutAttached(obj); + /*if (QGraphicsLinearLayoutObject *lo = qobject_cast<QGraphicsLinearLayoutObject*>(obj->parent())) + QObject::connect(rv, SIGNAL(stretchChanged(QGraphicsLayoutItem*,int)), + lo, SLOT(updateStretch(QGraphicsLayoutItem*,int))); + QObject::connect(rv, SIGNAL(alignmentChanged(QGraphicsLayoutItem*,Qt::Alignment)), + lo, SLOT(updateAlignment(QGraphicsLayoutItem*,Qt::Alignment)));*/ + attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv); + return rv; } ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -311,13 +310,12 @@ qreal QGraphicsGridLayoutObject::spacing() const QHash<QGraphicsLayoutItem*, QObject*> QGraphicsGridLayoutObject::attachedProperties; QObject *QGraphicsGridLayoutObject::qmlAttachedProperties(QObject *obj) { + // ### This is not allowed - you must attach to any object if (!qobject_cast<QGraphicsLayoutItem*>(obj)) return 0; - if(!attachedProperties.contains(qobject_cast<QGraphicsLayoutItem*>(obj))) { - GridLayoutAttached *rv = new GridLayoutAttached(obj); - attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv); - } - return attachedProperties.value(qobject_cast<QGraphicsLayoutItem*>(obj)); + GridLayoutAttached *rv = new GridLayoutAttached(obj); + attachedProperties.insert(qobject_cast<QGraphicsLayoutItem*>(obj), rv); + return rv; } QT_END_NAMESPACE |