diff options
author | Kai Koehne <kai.koehne@nokia.com> | 2009-08-25 06:18:02 (GMT) |
---|---|---|
committer | Kai Koehne <kai.koehne@nokia.com> | 2009-08-25 06:18:02 (GMT) |
commit | ab4269502cda34abef9fb52161405bd1f6172791 (patch) | |
tree | 764717934171fec0f1c49f45e9449e0d34d6ba7b /src/declarative | |
parent | d4c67f5293c0a6c7d7b586a401e1972b964d0c16 (diff) | |
parent | 8d5bd63dcbfc610128166f6d277680c9385aa665 (diff) | |
download | Qt-ab4269502cda34abef9fb52161405bd1f6172791.zip Qt-ab4269502cda34abef9fb52161405bd1f6172791.tar.gz Qt-ab4269502cda34abef9fb52161405bd1f6172791.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/fx/qfxitem.cpp | 260 | ||||
-rw-r--r-- | src/declarative/fx/qfxitem.h | 4 | ||||
-rw-r--r-- | src/declarative/fx/qfxitem_p.h | 4 | ||||
-rw-r--r-- | src/declarative/fx/qfxlistview.cpp | 9 | ||||
-rw-r--r-- | src/declarative/qml/qmlbindingoptimizations.cpp | 12 | ||||
-rw-r--r-- | src/declarative/qml/qmlbindingoptimizations_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 60 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine_p.h | 12 | ||||
-rw-r--r-- | src/declarative/util/qmlstate.h | 6 |
10 files changed, 329 insertions, 48 deletions
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index feb4e8c..7938dc9 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -299,6 +299,229 @@ void QFxContents::setItem(QFxItem *item) calcWidth(); } +/* + Key filters can be installed on a QFxItem, but not removed. Currently they + are only used by attached objects (which are only destroyed on Item + destruction), so this isn't a problem. If in future this becomes any form + of public API, they will have to support removal too. +*/ +class QFxItemKeyFilter +{ +public: + QFxItemKeyFilter(QFxItem * = 0); + virtual ~QFxItemKeyFilter(); + + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); + +private: + QFxItemKeyFilter *m_next; +}; + +QFxItemKeyFilter::QFxItemKeyFilter(QFxItem *item) +: m_next(0) +{ + QFxItemPrivate *p = + item?static_cast<QFxItemPrivate *>(QGraphicsItemPrivate::get(item)):0; + if (p) { + m_next = p->keyHandler; + p->keyHandler = this; + } +} + +QFxItemKeyFilter::~QFxItemKeyFilter() +{ +} + +void QFxItemKeyFilter::keyPressed(QKeyEvent *event) +{ + if (m_next) m_next->keyPressed(event); +} + +void QFxItemKeyFilter::keyReleased(QKeyEvent *event) +{ + if (m_next) m_next->keyReleased(event); +} + +class QFxKeyNavigationAttachedPrivate : public QObjectPrivate +{ +public: + QFxKeyNavigationAttachedPrivate() + : QObjectPrivate(), left(0), right(0), up(0), down(0) {} + + QFxItem *left; + QFxItem *right; + QFxItem *up; + QFxItem *down; +}; + +class QFxKeyNavigationAttached : public QObject, public QFxItemKeyFilter +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QFxKeyNavigationAttached); + + Q_PROPERTY(QFxItem *left READ left WRITE setLeft NOTIFY changed); + Q_PROPERTY(QFxItem *right READ right WRITE setRight NOTIFY changed); + Q_PROPERTY(QFxItem *up READ up WRITE setUp NOTIFY changed); + Q_PROPERTY(QFxItem *down READ down WRITE setDown NOTIFY changed); +public: + QFxKeyNavigationAttached(QObject * = 0); + + QFxItem *left() const; + void setLeft(QFxItem *); + QFxItem *right() const; + void setRight(QFxItem *); + QFxItem *up() const; + void setUp(QFxItem *); + QFxItem *down() const; + void setDown(QFxItem *); + + static QFxKeyNavigationAttached *qmlAttachedProperties(QObject *); + +signals: + void changed(); + +private: + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); +}; + +QFxKeyNavigationAttached::QFxKeyNavigationAttached(QObject *parent) +: QObject(*(new QFxKeyNavigationAttachedPrivate), parent), + QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) +{ +} + +QFxKeyNavigationAttached * +QFxKeyNavigationAttached::qmlAttachedProperties(QObject *obj) +{ + return new QFxKeyNavigationAttached(obj); +} + +QFxItem *QFxKeyNavigationAttached::left() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->left; +} + +void QFxKeyNavigationAttached::setLeft(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->left = i; + emit changed(); +} + +QFxItem *QFxKeyNavigationAttached::right() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->right; +} + +void QFxKeyNavigationAttached::setRight(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->right = i; + emit changed(); +} + +QFxItem *QFxKeyNavigationAttached::up() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->up; +} + +void QFxKeyNavigationAttached::setUp(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->up = i; + emit changed(); +} + +QFxItem *QFxKeyNavigationAttached::down() const +{ + Q_D(const QFxKeyNavigationAttached); + return d->down; +} + +void QFxKeyNavigationAttached::setDown(QFxItem *i) +{ + Q_D(QFxKeyNavigationAttached); + d->down = i; + emit changed(); +} + +void QFxKeyNavigationAttached::keyPressed(QKeyEvent *event) +{ + Q_D(QFxKeyNavigationAttached); + + event->ignore(); + + switch(event->key()) { + case Qt::Key_Left: + if (d->left) { + d->left->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Right: + if (d->right) { + d->right->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Up: + if (d->up) { + d->up->setFocus(true); + event->accept(); + } + break; + case Qt::Key_Down: + if (d->down) { + d->down->setFocus(true); + event->accept(); + } + break; + default: + break; + } + + if (!event->isAccepted()) QFxItemKeyFilter::keyPressed(event); +} + +void QFxKeyNavigationAttached::keyReleased(QKeyEvent *event) +{ + Q_D(QFxKeyNavigationAttached); + + event->ignore(); + + switch(event->key()) { + case Qt::Key_Left: + if (d->left) { + event->accept(); + } + break; + case Qt::Key_Right: + if (d->right) { + event->accept(); + } + break; + case Qt::Key_Up: + if (d->up) { + event->accept(); + } + break; + case Qt::Key_Down: + if (d->down) { + event->accept(); + } + break; + default: + break; + } + + if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); +} + /*! \qmlclass Keys \brief The Keys attached property provides key handling to Items. @@ -616,7 +839,7 @@ public: bool enabled; }; -class QFxKeysAttached : public QObject +class QFxKeysAttached : public QObject, public QFxItemKeyFilter { Q_OBJECT Q_DECLARE_PRIVATE(QFxKeysAttached); @@ -681,8 +904,8 @@ signals: void volumeDownPressed(QFxKeyEvent *event); private: - void keyPressed(QKeyEvent *event); - void keyReleased(QKeyEvent *event); + virtual void keyPressed(QKeyEvent *event); + virtual void keyReleased(QKeyEvent *event); const char *keyToSignal(int key) { QByteArray keySignal; @@ -704,8 +927,6 @@ private: }; static const SigMap sigMap[]; - static QHash<QObject*, QFxKeysAttached*> attachedProperties; - friend class QFxItem; }; const QFxKeysAttached::SigMap QFxKeysAttached::sigMap[] = { @@ -738,24 +959,19 @@ const QFxKeysAttached::SigMap QFxKeysAttached::sigMap[] = { { 0, 0 } }; -QHash<QObject*, QFxKeysAttached*> QFxKeysAttached::attachedProperties; - bool QFxKeysAttachedPrivate::isConnected(const char *signalName) { return isSignalConnected(signalIndex(signalName)); } QFxKeysAttached::QFxKeysAttached(QObject *parent) - : QObject(*(new QFxKeysAttachedPrivate), parent) +: QObject(*(new QFxKeysAttachedPrivate), parent), + QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) { - if (QFxItem *item = qobject_cast<QFxItem*>(parent)) - item->setKeyHandler(this); } QFxKeysAttached::~QFxKeysAttached() { - if (QFxItem *item = qobject_cast<QFxItem*>(parent())) - item->setKeyHandler(0); } void QFxKeysAttached::keyPressed(QKeyEvent *event) @@ -780,6 +996,8 @@ void QFxKeysAttached::keyPressed(QKeyEvent *event) if (!ke.isAccepted()) emit pressed(&ke); event->setAccepted(ke.isAccepted()); + + if (!event->isAccepted()) QFxItemKeyFilter::keyPressed(event); } void QFxKeysAttached::keyReleased(QKeyEvent *event) @@ -792,19 +1010,15 @@ void QFxKeysAttached::keyReleased(QKeyEvent *event) QFxKeyEvent ke(*event); emit released(&ke); event->setAccepted(ke.isAccepted()); + + if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); } QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj) { - QFxKeysAttached *rv = attachedProperties.value(obj); - if (!rv) { - rv = new QFxKeysAttached(obj); - attachedProperties.insert(obj, rv); - } - return rv; + return new QFxKeysAttached(obj); } - /*! \qmlclass Item QFxItem \brief The Item is the most basic of all visual items in QML. @@ -1423,12 +1637,6 @@ void QFxItem::geometryChanged(const QRectF &newGeometry, } } -void QFxItem::setKeyHandler(QFxKeysAttached *handler) -{ - Q_D(QFxItem); - d->keyHandler = handler; -} - /*! \reimp */ @@ -2438,6 +2646,8 @@ QT_END_NAMESPACE QML_DECLARE_TYPE(QFxKeysAttached) QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,Keys,QFxKeysAttached) +QML_DECLARE_TYPE(QFxKeyNavigationAttached) +QML_DEFINE_TYPE(Qt,4,6,(QT_VERSION&0x00ff00)>>8,KeyNavigation,QFxKeyNavigationAttached) #include "moc_qfxitem.cpp" #include "qfxitem.moc" diff --git a/src/declarative/fx/qfxitem.h b/src/declarative/fx/qfxitem.h index 89c2cf1..cb2d97a 100644 --- a/src/declarative/fx/qfxitem.h +++ b/src/declarative/fx/qfxitem.h @@ -63,7 +63,6 @@ class QmlTransition; class QFxKeyEvent; class QFxAnchors; class QFxItemPrivate; -class QFxKeysAttached; class Q_DECLARATIVE_EXPORT QFxItem : public QGraphicsObject, public QmlParserStatus { Q_OBJECT @@ -197,11 +196,8 @@ private: QFxAnchorLine verticalCenter() const; QFxAnchorLine baseline() const; - void setKeyHandler(QFxKeysAttached *); - friend class QmlStatePrivate; friend class QFxAnchors; - friend class QFxKeysAttached; Q_DISABLE_COPY(QFxItem) Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr, QFxItem) }; diff --git a/src/declarative/fx/qfxitem_p.h b/src/declarative/fx/qfxitem_p.h index 1d4bef3..d30e324 100644 --- a/src/declarative/fx/qfxitem_p.h +++ b/src/declarative/fx/qfxitem_p.h @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE class QNetworkReply; -class QFxKeysAttached; +class QFxItemKeyFilter; //### merge into private? class QFxContents : public QObject @@ -209,7 +209,7 @@ public: bool _keepMouse:1; bool smooth:1; - QFxKeysAttached *keyHandler; + QFxItemKeyFilter *keyHandler; qreal width; qreal height; diff --git a/src/declarative/fx/qfxlistview.cpp b/src/declarative/fx/qfxlistview.cpp index 8dfe171..4b28462 100644 --- a/src/declarative/fx/qfxlistview.cpp +++ b/src/declarative/fx/qfxlistview.cpp @@ -59,7 +59,7 @@ public: attachedProperties.remove(parent()); } - Q_PROPERTY(QFxListView *view READ view) + Q_PROPERTY(QFxListView *view READ view CONSTANT) QFxListView *view() { return m_view; } Q_PROPERTY(bool isCurrentItem READ isCurrentItem NOTIFY currentItemChanged) @@ -212,8 +212,11 @@ public: qreal startPosition() const { qreal pos = 0; - if (!visibleItems.isEmpty()) - pos = visibleItems.first()->position() - visibleIndex * (averageSize + spacing); + if (!visibleItems.isEmpty()) { + pos = visibleItems.first()->position(); + if (visibleIndex > 0) + pos -= visibleIndex * (averageSize + spacing) - spacing; + } return pos; } diff --git a/src/declarative/qml/qmlbindingoptimizations.cpp b/src/declarative/qml/qmlbindingoptimizations.cpp index e1f4a90..e4ca358 100644 --- a/src/declarative/qml/qmlbindingoptimizations.cpp +++ b/src/declarative/qml/qmlbindingoptimizations.cpp @@ -64,6 +64,11 @@ QmlBinding_Id::QmlBinding_Id(QObject *object, int propertyIdx, QmlAbstractExpression::setContext(context); } +QmlBinding_Id::~QmlBinding_Id() +{ + removeFromContext(); +} + void QmlBinding_Id::setEnabled(bool e) { if (e) { @@ -103,7 +108,7 @@ void QmlBinding_Id::update() } } -void QmlBinding_Id::reset() +void QmlBinding_Id::removeFromContext() { if (m_prev) { *m_prev = m_next; @@ -111,6 +116,11 @@ void QmlBinding_Id::reset() m_next = 0; m_prev = 0; } +} + +void QmlBinding_Id::reset() +{ + removeFromContext(); QObject *o = 0; void *a[] = { &o, 0 }; diff --git a/src/declarative/qml/qmlbindingoptimizations_p.h b/src/declarative/qml/qmlbindingoptimizations_p.h index 2d2ffec..ab264c7 100644 --- a/src/declarative/qml/qmlbindingoptimizations_p.h +++ b/src/declarative/qml/qmlbindingoptimizations_p.h @@ -65,7 +65,8 @@ class QmlBinding_Id : public QmlAbstractExpression, { public: QmlBinding_Id(QObject *object, int propertyIdx, - QmlContext *context, int id); + QmlContext *context, int id); + virtual ~QmlBinding_Id(); // Inherited from QmlAbstractBinding virtual void setEnabled(bool); @@ -75,6 +76,8 @@ public: void reset(); private: + void removeFromContext(); + QmlBinding_Id **m_prev; QmlBinding_Id *m_next; diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 1771cb4..3dcc448 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1176,11 +1176,19 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, } QmlType *type = 0; - QmlEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, &type, 0); - // 0: attached properties not supported in QML component files - - if (!type || !type->attachedPropertiesType()) + QmlEnginePrivate::ImportedNamespace *typeNamespace = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, + &type, 0, &typeNamespace); + + if (typeNamespace) { + // ### We might need to indicate that this property is a namespace + // for the DOM API + COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, + ctxt)); + return true; + } else if (!type || !type->attachedPropertiesType()) { COMPILE_EXCEPTION(prop, "Non-existant attached object"); + } if (!prop->value) COMPILE_EXCEPTION(prop, "Invalid attached object assignment"); @@ -1265,6 +1273,40 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, return true; } +bool +QmlCompiler::buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns, + QmlParser::Property *nsProp, + QmlParser::Object *obj, + const BindingContext &ctxt) +{ + if (!nsProp->value) + COMPILE_EXCEPTION(nsProp, "Invalid use of namespace"); + + foreach (Property *prop, nsProp->value->properties) { + + if (!isAttachedPropertyName(prop->name)) + COMPILE_EXCEPTION(prop, "Not an attached property name"); + + // Setup attached property data + + QmlType *type = 0; + QmlEnginePrivate::get(engine)->resolveTypeInNamespace(ns, prop->name, + &type, 0); + + if (!type || !type->attachedPropertiesType()) + COMPILE_EXCEPTION(prop, "Non-existant attached object"); + + if (!prop->value) + COMPILE_EXCEPTION(prop, "Invalid attached object assignment"); + + Q_ASSERT(type->attachedPropertiesFunction()); + prop->index = type->index(); + prop->value->metatype = type->attachedPropertiesType(); + + COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt)); + } +} + void QmlCompiler::genValueProperty(QmlParser::Property *prop, QmlParser::Object *obj) { @@ -1407,11 +1449,19 @@ bool QmlCompiler::buildIdProperty(QmlParser::Property *prop, prop->values.at(0)->object) COMPILE_EXCEPTION(prop, "Invalid use of id property"); - QString val = prop->values.at(0)->primitive(); + QmlParser::Value *idValue = prop->values.at(0); + QString val = idValue->primitive(); if (!isValidId(val)) COMPILE_EXCEPTION(prop, val << "is not a valid object id"); + // We disallow id's that conflict with import prefixes + QmlEnginePrivate::ImportedNamespace *ns = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, val.toUtf8(), + 0, 0, &ns); + if (ns) + COMPILE_EXCEPTION(idValue, "id conflicts with namespace prefix"); + if (compileState.ids.contains(val)) COMPILE_EXCEPTION(prop, "id is not unique"); diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 58279c4..c42c2d9 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -60,6 +60,7 @@ #include <private/qmlinstruction_p.h> #include <private/qmlcompositetypemanager_p.h> #include <private/qmlparser_p.h> +#include <private/qmlengine_p.h> QT_BEGIN_NAMESPACE @@ -165,6 +166,10 @@ private: const BindingContext &); bool buildProperty(QmlParser::Property *prop, QmlParser::Object *obj, const BindingContext &); + bool buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns, + QmlParser::Property *prop, + QmlParser::Object *obj, + const BindingContext &); bool buildIdProperty(QmlParser::Property *prop, QmlParser::Object *obj); bool buildAttachedProperty(QmlParser::Property *prop, QmlParser::Object *obj, diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index c84b3b5..18e3765 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -209,10 +209,14 @@ public: bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; - bool resolveType(const Imports&, const QByteArray& type, QmlType** type_return, QUrl* url_return, ImportedNamespace** ns_return=0) const; - - void resolveNamespace(const Imports& imports, const QByteArray &type, ImportedNamespace **s, QByteArray *unqualifiedType) const; - bool resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const; + bool resolveType(const Imports&, const QByteArray& type, + QmlType** type_return, QUrl* url_return, + ImportedNamespace** ns_return=0) const; + void resolveNamespace(const Imports& imports, const QByteArray &type, + ImportedNamespace **s, + QByteArray *unqualifiedType) const; + bool resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, + QmlType** type_return, QUrl* url_return ) const; static QScriptValue qmlScriptObject(QObject*, QmlEngine*); diff --git a/src/declarative/util/qmlstate.h b/src/declarative/util/qmlstate.h index d15bd4a..0b48449 100644 --- a/src/declarative/util/qmlstate.h +++ b/src/declarative/util/qmlstate.h @@ -81,7 +81,7 @@ public: void deleteFromBinding(); }; -class ActionEvent +class ActionEvent { public: virtual ~ActionEvent(); @@ -126,7 +126,7 @@ class Q_DECLARATIVE_EXPORT QmlState : public QObject Q_PROPERTY(QString name READ name WRITE setName) Q_PROPERTY(QmlBinding *when READ when WRITE setWhen) - Q_PROPERTY(QString extends READ extends WRITE setExtends) + Q_PROPERTY(QString extend READ extends WRITE setExtends) Q_PROPERTY(QmlList<QmlStateOperation *>* changes READ changes) Q_CLASSINFO("DefaultProperty", "changes") @@ -137,7 +137,7 @@ public: QString name() const; void setName(const QString &); - /*'when' is a QmlBinding to limit state changes oscillation + /*'when' is a QmlBinding to limit state changes oscillation due to the unpredictable order of evaluation of bound expressions*/ bool isWhenKnown() const; QmlBinding *when() const; |