src/hbcore/inputfw/hbinputfocusobject.cpp
changeset 5 627c4a0fd0e7
parent 2 06ff229162e9
child 6 c3690ec91ef8
--- a/src/hbcore/inputfw/hbinputfocusobject.cpp	Thu May 27 13:10:59 2010 +0300
+++ b/src/hbcore/inputfw/hbinputfocusobject.cpp	Fri Jun 11 13:58:22 2010 +0300
@@ -29,14 +29,18 @@
 #include <QLineEdit>
 #include <QTextEdit>
 #include <QPointer>
+#include <QGraphicsView>
 
 #include "hbinputmethod.h"
 #include "hbinputfocusobject.h"
 #include "hbinputeditorinterface.h"
 #include "hbinputvkbhost.h"
 #include "hbinputstandardfilters.h"
+#include "hbinpututils.h"
 #include "hbnamespace_p.h"
 
+
+
 /*!
 @alpha
 @hbcore
@@ -141,16 +145,26 @@
     }
 
     if (d->mFocusedObject) {
-        QApplication::sendEvent(d->mFocusedObject, &event);
         if (event.type() == QEvent::InputMethod) {
+            QInputContext *ic = qApp->inputContext();
+            QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event);
+            if (ic) {
+                ic->sendEvent(*imEvent);
+            }
             // Currently in Qt, QTextEdit doesn't ensure cursor visibility
             // in case we are sending text in the form of QInputMethodEvent. So we need
             // to call QTextEdit:ensureCursorVisible() here till we get a fix from Qt.
             ensureCursorVisible(d->mFocusedObject);
+        } else {
+            QInputContext *ic = qApp->inputContext();
+            if (ic && ic->focusWidget()) {
+                QApplication::sendEvent(ic->focusWidget(), &event);
+            }
         }
     }
 }
 
+
 /*!
 Posts given event to focused editor in an asynchronous manner.
 */
@@ -179,14 +193,27 @@
 {
     Q_D(const HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (graphicsWidget && graphicsWidget->scene()) {
-        return graphicsWidget->scene()->inputMethodQuery(query);
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (graphicsObject && graphicsObject->scene()) {
+        return graphicsObject->scene()->inputMethodQuery(query);
     }
 
+    // check if QWidget is embedded as a proxy in scene. If yes try to get details
+    // from the scene.
     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
+    QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget);
+    if (pw && pw->scene()) {
+        return pw->scene()->inputMethodQuery(query);
+    }
+    
     if (widget) {
-        return widget->inputMethodQuery(query);
+        // QWidget returns microfocus in local coordinate.
+        // we need to map it to global coordinate.
+        QVariant v = widget->inputMethodQuery(query);
+        if (v.type() == QVariant::Rect) {
+            v = v.toRect().translated(widget->mapToGlobal(QPoint(0, 0)));
+        }
+        return v;
     }
 
     return QVariant();
@@ -257,20 +284,19 @@
 {
     Q_D(HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (!graphicsWidget) {
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (!graphicsObject) {
         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
         if (widget) {
-            if (widget->graphicsProxyWidget()) {
-                graphicsWidget = widget->graphicsProxyWidget();
-            } else {
+            if (!(graphicsObject = HbInputUtils::graphicsProxyWidget(widget))) {
                 widget->clearFocus();
+                return;
             }
         }
     }
 
-    if (graphicsWidget && graphicsWidget->scene()) {
-        graphicsWidget->scene()->setFocusItem(0);
+    if (graphicsObject && graphicsObject->scene()) {
+        graphicsObject->scene()->setFocusItem(0);
     }
 }
 
@@ -308,26 +334,41 @@
 }
 
 /*!
-Returns editor widget geometry. In case of QGraphicsWidget, the returned value is in scene coordinates.
+Returns editor widget geometry. In case of QGraphicsObject, the returned value is in scene coordinates.
 */
 QRectF HbInputFocusObject::editorGeometry() const
 {
     Q_D(const HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (!graphicsWidget) {
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (!graphicsObject) {
         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
         if (widget) {
-            if (widget->graphicsProxyWidget()) {
-                graphicsWidget = widget->graphicsProxyWidget();
+            // check if widget is inside a proxy.
+            QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget);
+            if (pw) {
+                // check if we are pointing to the toplevel
+                // proxy widget, if not then we must check for
+                // the widgets window and see if it is a proxy.
+                if (pw->widget() == widget) {
+                    graphicsObject = pw;
+                } else if (pw->widget() == widget->window()) {
+                    // focused object is not a proxy but it is 
+                    // inside a proxy, query to proxy about
+                    // the focused objects rect.
+                    QRectF rect = pw->subWidgetRect(widget);
+                    rect.translate(pw->scenePos());
+                    return rect;
+                }
             } else {
-                return widget->geometry();
+                return QRectF(widget->mapToGlobal(QPoint(0, 0)), widget->size());
             }
         }
     }
 
-    if (graphicsWidget) {
-        return QRectF(graphicsWidget->scenePos(), graphicsWidget->size());
+    // we need to find the editor which is inside 
+    if (graphicsObject) {
+        return QRectF(graphicsObject->scenePos(), graphicsObject->boundingRect().size());
     }
 
     return QRectF();
@@ -335,7 +376,7 @@
 
 /*!
 Returns cursor micro focus by sending Qt::ImMicroFocus to focused editor.
-In case of QGraphicsWidget, the returned rectangle is in scene coordinates.
+In case of QGraphicsObject, the returned rectangle is in scene coordinates.
 */
 QRectF HbInputFocusObject::microFocus() const
 {
@@ -360,36 +401,38 @@
 {
     Q_D(const HbInputFocusObject);
 
-    QGraphicsWidget *editorWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
+    QGraphicsObject *editorWidget = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
     if (!editorWidget) {
         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
         if (widget) {
-            editorWidget = widget->graphicsProxyWidget();
+            editorWidget = HbInputUtils::graphicsProxyWidget(widget);
         }
     }
 
     if (editorWidget) {
         qreal result = editorWidget->zValue();
-        for (QGraphicsWidget *parent = editorWidget->parentWidget(); parent; parent = parent->parentWidget()) {
+        for (QGraphicsObject *parent = editorWidget->parentObject(); parent; parent = parent->parentObject()) {
             result += parent->zValue();
         }
-
-        return result + HbPrivate::VKBValueUnit;
+        result += HbPrivate::VKBValueUnit;
+        if(result >= 0) {
+            return result;
+        }
     }
 
     return 0.0;
 }
 
 /*!
-Returns input method hints. See QWidget and QGraphicsWidget documentation for more information.
+Returns input method hints. See QWidget and QGraphicsItem documentation for more information.
 */
 Qt::InputMethodHints HbInputFocusObject::inputMethodHints() const
 {
     Q_D(const HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (graphicsWidget) {
-        return graphicsWidget->inputMethodHints();
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (graphicsObject) {
+        return graphicsObject->inputMethodHints();
     }
 
     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
@@ -407,9 +450,9 @@
 {
     Q_D(HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (graphicsWidget) {
-        graphicsWidget->setInputMethodHints(hints);
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (graphicsObject) {
+        graphicsObject->setInputMethodHints(hints);
         return;
     }
 
@@ -473,21 +516,37 @@
 
 /*!
 Returns the scenePos of the associated editor widget, if the concept makes sense
-in its context (i.e. the editor is part of a scene, either being a QGraphicsWidget or
+in its context (i.e. the editor is part of a scene, either being a QGraphicsObject or
 a QWidget embedded in a QGraphicsProxyWidget). Otherwise returns QPointF(0.0, 0.0).
 */
 QPointF HbInputFocusObject::scenePos() const
 {
     Q_D(const HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (graphicsWidget) {
-        return graphicsWidget->scenePos();
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (graphicsObject) {
+        return graphicsObject->scenePos();
     }
 
-    QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
-    if (widget && widget->graphicsProxyWidget()) {
-        return widget->graphicsProxyWidget()->scenePos();
+    QWidget *w = qobject_cast<QWidget*>(d->mFocusedObject);
+    // check if widget is inside a proxy.
+    QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(w);
+    if (pw) {
+        // check if we are pointing to the toplevel
+        // proxy widget, if not then we must check for
+        // the widgets window and see if it is a proxy.
+        if (pw->widget() == w) {
+            return pw->scenePos();
+        } else if (pw->widget() == w->window()) {
+            QRectF rect = pw->subWidgetRect(w);
+            rect.translate(pw->scenePos());
+            return rect.topLeft();
+        }
+    }
+
+    if (w) {
+        // not a proxy.. Meaning widget is inside a QWidget window.
+        return w->mapToGlobal(QPoint(0,0));
     }
 
     return QPointF(0.0, 0.0);
@@ -570,9 +629,9 @@
 
             return false;
         } else {
-            QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(editorObject);
-            if (graphicsWidget) {
-                if (!(graphicsWidget->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
+            QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(editorObject);
+            if (graphicsObject) {
+                if (!(graphicsObject->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
                     return true;
                 }
             }
@@ -583,23 +642,21 @@
 
     return true;
 }
-
 /*!
 Returns true if the input framework recognizes given object as editor.
 */
 bool HbInputFocusObject::isEditor(QObject *object)
 {
-    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(object);
-    if (graphicsObject) {
-        return ((graphicsObject->flags() & QGraphicsItem::ItemAcceptsInputMethod) != 0);
+    if (QWidget *w = qobject_cast<QWidget *>(object)) {
+        if (w->testAttribute(Qt::WA_InputMethodEnabled)) {
+            return true;
+        }
     }
 
-    if (qobject_cast<QLineEdit*>(object)) {
-        return true;
-    }
-
-    if (qobject_cast<QTextEdit*>(object)) {
-        return true;
+    if (QGraphicsObject *gw = qobject_cast<QGraphicsObject *>(object)) {
+        if (gw->flags() & QGraphicsItem::ItemAcceptsInputMethod) {
+            return true;
+        }
     }
 
     return false;
@@ -615,9 +672,9 @@
 {
     Q_D(HbInputFocusObject);
 
-    QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
-    if (graphicsWidget && graphicsWidget->scene()) {
-        graphicsWidget->scene()->setFocusItem(graphicsWidget);
+    QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
+    if (graphicsObject && graphicsObject->scene()) {
+        graphicsObject->scene()->setFocusItem(graphicsObject);
     } else {
         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
         if (widget) {