summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorKai Koehne <kai.koehne@nokia.com>2009-08-25 06:18:02 (GMT)
committerKai Koehne <kai.koehne@nokia.com>2009-08-25 06:18:02 (GMT)
commitab4269502cda34abef9fb52161405bd1f6172791 (patch)
tree764717934171fec0f1c49f45e9449e0d34d6ba7b /src/declarative
parentd4c67f5293c0a6c7d7b586a401e1972b964d0c16 (diff)
parent8d5bd63dcbfc610128166f6d277680c9385aa665 (diff)
downloadQt-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.cpp260
-rw-r--r--src/declarative/fx/qfxitem.h4
-rw-r--r--src/declarative/fx/qfxitem_p.h4
-rw-r--r--src/declarative/fx/qfxlistview.cpp9
-rw-r--r--src/declarative/qml/qmlbindingoptimizations.cpp12
-rw-r--r--src/declarative/qml/qmlbindingoptimizations_p.h5
-rw-r--r--src/declarative/qml/qmlcompiler.cpp60
-rw-r--r--src/declarative/qml/qmlcompiler_p.h5
-rw-r--r--src/declarative/qml/qmlengine_p.h12
-rw-r--r--src/declarative/util/qmlstate.h6
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;