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 } |