src/hbcore/inputfw/hbinputmethod.cpp
changeset 5 627c4a0fd0e7
parent 3 11d3954df52a
child 6 c3690ec91ef8
equal deleted inserted replaced
3:11d3954df52a 5:627c4a0fd0e7
    60 
    60 
    61 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
    62 activated from UI, input mode cache stops resolving input methods upon focus operations
    62 activated from UI, input mode cache stops resolving input methods upon focus operations
    63 and the custom input is active in all editors until it is deactivated.
    63 and the custom input is active in all editors until it is deactivated.
    64 
    64 
    65 Following is the basic input framework program flow:
    65 \bold The input framework program flow
    66 
    66 
    67 1. An editor gains input focus.
    67 1. An editor gains input focus.<BR>
    68 2  Input mode cache resolves correct mode handler and activates it.
    68 2. Editor sets requestSoftwareInputPanel event to active input context.<BR>
    69 3. A virtual function HbInputMethod::focusReceived is called. At this point the input method
    69 3. The input framework creates input state based on editor attributes and the input mode cache <BR>
    70    initializes whatever it needs to initialize in order to start the input operation (for example,
    70    resolves correct mode handler and activates it.<BR>
    71    opens the virtual keyboard by using HbVkbHost API) and waits for user actions.
    71 4. A virtual function HbInputMethod::focusReceived is called. At this point the input method<BR>
    72 4. Text is written. The input method delivers results to the editor buffer by using HbInputFocusObject API.
    72    initializes whatever it needs to initialize in order to start the input operation (for example,<BR>
    73    It can access editor attributes via HbEditorInterface API.
    73    opens the virtual keyboard by using HbVkbHost API) and waits for user actions.<BR>
    74 5. The active editor loses focus. At this point the input method receives a call to virtual function
    74 5. Text is written. The input method delivers results to the editor buffer by using HbInputFocusObject API.<BR>
    75    HbInputMethod::focusLost and is expected to conclude any ongoing input operations and shut down active
    75    It can access editor attributes via HbEditorInterface API.<BR>
    76    UI elements (such as the virtual keyboard).
    76 6. The active editor loses focus. At this point the input method receives a call to virtual function<BR>
    77 6. The input method waits for next focusReceived() call.
    77    HbInputMethod::focusLost and is expected to conclude any ongoing input operations and shut down active<BR>
       
    78    UI elements (such as the virtual keyboard).<BR>
       
    79 7. The input method waits for next focusReceived() call. <BR>
       
    80 
       
    81 \bold Input method resolving
       
    82 
       
    83 The input framework resolves correct input state handler based on three attributes: input mode,
       
    84 keyboard type and input language.
       
    85 
       
    86 The framework recognizes three different input modes: default, numeric and custom.
       
    87 Default and numeric input modes are something that the framework resolves for active
       
    88 input language and keyboard type. Custom input mode is something that the framework never
       
    89 activates automatically, but it is activated from UI or directly from application
       
    90 (or input method) code.
       
    91 
       
    92 Numeric input mode is something that can handle those editors that are configured to only accept
       
    93 numeric data (for example those that have Qt::ImhDigitsOnly hints on).
       
    94 
       
    95 Language attribute is matched either as a direct match or as a language range. Language range
       
    96 means the input method is capable of handling all the languages that
       
    97 HbKeymapFactory::availableLanguages() returns. Direct match always wins so it is possible
       
    98 to override language range for specific languages.
       
    99 
       
   100 The keyboard attribute is always matched directly. Note that event though the constant
       
   101 has term "keyboard" in it, it covers all input devices such as hand writing recognition widgets
       
   102 that don't utilize traditional keys. it is up the the input method what that constant
       
   103 really means.
       
   104 
       
   105 The input method resolving parameters are part of input plugin meta data and they are returned
       
   106 by QInputContextPlugin::languages() method. A single entry in the returned string list
       
   107 is formed by packing resolving parameters into HbInputModeProperties structure and calling
       
   108 HbInputModeProperties::asString() method.
       
   109 
       
   110 Following code snippet shows how the input context plugin returns resolving parameters
       
   111 
       
   112 \snippet{unittest_hbinputmethod/unittest_hbinputmethod.cpp,1}
       
   113 
       
   114 \bold Input method resolving example
       
   115 
       
   116 Say that we have implemented touch input methods for 12 key portrait mode and qwerty landscape mode.
       
   117 Then we have Chinese touch input method for both portrait and landscape orientations and also
       
   118 Chinese handwriting recognition input mode for portrait mode.
       
   119 
       
   120 Touch input methods resolve to language range, which means that they will be handle all
       
   121 the other languages, except Chinese, which has its own designated input method.
       
   122 
       
   123 Touch input methods also implement support for numeric mode. Because Chinese language uses
       
   124 same numeric system as "latin" based languages, we only want to implement numeric mode
       
   125 handling in one input method and arrange resolving parameters so that the numeric mode
       
   126 is handled by default touch input method even when the global input language is Chinese.
       
   127 
       
   128 Chinese handwriting input method is something that is a custom mode, and will be activated
       
   129 from UI.
       
   130 
       
   131 Following example shows how the resolving attributes are set up to achieve above configuration.
       
   132 
       
   133 Portait touch input method returns following attributes
       
   134 
       
   135 \snippet{unittest_hbinputmethod/unittest_hbinputmethod.cpp,2}
       
   136 
       
   137 Landscape touch input method returns following attributes
       
   138 
       
   139 \snippet{unittest_hbinputmethod/unittest_hbinputmethod.cpp,3}
       
   140 
       
   141 Chinese portrait input method returns following attributes
       
   142 
       
   143 \snippet{unittest_hbinputmethod/unittest_hbinputmethod.cpp,4}
       
   144 
       
   145 Chinese landscape input method returns following attributes
       
   146 
       
   147 \snippet{unittest_hbinputmethod/unittest_hbinputmethod.cpp,5}
       
   148 
       
   149 Chinese handwriting recognition input method returns following attributes
       
   150 (note use of HbInputModeCustom, in this example HWR is something that we
       
   151 want to active from UI separately).
       
   152 
       
   153 \snippet{unittest_hbinputmethod/unittest_hbinputmethod.cpp,6}
    78 
   154 
    79 \sa QInputContext
   155 \sa QInputContext
    80 \sa HbInputFocusObject
   156 \sa HbInputFocusObject
    81 \sa HbEditorInterface
   157 \sa HbEditorInterface
    82 \sa HbVkbHost
   158 \sa HbVkbHost
   118     }
   194     }
   119 
   195 
   120     master->d_ptr->mIsActive = true;
   196     master->d_ptr->mIsActive = true;
   121 
   197 
   122     // Finally set application input context.
   198     // Finally set application input context.
   123     QInputContext* proxy = master->d_ptr->newProxy();
   199     QInputContext* proxy = master->d_ptr->proxy();    
   124     app.setInputContext(proxy);
   200     // A check required so that Qt does not delete inputcontext
       
   201     // which we are passing.
       
   202     if (proxy != app.inputContext())
       
   203         app.setInputContext(proxy);
   125 
   204 
   126     return true;
   205     return true;
   127 }
   206 }
   128 
   207 
   129 /*!
   208 /*!
   161 {
   240 {
   162     return HbInputModeCache::instance()->listCustomInputMethods();
   241     return HbInputModeCache::instance()->listCustomInputMethods();
   163 }
   242 }
   164 
   243 
   165 /*!
   244 /*!
   166 Activates given input method. Input context is
   245 Activates given input method. Returns false if input method was not found
   167 switched to custom method. Returns false if input method was not found
       
   168 or the framework was not able to activate it.
   246 or the framework was not able to activate it.
   169 */
   247 */
   170 bool HbInputMethod::activateInputMethod(const HbInputMethodDescriptor &inputMethod)
   248 bool HbInputMethod::activateInputMethod(const HbInputMethodDescriptor &inputMethod)
   171 {
   249 {
   172     Q_D(HbInputMethod);
   250     Q_D(HbInputMethod);
   173 
   251 
   174     if (!inputMethod.isEmpty()) {
   252     if (!inputMethod.isEmpty()) {       
   175         HbInputSettingProxy::instance()->setActiveCustomInputMethod(inputMethod);
       
   176 
       
   177         if (inputMethod.isDefault()) {
   253         if (inputMethod.isDefault()) {
   178            d->setFocusCommon();
   254            d->setFocusCommon();
   179            return true;
   255            return true;
   180         } else {
   256         } else {
   181             HbInputMethod *customMethod = HbInputModeCache::instance()->loadInputMethod(inputMethod);
   257             HbInputMethod *customMethod = HbInputModeCache::instance()->loadInputMethod(inputMethod);
   182             if (customMethod) {
   258             if (customMethod) {              
   183                 d->contextSwitch(customMethod);
   259                d->contextSwitch(customMethod);
   184                return true;
   260                return true;
   185            }
   261            }
   186         }
   262         }
   187     }
   263     }
   188 
   264 
   299 \sa setFocusObject
   375 \sa setFocusObject
   300 */
   376 */
   301 void HbInputMethod::setFocusWidget(QWidget* widget)
   377 void HbInputMethod::setFocusWidget(QWidget* widget)
   302 {
   378 {
   303     Q_D(HbInputMethod);
   379     Q_D(HbInputMethod);
   304 
   380     
   305     if (d->mFocusLocked) {
   381     if (d->mFocusLocked) {
   306         return;
   382 	    return;
   307     }
   383 	}
   308 
   384 		
   309     QInputContext::setFocusWidget(widget);
   385     // attach focuswidget to prxoy inputcontext as proxy is 
   310 
   386     // the only inputcotext known to qt framework.
       
   387     d->proxy()->QInputContext::setFocusWidget(widget);
       
   388     
   311     if (!widget) {
   389     if (!widget) {
   312         // Losing focus.
   390         // Losing focus.
   313         if (d->mFocusObject) {
   391         if (d->mFocusObject) {
   314             focusLost(false);
   392             focusLost(false);
       
   393             d->hideMainWindow();
   315             delete d->mFocusObject;
   394             delete d->mFocusObject;
   316             d->mFocusObject = 0;
   395             d->mFocusObject = 0;
   317         }
   396         }
   318         return;
   397         return;
   319     }
   398     }
   337     // Focusing widget doesn't have input capabilities
   416     // Focusing widget doesn't have input capabilities
   338     // or it is read-only.
   417     // or it is read-only.
   339     if (readOnly && HbInputFocusObject::isReadOnlyWidget(widget)) {
   418     if (readOnly && HbInputFocusObject::isReadOnlyWidget(widget)) {
   340         if (d->mFocusObject) {
   419         if (d->mFocusObject) {
   341             focusLost();
   420             focusLost();
       
   421             d->hideMainWindow();
   342         }
   422         }
   343         return;
   423         return;
   344     }
   424     }
   345 
   425 
   346     if (d->mFocusObject) {
   426     if (d->mFocusObject) {
   388     Q_D(HbInputMethod);
   468     Q_D(HbInputMethod);
   389 
   469 
   390     if (d->mFocusObject && d->mFocusObject->object() == widget) {
   470     if (d->mFocusObject && d->mFocusObject->object() == widget) {
   391         delete d->mFocusObject;
   471         delete d->mFocusObject;
   392         d->mFocusObject = 0;
   472         d->mFocusObject = 0;
       
   473         // passing to actual QInputContext which is attached to Qt framework.
       
   474         // which will internally set QInputContext::focusWidget to Null.
       
   475         d->proxy()->QInputContext::widgetDestroyed(widget);
   393     }
   476     }
   394 }
   477 }
   395 
   478 
   396 /*!
   479 /*!
   397 Graphics item based editors (or any other object that implements
   480 Graphics item based editors (or any other object that implements
   412     }
   495     }
   413 
   496 
   414     if (focusObject == 0) {
   497     if (focusObject == 0) {
   415         // Losing focus.
   498         // Losing focus.
   416         if (d->mFocusObject != 0) {
   499         if (d->mFocusObject != 0) {
       
   500             disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   417             focusLost(false);
   501             focusLost(false);
       
   502             d->hideMainWindow();
   418             delete d->mFocusObject;
   503             delete d->mFocusObject;
   419             d->mFocusObject = 0;
   504             d->mFocusObject = 0;
   420         }
   505         }
   421         return;
   506         return;
   422     }
   507     }
   441         focusLost(true);
   526         focusLost(true);
   442         disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   527         disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   443         delete d->mFocusObject;
   528         delete d->mFocusObject;
   444         d->mFocusObject = 0;
   529         d->mFocusObject = 0;
   445     }
   530     }
   446     QInputContext::setFocusWidget(0);
       
   447 
   531 
   448     // Attach focus.
   532     // Attach focus.
   449     d->mFocusObject = focusObject;
   533     d->mFocusObject = focusObject;
   450     connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   534     connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   451 
       
   452     // If this is embedded QWidget, then set base class focus too.
       
   453     QWidget *widget = qobject_cast<QWidget*>(focusObject->object());
       
   454     if (widget) {
       
   455         QInputContext::setFocusWidget(widget);
       
   456     }
       
   457 
   535 
   458     d->setFocusCommon();
   536     d->setFocusCommon();
   459 
   537 
   460     // The focus jumped from one editor to another. Make sure that vkb host
   538     // The focus jumped from one editor to another. Make sure that vkb host
   461     // updates the situation correctly.
   539     // updates the situation correctly.
   774 {
   852 {
   775     Q_D(HbInputMethod);
   853     Q_D(HbInputMethod);
   776     Q_UNUSED(obj);
   854     Q_UNUSED(obj);
   777 
   855 
   778     focusLost();
   856     focusLost();
   779 
   857 	d->hideMainWindow();
   780     delete d->mFocusObject;
   858     delete d->mFocusObject;
   781     d->mFocusObject = 0;
   859     d->mFocusObject = 0;
   782 
   860 
   783     reset();
   861     reset();
   784 }
   862 }
   785 
   863 
       
   864 /*!
       
   865 Returns the input method descriptor the framework used for loading this plugin.
       
   866 Returns empty descriptor if the framework doesn't recognize this input method
       
   867 (ie. it was not resolved by input mode cache).
       
   868 */
       
   869 HbInputMethodDescriptor HbInputMethod::descriptor() const
       
   870 {
       
   871     return HbInputModeCache::instance()->descriptor(this);
       
   872 }
       
   873 
   786 // End of file
   874 // End of file
   787 
   875