--- 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 <QInputMethodEvent>
-#include <QGraphicsWidget>
+#include <QGraphicsObject>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QLineEdit>
#include <QTextEdit>
-#include <QPointer>
-#include <QGraphicsView>
#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<QTextEdit *>(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<QObject> mFocusedObject;
- HbEditorInterface mEditorInterface;
- QString mPreEditString;
-};
-
HbMainWindow *HbInputFocusObjectPrivate::mainWindow() const
{
- QWidget *qWidgetObject = qobject_cast<QWidget *>(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<QGraphicsObject *>(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<QTextEdit *>(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<QWidget*>(focusedObject);
+ } else {
+ QGraphicsProxyWidget *proxy = qobject_cast<QGraphicsProxyWidget*>(focusedObject);
+ if (proxy) {
+ d->mWidget = proxy->widget();
+ } else {
+ d->mGraphicsObject = qobject_cast<QGraphicsObject*>(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<QInputMethodEvent *>(&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<QGraphicsObject *>(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<QWidget *>(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<QGraphicsObject *>(d->mFocusedObject);
+ QGraphicsObject *graphicsObject = d->mGraphicsObject;
if (!graphicsObject) {
- QWidget *widget = qobject_cast<QWidget *>(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<QGraphicsObject *>(d->mFocusedObject);
+ QGraphicsObject *graphicsObject = d->mGraphicsObject;
if (!graphicsObject) {
- QWidget *widget = qobject_cast<QWidget *>(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<QGraphicsObject*>(d->mFocusedObject);
+ QGraphicsObject *editorWidget = d->mGraphicsObject;
if (editorWidget) {
rect = editorWidget->mapRectToScene(rect);
}
@@ -468,11 +456,11 @@
{
Q_D(const HbInputFocusObject);
- QGraphicsObject *editorWidget = qobject_cast<QGraphicsObject *>(d->mFocusedObject);
+ QGraphicsObject *editorWidget = d->mGraphicsObject;
if (!editorWidget) {
- QWidget *widget = qobject_cast<QWidget *>(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<QGraphicsObject *>(d->mFocusedObject);
+ QGraphicsObject *graphicsObject = d->mGraphicsObject;
if (graphicsObject) {
return graphicsObject->inputMethodHints();
}
- QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject);
+ QWidget *widget = d->mWidget;
if (widget) {
return widget->inputMethodHints();
}
@@ -517,13 +505,13 @@
{
Q_D(HbInputFocusObject);
- QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject);
+ QGraphicsObject *graphicsObject = d->mGraphicsObject;
if (graphicsObject) {
graphicsObject->setInputMethodHints(hints);
return;
}
- QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject);
+ QWidget *widget = d->mWidget;
if (widget) {
widget->setInputMethodHints(hints);
}
@@ -590,30 +578,18 @@
{
Q_D(const HbInputFocusObject);
- QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject);
+ QGraphicsObject *graphicsObject = d->mGraphicsObject;
if (graphicsObject) {
return graphicsObject->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();
+ 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<QGraphicsObject *>(d->mFocusedObject);
+ bool sendRequest = false;
+ QGraphicsObject *graphicsObject = d->mGraphicsObject;
if (graphicsObject && graphicsObject->scene()) {
graphicsObject->scene()->setFocusItem(graphicsObject);
+ sendRequest = true;
} else {
- QWidget *widget = qobject_cast<QWidget *>(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;
+ }
}
}