src/hbcore/inputfw/hbinputfocusobject.cpp
changeset 5 627c4a0fd0e7
parent 2 06ff229162e9
child 6 c3690ec91ef8
equal deleted inserted replaced
3:11d3954df52a 5:627c4a0fd0e7
    27 #include <QGraphicsScene>
    27 #include <QGraphicsScene>
    28 #include <QGraphicsProxyWidget>
    28 #include <QGraphicsProxyWidget>
    29 #include <QLineEdit>
    29 #include <QLineEdit>
    30 #include <QTextEdit>
    30 #include <QTextEdit>
    31 #include <QPointer>
    31 #include <QPointer>
       
    32 #include <QGraphicsView>
    32 
    33 
    33 #include "hbinputmethod.h"
    34 #include "hbinputmethod.h"
    34 #include "hbinputfocusobject.h"
    35 #include "hbinputfocusobject.h"
    35 #include "hbinputeditorinterface.h"
    36 #include "hbinputeditorinterface.h"
    36 #include "hbinputvkbhost.h"
    37 #include "hbinputvkbhost.h"
    37 #include "hbinputstandardfilters.h"
    38 #include "hbinputstandardfilters.h"
       
    39 #include "hbinpututils.h"
    38 #include "hbnamespace_p.h"
    40 #include "hbnamespace_p.h"
       
    41 
       
    42 
    39 
    43 
    40 /*!
    44 /*!
    41 @alpha
    45 @alpha
    42 @hbcore
    46 @hbcore
    43 \class HbInputFocusObject
    47 \class HbInputFocusObject
   139             d->mPreEditString = imEvent->preeditString();
   143             d->mPreEditString = imEvent->preeditString();
   140         }
   144         }
   141     }
   145     }
   142 
   146 
   143     if (d->mFocusedObject) {
   147     if (d->mFocusedObject) {
   144         QApplication::sendEvent(d->mFocusedObject, &event);
       
   145         if (event.type() == QEvent::InputMethod) {
   148         if (event.type() == QEvent::InputMethod) {
       
   149             QInputContext *ic = qApp->inputContext();
       
   150             QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event);
       
   151             if (ic) {
       
   152                 ic->sendEvent(*imEvent);
       
   153             }
   146             // Currently in Qt, QTextEdit doesn't ensure cursor visibility
   154             // Currently in Qt, QTextEdit doesn't ensure cursor visibility
   147             // in case we are sending text in the form of QInputMethodEvent. So we need
   155             // in case we are sending text in the form of QInputMethodEvent. So we need
   148             // to call QTextEdit:ensureCursorVisible() here till we get a fix from Qt.
   156             // to call QTextEdit:ensureCursorVisible() here till we get a fix from Qt.
   149             ensureCursorVisible(d->mFocusedObject);
   157             ensureCursorVisible(d->mFocusedObject);
   150         }
   158         } else {
   151     }
   159             QInputContext *ic = qApp->inputContext();
   152 }
   160             if (ic && ic->focusWidget()) {
       
   161                 QApplication::sendEvent(ic->focusWidget(), &event);
       
   162             }
       
   163         }
       
   164     }
       
   165 }
       
   166 
   153 
   167 
   154 /*!
   168 /*!
   155 Posts given event to focused editor in an asynchronous manner.
   169 Posts given event to focused editor in an asynchronous manner.
   156 */
   170 */
   157 void HbInputFocusObject::postEvent(QEvent& event)
   171 void HbInputFocusObject::postEvent(QEvent& event)
   177 */
   191 */
   178 QVariant HbInputFocusObject::inputMethodQuery(Qt::InputMethodQuery query) const
   192 QVariant HbInputFocusObject::inputMethodQuery(Qt::InputMethodQuery query) const
   179 {
   193 {
   180     Q_D(const HbInputFocusObject);
   194     Q_D(const HbInputFocusObject);
   181 
   195 
   182     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   196     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   183     if (graphicsWidget && graphicsWidget->scene()) {
   197     if (graphicsObject && graphicsObject->scene()) {
   184         return graphicsWidget->scene()->inputMethodQuery(query);
   198         return graphicsObject->scene()->inputMethodQuery(query);
   185     }
   199     }
   186 
   200 
       
   201     // check if QWidget is embedded as a proxy in scene. If yes try to get details
       
   202     // from the scene.
   187     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   203     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
       
   204     QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget);
       
   205     if (pw && pw->scene()) {
       
   206         return pw->scene()->inputMethodQuery(query);
       
   207     }
       
   208     
   188     if (widget) {
   209     if (widget) {
   189         return widget->inputMethodQuery(query);
   210         // QWidget returns microfocus in local coordinate.
       
   211         // we need to map it to global coordinate.
       
   212         QVariant v = widget->inputMethodQuery(query);
       
   213         if (v.type() == QVariant::Rect) {
       
   214             v = v.toRect().translated(widget->mapToGlobal(QPoint(0, 0)));
       
   215         }
       
   216         return v;
   190     }
   217     }
   191 
   218 
   192     return QVariant();
   219     return QVariant();
   193 }
   220 }
   194 
   221 
   255 */
   282 */
   256 void HbInputFocusObject::releaseFocus()
   283 void HbInputFocusObject::releaseFocus()
   257 {
   284 {
   258     Q_D(HbInputFocusObject);
   285     Q_D(HbInputFocusObject);
   259 
   286 
   260     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   287     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   261     if (!graphicsWidget) {
   288     if (!graphicsObject) {
   262         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   289         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   263         if (widget) {
   290         if (widget) {
   264             if (widget->graphicsProxyWidget()) {
   291             if (!(graphicsObject = HbInputUtils::graphicsProxyWidget(widget))) {
   265                 graphicsWidget = widget->graphicsProxyWidget();
       
   266             } else {
       
   267                 widget->clearFocus();
   292                 widget->clearFocus();
   268             }
   293                 return;
   269         }
   294             }
   270     }
   295         }
   271 
   296     }
   272     if (graphicsWidget && graphicsWidget->scene()) {
   297 
   273         graphicsWidget->scene()->setFocusItem(0);
   298     if (graphicsObject && graphicsObject->scene()) {
       
   299         graphicsObject->scene()->setFocusItem(0);
   274     }
   300     }
   275 }
   301 }
   276 
   302 
   277 /*!
   303 /*!
   278 Runs the given character through active input filter and commits it if it was accepted.
   304 Runs the given character through active input filter and commits it if it was accepted.
   306 
   332 
   307     return true;
   333     return true;
   308 }
   334 }
   309 
   335 
   310 /*!
   336 /*!
   311 Returns editor widget geometry. In case of QGraphicsWidget, the returned value is in scene coordinates.
   337 Returns editor widget geometry. In case of QGraphicsObject, the returned value is in scene coordinates.
   312 */
   338 */
   313 QRectF HbInputFocusObject::editorGeometry() const
   339 QRectF HbInputFocusObject::editorGeometry() const
   314 {
   340 {
   315     Q_D(const HbInputFocusObject);
   341     Q_D(const HbInputFocusObject);
   316 
   342 
   317     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   343     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   318     if (!graphicsWidget) {
   344     if (!graphicsObject) {
   319         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   345         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   320         if (widget) {
   346         if (widget) {
   321             if (widget->graphicsProxyWidget()) {
   347             // check if widget is inside a proxy.
   322                 graphicsWidget = widget->graphicsProxyWidget();
   348             QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget);
       
   349             if (pw) {
       
   350                 // check if we are pointing to the toplevel
       
   351                 // proxy widget, if not then we must check for
       
   352                 // the widgets window and see if it is a proxy.
       
   353                 if (pw->widget() == widget) {
       
   354                     graphicsObject = pw;
       
   355                 } else if (pw->widget() == widget->window()) {
       
   356                     // focused object is not a proxy but it is 
       
   357                     // inside a proxy, query to proxy about
       
   358                     // the focused objects rect.
       
   359                     QRectF rect = pw->subWidgetRect(widget);
       
   360                     rect.translate(pw->scenePos());
       
   361                     return rect;
       
   362                 }
   323             } else {
   363             } else {
   324                 return widget->geometry();
   364                 return QRectF(widget->mapToGlobal(QPoint(0, 0)), widget->size());
   325             }
   365             }
   326         }
   366         }
   327     }
   367     }
   328 
   368 
   329     if (graphicsWidget) {
   369     // we need to find the editor which is inside 
   330         return QRectF(graphicsWidget->scenePos(), graphicsWidget->size());
   370     if (graphicsObject) {
       
   371         return QRectF(graphicsObject->scenePos(), graphicsObject->boundingRect().size());
   331     }
   372     }
   332 
   373 
   333     return QRectF();
   374     return QRectF();
   334 }
   375 }
   335 
   376 
   336 /*!
   377 /*!
   337 Returns cursor micro focus by sending Qt::ImMicroFocus to focused editor.
   378 Returns cursor micro focus by sending Qt::ImMicroFocus to focused editor.
   338 In case of QGraphicsWidget, the returned rectangle is in scene coordinates.
   379 In case of QGraphicsObject, the returned rectangle is in scene coordinates.
   339 */
   380 */
   340 QRectF HbInputFocusObject::microFocus() const
   381 QRectF HbInputFocusObject::microFocus() const
   341 {
   382 {
   342     return inputMethodQuery(Qt::ImMicroFocus).toRectF();
   383     return inputMethodQuery(Qt::ImMicroFocus).toRectF();
   343 }
   384 }
   358 */
   399 */
   359 qreal HbInputFocusObject::findVkbZValue() const
   400 qreal HbInputFocusObject::findVkbZValue() const
   360 {
   401 {
   361     Q_D(const HbInputFocusObject);
   402     Q_D(const HbInputFocusObject);
   362 
   403 
   363     QGraphicsWidget *editorWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   404     QGraphicsObject *editorWidget = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   364     if (!editorWidget) {
   405     if (!editorWidget) {
   365         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   406         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   366         if (widget) {
   407         if (widget) {
   367             editorWidget = widget->graphicsProxyWidget();
   408             editorWidget = HbInputUtils::graphicsProxyWidget(widget);
   368         }
   409         }
   369     }
   410     }
   370 
   411 
   371     if (editorWidget) {
   412     if (editorWidget) {
   372         qreal result = editorWidget->zValue();
   413         qreal result = editorWidget->zValue();
   373         for (QGraphicsWidget *parent = editorWidget->parentWidget(); parent; parent = parent->parentWidget()) {
   414         for (QGraphicsObject *parent = editorWidget->parentObject(); parent; parent = parent->parentObject()) {
   374             result += parent->zValue();
   415             result += parent->zValue();
   375         }
   416         }
   376 
   417         result += HbPrivate::VKBValueUnit;
   377         return result + HbPrivate::VKBValueUnit;
   418         if(result >= 0) {
       
   419             return result;
       
   420         }
   378     }
   421     }
   379 
   422 
   380     return 0.0;
   423     return 0.0;
   381 }
   424 }
   382 
   425 
   383 /*!
   426 /*!
   384 Returns input method hints. See QWidget and QGraphicsWidget documentation for more information.
   427 Returns input method hints. See QWidget and QGraphicsItem documentation for more information.
   385 */
   428 */
   386 Qt::InputMethodHints HbInputFocusObject::inputMethodHints() const
   429 Qt::InputMethodHints HbInputFocusObject::inputMethodHints() const
   387 {
   430 {
   388     Q_D(const HbInputFocusObject);
   431     Q_D(const HbInputFocusObject);
   389 
   432 
   390     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   433     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   391     if (graphicsWidget) {
   434     if (graphicsObject) {
   392         return graphicsWidget->inputMethodHints();
   435         return graphicsObject->inputMethodHints();
   393     }
   436     }
   394 
   437 
   395     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   438     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   396     if (widget) {
   439     if (widget) {
   397         return widget->inputMethodHints();
   440         return widget->inputMethodHints();
   405 */
   448 */
   406 void HbInputFocusObject::setInputMethodHints(Qt::InputMethodHints hints)
   449 void HbInputFocusObject::setInputMethodHints(Qt::InputMethodHints hints)
   407 {
   450 {
   408     Q_D(HbInputFocusObject);
   451     Q_D(HbInputFocusObject);
   409 
   452 
   410     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   453     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   411     if (graphicsWidget) {
   454     if (graphicsObject) {
   412         graphicsWidget->setInputMethodHints(hints);
   455         graphicsObject->setInputMethodHints(hints);
   413         return;
   456         return;
   414     }
   457     }
   415 
   458 
   416     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   459     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   417     if (widget) {
   460     if (widget) {
   471     return true;
   514     return true;
   472 }
   515 }
   473 
   516 
   474 /*!
   517 /*!
   475 Returns the scenePos of the associated editor widget, if the concept makes sense
   518 Returns the scenePos of the associated editor widget, if the concept makes sense
   476 in its context (i.e. the editor is part of a scene, either being a QGraphicsWidget or
   519 in its context (i.e. the editor is part of a scene, either being a QGraphicsObject or
   477 a QWidget embedded in a QGraphicsProxyWidget). Otherwise returns QPointF(0.0, 0.0).
   520 a QWidget embedded in a QGraphicsProxyWidget). Otherwise returns QPointF(0.0, 0.0).
   478 */
   521 */
   479 QPointF HbInputFocusObject::scenePos() const
   522 QPointF HbInputFocusObject::scenePos() const
   480 {
   523 {
   481     Q_D(const HbInputFocusObject);
   524     Q_D(const HbInputFocusObject);
   482 
   525 
   483     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   526     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   484     if (graphicsWidget) {
   527     if (graphicsObject) {
   485         return graphicsWidget->scenePos();
   528         return graphicsObject->scenePos();
   486     }
   529     }
   487 
   530 
   488     QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   531     QWidget *w = qobject_cast<QWidget*>(d->mFocusedObject);
   489     if (widget && widget->graphicsProxyWidget()) {
   532     // check if widget is inside a proxy.
   490         return widget->graphicsProxyWidget()->scenePos();
   533     QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(w);
       
   534     if (pw) {
       
   535         // check if we are pointing to the toplevel
       
   536         // proxy widget, if not then we must check for
       
   537         // the widgets window and see if it is a proxy.
       
   538         if (pw->widget() == w) {
       
   539             return pw->scenePos();
       
   540         } else if (pw->widget() == w->window()) {
       
   541             QRectF rect = pw->subWidgetRect(w);
       
   542             rect.translate(pw->scenePos());
       
   543             return rect.topLeft();
       
   544         }
       
   545     }
       
   546 
       
   547     if (w) {
       
   548         // not a proxy.. Meaning widget is inside a QWidget window.
       
   549         return w->mapToGlobal(QPoint(0,0));
   491     }
   550     }
   492 
   551 
   493     return QPointF(0.0, 0.0);
   552     return QPointF(0.0, 0.0);
   494 }
   553 }
   495 
   554 
   568                 return textEdit->isReadOnly();
   627                 return textEdit->isReadOnly();
   569             }
   628             }
   570 
   629 
   571             return false;
   630             return false;
   572         } else {
   631         } else {
   573             QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(editorObject);
   632             QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(editorObject);
   574             if (graphicsWidget) {
   633             if (graphicsObject) {
   575                 if (!(graphicsWidget->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
   634                 if (!(graphicsObject->flags() & QGraphicsItem::ItemAcceptsInputMethod)) {
   576                     return true;
   635                     return true;
   577                 }
   636                 }
   578             }
   637             }
   579 
   638 
   580             return false;
   639             return false;
   581         }
   640         }
   582     }
   641     }
   583 
   642 
   584     return true;
   643     return true;
   585 }
   644 }
   586 
       
   587 /*!
   645 /*!
   588 Returns true if the input framework recognizes given object as editor.
   646 Returns true if the input framework recognizes given object as editor.
   589 */
   647 */
   590 bool HbInputFocusObject::isEditor(QObject *object)
   648 bool HbInputFocusObject::isEditor(QObject *object)
   591 {
   649 {
   592     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(object);
   650     if (QWidget *w = qobject_cast<QWidget *>(object)) {
   593     if (graphicsObject) {
   651         if (w->testAttribute(Qt::WA_InputMethodEnabled)) {
   594         return ((graphicsObject->flags() & QGraphicsItem::ItemAcceptsInputMethod) != 0);
   652             return true;
   595     }
   653         }
   596 
   654     }
   597     if (qobject_cast<QLineEdit*>(object)) {
   655 
   598         return true;
   656     if (QGraphicsObject *gw = qobject_cast<QGraphicsObject *>(object)) {
   599     }
   657         if (gw->flags() & QGraphicsItem::ItemAcceptsInputMethod) {
   600 
   658             return true;
   601     if (qobject_cast<QTextEdit*>(object)) {
   659         }
   602         return true;
       
   603     }
   660     }
   604 
   661 
   605     return false;
   662     return false;
   606 }
   663 }
   607 
   664 
   613 */
   670 */
   614 void HbInputFocusObject::setFocus()
   671 void HbInputFocusObject::setFocus()
   615 {
   672 {
   616     Q_D(HbInputFocusObject);
   673     Q_D(HbInputFocusObject);
   617 
   674 
   618     QGraphicsWidget *graphicsWidget = qobject_cast<QGraphicsWidget*>(d->mFocusedObject);
   675     QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject);
   619     if (graphicsWidget && graphicsWidget->scene()) {
   676     if (graphicsObject && graphicsObject->scene()) {
   620         graphicsWidget->scene()->setFocusItem(graphicsWidget);
   677         graphicsObject->scene()->setFocusItem(graphicsObject);
   621     } else {
   678     } else {
   622         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   679         QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject);
   623         if (widget) {
   680         if (widget) {
   624             widget->setFocus();
   681             widget->setFocus();
   625         }
   682         }