diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-09-07 03:53:46 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-09-07 03:53:46 (GMT) |
commit | 8a331b54431905dd171cd874f1c7b441a0b6ae9c (patch) | |
tree | f6bbba1188de6544b65fe898dc9a62591c70b64e /src/declarative/fx/qfxitem.cpp | |
parent | 462456192424082ccc5ccc7238a751f92521ddcf (diff) | |
parent | b238bb40f8eb3c82b03f179cbc516013bdbadf1e (diff) | |
download | Qt-8a331b54431905dd171cd874f1c7b441a0b6ae9c.zip Qt-8a331b54431905dd171cd874f1c7b441a0b6ae9c.tar.gz Qt-8a331b54431905dd171cd874f1c7b441a0b6ae9c.tar.bz2 |
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
Diffstat (limited to 'src/declarative/fx/qfxitem.cpp')
-rw-r--r-- | src/declarative/fx/qfxitem.cpp | 192 |
1 files changed, 186 insertions, 6 deletions
diff --git a/src/declarative/fx/qfxitem.cpp b/src/declarative/fx/qfxitem.cpp index 073d5d9..88a0854 100644 --- a/src/declarative/fx/qfxitem.cpp +++ b/src/declarative/fx/qfxitem.cpp @@ -334,6 +334,8 @@ public: virtual void keyPressed(QKeyEvent *event); virtual void keyReleased(QKeyEvent *event); + virtual void inputMethodEvent(QInputMethodEvent *event); + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; private: QFxItemKeyFilter *m_next; @@ -364,6 +366,17 @@ void QFxItemKeyFilter::keyReleased(QKeyEvent *event) if (m_next) m_next->keyReleased(event); } +void QFxItemKeyFilter::inputMethodEvent(QInputMethodEvent *event) +{ + if (m_next) m_next->inputMethodEvent(event); +} + +QVariant QFxItemKeyFilter::inputMethodQuery(Qt::InputMethodQuery query) const +{ + if (m_next) return m_next->inputMethodQuery(query); + return QVariant(); +} + class QFxKeyNavigationAttachedPrivate : public QObjectPrivate { public: @@ -592,6 +605,25 @@ void QFxKeyNavigationAttached::keyReleased(QKeyEvent *event) */ /*! + \qmlproperty List<Object> Keys::forwardTo + + This property provides a way to forward key presses, key releases, and keyboard input + coming from input methods to other items. This can be useful when you want + one item to handle some keys (e.g. the up and down arrow keys), and another item to + handle other keys (e.g. the left and right arrow keys). Once an item that has been + forwarded keys accepts the event it is no longer forwarded to items later in the + list. + + This example forwards key events to two lists: + \qml + ListView { id: List1 ... } + ListView { id: List2 ... } + Keys.forwardTo: [List1, List2] + focus: true + \endqml +*/ + +/*! \qmlsignal Keys::onPressed(event) This handler is called when a key has been pressed. The \a event @@ -853,19 +885,42 @@ void QFxKeyNavigationAttached::keyReleased(QKeyEvent *event) class QFxKeysAttachedPrivate : public QObjectPrivate { public: - QFxKeysAttachedPrivate() : QObjectPrivate(), enabled(true) {} + QFxKeysAttachedPrivate() + : QObjectPrivate(), inPress(false), inRelease(false) + , inIM(false), enabled(true), imeItem(0), item(0) + {} bool isConnected(const char *signalName); - bool enabled; + QGraphicsItem *finalFocusProxy(QGraphicsItem *item) const + { + QGraphicsItem *fp; + while ((fp = item->focusProxy())) + item = fp; + return item; + } + + //loop detection + bool inPress:1; + bool inRelease:1; + bool inIM:1; + + bool enabled : 1; + + QGraphicsItem *imeItem; + QList<QFxItem *> targets; + QFxItem *item; }; -class QFxKeysAttached : public QObject, public QFxItemKeyFilter +class QFxKeysAttached : public QObject, public QFxItemKeyFilter, public QmlParserStatus { Q_OBJECT - Q_DECLARE_PRIVATE(QFxKeysAttached); + Q_DECLARE_PRIVATE(QFxKeysAttached) + Q_INTERFACES(QmlParserStatus) Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + Q_PROPERTY(QList<QFxItem *> *forwardTo READ forwardTo) + public: QFxKeysAttached(QObject *parent=0); ~QFxKeysAttached(); @@ -879,6 +934,13 @@ public: } } + QList<QFxItem *> *forwardTo() { + Q_D(QFxKeysAttached); + return &d->targets; + } + + virtual void componentComplete(); + static QFxKeysAttached *qmlAttachedProperties(QObject *); Q_SIGNALS: @@ -927,6 +989,8 @@ Q_SIGNALS: private: virtual void keyPressed(QKeyEvent *event); virtual void keyReleased(QKeyEvent *event); + virtual void inputMethodEvent(QInputMethodEvent *); + virtual QVariant inputMethodQuery(Qt::InputMethodQuery query) const; const QByteArray keyToSignal(int key) { QByteArray keySignal; @@ -989,20 +1053,52 @@ QFxKeysAttached::QFxKeysAttached(QObject *parent) : QObject(*(new QFxKeysAttachedPrivate), parent), QFxItemKeyFilter(qobject_cast<QFxItem*>(parent)) { + Q_D(QFxKeysAttached); + d->item = qobject_cast<QFxItem*>(parent); } QFxKeysAttached::~QFxKeysAttached() { } +void QFxKeysAttached::componentComplete() +{ + Q_D(QFxKeysAttached); + if (d->item) { + for (int ii = 0; ii < d->targets.count(); ++ii) { + QGraphicsItem *targetItem = d->finalFocusProxy(d->targets.at(ii)); + if (targetItem && (targetItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + d->item->setFlag(QGraphicsItem::ItemAcceptsInputMethod); + break; + } + } + } +} + void QFxKeysAttached::keyPressed(QKeyEvent *event) { Q_D(QFxKeysAttached); - if (!d->enabled) { + if (!d->enabled || d->inPress) { event->ignore(); return; } + // first process forwards + if (d->item && d->item->scene()) { + d->inPress = true; + for (int ii = 0; ii < d->targets.count(); ++ii) { + QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); + if (i) { + d->item->scene()->sendEvent(i, event); + if (event->isAccepted()) { + d->inPress = false; + return; + } + } + } + d->inPress = false; + } + QFxKeyEvent ke(*event); QByteArray keySignal = keyToSignal(event->key()); if (!keySignal.isEmpty()) { @@ -1024,10 +1120,26 @@ void QFxKeysAttached::keyPressed(QKeyEvent *event) void QFxKeysAttached::keyReleased(QKeyEvent *event) { Q_D(QFxKeysAttached); - if (!d->enabled) { + if (!d->enabled || d->inRelease) { event->ignore(); return; } + + if (d->item && d->item->scene()) { + d->inRelease = true; + for (int ii = 0; ii < d->targets.count(); ++ii) { + QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); + if (i) { + d->item->scene()->sendEvent(i, event); + if (event->isAccepted()) { + d->inRelease = false; + return; + } + } + } + d->inRelease = false; + } + QFxKeyEvent ke(*event); emit released(&ke); event->setAccepted(ke.isAccepted()); @@ -1035,6 +1147,52 @@ void QFxKeysAttached::keyReleased(QKeyEvent *event) if (!event->isAccepted()) QFxItemKeyFilter::keyReleased(event); } +void QFxKeysAttached::inputMethodEvent(QInputMethodEvent *event) +{ + Q_D(QFxKeysAttached); + if (d->item && !d->inIM && d->item->scene()) { + d->inIM = true; + for (int ii = 0; ii < d->targets.count(); ++ii) { + QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); + if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + d->item->scene()->sendEvent(i, event); + if (event->isAccepted()) { + d->imeItem = i; + d->inIM = false; + return; + } + } + } + d->inIM = false; + } + if (!event->isAccepted()) QFxItemKeyFilter::inputMethodEvent(event); +} + +class QFxItemAccessor : public QGraphicsItem +{ +public: + QVariant doInputMethodQuery(Qt::InputMethodQuery query) const { + return QGraphicsItem::inputMethodQuery(query); + } +}; + +QVariant QFxKeysAttached::inputMethodQuery(Qt::InputMethodQuery query) const +{ + Q_D(const QFxKeysAttached); + if (d->item) { + for (int ii = 0; ii < d->targets.count(); ++ii) { + QGraphicsItem *i = d->finalFocusProxy(d->targets.at(ii)); + if (i && (i->flags() & QGraphicsItem::ItemAcceptsInputMethod) && i == d->imeItem) { //### how robust is i == d->imeItem check? + QVariant v = static_cast<QFxItemAccessor *>(i)->doInputMethodQuery(query); + if (v.type() == QVariant::RectF) + v = d->item->mapRectFromItem(i, v.toRectF()); //### cost? + return v; + } + } + } + return QFxItemKeyFilter::inputMethodQuery(query); +} + QFxKeysAttached *QFxKeysAttached::qmlAttachedProperties(QObject *obj) { return new QFxKeysAttached(obj); @@ -1672,6 +1830,28 @@ void QFxItem::keyReleaseEvent(QKeyEvent *event) event->ignore(); } +void QFxItem::inputMethodEvent(QInputMethodEvent *event) +{ + Q_D(QFxItem); + if (d->keyHandler) + d->keyHandler->inputMethodEvent(event); + else + event->ignore(); +} + +QVariant QFxItem::inputMethodQuery(Qt::InputMethodQuery query) const +{ + Q_D(const QFxItem); + QVariant v; + if (d->keyHandler) + v = d->keyHandler->inputMethodQuery(query); + + if (!v.isValid()) + v = QGraphicsObject::inputMethodQuery(query); + + return v; +} + /*! \qmlproperty string Item::id This property holds the identifier for the item. |