diff -r e6ad4ef83b23 -r b7da29130b0e src/hbcore/inputfw/hbinputfocusobject.cpp --- a/src/hbcore/inputfw/hbinputfocusobject.cpp Thu Sep 02 20:44:51 2010 +0300 +++ b/src/hbcore/inputfw/hbinputfocusobject.cpp Fri Sep 17 08:32:10 2010 +0300 @@ -23,22 +23,19 @@ ** ****************************************************************************/ #include "hbinputfocusobject.h" +#include "hbinputfocusobject_p.h" #include -#include +#include #include #include #include #include -#include -#include #include "hbinputmethod.h" -#include "hbinputeditorinterface.h" #include "hbinputvkbhost.h" #include "hbinputstandardfilters.h" #include "hbdeviceprofile.h" -#include "hbinpututils.h" #include "hbnamespace_p.h" #include "hbmainwindow.h" #include "hbevent.h" @@ -46,73 +43,52 @@ #include "hbinputmainwindow_p.h" /*! -@alpha +@beta @hbcore \class HbInputFocusObject \brief A helper class for accessing editor widget in abstract way. -This class is input method side API for accessing editor widgets. It was added because -in some cases Qt's QInputMethodEvent/inputMethodQuery system is not enough and direct -access via type casting between QWidget and QGraphiscWidget based editors is needed. -Focus object hides those cases behind a convinience API. +This class is input method side API for accessing editor widgets. It hides +the details of performing editor related operations, such as sending input +method events, querying editor geometry, querying editor attributes and so on. +It implements a collection of convenience methods for most commonly used +editor operations. This class is purely a convenience or helper type of class in nature. Everything -it does, can be done directly in input method code as well. It just wraps -most commonly used operations behind one API to avoid duplicate code. +it does, can be done directly in input method code as well. The benefit from using +this class is that an input method implementation doesn't need to care whether +the focused editor is QWidget or QGraphicsWidget based (or proxied QWidget). -Application developers should never need to use this class, it is for input method developers only. +Application developers typically do not need this class, it is for input method +developers only. + +The active focus object can be accessed through HbInputMethod::focusObject() +method. \sa HbEditorInterface +\sa HbInputMethod */ /// @cond -/* -This function ensures cursor visibility for known editor types. +/*! +\internal +Returns main window in case the editor is QGraphicsObject based and lives +inside HbGraphicsScene. */ -void ensureCursorVisible(QObject *widget) -{ - if (widget) { - QTextEdit *textEdit = qobject_cast(widget); - if (textEdit) { - textEdit->ensureCursorVisible(); - } - } -} - -class HbInputFocusObjectPrivate -{ - Q_DECLARE_PUBLIC(HbInputFocusObject) - -public: - HbInputFocusObjectPrivate(QObject *focusedObject) - : mFocusedObject(focusedObject), - mEditorInterface(focusedObject) - {} - - HbMainWindow *mainWindow() const; - -public: - HbInputFocusObject *q_ptr; - QPointer mFocusedObject; - HbEditorInterface mEditorInterface; - QString mPreEditString; -}; - HbMainWindow *HbInputFocusObjectPrivate::mainWindow() const { - QWidget *qWidgetObject = qobject_cast(mFocusedObject); QGraphicsObject *graphicsObject = 0; // check for graphics view related widgets. - if (qWidgetObject) { - if (qWidgetObject->graphicsProxyWidget()) { - graphicsObject = qWidgetObject->graphicsProxyWidget(); + if (mWidget) { + if (mWidget->graphicsProxyWidget()) { + graphicsObject = mWidget->graphicsProxyWidget(); } else { return HbInputMainWindow::instance(); } } else { - graphicsObject = qobject_cast(mFocusedObject); + graphicsObject = mGraphicsObject; } if (graphicsObject) { @@ -132,6 +108,20 @@ return 0; } +/*! +\internal +Ensures cursor visibility for known editor types. +*/ +void HbInputFocusObjectPrivate::ensureCursorVisible(QObject *widget) +{ + if (widget) { + QTextEdit *textEdit = qobject_cast(widget); + if (textEdit) { + textEdit->ensureCursorVisible(); + } + } +} + /// @endcond HbInputFocusObject::HbInputFocusObject(QObject *focusedObject) @@ -141,6 +131,17 @@ d->q_ptr = this; if (focusedObject) { + if (focusedObject->isWidgetType()) { + d->mWidget = qobject_cast(focusedObject); + } else { + QGraphicsProxyWidget *proxy = qobject_cast(focusedObject); + if (proxy) { + d->mWidget = proxy->widget(); + } else { + d->mGraphicsObject = qobject_cast(focusedObject); + } + } + HbEvent *event = new HbEvent(HbEvent::InputMethodFocusIn); QCoreApplication::sendEvent(focusedObject, event); delete event; @@ -155,11 +156,10 @@ HbInputFocusObject::~HbInputFocusObject() { - Q_D(HbInputFocusObject); - - if (d->mFocusedObject) { + QObject *obj = object(); + if (obj) { HbEvent *event = new HbEvent(HbEvent::InputMethodFocusOut); - QCoreApplication::postEvent(d->mFocusedObject, event); + QCoreApplication::postEvent(obj, event); } delete d_ptr; @@ -204,7 +204,8 @@ } } - if (d->mFocusedObject) { + QObject *obj = object(); + if (obj) { if (event.type() == QEvent::InputMethod) { QInputContext *ic = qApp->inputContext(); QInputMethodEvent *imEvent = static_cast(&event); @@ -214,7 +215,7 @@ // 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); + d->ensureCursorVisible(obj); } else { QInputContext *ic = qApp->inputContext(); if (ic && ic->focusWidget()) { @@ -240,31 +241,29 @@ } } - if (d->mFocusedObject) { - QApplication::postEvent(d->mFocusedObject, &event); + QObject *obj = object(); + if (obj) { + QApplication::postEvent(obj, &event); } } /*! -Passes input method query to focused editor. +Passes input method query to focused editor widget. */ QVariant HbInputFocusObject::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); - if (graphicsObject && graphicsObject->scene()) { - return graphicsObject->scene()->inputMethodQuery(query); + QGraphicsObject *graphicsObject = d->mGraphicsObject; + if (graphicsObject) { + if (graphicsObject->scene()) { + return graphicsObject->scene()->inputMethodQuery(query); + } + + return QVariant(); } - // check if QWidget is embedded as a proxy in scene. If yes try to get details - // from the scene. - QWidget *widget = qobject_cast(d->mFocusedObject); - QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget); - if (pw && pw->scene()) { - return pw->scene()->inputMethodQuery(query); - } - + QWidget *widget = d->mWidget; if (widget) { // QWidget returns microfocus in local coordinate. // we need to map it to global coordinate. @@ -343,11 +342,13 @@ { Q_D(HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); + QGraphicsObject *graphicsObject = d->mGraphicsObject; if (!graphicsObject) { - QWidget *widget = qobject_cast(d->mFocusedObject); + QWidget *widget = d->mWidget; if (widget) { - if (!(graphicsObject = HbInputUtils::graphicsProxyWidget(widget))) { + if (widget->graphicsProxyWidget()) { + graphicsObject = widget->graphicsProxyWidget(); + } else { widget->clearFocus(); return; } @@ -399,33 +400,20 @@ { Q_D(const HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); + QGraphicsObject *graphicsObject = d->mGraphicsObject; if (!graphicsObject) { - QWidget *widget = qobject_cast(d->mFocusedObject); + QWidget *widget = d->mWidget; if (widget) { - // check if widget is inside a proxy. - QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget); + // Check if widget is inside a proxy. + QGraphicsProxyWidget *pw = widget->graphicsProxyWidget(); 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; - } + graphicsObject = pw; } else { return QRectF(widget->mapToGlobal(QPoint(0, 0)), widget->size()); } } } - // we need to find the editor which is inside if (graphicsObject) { return QRectF(graphicsObject->scenePos(), graphicsObject->boundingRect().size()); } @@ -442,7 +430,7 @@ Q_D(const HbInputFocusObject); QRectF rect = inputMethodQuery(Qt::ImMicroFocus).toRectF(); - QGraphicsObject *editorWidget = qobject_cast(d->mFocusedObject); + QGraphicsObject *editorWidget = d->mGraphicsObject; if (editorWidget) { rect = editorWidget->mapRectToScene(rect); } @@ -468,11 +456,11 @@ { Q_D(const HbInputFocusObject); - QGraphicsObject *editorWidget = qobject_cast(d->mFocusedObject); + QGraphicsObject *editorWidget = d->mGraphicsObject; if (!editorWidget) { - QWidget *widget = qobject_cast(d->mFocusedObject); + QWidget *widget = d->mWidget; if (widget) { - editorWidget = HbInputUtils::graphicsProxyWidget(widget); + editorWidget = widget->graphicsProxyWidget(); } } @@ -497,12 +485,12 @@ { Q_D(const HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); + QGraphicsObject *graphicsObject = d->mGraphicsObject; if (graphicsObject) { return graphicsObject->inputMethodHints(); } - QWidget *widget = qobject_cast(d->mFocusedObject); + QWidget *widget = d->mWidget; if (widget) { return widget->inputMethodHints(); } @@ -517,13 +505,13 @@ { Q_D(HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); + QGraphicsObject *graphicsObject = d->mGraphicsObject; if (graphicsObject) { graphicsObject->setInputMethodHints(hints); return; } - QWidget *widget = qobject_cast(d->mFocusedObject); + QWidget *widget = d->mWidget; if (widget) { widget->setInputMethodHints(hints); } @@ -590,30 +578,18 @@ { Q_D(const HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); + QGraphicsObject *graphicsObject = d->mGraphicsObject; if (graphicsObject) { return graphicsObject->scenePos(); } - QWidget *w = qobject_cast(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(); + QWidget *widget = d->mWidget; + if (widget) { + QGraphicsProxyWidget *proxy = widget->graphicsProxyWidget(); + if (proxy) { + return proxy->scenePos(); } - } - - if (w) { - // not a proxy.. Meaning widget is inside a QWidget window. - return w->mapToGlobal(QPoint(0, 0)); + return widget->mapToGlobal(QPoint(0, 0)); } return QPointF(0.0, 0.0); @@ -625,7 +601,7 @@ bool HbInputFocusObject::stringAllowedInEditor(const QString &string) const { // Two pass filtering. This can be a case constrained editor with a filter. - Qt::InputMethodHints hints; + Qt::InputMethodHints hints = inputMethodHints(); if (hints & Qt::ImhLowercaseOnly) { QString outStr; HbInputLowerCaseFilter::instance()->filterString(string, outStr); @@ -655,10 +631,9 @@ */ void HbInputFocusObject::commitSmiley(QString smiley) { - Q_D(HbInputFocusObject); - - if (d->mFocusedObject) { - d->mFocusedObject->setProperty("SmileyIcon", smiley); + QObject *obj = object(); + if (obj) { + obj->setProperty("SmileyIcon", smiley); } } @@ -668,7 +643,12 @@ QObject *HbInputFocusObject::object() const { Q_D(const HbInputFocusObject); - return d->mFocusedObject; + + if (d->mGraphicsObject) { + return d->mGraphicsObject.data(); + } + + return d->mWidget.data(); } /*! @@ -739,21 +719,26 @@ { Q_D(HbInputFocusObject); - QGraphicsObject *graphicsObject = qobject_cast(d->mFocusedObject); + bool sendRequest = false; + QGraphicsObject *graphicsObject = d->mGraphicsObject; if (graphicsObject && graphicsObject->scene()) { graphicsObject->scene()->setFocusItem(graphicsObject); + sendRequest = true; } else { - QWidget *widget = qobject_cast(d->mFocusedObject); + QWidget *widget = d->mWidget; if (widget) { widget->setFocus(); + sendRequest = true; } } - QInputContext* ic = qApp->inputContext(); - if (ic) { - QEvent *openEvent = new QEvent(QEvent::RequestSoftwareInputPanel); - ic->filterEvent(openEvent); - delete openEvent; + if (sendRequest) { + QInputContext* ic = qApp->inputContext(); + if (ic) { + QEvent *openEvent = new QEvent(QEvent::RequestSoftwareInputPanel); + ic->filterEvent(openEvent); + delete openEvent; + } } }