summaryrefslogtreecommitdiffstats
path: root/src/declarative/fx/qfxitem.cpp
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-09-07 03:53:46 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-09-07 03:53:46 (GMT)
commit8a331b54431905dd171cd874f1c7b441a0b6ae9c (patch)
treef6bbba1188de6544b65fe898dc9a62591c70b64e /src/declarative/fx/qfxitem.cpp
parent462456192424082ccc5ccc7238a751f92521ddcf (diff)
parentb238bb40f8eb3c82b03f179cbc516013bdbadf1e (diff)
downloadQt-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.cpp192
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.