33 #include "hbinputsettingproxy.h" |
33 #include "hbinputsettingproxy.h" |
34 #include "hbinputcontextproxy_p.h" |
34 #include "hbinputcontextproxy_p.h" |
35 #include "hbinputfilter.h" |
35 #include "hbinputfilter.h" |
36 #include "hbinputmethodnull_p.h" |
36 #include "hbinputmethodnull_p.h" |
37 #include "hbinputpredictionfactory.h" |
37 #include "hbinputpredictionfactory.h" |
|
38 #include "hbinputextradictionaryfactory.h" |
38 #include "hbinputstandardfilters.h" |
39 #include "hbinputstandardfilters.h" |
39 #include "hbinpututils.h" |
40 #include "hbinpututils.h" |
40 #include "hbinputvkbhost.h" |
41 #include "hbinputvkbhost.h" |
41 |
42 |
42 /*! |
43 /*! |
44 @hbcore |
45 @hbcore |
45 \class HbInputMethod |
46 \class HbInputMethod |
46 \brief A base class for input method implementations. |
47 \brief A base class for input method implementations. |
47 |
48 |
48 HbInputMethod is the base class for input method implementations. It inherits from QInputContext, |
49 HbInputMethod is the base class for input method implementations. It inherits from QInputContext, |
49 connects to the input framework behind the scenes and provides focusing and other framework level |
50 connects to the input framework behind the scenes and resolves correct input state handler when |
50 services. |
51 an editor widget is focused. |
51 |
52 |
52 An internal framework class called HbInputModeCache scans through the system and looks for available HbInputMethod instances. It then forms a list of available input methods based on language |
53 An internal framework class called HbInputModeCache scans through the system and looks for |
53 and keyboard type. Input method plugin reports (on plugin level, as meta-data) which languages, keyboards and input modes that input method instance supports. Input mode cache then activates suitable |
54 available HbInputMethod instances. It then forms a list of input methods based on language |
54 input method depending on the situation. It can also switch active input method on the fly |
55 and keyboard type. Input method plugin reports (as plugin meta-data) which languages, |
55 when the focus switches between editors and the previously active input method is unable to |
56 keyboards and input modes that plugin instance implements. Input mode cache then activates matching |
|
57 HbInputMethod depending on the editor properties. It switches the active input method on the fly |
|
58 when the focus switches between editors if the previous input method is unable to |
56 support newly focused editor. |
59 support newly focused editor. |
57 |
60 |
58 Custom input methods are a special class of input methods. Once a custom input method is |
61 Custom input methods are a special class of input methods. Once a custom input method is |
59 activated from UI, input mode cache stops resolving suitable input methods upon focus operations |
62 activated from UI, input mode cache stops resolving input methods upon focus operations |
60 and the custom input is ative in all editors until it is deactivated. |
63 and the custom input is active in all editors until it is deactivated. |
61 |
64 |
62 Following is the basic input framework program flow: |
65 Following is the basic input framework program flow: |
63 |
66 |
64 1. An editor gains input focus. |
67 1. An editor gains input focus. |
65 2 Input mode cache resolves correct mode handler and activates it. |
68 2 Input mode cache resolves correct mode handler and activates it. |
66 3. A virtual function HbInputMethod::focusReceived is called. At this point the input method |
69 3. A virtual function HbInputMethod::focusReceived is called. At this point the input method |
67 initializes whatever it needs to initialize in order to start the input operation (for example, |
70 initializes whatever it needs to initialize in order to start the input operation (for example, |
68 opens the virtual keyboard by using HbVkbHost API) and waits for user actions. |
71 opens the virtual keyboard by using HbVkbHost API) and waits for user actions. |
69 4. Text is written. The input method delivers results to the editor buffer by using HbInputFocusObject API. |
72 4. Text is written. The input method delivers results to the editor buffer by using HbInputFocusObject API. |
70 It can access editor attributes via HbEditorInterface API. |
73 It can access editor attributes via HbEditorInterface API. |
71 5. The active editor loses focus. At this point the input method receives a call to virtual function |
74 5. The active editor loses focus. At this point the input method receives a call to virtual function |
72 HbInputMethod::focusLost and is expected to conclude any ongoing input operations and shut down active |
75 HbInputMethod::focusLost and is expected to conclude any ongoing input operations and shut down active |
73 UI elements (such as the virtual keyboard). |
76 UI elements (such as the virtual keyboard). |
74 6. The input method waits for next focusReceived() call. |
77 6. The input method waits for next focusReceived() call. |
75 |
78 |
76 \sa QInputContext |
79 \sa QInputContext |
77 \sa HbInputFocusObject |
80 \sa HbInputFocusObject |
78 \sa HbEditorInterface |
81 \sa HbEditorInterface |
96 |
99 |
97 delete d_ptr; |
100 delete d_ptr; |
98 } |
101 } |
99 |
102 |
100 /*! |
103 /*! |
101 Initializes the HbInputs framework. Each Qt application needs to call this |
104 Initializes the input framework. |
102 method once in order to connect to the HbInputs framework. |
|
103 */ |
105 */ |
104 bool HbInputMethod::initializeFramework(QApplication& app) |
106 bool HbInputMethod::initializeFramework(QApplication& app) |
105 { |
107 { |
106 // Activate singleton shutdown. |
108 // Activate singleton shutdown. |
107 connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown())); |
109 connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown())); |
108 connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown())); |
110 connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown())); |
109 connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown())); |
111 connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown())); |
|
112 connect(&app, SIGNAL(aboutToQuit()), HbExtraDictionaryFactory::instance(), SLOT(shutdown())); |
110 |
113 |
111 HbInputMethod *master = HbInputMethodNull::Instance(); |
114 HbInputMethod *master = HbInputMethodNull::Instance(); |
112 |
115 |
113 if (!master) { |
116 if (!master) { |
114 return false; |
117 return false; |
122 |
125 |
123 return true; |
126 return true; |
124 } |
127 } |
125 |
128 |
126 /*! |
129 /*! |
127 Returns active instance of HbInputMethod. There is always active HbInputMethod instance after |
130 Returns the active instance of HbInputMethod. There is always active HbInputMethod instance after |
128 InitializeFramework method has been called, even when there is no focused editor (in some cases it may |
131 InitializeFramework method has been called, even when there is no focused editor (in some cases it may |
129 be so called null input method). Normally this method is needed only for special cases, such as developing |
132 be so called null input method). |
130 and debugging framework level code, but it is made public for convenience. |
|
131 */ |
133 */ |
132 HbInputMethod* HbInputMethod::activeInputMethod() |
134 HbInputMethod* HbInputMethod::activeInputMethod() |
133 { |
135 { |
134 // First try, try app input context directly. It is possible that it is an instance |
136 // First try, try app input context directly. It is possible that it is an instance |
135 // of HbInputMethod that is installed directly there without framework knowing about it |
137 // of HbInputMethod that is installed directly there without framework knowing about it |
185 } |
187 } |
186 |
188 |
187 return false; |
189 return false; |
188 } |
190 } |
189 |
191 |
190 |
|
191 /*! |
192 /*! |
192 This slot is called when the input language changes. The framework connects it |
193 This slot is called when the input language changes. The framework connects it |
193 to the input setting proxy. When the signal is received, the input method implementation |
194 to the input setting proxy. When the signal is received, the input method implementation |
194 is notified by calling inputLanguageChanged. |
195 is notified by calling inputLanguageChanged. |
195 |
196 |
196 \sa inputLanguageChanged |
197 \sa inputLanguageChanged |
197 \sa HbInputSettingProxy |
198 \sa HbInputSettingProxy |
198 */ |
199 */ |
199 void HbInputMethod::globalInputLanguageChanged(const HbInputLanguage &newLanguage) |
200 void HbInputMethod::globalInputLanguageChanged(const HbInputLanguage &newLanguage) |
200 { |
201 { |
201 Q_D(HbInputMethod); |
202 Q_D(HbInputMethod); |
202 |
203 |
203 inputLanguageChanged(newLanguage); |
204 inputLanguageChanged(newLanguage); |
204 |
205 |
205 if (!isActiveMethod()) { |
206 if (!isActiveMethod()) { |
206 // Notify non-active input methods of language change, but check |
207 // Notify non-active input methods of language change, but check |
207 // if the method has promised to handle the new language only |
208 // if the method has promised to handle the new language only |
208 // in the active method |
209 // in the active method |
209 return; |
210 return; |
210 } |
211 } |
211 |
212 |
212 // Just behave as if this was the first focus operation |
213 // Just behave as if this was the first focus operation |
213 // to this editor. |
214 // to this editor. |
214 if (d->mFocusObject) { |
215 if (d->mFocusObject) { |
215 HbInputState state; |
216 HbInputState state; |
216 editorRootState(state); |
217 editorRootState(state); |
217 activateState(state); |
218 activateState(state); |
218 } |
219 } |
219 } |
220 } |
220 |
221 |
221 /*! |
222 /*! |
224 is notified by calling secondaryInputLanguageChanged. |
225 is notified by calling secondaryInputLanguageChanged. |
225 |
226 |
226 \sa secondaryInputLanguageChanged |
227 \sa secondaryInputLanguageChanged |
227 \sa HbInputSettingProxy |
228 \sa HbInputSettingProxy |
228 */ |
229 */ |
229 void HbInputMethod::globalSecondaryInputLanguageChanged(const HbInputLanguage &aNewLanguage) |
230 void HbInputMethod::globalSecondaryInputLanguageChanged(const HbInputLanguage &newLanguage) |
230 { |
231 { |
231 secondaryInputLanguageChanged(aNewLanguage); |
232 secondaryInputLanguageChanged(newLanguage); |
232 } |
233 } |
233 |
234 |
234 /*! |
235 /*! |
235 This slot is connected to the setting proxy hw keyboard attribute. It will |
236 \deprecated HbInputMethod::activeHwKeyboardChanged(HbKeyboardType) |
236 do refreshState() when the signal is received. |
237 is deprecated. |
237 */ |
238 */ |
238 void HbInputMethod::activeHwKeyboardChanged(HbKeyboardType newKeyboard) |
239 void HbInputMethod::activeHwKeyboardChanged(HbKeyboardType newKeyboard) |
239 { |
240 { |
240 Q_UNUSED(newKeyboard); |
241 Q_UNUSED(newKeyboard); |
241 Q_D(HbInputMethod); |
242 Q_D(HbInputMethod); |
268 if (!isActiveMethod()) { |
268 if (!isActiveMethod()) { |
269 return; |
269 return; |
270 } |
270 } |
271 Q_D(HbInputMethod); |
271 Q_D(HbInputMethod); |
272 d->mInputState.setKeyboard(newKeyboard); |
272 d->mInputState.setKeyboard(newKeyboard); |
273 HbInputMethod* stateHandler = d->findStateHandler(d->mInputState); |
273 HbInputMethod* stateHandler = d->findStateHandler(d->mInputState); |
274 if (stateHandler) { |
274 if (stateHandler) { |
275 d->inputStateToEditor(d->mInputState); |
275 d->inputStateToEditor(d->mInputState); |
276 if (stateHandler != this) { |
276 if (stateHandler != this) { |
277 // Context switch needed. |
277 // Context switch needed. |
278 d->contextSwitch(stateHandler); |
278 d->contextSwitch(stateHandler); |
282 } |
282 } |
283 } |
283 } |
284 } |
284 } |
285 |
285 |
286 /*! |
286 /*! |
287 This slot is called when the predictive input state changes. The framework connects it |
287 \deprecated HbInputMethod::predictiveInputStateChanged(int newStatus) |
288 to the input setting proxy. When the signal is received, the input method implementation |
288 is deprecated. |
289 is notified by calling predictiveInputStatusChanged. |
|
290 |
|
291 \sa predictiveInputStatusChanged |
|
292 \sa HbInputSettingProxy |
|
293 */ |
289 */ |
294 void HbInputMethod::predictiveInputStateChanged(int newStatus) |
290 void HbInputMethod::predictiveInputStateChanged(int newStatus) |
295 { |
291 { |
296 // Do here whatever needs to be done on HbInputMethod level, then |
292 Q_UNUSED(newStatus); |
297 // call virtual predictiveInputStatusChanged() in case plugin needs to do something. |
293 } |
298 // ... |
294 |
299 |
295 /*! |
300 predictiveInputStatusChanged(newStatus); |
296 \deprecated HbInputMethod::predictiveInputStateChanged(HbKeyboardSettingFlags, bool) |
|
297 is deprecated. |
|
298 */ |
|
299 void HbInputMethod::predictiveInputStateChanged(HbKeyboardSettingFlags keyboardType, bool newState) |
|
300 { |
|
301 Q_UNUSED(keyboardType); |
|
302 Q_UNUSED(newState); |
301 } |
303 } |
302 |
304 |
303 /*! |
305 /*! |
304 The framework calls this method when an input capable widget receives UI focus. This is empty |
306 The framework calls this method when an input capable widget receives UI focus. This is empty |
305 default implementation and the inheriting class should override it. |
307 default implementation and the inheriting class should override it. |
452 } |
452 } |
453 |
453 |
454 /*! |
454 /*! |
455 Graphics item based editors (or any other object that implements |
455 Graphics item based editors (or any other object that implements |
456 HbInputFocusObject) send their focus events notifications through this method. |
456 HbInputFocusObject) send their focus events notifications through this method. |
457 Since Qt's QInputContext mechanism works only with QWidget based editors, |
457 |
458 this alternate focus channel is needed for objects belonging to a graphics scene |
458 Typically this method is called by HbInputContextProxy when it receives |
459 (in case of a graphics scene, the topmost QWidget that has focus is |
459 requestSoftwareInputPanel event. |
460 graphics view, not the the object inside the view). The ownership of |
|
461 incoming focus object is transferred to the input framework. |
|
462 |
460 |
463 \sa setFocusWidget |
461 \sa setFocusWidget |
464 \sa HbInputFocusObject |
462 \sa HbInputFocusObject |
465 */ |
463 */ |
466 void HbInputMethod::setFocusObject(HbInputFocusObject* focusObject) |
464 void HbInputMethod::setFocusObject(HbInputFocusObject* focusObject) |
526 } |
524 } |
527 } |
525 } |
528 } |
526 } |
529 |
527 |
530 /*! |
528 /*! |
531 The secondary channel uses this slot for inserting text active editor. |
529 \deprecated HbInputMethod::receiveText(const QString&) |
|
530 is deprecated. |
532 */ |
531 */ |
533 void HbInputMethod::receiveText(const QString& string) |
532 void HbInputMethod::receiveText(const QString& string) |
534 { |
533 { |
535 Q_D(HbInputMethod); |
534 Q_UNUSED(string); |
536 |
535 } |
537 if (isActiveMethod() && d->mFocusObject && |
536 |
538 (d->editorConstraints() & HbEditorConstraintsNoSecondaryChannel) == 0) { |
537 /*! |
539 QList<QInputMethodEvent::Attribute> list; |
538 \deprecated HbInputMethod::candidatePopupClosed(int closingKey) |
540 QInputMethodEvent event(QString(), list); |
539 is deprecated. |
541 event.setCommitString(string); |
|
542 d->mFocusObject->sendEvent(event); |
|
543 } |
|
544 } |
|
545 |
|
546 /*! |
|
547 This slot is called when the candidate list popup is closed. The base |
|
548 class implementation is empty so any input method interested in |
|
549 candidate list close event should implement it. |
|
550 */ |
540 */ |
551 void HbInputMethod::candidatePopupClosed(int closingKey) |
541 void HbInputMethod::candidatePopupClosed(int closingKey) |
552 { |
542 { |
553 Q_UNUSED(closingKey); |
543 Q_UNUSED(closingKey); |
554 // Empty default implementation |
544 // Empty default implementation |
679 stateHandler = HbInputMethodNull::Instance(); |
668 stateHandler = HbInputMethodNull::Instance(); |
680 } |
669 } |
681 |
670 |
682 d->mInputState = state; |
671 d->mInputState = state; |
683 |
672 |
684 if (stateHandler != this) { |
673 if (stateHandler != this) { |
685 stateHandler->d_ptr->mStateChangeInProgress = true; |
674 stateHandler->d_ptr->mStateChangeInProgress = true; |
686 // Context switch needed. |
675 // Context switch needed. |
687 d->inputStateToEditor(d->mInputState); |
676 d->inputStateToEditor(d->mInputState); |
688 d->contextSwitch(stateHandler); |
677 d->contextSwitch(stateHandler); |
689 stateHandler->d_ptr->mStateChangeInProgress = false; |
678 stateHandler->d_ptr->mStateChangeInProgress = false; |
690 } else { |
679 } else { |
691 // Same method handles new state, just report the state change. |
680 // Same method handles new state, just report the state change. |
692 d->inputStateToEditor(d->mInputState); |
681 d->inputStateToEditor(d->mInputState); |
693 inputStateActivated(d->mInputState); |
682 inputStateActivated(d->mInputState); |
694 } |
683 } |
695 |
684 |
841 |
829 |
842 if (active) { |
830 if (active) { |
843 active->focusLost(false); |
831 active->focusLost(false); |
844 active->releaseFocus(); |
832 active->releaseFocus(); |
845 delete active->d_ptr->mFocusObject; |
833 delete active->d_ptr->mFocusObject; |
846 active->d_ptr->mFocusObject = 0; |
834 active->d_ptr->mFocusObject = 0; |
847 } |
835 } |
848 } |
836 } |
849 |
837 |
850 /*! |
838 /*! |
851 Wrapper |
839 Wrapper. |
852 */ |
840 */ |
853 bool HbInputMethod::automaticTextCaseNeeded() const |
841 bool HbInputMethod::automaticTextCaseNeeded() const |
854 { |
842 { |
855 Q_D(const HbInputMethod); |
843 Q_D(const HbInputMethod); |
856 return d->automaticTextCaseNeeded(); |
844 return d->automaticTextCaseNeeded(); |
857 } |
845 } |
858 |
846 |
859 /*! |
847 /*! |
860 Wrapper |
848 Deep copies the input state back to editor interface. |
861 */ |
849 */ |
862 void HbInputMethod::inputStateToEditor(const HbInputState& source) |
850 void HbInputMethod::inputStateToEditor(const HbInputState& source) |
863 { |
851 { |
864 Q_D(HbInputMethod); |
852 Q_D(HbInputMethod); |
865 d->inputStateToEditor(source); |
853 d->inputStateToEditor(source); |