20 ** |
20 ** |
21 ** If you have questions regarding the use of this file, please contact |
21 ** If you have questions regarding the use of this file, please contact |
22 ** Nokia at developer.feedback@nokia.com. |
22 ** Nokia at developer.feedback@nokia.com. |
23 ** |
23 ** |
24 ****************************************************************************/ |
24 ****************************************************************************/ |
|
25 #include "hbinputfocusobject.h" |
|
26 |
25 #include <QInputMethodEvent> |
27 #include <QInputMethodEvent> |
26 #include <QGraphicsWidget> |
28 #include <QGraphicsWidget> |
27 #include <QGraphicsScene> |
29 #include <QGraphicsScene> |
28 #include <QGraphicsProxyWidget> |
30 #include <QGraphicsProxyWidget> |
29 #include <QLineEdit> |
31 #include <QLineEdit> |
30 #include <QTextEdit> |
32 #include <QTextEdit> |
31 #include <QPointer> |
33 #include <QPointer> |
32 #include <QGraphicsView> |
34 #include <QGraphicsView> |
33 |
35 |
34 #include "hbinputmethod.h" |
36 #include "hbinputmethod.h" |
35 #include "hbinputfocusobject.h" |
|
36 #include "hbinputeditorinterface.h" |
37 #include "hbinputeditorinterface.h" |
37 #include "hbinputvkbhost.h" |
38 #include "hbinputvkbhost.h" |
38 #include "hbinputstandardfilters.h" |
39 #include "hbinputstandardfilters.h" |
39 #include "hbinpututils.h" |
40 #include "hbinpututils.h" |
40 #include "hbnamespace_p.h" |
41 #include "hbnamespace_p.h" |
41 |
42 |
42 |
|
43 |
|
44 /*! |
43 /*! |
45 @alpha |
44 @alpha |
46 @hbcore |
45 @hbcore |
47 \class HbInputFocusObject |
46 \class HbInputFocusObject |
48 \brief A helper class for accessing editor widget in abstract way. |
47 \brief A helper class for accessing editor widget in abstract way. |
107 |
106 |
108 /*! |
107 /*! |
109 Creates an input method event where given string is a pre-edit string and sends |
108 Creates an input method event where given string is a pre-edit string and sends |
110 it to focused editor. See QInputMethodEvent for more information on pre-edit strings. |
109 it to focused editor. See QInputMethodEvent for more information on pre-edit strings. |
111 */ |
110 */ |
112 void HbInputFocusObject::sendPreEditString(const QString& string) |
111 void HbInputFocusObject::sendPreEditString(const QString &string) |
113 { |
112 { |
114 QList<QInputMethodEvent::Attribute> list; |
113 QList<QInputMethodEvent::Attribute> list; |
115 QInputMethodEvent event(string, list); |
114 QInputMethodEvent event(string, list); |
116 sendEvent(event); |
115 sendEvent(event); |
117 } |
116 } |
118 |
117 |
119 /*! |
118 /*! |
120 Creates an input method event where given string is a commit string and sends |
119 Creates an input method event where given string is a commit string and sends |
121 it to focused editor. See QInputMethodEvent for more information on commit strings. |
120 it to focused editor. See QInputMethodEvent for more information on commit strings. |
122 */ |
121 */ |
123 void HbInputFocusObject::sendCommitString(const QString& string) |
122 void HbInputFocusObject::sendCommitString(const QString &string) |
124 { |
123 { |
125 QList<QInputMethodEvent::Attribute> list; |
124 QList<QInputMethodEvent::Attribute> list; |
126 QInputMethodEvent event(QString(), list); |
125 QInputMethodEvent event(QString(), list); |
127 event.setCommitString(string); |
126 event.setCommitString(string); |
128 sendEvent(event); |
127 sendEvent(event); |
129 } |
128 } |
130 |
129 |
131 /*! |
130 /*! |
132 Sends given event to focused editor. |
131 Sends given event to focused editor. |
133 */ |
132 */ |
134 void HbInputFocusObject::sendEvent(QEvent& event) |
133 void HbInputFocusObject::sendEvent(QEvent &event) |
135 { |
134 { |
136 Q_D(HbInputFocusObject); |
135 Q_D(HbInputFocusObject); |
137 |
136 |
138 if (event.type() == QEvent::InputMethod) { |
137 if (event.type() == QEvent::InputMethod) { |
139 QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event); |
138 QInputMethodEvent *imEvent = static_cast<QInputMethodEvent *>(&event); |
140 if (imEvent->commitString().size() > 0) { |
139 if (imEvent->commitString().size() > 0) { |
141 d->mPreEditString = QString(); |
140 d->mPreEditString.clear(); |
142 } else { |
141 } else { |
143 d->mPreEditString = imEvent->preeditString(); |
142 d->mPreEditString = imEvent->preeditString(); |
144 } |
143 } |
145 } |
144 } |
146 |
145 |
147 if (d->mFocusedObject) { |
146 if (d->mFocusedObject) { |
148 if (event.type() == QEvent::InputMethod) { |
147 if (event.type() == QEvent::InputMethod) { |
149 QInputContext *ic = qApp->inputContext(); |
148 QInputContext *ic = qApp->inputContext(); |
150 QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event); |
149 QInputMethodEvent *imEvent = static_cast<QInputMethodEvent *>(&event); |
151 if (ic) { |
150 if (ic) { |
152 ic->sendEvent(*imEvent); |
151 ic->sendEvent(*imEvent); |
153 } |
152 } |
154 // Currently in Qt, QTextEdit doesn't ensure cursor visibility |
153 // Currently in Qt, QTextEdit doesn't ensure cursor visibility |
155 // in case we are sending text in the form of QInputMethodEvent. So we need |
154 // in case we are sending text in the form of QInputMethodEvent. So we need |
166 |
165 |
167 |
166 |
168 /*! |
167 /*! |
169 Posts given event to focused editor in an asynchronous manner. |
168 Posts given event to focused editor in an asynchronous manner. |
170 */ |
169 */ |
171 void HbInputFocusObject::postEvent(QEvent& event) |
170 void HbInputFocusObject::postEvent(QEvent &event) |
172 { |
171 { |
173 Q_D(HbInputFocusObject); |
172 Q_D(HbInputFocusObject); |
174 |
173 |
175 if (event.type() == QEvent::InputMethod) { |
174 if (event.type() == QEvent::InputMethod) { |
176 QInputMethodEvent* imEvent = static_cast<QInputMethodEvent*>(&event); |
175 QInputMethodEvent *imEvent = static_cast<QInputMethodEvent *>(&event); |
177 if (imEvent->commitString().size() > 0) { |
176 if (imEvent->commitString().size() > 0) { |
178 d->mPreEditString = QString(); |
177 d->mPreEditString.clear(); |
179 } else { |
178 } else { |
180 d->mPreEditString = imEvent->preeditString(); |
179 d->mPreEditString = imEvent->preeditString(); |
181 } |
180 } |
182 } |
181 } |
183 |
182 |
191 */ |
190 */ |
192 QVariant HbInputFocusObject::inputMethodQuery(Qt::InputMethodQuery query) const |
191 QVariant HbInputFocusObject::inputMethodQuery(Qt::InputMethodQuery query) const |
193 { |
192 { |
194 Q_D(const HbInputFocusObject); |
193 Q_D(const HbInputFocusObject); |
195 |
194 |
196 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
195 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
197 if (graphicsObject && graphicsObject->scene()) { |
196 if (graphicsObject && graphicsObject->scene()) { |
198 return graphicsObject->scene()->inputMethodQuery(query); |
197 return graphicsObject->scene()->inputMethodQuery(query); |
199 } |
198 } |
200 |
199 |
201 // check if QWidget is embedded as a proxy in scene. If yes try to get details |
200 // check if QWidget is embedded as a proxy in scene. If yes try to get details |
202 // from the scene. |
201 // from the scene. |
203 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
202 QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject); |
204 QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget); |
203 QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget); |
205 if (pw && pw->scene()) { |
204 if (pw && pw->scene()) { |
206 return pw->scene()->inputMethodQuery(query); |
205 return pw->scene()->inputMethodQuery(query); |
207 } |
206 } |
208 |
207 |
209 if (widget) { |
208 if (widget) { |
210 // QWidget returns microfocus in local coordinate. |
209 // QWidget returns microfocus in local coordinate. |
211 // we need to map it to global coordinate. |
210 // we need to map it to global coordinate. |
212 QVariant v = widget->inputMethodQuery(query); |
211 QVariant v = widget->inputMethodQuery(query); |
213 if (v.type() == QVariant::Rect) { |
212 if (v.type() == QVariant::Rect) { |
282 */ |
281 */ |
283 void HbInputFocusObject::releaseFocus() |
282 void HbInputFocusObject::releaseFocus() |
284 { |
283 { |
285 Q_D(HbInputFocusObject); |
284 Q_D(HbInputFocusObject); |
286 |
285 |
287 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
286 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
288 if (!graphicsObject) { |
287 if (!graphicsObject) { |
289 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
288 QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject); |
290 if (widget) { |
289 if (widget) { |
291 if (!(graphicsObject = HbInputUtils::graphicsProxyWidget(widget))) { |
290 if (!(graphicsObject = HbInputUtils::graphicsProxyWidget(widget))) { |
292 widget->clearFocus(); |
291 widget->clearFocus(); |
293 return; |
292 return; |
294 } |
293 } |
338 */ |
337 */ |
339 QRectF HbInputFocusObject::editorGeometry() const |
338 QRectF HbInputFocusObject::editorGeometry() const |
340 { |
339 { |
341 Q_D(const HbInputFocusObject); |
340 Q_D(const HbInputFocusObject); |
342 |
341 |
343 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
342 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
344 if (!graphicsObject) { |
343 if (!graphicsObject) { |
345 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
344 QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject); |
346 if (widget) { |
345 if (widget) { |
347 // check if widget is inside a proxy. |
346 // check if widget is inside a proxy. |
348 QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget); |
347 QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(widget); |
349 if (pw) { |
348 if (pw) { |
350 // check if we are pointing to the toplevel |
349 // check if we are pointing to the toplevel |
351 // proxy widget, if not then we must check for |
350 // proxy widget, if not then we must check for |
352 // the widgets window and see if it is a proxy. |
351 // the widgets window and see if it is a proxy. |
353 if (pw->widget() == widget) { |
352 if (pw->widget() == widget) { |
354 graphicsObject = pw; |
353 graphicsObject = pw; |
355 } else if (pw->widget() == widget->window()) { |
354 } else if (pw->widget() == widget->window()) { |
356 // focused object is not a proxy but it is |
355 // focused object is not a proxy but it is |
357 // inside a proxy, query to proxy about |
356 // inside a proxy, query to proxy about |
358 // the focused objects rect. |
357 // the focused objects rect. |
359 QRectF rect = pw->subWidgetRect(widget); |
358 QRectF rect = pw->subWidgetRect(widget); |
360 rect.translate(pw->scenePos()); |
359 rect.translate(pw->scenePos()); |
361 return rect; |
360 return rect; |
428 */ |
427 */ |
429 Qt::InputMethodHints HbInputFocusObject::inputMethodHints() const |
428 Qt::InputMethodHints HbInputFocusObject::inputMethodHints() const |
430 { |
429 { |
431 Q_D(const HbInputFocusObject); |
430 Q_D(const HbInputFocusObject); |
432 |
431 |
433 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
432 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
434 if (graphicsObject) { |
433 if (graphicsObject) { |
435 return graphicsObject->inputMethodHints(); |
434 return graphicsObject->inputMethodHints(); |
436 } |
435 } |
437 |
436 |
438 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
437 QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject); |
439 if (widget) { |
438 if (widget) { |
440 return widget->inputMethodHints(); |
439 return widget->inputMethodHints(); |
441 } |
440 } |
442 |
441 |
443 return Qt::ImhNone; |
442 return Qt::ImhNone; |
448 */ |
447 */ |
449 void HbInputFocusObject::setInputMethodHints(Qt::InputMethodHints hints) |
448 void HbInputFocusObject::setInputMethodHints(Qt::InputMethodHints hints) |
450 { |
449 { |
451 Q_D(HbInputFocusObject); |
450 Q_D(HbInputFocusObject); |
452 |
451 |
453 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
452 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
454 if (graphicsObject) { |
453 if (graphicsObject) { |
455 graphicsObject->setInputMethodHints(hints); |
454 graphicsObject->setInputMethodHints(hints); |
456 return; |
455 return; |
457 } |
456 } |
458 |
457 |
459 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
458 QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject); |
460 if (widget) { |
459 if (widget) { |
461 widget->setInputMethodHints(hints); |
460 widget->setInputMethodHints(hints); |
462 } |
461 } |
463 } |
462 } |
464 |
463 |
465 /*! |
464 /*! |
466 A convenience method for filtering strings. Uses filter attached to connected editor |
465 A convenience method for filtering strings. Uses filter attached to connected editor |
467 and filters given string with it. |
466 and filters given string with it. |
468 */ |
467 */ |
469 void HbInputFocusObject::filterStringWithEditorFilter(const QString& source, QString& result) |
468 void HbInputFocusObject::filterStringWithEditorFilter(const QString &source, QString &result) |
470 { |
469 { |
471 QString intermediate = source; |
470 QString intermediate = source; |
472 |
471 |
473 // Chained two-pass filtering because this can be case-constrained editor with a filter. |
472 // Chained two-pass filtering because this can be case-constrained editor with a filter. |
474 Qt::InputMethodHints hints = inputMethodHints(); |
473 Qt::InputMethodHints hints = inputMethodHints(); |
521 */ |
520 */ |
522 QPointF HbInputFocusObject::scenePos() const |
521 QPointF HbInputFocusObject::scenePos() const |
523 { |
522 { |
524 Q_D(const HbInputFocusObject); |
523 Q_D(const HbInputFocusObject); |
525 |
524 |
526 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
525 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
527 if (graphicsObject) { |
526 if (graphicsObject) { |
528 return graphicsObject->scenePos(); |
527 return graphicsObject->scenePos(); |
529 } |
528 } |
530 |
529 |
531 QWidget *w = qobject_cast<QWidget*>(d->mFocusedObject); |
530 QWidget *w = qobject_cast<QWidget *>(d->mFocusedObject); |
532 // check if widget is inside a proxy. |
531 // check if widget is inside a proxy. |
533 QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(w); |
532 QGraphicsProxyWidget *pw = HbInputUtils::graphicsProxyWidget(w); |
534 if (pw) { |
533 if (pw) { |
535 // check if we are pointing to the toplevel |
534 // check if we are pointing to the toplevel |
536 // proxy widget, if not then we must check for |
535 // proxy widget, if not then we must check for |
544 } |
543 } |
545 } |
544 } |
546 |
545 |
547 if (w) { |
546 if (w) { |
548 // not a proxy.. Meaning widget is inside a QWidget window. |
547 // not a proxy.. Meaning widget is inside a QWidget window. |
549 return w->mapToGlobal(QPoint(0,0)); |
548 return w->mapToGlobal(QPoint(0, 0)); |
550 } |
549 } |
551 |
550 |
552 return QPointF(0.0, 0.0); |
551 return QPointF(0.0, 0.0); |
553 } |
552 } |
554 |
553 |
555 /*! |
554 /*! |
556 Returns true if all the characters in given string are allowed in active editor. |
555 Returns true if all the characters in given string are allowed in active editor. |
557 */ |
556 */ |
558 bool HbInputFocusObject::stringAllowedInEditor(const QString& string) const |
557 bool HbInputFocusObject::stringAllowedInEditor(const QString &string) const |
559 { |
558 { |
560 // Two pass filtering. This can be a case constrained editor with a filter. |
559 // Two pass filtering. This can be a case constrained editor with a filter. |
561 Qt::InputMethodHints hints; |
560 Qt::InputMethodHints hints; |
562 if (hints & Qt::ImhLowercaseOnly) { |
561 if (hints & Qt::ImhLowercaseOnly) { |
563 QString outStr; |
562 QString outStr; |
586 /*! |
585 /*! |
587 Commits given smiley. |
586 Commits given smiley. |
588 */ |
587 */ |
589 void HbInputFocusObject::commitSmiley(QString smiley) |
588 void HbInputFocusObject::commitSmiley(QString smiley) |
590 { |
589 { |
591 Q_D(HbInputFocusObject); |
590 Q_D(HbInputFocusObject); |
592 |
591 |
593 if (d->mFocusedObject) { |
592 if (d->mFocusedObject) { |
594 d->mFocusedObject->setProperty("SmileyIcon", smiley); |
593 d->mFocusedObject->setProperty("SmileyIcon", smiley); |
595 } |
594 } |
596 } |
595 } |
597 |
596 |
598 /*! |
597 /*! |
599 Returns the editor widget as QObject. |
598 Returns the editor widget as QObject. |
600 */ |
599 */ |
609 only for known editor types. |
608 only for known editor types. |
610 */ |
609 */ |
611 bool HbInputFocusObject::isReadOnlyWidget(QObject *editorObject) |
610 bool HbInputFocusObject::isReadOnlyWidget(QObject *editorObject) |
612 { |
611 { |
613 if (editorObject) { |
612 if (editorObject) { |
614 QWidget *widget = qobject_cast<QWidget*>(editorObject); |
613 QWidget *widget = qobject_cast<QWidget *>(editorObject); |
615 if (widget) { |
614 if (widget) { |
616 if (!widget->testAttribute(Qt::WA_InputMethodEnabled)) { |
615 if (!widget->testAttribute(Qt::WA_InputMethodEnabled)) { |
617 return true; |
616 return true; |
618 } |
617 } |
619 |
618 |
620 QLineEdit *lineEdit = qobject_cast<QLineEdit*>(widget); |
619 QLineEdit *lineEdit = qobject_cast<QLineEdit *>(widget); |
621 if (lineEdit) { |
620 if (lineEdit) { |
622 return lineEdit->isReadOnly(); |
621 return lineEdit->isReadOnly(); |
623 } |
622 } |
624 |
623 |
625 QTextEdit *textEdit = qobject_cast<QTextEdit*>(widget); |
624 QTextEdit *textEdit = qobject_cast<QTextEdit *>(widget); |
626 if (textEdit) { |
625 if (textEdit) { |
627 return textEdit->isReadOnly(); |
626 return textEdit->isReadOnly(); |
628 } |
627 } |
629 |
628 |
630 return false; |
629 return false; |
631 } else { |
630 } else { |
632 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(editorObject); |
631 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(editorObject); |
633 if (graphicsObject) { |
632 if (graphicsObject) { |
634 if (!(graphicsObject->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { |
633 if (!(graphicsObject->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { |
635 return true; |
634 return true; |
636 } |
635 } |
637 } |
636 } |
670 */ |
669 */ |
671 void HbInputFocusObject::setFocus() |
670 void HbInputFocusObject::setFocus() |
672 { |
671 { |
673 Q_D(HbInputFocusObject); |
672 Q_D(HbInputFocusObject); |
674 |
673 |
675 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject*>(d->mFocusedObject); |
674 QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(d->mFocusedObject); |
676 if (graphicsObject && graphicsObject->scene()) { |
675 if (graphicsObject && graphicsObject->scene()) { |
677 graphicsObject->scene()->setFocusItem(graphicsObject); |
676 graphicsObject->scene()->setFocusItem(graphicsObject); |
678 } else { |
677 } else { |
679 QWidget *widget = qobject_cast<QWidget*>(d->mFocusedObject); |
678 QWidget *widget = qobject_cast<QWidget *>(d->mFocusedObject); |
680 if (widget) { |
679 if (widget) { |
681 widget->setFocus(); |
680 widget->setFocus(); |
682 } |
681 } |
683 } |
682 } |
684 } |
683 } |