src/hbcore/inputfw/hbinputmethod.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 #include <QInputMethodEvent>
       
    26 #include <QGraphicsView>
       
    27 #include <QGraphicsProxyWidget>
       
    28 #include <QLocale>
       
    29 
       
    30 #include "hbinputmethod.h"
       
    31 #include "hbinputmethod_p.h"
       
    32 #include "hbinputmodecache_p.h"
       
    33 #include "hbinputsettingproxy.h"
       
    34 #include "hbinputcontextproxy_p.h"
       
    35 #include "hbinputfilter.h"
       
    36 #include "hbinputmethodnull_p.h"
       
    37 #include "hbinputpredictionfactory.h"
       
    38 #include "hbinputstandardfilters.h"
       
    39 #include "hbinpututils.h"
       
    40 #include "hbinputvkbhost.h"
       
    41 
       
    42 /*!
       
    43 @alpha
       
    44 @hbcore
       
    45 \class HbInputMethod
       
    46 \brief A base class for input method implementations.
       
    47 
       
    48 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 services.   
       
    51 
       
    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 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 input method depending on the situation. It can also switch active input method on the fly
       
    55 when the focus switches between editors and the previously active input method is unable to 
       
    56 support newly focused editor.
       
    57 
       
    58 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
       
    60 and the custom input is ative in all editors until it is deactivated.
       
    61 
       
    62 Following is the basic input framework program flow:
       
    63 
       
    64 1. An editor gains input focus.
       
    65 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
       
    67    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.
       
    69 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.
       
    71 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
       
    73    UI elements (such as the virtual keyboard).   
       
    74 6. The input method waits for next focusReceived() call.
       
    75 
       
    76 \sa QInputContext
       
    77 \sa HbInputFocusObject
       
    78 \sa HbEditorInterface
       
    79 \sa HbVkbHost
       
    80 */
       
    81 
       
    82 /*!
       
    83 Constructs the object
       
    84 */
       
    85 HbInputMethod::HbInputMethod() : d_ptr(new HbInputMethodPrivate(this))
       
    86 {
       
    87     HbInputSettingProxy::instance()->connectObservingObject(this);  
       
    88 }
       
    89 
       
    90 /*!
       
    91 Destructs the object
       
    92 */
       
    93 HbInputMethod::~HbInputMethod()
       
    94 {
       
    95     HbInputSettingProxy::instance()->disconnectObservingObject(this);
       
    96 
       
    97     delete d_ptr;
       
    98 }
       
    99 
       
   100 /*!
       
   101 Initializes the HbInputs framework. Each Qt application needs to call this
       
   102 method once in order to connect to the HbInputs framework.
       
   103 */
       
   104 bool HbInputMethod::initializeFramework(QApplication& app)
       
   105 {
       
   106     // Activate singleton shutdown.
       
   107     connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown()));
       
   108     connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown()));
       
   109     connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown()));
       
   110 
       
   111     HbInputMethod *master = HbInputMethodNull::Instance();
       
   112 
       
   113     if (!master) {
       
   114         return false;
       
   115     }
       
   116 
       
   117     master->d_ptr->mIsActive = true;
       
   118 
       
   119     // Finally set application input context.
       
   120     QInputContext* proxy = master->d_ptr->newProxy();
       
   121     app.setInputContext(proxy);
       
   122 
       
   123     return true;
       
   124 }
       
   125 
       
   126 /*!
       
   127 Returns 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
       
   129 be so called null input method). Normally this method is needed only for special cases, such as developing
       
   130 and debugging framework level code, but it is made public for convenience.
       
   131 */
       
   132 HbInputMethod* HbInputMethod::activeInputMethod()
       
   133 {
       
   134     // 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
       
   136     // (that shouldn't be done, but it is possible). That's why we rely on app input context as
       
   137     // a primary source instead of mode cache.
       
   138     QInputContext* context = qApp->inputContext();
       
   139     if (context && context->inherits("HbInputMethod")) {
       
   140         HbInputMethod* active = static_cast<HbInputMethod*>(context);
       
   141         return active;
       
   142     }
       
   143 
       
   144     // Then check if the 'null' is active.
       
   145     HbInputMethod* nullInstance = HbInputMethodNull::Instance();
       
   146     if (nullInstance && nullInstance->isActiveMethod()) {
       
   147         return nullInstance;
       
   148     }
       
   149 
       
   150     // No it wasn't, then go through the methods in the cache and see which one is
       
   151     // active.
       
   152     return HbInputModeCache::instance()->activeMethod();
       
   153 }
       
   154 
       
   155 /*!
       
   156 Lists custom input methods.
       
   157 */
       
   158 QList<HbInputMethodDescriptor> HbInputMethod::listCustomInputMethods()
       
   159 {
       
   160     return HbInputModeCache::instance()->listCustomInputMethods();
       
   161 }
       
   162 
       
   163 /*!
       
   164 Activates given input method. input context is
       
   165 switched to custom method. Returns false if input method was not found
       
   166 or the framework was not able to activate it.
       
   167 */
       
   168 bool HbInputMethod::activateInputMethod(const HbInputMethodDescriptor &inputMethod)
       
   169 {
       
   170     Q_D(HbInputMethod);
       
   171 
       
   172     if (!inputMethod.isEmpty()) {
       
   173         HbInputSettingProxy::instance()->setActiveCustomInputMethod(inputMethod);
       
   174 
       
   175         if (inputMethod.isDefault()) {
       
   176            d->setFocusCommon();
       
   177            return true;
       
   178         } else {
       
   179             HbInputMethod *customMethod = HbInputModeCache::instance()->loadInputMethod(inputMethod);
       
   180             if (customMethod) {
       
   181                 d->contextSwitch(customMethod);
       
   182                return true;
       
   183            }
       
   184         }
       
   185     }
       
   186 
       
   187     return false;
       
   188 }
       
   189 
       
   190 
       
   191 /*!
       
   192 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 is notified by calling inputLanguageChanged.
       
   195 
       
   196 \sa inputLanguageChanged
       
   197 \sa HbInputSettingProxy
       
   198 */
       
   199 void HbInputMethod::globalInputLanguageChanged(const HbInputLanguage &newLanguage)
       
   200 { 
       
   201     Q_D(HbInputMethod);
       
   202 
       
   203     inputLanguageChanged(newLanguage);
       
   204 
       
   205     if (!isActiveMethod()) {
       
   206         // Notify non-active input methods of language change, but check
       
   207         // if the method has promised to handle the new language only
       
   208         // in the active method
       
   209         return;
       
   210     }
       
   211    
       
   212     // Just behave as if this was the first focus operation
       
   213     // to this editor.
       
   214     if (d->mFocusObject) { 
       
   215         HbInputState state;
       
   216         editorRootState(state);  
       
   217         activateState(state);
       
   218     }
       
   219 }
       
   220 
       
   221 /*!
       
   222 This slot is called when the secondary input language changes. The framework connects it
       
   223 to the input setting proxy. When the signal is received, the input method implementation
       
   224 is notified by calling secondaryInputLanguageChanged.
       
   225 
       
   226 \sa secondaryInputLanguageChanged
       
   227 \sa HbInputSettingProxy
       
   228 */
       
   229 void HbInputMethod::globalSecondaryInputLanguageChanged(const HbInputLanguage &aNewLanguage)
       
   230 {
       
   231     secondaryInputLanguageChanged(aNewLanguage);
       
   232 }
       
   233 
       
   234 /*!
       
   235 This slot is connected to the setting proxy hw keyboard attribute. It will
       
   236 do refreshState() when the signal is received.
       
   237 */
       
   238 void HbInputMethod::activeHwKeyboardChanged(HbKeyboardType newKeyboard)
       
   239 {
       
   240     Q_UNUSED(newKeyboard);
       
   241     Q_D(HbInputMethod);
       
   242 
       
   243     // Do here whatever needs to be done on HbInputMethod level, then
       
   244     // call virtual ActiveKeyboardChanged() in case plugin needs to do something.
       
   245     // ...
       
   246     d->refreshState();
       
   247 }
       
   248 
       
   249 /*!
       
   250 This slot is connected to the setting proxy touch keyboard attribute. It will
       
   251 do refreshState() when the signal is received.
       
   252 */
       
   253 void HbInputMethod::activeTouchKeyboardChanged(HbKeyboardType newKeyboard)
       
   254 {
       
   255     Q_UNUSED(newKeyboard);
       
   256     Q_D(HbInputMethod);
       
   257 
       
   258     d->refreshState();
       
   259 }
       
   260 
       
   261 
       
   262 /*!
       
   263 This slot is connected to the setting proxy activeKeyboard attribute. It will
       
   264 activate proper state when the signal is received.
       
   265 */
       
   266 void HbInputMethod::activeKeyboardChanged(HbKeyboardType newKeyboard)
       
   267 {
       
   268     if (!isActiveMethod()) {
       
   269         return;
       
   270     }
       
   271     Q_D(HbInputMethod);
       
   272     d->mInputState.setKeyboard(newKeyboard);
       
   273     HbInputMethod* stateHandler = d->findStateHandler(d->mInputState); 
       
   274     if (stateHandler) {
       
   275         d->inputStateToEditor(d->mInputState);
       
   276         if (stateHandler != this) {
       
   277             // Context switch needed.
       
   278             d->contextSwitch(stateHandler);
       
   279         } else {
       
   280             // Same method handles new state, just report the state change.
       
   281             inputStateActivated(d->mInputState);
       
   282         }
       
   283     }
       
   284 }
       
   285 
       
   286 /*!
       
   287 This slot is called when the predictive input state changes. The framework connects it
       
   288 to the input setting proxy. When the signal is received, the input method implementation
       
   289 is notified by calling predictiveInputStatusChanged.
       
   290 
       
   291 \sa predictiveInputStatusChanged
       
   292 \sa HbInputSettingProxy
       
   293 */
       
   294 void HbInputMethod::predictiveInputStateChanged(int newStatus)
       
   295 {
       
   296     // Do here whatever needs to be done on HbInputMethod level, then
       
   297     // call virtual predictiveInputStatusChanged() in case plugin needs to do something.
       
   298     // ...
       
   299 
       
   300     predictiveInputStatusChanged(newStatus);
       
   301 }
       
   302 
       
   303 /*!
       
   304 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.
       
   306 
       
   307 \sa focusLost
       
   308 */
       
   309 void HbInputMethod::focusReceived()
       
   310 {
       
   311     // Empty default implementation, do nothing.
       
   312 }
       
   313 
       
   314 /*!
       
   315 The framework calls this method when an active editor loses focus. The parameter focusSwitch
       
   316 is true if the focus is moving from one editor to another and false if the input focus
       
   317 going to be lost completely.
       
   318 
       
   319 \sa focusReceived
       
   320 */
       
   321 void HbInputMethod::focusLost(bool focusSwitch)
       
   322 {
       
   323     Q_UNUSED(focusSwitch);
       
   324     // Empty default implementation, do nothing.
       
   325 }
       
   326 
       
   327 /*!
       
   328 Returns pointer to active focus object.
       
   329 */
       
   330 HbInputFocusObject* HbInputMethod::focusObject() const
       
   331 {
       
   332     Q_D(const HbInputMethod);
       
   333     return d->mFocusObject;
       
   334 }
       
   335 
       
   336 /*!
       
   337 QWidget based editors notify focus changes through this method. This is the
       
   338 default focus handling mechanism for QInputContext system. Input method
       
   339 implementation should never override this method unless it knows what it is doing.
       
   340 
       
   341 \sa setFocusObject
       
   342 */
       
   343 void HbInputMethod::setFocusWidget(QWidget* widget)
       
   344 {
       
   345     Q_D(HbInputMethod);
       
   346 
       
   347     if (d->mFocusLocked) {
       
   348         return;
       
   349     }
       
   350 
       
   351     QInputContext::setFocusWidget(widget);
       
   352 
       
   353     if (!widget) {
       
   354         // Losing focus.
       
   355         if (d->mFocusObject) { 
       
   356             focusLost(false);
       
   357             delete d->mFocusObject;
       
   358             d->mFocusObject = 0;
       
   359         }
       
   360         return;
       
   361     }
       
   362 
       
   363     QGraphicsView* gView = qobject_cast<QGraphicsView*>(widget);
       
   364     if (gView) {
       
   365         // We don't want to focus to graphics view but the items inside the scene, so just return
       
   366         return;
       
   367     }
       
   368 
       
   369     // Check whether the editor has read-only constraint and reject focus
       
   370     // if so.
       
   371     bool readOnly = false;
       
   372     if (HbEditorInterface::isConnected(widget)) {
       
   373         HbEditorInterface eInt(widget);
       
   374         if (eInt.constraints() & HbEditorConstraintIgnoreFocus) {
       
   375             readOnly = true;
       
   376         }
       
   377     }
       
   378 
       
   379     // Focusing widget doesn't have input capabilities
       
   380     // or it is read-only.
       
   381     if (readOnly && HbInputFocusObject::isReadOnlyWidget(widget)) {
       
   382         if (d->mFocusObject) {
       
   383             focusLost();
       
   384         }
       
   385         return;
       
   386     }
       
   387    
       
   388     if (d->mFocusObject) {
       
   389         if (d->mFocusObject->object() == widget) {
       
   390             // Focus remains in same widget, do nothing.
       
   391             return;
       
   392         } else {
       
   393             // Lose editor focus unless we are focusing back to the editor from e.g. a vkb
       
   394             focusLost();
       
   395         }
       
   396     }
       
   397 
       
   398     bool refreshHost = false;
       
   399 
       
   400     // Delete previous focus object.
       
   401     if (d->mFocusObject) {
       
   402         refreshHost = true;
       
   403         disconnect(d->mFocusObject, SIGNAL(editorDeleted()), this, SLOT(editorDeleted()));
       
   404     }
       
   405     delete d->mFocusObject;
       
   406     d->mFocusObject = 0;
       
   407 
       
   408     // Attach focus.
       
   409     d->mFocusObject = new HbInputFocusObject(widget);
       
   410     connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
       
   411 
       
   412     d->setFocusCommon();
       
   413 
       
   414     // The focus jumped from one editor to another. Make sure that vkb host
       
   415     // updates the situation correctly.
       
   416     if (refreshHost && d->mFocusObject) {
       
   417         HbVkbHost *vkbHost = d->mFocusObject->editorInterface().vkbHost();
       
   418         if (vkbHost) {
       
   419             vkbHost->refresh();
       
   420         }
       
   421     }
       
   422 }
       
   423 
       
   424 /*!
       
   425 Checks if the destroyed widget is currently focused and clears the focus
       
   426 if needed. This method should not be overridden.
       
   427 
       
   428 \sa focusObjectDestroyed
       
   429 */
       
   430 void HbInputMethod::widgetDestroyed(QWidget* widget)
       
   431 {
       
   432     Q_D(HbInputMethod);
       
   433 
       
   434     if (d->mFocusObject && d->mFocusObject->object() == widget) {
       
   435         releaseFocus();
       
   436     }
       
   437 }
       
   438 
       
   439 /*!
       
   440 Checks if the destroyed object is currently focused and clears the focus
       
   441 if needed.
       
   442 
       
   443 \sa widgetDestroyed
       
   444 */
       
   445 void HbInputMethod::focusObjectDestroyed(const HbInputFocusObject* focusObject)
       
   446 {
       
   447     Q_D(HbInputMethod);
       
   448 
       
   449     if (focusObject && focusObject == d->mFocusObject) {
       
   450         releaseFocus();
       
   451     }
       
   452 }
       
   453 
       
   454 /*!
       
   455 Graphics item based editors (or any other object that implements
       
   456 HbInputFocusObject) send their focus events notifications through this method.
       
   457 Since Qt's QInputContext mechanism works only with QWidget based editors,
       
   458 this alternate focus channel is needed for objects belonging to a graphics scene
       
   459 (in case of a graphics scene, the topmost QWidget that has focus is
       
   460 graphics view, not the the object inside the view). The ownership of
       
   461 incoming focus object is transferred to the input framework.
       
   462 
       
   463 \sa setFocusWidget
       
   464 \sa HbInputFocusObject
       
   465 */
       
   466 void HbInputMethod::setFocusObject(HbInputFocusObject* focusObject)
       
   467 {
       
   468     Q_D(HbInputMethod);
       
   469 
       
   470     if (d->mFocusLocked) {
       
   471         return;
       
   472     }
       
   473 
       
   474     if (focusObject == 0) {
       
   475         // Losing focus.
       
   476         if (d->mFocusObject != 0) {
       
   477             focusLost(false);
       
   478             delete d->mFocusObject;
       
   479             d->mFocusObject = 0;
       
   480         }
       
   481         return;
       
   482     }
       
   483 
       
   484     if(d->compareWithCurrentFocusObject( focusObject )) {
       
   485        // The incoming focus object is either same or points to same
       
   486         // widget that the framework is already focused to and nothing needs to be done here.
       
   487         // But because the ownership of the focus object is transferred to the
       
   488         // the framework, we need to delete the the incoming focus object in case it is
       
   489         // dirrefent than current one.
       
   490         if (d->mFocusObject != focusObject) {
       
   491             delete focusObject;
       
   492         }
       
   493         return;
       
   494     }
       
   495    
       
   496     bool refreshHost = false;
       
   497 
       
   498     // Delete previous focus object.
       
   499     if (d->mFocusObject) {
       
   500         refreshHost = true;
       
   501         focusLost(true);
       
   502         disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
       
   503         delete d->mFocusObject;
       
   504         d->mFocusObject = 0;
       
   505     }
       
   506     QInputContext::setFocusWidget(0);
       
   507 
       
   508     // Attach focus.
       
   509     d->mFocusObject = focusObject;
       
   510     connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
       
   511 
       
   512     // If this is embedded QWidget, then set base class focus too.
       
   513     QWidget *widget = qobject_cast<QWidget*>(focusObject->object());
       
   514     if (widget) {
       
   515         QInputContext::setFocusWidget(widget);
       
   516     }
       
   517 
       
   518     d->setFocusCommon();
       
   519 
       
   520     // The focus jumped from one editor to another. Make sure that vkb host
       
   521     // updates the situation correctly.
       
   522     if (refreshHost && d->mFocusObject) {
       
   523         HbVkbHost *vkbHost = d->mFocusObject->editorInterface().vkbHost();
       
   524         if (vkbHost) {
       
   525             vkbHost->refresh();
       
   526         }
       
   527     }
       
   528 }
       
   529 
       
   530 /*!
       
   531 The secondary channel uses this slot for inserting text active editor.
       
   532 */
       
   533 void HbInputMethod::receiveText(const QString& string)
       
   534 {
       
   535     Q_D(HbInputMethod);
       
   536 
       
   537     if (isActiveMethod() && d->mFocusObject &&
       
   538         (d->editorConstraints() & HbEditorConstraintsNoSecondaryChannel) == 0) {
       
   539         QList<QInputMethodEvent::Attribute> list;
       
   540         QInputMethodEvent event(QString(), list);
       
   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 */
       
   551 void HbInputMethod::candidatePopupClosed(int closingKey)
       
   552 {
       
   553     Q_UNUSED(closingKey);
       
   554     // Empty default implementation
       
   555 }
       
   556 
       
   557 /*!
       
   558 The framework calls this method when device-wide input language changes.
       
   559 The base class implementation is empty so any input method interested in
       
   560 language switch events should implement it. Note that this method reports
       
   561 change in system wide input language. Local input language in active editor
       
   562 may still remain same.
       
   563 
       
   564 \sa activeLanguage
       
   565 */
       
   566 void HbInputMethod::inputLanguageChanged(const HbInputLanguage &newLanguage)
       
   567 {
       
   568     Q_UNUSED(newLanguage);
       
   569     // Empty default implementation.
       
   570 }
       
   571 
       
   572 /*!
       
   573 The framework calls this method when device-wide secondary input language changes.
       
   574 The base class implementation is empty so any input method interested in language switch
       
   575 events should override it in the actual inputmethod.
       
   576 */
       
   577 void HbInputMethod::secondaryInputLanguageChanged(const HbInputLanguage &aNewLanguage)
       
   578 {
       
   579     // Empty default implementation.
       
   580     Q_UNUSED(aNewLanguage);
       
   581 }
       
   582 
       
   583 /*!
       
   584 The framework calls this method when the predictive input status changes.
       
   585 The base class implementation is empty so any input method interested in
       
   586 prediction status events should implement it.
       
   587 */
       
   588 void HbInputMethod::predictiveInputStatusChanged(int newStatus)
       
   589 {
       
   590     Q_UNUSED(newStatus);
       
   591     // Empty default implementation.
       
   592 }
       
   593 
       
   594 /*!
       
   595 Returns true if given input mode is allowed in active editor.
       
   596 */
       
   597 bool HbInputMethod::modeAllowedInEditor(HbInputModeType mode) const
       
   598 {
       
   599     Q_D(const HbInputMethod);
       
   600     return d->modeAllowedInEditor(mode);
       
   601 }
       
   602 
       
   603 /*!
       
   604 Returns true if this instance is currently active QInputContext in QApplication.
       
   605 */
       
   606 bool HbInputMethod::isActiveMethod() const
       
   607 {
       
   608     Q_D(const HbInputMethod);
       
   609     return d->mIsActive;
       
   610 }
       
   611 
       
   612 /*!
       
   613 The framework calls this method every time the input state changes. This is an empty default
       
   614 implementation and the inheriting class should override it.
       
   615 */
       
   616 void HbInputMethod::inputStateActivated(const HbInputState& newState)
       
   617 {
       
   618     Q_UNUSED(newState);
       
   619     // Empty default implementation.
       
   620     if (this != HbInputMethodNull::Instance()) {
       
   621         qDebug("WARNING: inputStateActivated() default implementation called: Is that ok?");
       
   622     }
       
   623 }
       
   624 
       
   625 /*!
       
   626 Returns active input state.
       
   627 
       
   628 \sa activateState
       
   629 \sa activateNextState
       
   630 */
       
   631 HbInputState HbInputMethod::inputState() const
       
   632 {
       
   633     Q_D(const HbInputMethod);
       
   634     return d->mInputState;
       
   635 }
       
   636 
       
   637 /*!
       
   638 Returns the first input state that should be activated when an editor is 
       
   639 focused for the first time. The state is constructed from edirtor attributes and
       
   640 input settings.
       
   641 */
       
   642 void HbInputMethod::editorRootState(HbInputState &result) const
       
   643 {
       
   644     Q_D(const HbInputMethod);
       
   645     d->editorRootState(result);
       
   646 }
       
   647 
       
   648 /*!
       
   649 
       
   650 */
       
   651 void HbInputMethod::constructLatinState(HbInputState &result) const
       
   652 {
       
   653     Q_D(const HbInputMethod);
       
   654     d->constructLatinState(result);
       
   655 }
       
   656 
       
   657 /*!
       
   658 Activates given input state. State handler must be among cached input methods, this
       
   659 method doesn't resolve it from non-cached plugins. Returns true if the framework was
       
   660 able to find handler for the new state. A context switch to another input method
       
   661 instance may occur.
       
   662 
       
   663 \sa activateNextState
       
   664 \sa InputState
       
   665 */
       
   666 bool HbInputMethod::activateState(const HbInputState& state)
       
   667 {
       
   668     Q_D(HbInputMethod);
       
   669 
       
   670     if (!d->stateAllowedInEditor(state)) {
       
   671         return false;
       
   672     }
       
   673 
       
   674     d->mStateChangeInProgress = true;
       
   675 
       
   676     HbInputMethod* stateHandler = HbInputModeCache::instance()->findStateHandler(state);
       
   677 
       
   678     if (!stateHandler) {
       
   679         stateHandler = HbInputMethodNull::Instance();
       
   680     }
       
   681 
       
   682     d->mInputState = state;
       
   683 
       
   684     if (stateHandler != this) {     
       
   685         stateHandler->d_ptr->mStateChangeInProgress = true;
       
   686         // Context switch needed.
       
   687         d->inputStateToEditor(d->mInputState);        
       
   688         d->contextSwitch(stateHandler);
       
   689         stateHandler->d_ptr->mStateChangeInProgress = false;
       
   690     } else {         
       
   691         // Same method handles new state, just report the state change.
       
   692         d->inputStateToEditor(d->mInputState);
       
   693         inputStateActivated(d->mInputState);
       
   694     }
       
   695 
       
   696     d->mStateChangeInProgress = false;
       
   697 
       
   698     return true;
       
   699 }
       
   700 
       
   701 /*!
       
   702 Updates the input state to automatic or lower case, with a check on editor contraints.
       
   703 */
       
   704 void HbInputMethod::updateState()
       
   705 {
       
   706     Q_D(HbInputMethod);
       
   707 
       
   708     if (!d->textCaseApplies()) {
       
   709         return;
       
   710     }
       
   711 
       
   712     bool autoCaseNeeded = d->automaticTextCaseNeeded();
       
   713     HbTextCase currentTextCase = d->mInputState.textCase();
       
   714 
       
   715     bool refresh = false;
       
   716 
       
   717     if (currentTextCase == HbTextCaseAutomatic) {
       
   718         if (!autoCaseNeeded) {
       
   719             currentTextCase = HbTextCaseLower;
       
   720             refresh = true;
       
   721         }
       
   722     } else if (autoCaseNeeded && currentTextCase != HbTextCaseUpper ) {
       
   723         if (!d->isFixedCaseEditor()) {
       
   724             currentTextCase = HbTextCaseAutomatic;
       
   725             refresh = true;
       
   726         } else {
       
   727             return;
       
   728         }
       
   729     }
       
   730 
       
   731     if (refresh) {
       
   732         d->mInputState.setTextCase(currentTextCase);
       
   733         d->inputStateToEditor(d->mInputState);
       
   734         inputStateActivated(d->mInputState);
       
   735     }
       
   736 }
       
   737 
       
   738 /*!
       
   739 Clears focus state from input method side. After calling this method,
       
   740 HbInputMethod instance thinks that it is not focused to any widget.
       
   741 The widget itself still remain focused to this input context.
       
   742 */
       
   743 void HbInputMethod::releaseFocus()
       
   744 {
       
   745     Q_D(HbInputMethod);
       
   746 
       
   747     delete d->mFocusObject;
       
   748     d->mFocusObject = 0;
       
   749 }
       
   750 
       
   751 /*!
       
   752 Receives the screen orientation signal. Will determine correct input state for new
       
   753 orientation and find state handler for it.
       
   754 */
       
   755 void HbInputMethod::orientationChanged(Qt::Orientation orientation)
       
   756 {
       
   757     Q_UNUSED(orientation);
       
   758 
       
   759     if (isActiveMethod()) {
       
   760         // Make sure that if there was an editor focus before the orientation change,
       
   761         // it will re-focus.
       
   762         QInputContext *ic = qApp->inputContext();
       
   763         if (ic) {
       
   764             QEvent *event = new QEvent(QEvent::RequestSoftwareInputPanel);
       
   765             ic->filterEvent(event);
       
   766             delete event;
       
   767         }
       
   768     }
       
   769 }
       
   770 
       
   771 /*!
       
   772 This slot is connected to setting proxy's orientation change warning signal. The default
       
   773 base class implementation is empty.
       
   774 
       
   775 \sa HbInputSettingProxy
       
   776 */
       
   777 void HbInputMethod::orientationAboutToChange()
       
   778 {
       
   779 }
       
   780 
       
   781 /*!
       
   782 Returns active input language. Unlike setting proxy's global input language,
       
   783 this method takes into account input state language and possible editor local language,
       
   784 so the return value reflects real situation in currently active editor instead of
       
   785 the global setting. If input state defines language, then that is used. Otherwise
       
   786 editor's local input language is checked first and if that is not specified, then
       
   787 global input language is returned.
       
   788 */
       
   789 HbInputLanguage HbInputMethod::activeLanguage() const
       
   790 {
       
   791     Q_D(const HbInputMethod);
       
   792     return d->activeLanguage();
       
   793 }
       
   794 
       
   795 /*!
       
   796 Once this method is called, the framework will ignore all the incoming focus events completely
       
   797 until focus is unlocked. Context switch operation will unlock it
       
   798 automatically. Usually this feature is not needed, but it may come handy in some cases
       
   799 where an input method implementation knows that is is going to do something on the UI-level
       
   800 that will steal the focus, but wants to ensure that the framework keeps its
       
   801 focus in the original editor during that time.
       
   802 
       
   803 \sa unlockFocus
       
   804 */
       
   805 void HbInputMethod::lockFocus()
       
   806 {
       
   807     Q_D(HbInputMethod);
       
   808     d->mFocusLocked = true;
       
   809 }
       
   810 
       
   811 /*!
       
   812 Unlocks the focus. After calling this method the framework will start to receive
       
   813 focus events again, in case they where locked out before.
       
   814 
       
   815 \sa lockFocus
       
   816 */
       
   817 void HbInputMethod::unlockFocus()
       
   818 {
       
   819     Q_D(HbInputMethod);
       
   820     d->mFocusLocked = false;
       
   821 }
       
   822 
       
   823 /*!
       
   824 Removes input method focus and asks active input plugin to close its active UI-components
       
   825 (such as touch keypads). This may be needed in some special cases where the underlying
       
   826 application wants to make sure that there are no input related elements on the screen.
       
   827 
       
   828 This is a if-all-else fails backup method. Same can be done (more efficiently) by doing
       
   829 following.
       
   830 
       
   831 \code
       
   832 QInputContext* inputContext = qApp->inputContext();
       
   833 if (inputContext) {
       
   834     inputContext->setFocusWidget(0);
       
   835 }
       
   836 \endcode
       
   837 */
       
   838 void HbInputMethod::forceUnfocus()
       
   839 {
       
   840     HbInputMethod* active = activeInputMethod();
       
   841 
       
   842     if (active) {
       
   843         active->focusLost(false);
       
   844         active->releaseFocus();
       
   845         delete active->d_ptr->mFocusObject;
       
   846         active->d_ptr->mFocusObject = 0;  
       
   847     }
       
   848 }
       
   849 
       
   850 /*!
       
   851 Wrapper
       
   852 */
       
   853 bool HbInputMethod::automaticTextCaseNeeded() const
       
   854 {
       
   855     Q_D(const HbInputMethod);
       
   856     return d->automaticTextCaseNeeded();
       
   857 }
       
   858 
       
   859 /*!
       
   860 Wrapper
       
   861 */
       
   862 void HbInputMethod::inputStateToEditor(const HbInputState& source)
       
   863 {
       
   864     Q_D(HbInputMethod);
       
   865     d->inputStateToEditor(source);
       
   866 }
       
   867 
       
   868 /*!
       
   869 Returns true if state change operation is in progress. This is useful in those
       
   870 cases where focus operations should behave differently during state change
       
   871 than in normal focus-in / focus-out operations. For example, we may not want
       
   872 to run virtual keyboard animations during state change but just switch to another
       
   873 vkb immediately.
       
   874 */
       
   875 bool HbInputMethod::stateChangeInProgress() const
       
   876 {
       
   877     Q_D(const HbInputMethod);
       
   878     return d->mStateChangeInProgress;
       
   879 }
       
   880 
       
   881 /*!
       
   882 When an editor becomes focused, the framework connects its destroyed signal
       
   883 to this slot and it takes care of closing the input and resetting the input method.
       
   884 */
       
   885 void HbInputMethod::editorDeleted(QObject *obj)
       
   886 {
       
   887     Q_UNUSED(obj);
       
   888 
       
   889     focusLost();
       
   890     releaseFocus();
       
   891     reset();
       
   892 }
       
   893 
       
   894 /*!
       
   895 This function returns true if there is a context switch happening due to a orientation
       
   896 switch.
       
   897 */
       
   898 bool HbInputMethod::orientationContextSwitchInProgress()
       
   899 {
       
   900     Q_D(HbInputMethod);
       
   901     return d->mIsOrientationContextSwitchInProgress;
       
   902 }
       
   903 
       
   904 // End of file
       
   905