41 #include "hbinpututils.h" |
41 #include "hbinpututils.h" |
42 #include "hbinputvkbhost.h" |
42 #include "hbinputvkbhost.h" |
43 #include "hbinputvkbhostbridge.h" |
43 #include "hbinputvkbhostbridge.h" |
44 |
44 |
45 /*! |
45 /*! |
46 @alpha |
46 @stable |
47 @hbcore |
47 @hbcore |
48 \class HbInputMethod |
48 \class HbInputMethod |
49 \brief A base class for input method implementations. |
49 \brief A base class for input method implementations. |
50 |
50 |
51 HbInputMethod is the base class for input method implementations. It inherits from QInputContext, |
51 HbInputMethod is the base class for input method implementations. It inherits from QInputContext, |
187 connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown())); |
187 connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown())); |
188 connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown())); |
188 connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown())); |
189 connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown())); |
189 connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown())); |
190 connect(&app, SIGNAL(aboutToQuit()), HbExtraDictionaryFactory::instance(), SLOT(shutdown())); |
190 connect(&app, SIGNAL(aboutToQuit()), HbExtraDictionaryFactory::instance(), SLOT(shutdown())); |
191 |
191 |
192 HbInputMethod *master = HbInputMethodNull::Instance(); |
192 HbInputMethodNull *master = HbInputMethodNull::Instance(); |
193 |
193 |
194 if (!master) { |
194 if (!master) { |
195 return false; |
195 return false; |
196 } |
196 } |
197 |
197 |
201 QInputContext *proxy = master->d_ptr->proxy(); |
201 QInputContext *proxy = master->d_ptr->proxy(); |
202 // A check required so that Qt does not delete inputcontext |
202 // A check required so that Qt does not delete inputcontext |
203 // which we are passing. |
203 // which we are passing. |
204 if (proxy != app.inputContext()) { |
204 if (proxy != app.inputContext()) { |
205 app.setInputContext(proxy); |
205 app.setInputContext(proxy); |
|
206 } |
|
207 |
|
208 if (master->delayedPanelRequest()) { |
|
209 master->setDelayedPanelRequest(false); |
|
210 QInputContext* ic = qApp->inputContext(); |
|
211 if (ic) { |
|
212 QEvent *openEvent = new QEvent(QEvent::RequestSoftwareInputPanel); |
|
213 ic->filterEvent(openEvent); |
|
214 delete openEvent; |
|
215 } |
206 } |
216 } |
207 |
217 |
208 return true; |
218 return true; |
209 } |
219 } |
210 |
220 |
326 { |
336 { |
327 secondaryInputLanguageChanged(newLanguage); |
337 secondaryInputLanguageChanged(newLanguage); |
328 } |
338 } |
329 |
339 |
330 /*! |
340 /*! |
331 This slot is connected to the setting proxy activeKeyboard attribute. It will |
341 \deprecated HbInputMethod::activeKeyboardChanged(HbKeyboardType) |
332 activate proper state when the signal is received. |
342 is deprecated. No need to call this outside of framework. |
333 */ |
343 */ |
334 void HbInputMethod::activeKeyboardChanged(HbKeyboardType newKeyboard) |
344 void HbInputMethod::activeKeyboardChanged(HbKeyboardType newKeyboard) |
335 { |
345 { |
336 if (!isActiveMethod() || !HbInputSettingProxy::instance()->orientationChangeCompleted()) { |
346 Q_UNUSED(newKeyboard); |
337 return; |
|
338 } |
|
339 |
|
340 Q_D(HbInputMethod); |
|
341 |
|
342 d->mInputState.setKeyboard(newKeyboard); |
|
343 HbInputMethod *stateHandler = d->findStateHandler(d->mInputState); |
|
344 if (stateHandler) { |
|
345 d->inputStateToEditor(d->mInputState); |
|
346 if (stateHandler != this) { |
|
347 // Context switch needed. |
|
348 d->contextSwitch(stateHandler); |
|
349 } else { |
|
350 // Same method handles new state, just report the state change. |
|
351 inputStateActivated(d->mInputState); |
|
352 } |
|
353 } |
|
354 } |
347 } |
355 |
348 |
356 /*! |
349 /*! |
357 The framework calls this method when an input capable widget receives UI focus. This is empty |
350 The framework calls this method when an input capable widget receives UI focus. This is empty |
358 default implementation and the inheriting class should override it. |
351 default implementation and the inheriting class should override it. |
411 } |
404 } |
412 } |
405 } |
413 |
406 |
414 // Losing focus. |
407 // Losing focus. |
415 if (d->mFocusObject && unfocus) { |
408 if (d->mFocusObject && unfocus) { |
416 focusLost(false); |
409 bool isNextFocusToEditor = false; |
417 d->hideMainWindow(); |
410 //The Qt framework sets the focused widget twice as and when there is a change |
|
411 //of focus. First time it sets the focus to NULL and second time it sets the focus |
|
412 //to the actual widget. But, we need to know if there is a focus switch to an editor |
|
413 //And we do a focusLost(false) only if the current focused widget is NULL. |
|
414 QWidget *newFocusedWidget = QApplication::focusWidget(); |
|
415 if (newFocusedWidget && newFocusedWidget->testAttribute(Qt::WA_InputMethodEnabled)) { |
|
416 if (newFocusedWidget->testAttribute(Qt::WA_WState_Created) |
|
417 && newFocusedWidget->isEnabled()) { |
|
418 isNextFocusToEditor = true; |
|
419 } |
|
420 } |
|
421 // inform plugin about the focus shift. |
|
422 focusLost(isNextFocusToEditor); |
|
423 // hide mainwindow only incase qApp has focus on a non-editor field. |
|
424 if (!isNextFocusToEditor) |
|
425 d->hideMainWindow(); |
|
426 |
418 delete d->mFocusObject; |
427 delete d->mFocusObject; |
419 d->mFocusObject = 0; |
428 d->mFocusObject = 0; |
|
429 d->proxy()->QInputContext::setFocusWidget(0); |
420 } |
430 } |
421 |
431 |
422 return; |
432 return; |
423 } |
433 } |
424 |
434 |
425 // attach focuswidget to prxoy inputcontext as proxy is |
435 // attach focuswidget to prxoy inputcontext as proxy is |
426 // the only inputcotext known to qt framework. |
436 // the only inputcotext known to qt framework. |
427 d->proxy()->QInputContext::setFocusWidget(widget); |
437 d->proxy()->QInputContext::setFocusWidget(widget); |
428 |
438 |
429 QGraphicsView *gView = qobject_cast<QGraphicsView *>(widget); |
439 QGraphicsView *gView = qobject_cast<QGraphicsView *>(widget); |
465 bool refreshHost = false; |
475 bool refreshHost = false; |
466 |
476 |
467 // Delete previous focus object. |
477 // Delete previous focus object. |
468 if (d->mFocusObject) { |
478 if (d->mFocusObject) { |
469 refreshHost = true; |
479 refreshHost = true; |
470 disconnect(d->mFocusObject, SIGNAL(editorDeleted()), this, SLOT(editorDeleted())); |
480 disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *))); |
471 } |
481 } |
472 delete d->mFocusObject; |
482 delete d->mFocusObject; |
473 d->mFocusObject = 0; |
483 d->mFocusObject = 0; |
474 |
484 |
475 // Attach focus. |
485 // Attach focus. |
476 d->mFocusObject = new HbInputFocusObject(widget); |
486 d->mFocusObject = d->createAndSetupFocusObject(widget); |
477 connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *))); |
487 connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *))); |
|
488 connect(d->mFocusObject, SIGNAL(aboutToChangeOrientation()), this, SLOT(_q_startOrientationSequence())); |
|
489 connect(d->mFocusObject, SIGNAL(orientationChanged()), this, SLOT(_q_endOrientationSequence())); |
478 |
490 |
479 d->setFocusCommon(); |
491 d->setFocusCommon(); |
480 |
492 |
481 // The focus jumped from one editor to another. Make sure that vkb host |
493 // The focus jumped from one editor to another. Make sure that vkb host |
482 // updates the situation correctly. |
494 // updates the situation correctly. |
494 */ |
506 */ |
495 void HbInputMethod::widgetDestroyed(QWidget *widget) |
507 void HbInputMethod::widgetDestroyed(QWidget *widget) |
496 { |
508 { |
497 Q_D(HbInputMethod); |
509 Q_D(HbInputMethod); |
498 |
510 |
499 if (d->mFocusObject && d->mFocusObject->object() == widget) { |
511 if (d->proxy()->focusWidget() == widget) { |
500 delete d->mFocusObject; |
512 delete d->mFocusObject; |
501 d->mFocusObject = 0; |
513 d->mFocusObject = 0; |
502 // passing to actual QInputContext which is attached to Qt framework. |
514 // update QInputContext internal focusWidget pointer. |
503 // which will internally set QInputContext::focusWidget to Null. |
|
504 d->proxy()->QInputContext::widgetDestroyed(widget); |
515 d->proxy()->QInputContext::widgetDestroyed(widget); |
505 d->proxy()->QInputContext::setFocusWidget(0); |
516 d->proxy()->QInputContext::setFocusWidget(0); |
506 } |
517 } |
507 } |
518 } |
508 |
519 |
554 } |
565 } |
555 |
566 |
556 // Attach focus. |
567 // Attach focus. |
557 d->mFocusObject = focusObject; |
568 d->mFocusObject = focusObject; |
558 connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *))); |
569 connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *))); |
|
570 connect(d->mFocusObject, SIGNAL(aboutToChangeOrientation()), this, SLOT(_q_startOrientationSequence())); |
|
571 connect(d->mFocusObject, SIGNAL(orientationChanged()), this, SLOT(_q_endOrientationSequence())); |
559 |
572 |
560 d->setFocusCommon(); |
573 d->setFocusCommon(); |
561 |
574 |
562 // The focus jumped from one editor to another. Make sure that vkb host |
575 // The focus jumped from one editor to another. Make sure that vkb host |
563 // updates the situation correctly. |
576 // updates the situation correctly. |
738 inputStateActivated(d->mInputState); |
751 inputStateActivated(d->mInputState); |
739 } |
752 } |
740 } |
753 } |
741 |
754 |
742 /*! |
755 /*! |
743 Receives the screen orientation signal. Will determine correct input state for new |
756 \deprecated HbInputMethod::orientationChanged(Qt::Orientation) |
744 orientation and find state handler for it. |
757 is deprecated. No need to call this from outside of the framework. |
745 */ |
758 */ |
746 void HbInputMethod::orientationChanged(Qt::Orientation orientation) |
759 void HbInputMethod::orientationChanged(Qt::Orientation orientation) |
747 { |
760 { |
748 Q_D(HbInputMethod); |
|
749 Q_UNUSED(orientation); |
761 Q_UNUSED(orientation); |
750 |
762 } |
751 if (d->mOldFocusObject) { |
763 |
752 setFocusObject(d->mOldFocusObject); |
764 /*! |
753 d->mOldFocusObject = 0; |
765 \deprecated HbInputMethod::orientationAboutToChange() |
754 } |
766 is deprecated. No need to call this from outside of the framework. |
755 |
|
756 } |
|
757 |
|
758 /*! |
|
759 This slot is connected to setting proxy's orientation change warning signal. The default |
|
760 base class implementation is empty. |
|
761 |
|
762 \sa HbInputSettingProxy |
|
763 */ |
767 */ |
764 void HbInputMethod::orientationAboutToChange() |
768 void HbInputMethod::orientationAboutToChange() |
765 { |
769 { |
766 Q_D(HbInputMethod); |
|
767 if(isActiveMethod()) { |
|
768 reset(); |
|
769 } |
|
770 d->inputStateToEditor(d->mInputState); |
|
771 if (d->mFocusObject) { |
|
772 d->mOldFocusObject = d->mFocusObject; |
|
773 d->mFocusObject = 0; |
|
774 } |
|
775 HbVkbHostBridge::instance()->closeKeypad(true); |
|
776 } |
770 } |
777 |
771 |
778 /*! |
772 /*! |
779 Returns active input language. Unlike setting proxy's global input language, |
773 Returns active input language. Unlike setting proxy's global input language, |
780 this method takes into account input state language and possible editor local language, |
774 this method takes into account input state language and possible editor local language, |
816 Q_D(HbInputMethod); |
810 Q_D(HbInputMethod); |
817 d->mFocusLocked = false; |
811 d->mFocusLocked = false; |
818 } |
812 } |
819 |
813 |
820 /*! |
814 /*! |
|
815 Returns true if focus is locked. If focus is locked, input framework will ignore |
|
816 all the incoming focus events completely until focus is unlocked. |
|
817 |
|
818 \sa lockFocus |
|
819 \sa unlockFocus |
|
820 */ |
|
821 bool HbInputMethod::isFocusLocked() |
|
822 { |
|
823 Q_D(HbInputMethod); |
|
824 return d->mFocusLocked; |
|
825 } |
|
826 |
|
827 /*! |
821 Removes input method focus and asks active input plugin to close its active UI-components |
828 Removes input method focus and asks active input plugin to close its active UI-components |
822 (such as touch keypads). This may be needed in some special cases where the underlying |
829 (such as touch keypads). This may be needed in some special cases where the underlying |
823 application wants to make sure that there are no input related elements on the screen. |
830 application wants to make sure that there are no input related elements on the screen. |
824 |
831 |
825 This is a if-all-else fails backup method. Same can be done by doing |
832 This is a if-all-else fails backup method. Same can be done by doing |
844 active->d_ptr->mFocusObject = 0; |
851 active->d_ptr->mFocusObject = 0; |
845 } |
852 } |
846 } |
853 } |
847 |
854 |
848 /*! |
855 /*! |
849 Wrapper. |
856 Returns true if automatic condititions for automatic upper case are met at |
|
857 current cursor position. Returns false if there isn't active editor. |
850 */ |
858 */ |
851 bool HbInputMethod::automaticTextCaseNeeded() const |
859 bool HbInputMethod::automaticTextCaseNeeded() const |
852 { |
860 { |
853 Q_D(const HbInputMethod); |
861 Q_D(const HbInputMethod); |
854 return d->automaticTextCaseNeeded(); |
862 return d->automaticTextCaseNeeded(); |