src/hbcore/inputfw/hbinputmethod.cpp
changeset 6 c3690ec91ef8
parent 5 627c4a0fd0e7
child 7 923ff622b8b9
equal deleted inserted replaced
5:627c4a0fd0e7 6:c3690ec91ef8
    20 **
    20 **
    21 ** If you have questions regarding the use of this file, please contact
    21 ** If you have questions regarding the use of this file, please contact
    22 ** Nokia at developer.feedback@nokia.com.
    22 ** Nokia at developer.feedback@nokia.com.
    23 **
    23 **
    24 ****************************************************************************/
    24 ****************************************************************************/
       
    25 #include "hbinputmethod.h"
       
    26 #include "hbinputmethod_p.h"
       
    27 
    25 #include <QInputMethodEvent>
    28 #include <QInputMethodEvent>
    26 #include <QGraphicsView>
    29 #include <QGraphicsView>
    27 #include <QGraphicsProxyWidget>
    30 #include <QGraphicsProxyWidget>
    28 #include <QLocale>
    31 #include <QLocale>
    29 
    32 
    30 #include "hbinputmethod.h"
       
    31 #include "hbinputmethod_p.h"
       
    32 #include "hbinputmodecache_p.h"
    33 #include "hbinputmodecache_p.h"
    33 #include "hbinputsettingproxy.h"
    34 #include "hbinputsettingproxy.h"
    34 #include "hbinputcontextproxy_p.h"
    35 #include "hbinputcontextproxy_p.h"
    35 #include "hbinputfilter.h"
    36 #include "hbinputfilter.h"
    36 #include "hbinputmethodnull_p.h"
    37 #include "hbinputmethodnull_p.h"
    37 #include "hbinputpredictionfactory.h"
    38 #include "hbinputpredictionfactory.h"
    38 #include "hbinputextradictionaryfactory.h"
    39 #include "hbinputextradictionaryfactory.h"
    39 #include "hbinputstandardfilters.h"
    40 #include "hbinputstandardfilters.h"
    40 #include "hbinpututils.h"
    41 #include "hbinpututils.h"
    41 #include "hbinputvkbhost.h"
    42 #include "hbinputvkbhost.h"
       
    43 #include "hbinputvkbhostbridge.h"
    42 
    44 
    43 /*!
    45 /*!
    44 @alpha
    46 @alpha
    45 @hbcore
    47 @hbcore
    46 \class HbInputMethod
    48 \class HbInputMethod
   177 }
   179 }
   178 
   180 
   179 /*!
   181 /*!
   180 Initializes the input framework.
   182 Initializes the input framework.
   181 */
   183 */
   182 bool HbInputMethod::initializeFramework(QApplication& app)
   184 bool HbInputMethod::initializeFramework(QApplication &app)
   183 {
   185 {
   184     // Activate singleton shutdown.
   186     // Activate singleton shutdown.
   185     connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown()));
   187     connect(&app, SIGNAL(aboutToQuit()), HbInputModeCache::instance(), SLOT(shutdown()));
   186     connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown()));
   188     connect(&app, SIGNAL(aboutToQuit()), HbInputSettingProxy::instance(), SLOT(shutdown()));
   187     connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown()));
   189     connect(&app, SIGNAL(aboutToQuit()), HbPredictionFactory::instance(), SLOT(shutDown()));
   194     }
   196     }
   195 
   197 
   196     master->d_ptr->mIsActive = true;
   198     master->d_ptr->mIsActive = true;
   197 
   199 
   198     // Finally set application input context.
   200     // Finally set application input context.
   199     QInputContext* proxy = master->d_ptr->proxy();    
   201     QInputContext *proxy = master->d_ptr->proxy();
   200     // A check required so that Qt does not delete inputcontext
   202     // A check required so that Qt does not delete inputcontext
   201     // which we are passing.
   203     // which we are passing.
   202     if (proxy != app.inputContext())
   204     if (proxy != app.inputContext()) {
   203         app.setInputContext(proxy);
   205         app.setInputContext(proxy);
       
   206     }
   204 
   207 
   205     return true;
   208     return true;
   206 }
   209 }
   207 
   210 
   208 /*!
   211 /*!
   209 Returns the active instance of HbInputMethod. There is always active HbInputMethod instance after
   212 Returns the active instance of HbInputMethod. There is always active HbInputMethod instance after
   210 InitializeFramework method has been called, even when there is no focused editor (in some cases it may
   213 InitializeFramework method has been called, even when there is no focused editor (in some cases it may
   211 be so called null input method).
   214 be so called null input method).
   212 */
   215 */
   213 HbInputMethod* HbInputMethod::activeInputMethod()
   216 HbInputMethod *HbInputMethod::activeInputMethod()
   214 {
   217 {
   215     // First try, try app input context directly. It is possible that it is an instance
   218     // First try, try app input context directly. It is possible that it is an instance
   216     // of HbInputMethod that is installed directly there without framework knowing about it
   219     // of HbInputMethod that is installed directly there without framework knowing about it
   217     // (that shouldn't be done, but it is possible). That's why we rely on app input context as
   220     // (that shouldn't be done, but it is possible). That's why we rely on app input context as
   218     // a primary source instead of mode cache.
   221     // a primary source instead of mode cache.
   219     QInputContext* context = qApp->inputContext();
   222     QInputContext *context = qApp->inputContext();
   220     if (context && context->inherits("HbInputMethod")) {
   223     if (context && context->inherits("HbInputMethod")) {
   221         HbInputMethod* active = static_cast<HbInputMethod*>(context);
   224         HbInputMethod *active = static_cast<HbInputMethod *>(context);
   222         return active;
   225         return active;
   223     }
   226     }
   224 
   227 
   225     // Then check if the 'null' is active.
   228     // Then check if the 'null' is active.
   226     HbInputMethod* nullInstance = HbInputMethodNull::Instance();
   229     HbInputMethod *nullInstance = HbInputMethodNull::Instance();
   227     if (nullInstance && nullInstance->isActiveMethod()) {
   230     if (nullInstance && nullInstance->isActiveMethod()) {
   228         return nullInstance;
   231         return nullInstance;
   229     }
   232     }
   230 
   233 
   231     // No it wasn't, then go through the methods in the cache and see which one is
   234     // No it wasn't, then go through the methods in the cache and see which one is
   247 */
   250 */
   248 bool HbInputMethod::activateInputMethod(const HbInputMethodDescriptor &inputMethod)
   251 bool HbInputMethod::activateInputMethod(const HbInputMethodDescriptor &inputMethod)
   249 {
   252 {
   250     Q_D(HbInputMethod);
   253     Q_D(HbInputMethod);
   251 
   254 
   252     if (!inputMethod.isEmpty()) {       
   255     if (!inputMethod.isEmpty()) {
   253         if (inputMethod.isDefault()) {
   256         if (inputMethod.isDefault()) {
   254            d->setFocusCommon();
   257             d->setFocusCommon();
   255            return true;
   258             return true;
   256         } else {
   259         } else {
   257             HbInputMethod *customMethod = HbInputModeCache::instance()->loadInputMethod(inputMethod);
   260             HbInputMethod *customMethod = HbInputModeCache::instance()->loadInputMethod(inputMethod);
   258             if (customMethod) {              
   261             if (customMethod) {
   259                d->contextSwitch(customMethod);
   262                 d->contextSwitch(customMethod);
   260                return true;
   263                 return true;
   261            }
   264             }
   262         }
   265         }
   263     }
   266     }
   264 
   267 
   265     return false;
   268     return false;
   266 }
   269 }
   312 This slot is connected to the setting proxy activeKeyboard attribute. It will
   315 This slot is connected to the setting proxy activeKeyboard attribute. It will
   313 activate proper state when the signal is received.
   316 activate proper state when the signal is received.
   314 */
   317 */
   315 void HbInputMethod::activeKeyboardChanged(HbKeyboardType newKeyboard)
   318 void HbInputMethod::activeKeyboardChanged(HbKeyboardType newKeyboard)
   316 {
   319 {
   317     if (!isActiveMethod()) {
   320     if (!isActiveMethod() || !HbInputSettingProxy::instance()->orientationChangeCompleted()) {
   318         return;
   321         return;
   319     }
   322     }
   320 
   323 
   321     Q_D(HbInputMethod);
   324     Q_D(HbInputMethod);
   322 
   325 
   323     d->mInputState.setKeyboard(newKeyboard);
   326     d->mInputState.setKeyboard(newKeyboard);
   324     HbInputMethod* stateHandler = d->findStateHandler(d->mInputState);
   327     HbInputMethod *stateHandler = d->findStateHandler(d->mInputState);
   325     if (stateHandler) {
   328     if (stateHandler) {
   326         d->inputStateToEditor(d->mInputState);
   329         d->inputStateToEditor(d->mInputState);
   327         if (stateHandler != this) {
   330         if (stateHandler != this) {
   328             // Context switch needed.
   331             // Context switch needed.
   329             d->contextSwitch(stateHandler);
   332             d->contextSwitch(stateHandler);
   359 }
   362 }
   360 
   363 
   361 /*!
   364 /*!
   362 Returns pointer to active focus object.
   365 Returns pointer to active focus object.
   363 */
   366 */
   364 HbInputFocusObject* HbInputMethod::focusObject() const
   367 HbInputFocusObject *HbInputMethod::focusObject() const
   365 {
   368 {
   366     Q_D(const HbInputMethod);
   369     Q_D(const HbInputMethod);
   367     return d->mFocusObject;
   370     return d->mFocusObject;
   368 }
   371 }
   369 
   372 
   372 default focus handling mechanism for QInputContext system. Input method
   375 default focus handling mechanism for QInputContext system. Input method
   373 implementation should never override this method unless it knows what it is doing.
   376 implementation should never override this method unless it knows what it is doing.
   374 
   377 
   375 \sa setFocusObject
   378 \sa setFocusObject
   376 */
   379 */
   377 void HbInputMethod::setFocusWidget(QWidget* widget)
   380 void HbInputMethod::setFocusWidget(QWidget *widget)
   378 {
   381 {
   379     Q_D(HbInputMethod);
   382     Q_D(HbInputMethod);
   380     
   383 
   381     if (d->mFocusLocked) {
   384     if (d->mFocusLocked) {
   382 	    return;
   385         return;
   383 	}
   386     }
   384 		
   387 
   385     // attach focuswidget to prxoy inputcontext as proxy is 
   388     // attach focuswidget to prxoy inputcontext as proxy is
   386     // the only inputcotext known to qt framework.
   389     // the only inputcotext known to qt framework.
   387     d->proxy()->QInputContext::setFocusWidget(widget);
   390     d->proxy()->QInputContext::setFocusWidget(widget);
   388     
   391 
   389     if (!widget) {
   392     if (!widget) {
   390         // Losing focus.
   393         // Losing focus.
   391         if (d->mFocusObject) {
   394         if (d->mFocusObject) {
   392             focusLost(false);
   395             focusLost(false);
   393             d->hideMainWindow();
   396             d->hideMainWindow();
   395             d->mFocusObject = 0;
   398             d->mFocusObject = 0;
   396         }
   399         }
   397         return;
   400         return;
   398     }
   401     }
   399 
   402 
   400     QGraphicsView* gView = qobject_cast<QGraphicsView*>(widget);
   403     QGraphicsView *gView = qobject_cast<QGraphicsView *>(widget);
   401     if (gView) {
   404     if (gView) {
   402         // We don't want to focus to graphics view but the items inside the scene, so just return
   405         // We don't want to focus to graphics view but the items inside the scene, so just return
   403         return;
   406         return;
   404     }
   407     }
   405 
   408 
   443     delete d->mFocusObject;
   446     delete d->mFocusObject;
   444     d->mFocusObject = 0;
   447     d->mFocusObject = 0;
   445 
   448 
   446     // Attach focus.
   449     // Attach focus.
   447     d->mFocusObject = new HbInputFocusObject(widget);
   450     d->mFocusObject = new HbInputFocusObject(widget);
   448     connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   451     connect(widget, SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *)));
   449 
   452 
   450     d->setFocusCommon();
   453     d->setFocusCommon();
   451 
   454 
   452     // The focus jumped from one editor to another. Make sure that vkb host
   455     // The focus jumped from one editor to another. Make sure that vkb host
   453     // updates the situation correctly.
   456     // updates the situation correctly.
   461 
   464 
   462 /*!
   465 /*!
   463 Checks if the destroyed widget is currently focused and clears the focus
   466 Checks if the destroyed widget is currently focused and clears the focus
   464 if needed. This method should not be overridden.
   467 if needed. This method should not be overridden.
   465 */
   468 */
   466 void HbInputMethod::widgetDestroyed(QWidget* widget)
   469 void HbInputMethod::widgetDestroyed(QWidget *widget)
   467 {
   470 {
   468     Q_D(HbInputMethod);
   471     Q_D(HbInputMethod);
   469 
   472 
   470     if (d->mFocusObject && d->mFocusObject->object() == widget) {
   473     if (d->mFocusObject && d->mFocusObject->object() == widget) {
   471         delete d->mFocusObject;
   474         delete d->mFocusObject;
   484 requestSoftwareInputPanel event.
   487 requestSoftwareInputPanel event.
   485 
   488 
   486 \sa setFocusWidget
   489 \sa setFocusWidget
   487 \sa HbInputFocusObject
   490 \sa HbInputFocusObject
   488 */
   491 */
   489 void HbInputMethod::setFocusObject(HbInputFocusObject* focusObject)
   492 void HbInputMethod::setFocusObject(HbInputFocusObject *focusObject)
   490 {
   493 {
   491     Q_D(HbInputMethod);
   494     Q_D(HbInputMethod);
   492 
   495 
   493     if (d->mFocusLocked) {
   496     if (d->mFocusLocked) {
   494         return;
   497         return;
   495     }
   498     }
   496 
   499 
   497     if (focusObject == 0) {
   500     if (focusObject == 0) {
   498         // Losing focus.
   501         // Losing focus.
   499         if (d->mFocusObject != 0) {
   502         if (d->mFocusObject != 0) {
   500             disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   503             disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *)));
   501             focusLost(false);
   504             focusLost(false);
   502             d->hideMainWindow();
   505             d->hideMainWindow();
   503             delete d->mFocusObject;
   506             delete d->mFocusObject;
   504             d->mFocusObject = 0;
   507             d->mFocusObject = 0;
   505         }
   508         }
   506         return;
   509         return;
   507     }
   510     }
   508 
   511 
   509     if(d->compareWithCurrentFocusObject( focusObject )) {
   512     if (d->compareWithCurrentFocusObject(focusObject)) {
   510        // The incoming focus object is either same or points to same
   513         // The incoming focus object is either same or points to same
   511         // widget that the framework is already focused to and nothing needs to be done here.
   514         // widget that the framework is already focused to and nothing needs to be done here.
   512         // But because the ownership of the focus object is transferred to the
   515         // But because the ownership of the focus object is transferred to the
   513         // the framework, we need to delete the the incoming focus object in case it is
   516         // the framework, we need to delete the the incoming focus object in case it is
   514         // dirrefent than current one.
   517         // dirrefent than current one.
   515         if (d->mFocusObject != focusObject) {
   518         if (d->mFocusObject != focusObject) {
   522 
   525 
   523     // Delete previous focus object.
   526     // Delete previous focus object.
   524     if (d->mFocusObject) {
   527     if (d->mFocusObject) {
   525         refreshHost = true;
   528         refreshHost = true;
   526         focusLost(true);
   529         focusLost(true);
   527         disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   530         disconnect(d->mFocusObject->object(), SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *)));
   528         delete d->mFocusObject;
   531         delete d->mFocusObject;
   529         d->mFocusObject = 0;
   532         d->mFocusObject = 0;
   530     }
   533     }
   531 
   534 
   532     // Attach focus.
   535     // Attach focus.
   533     d->mFocusObject = focusObject;
   536     d->mFocusObject = focusObject;
   534     connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject*)), this, SLOT(editorDeleted(QObject*)));
   537     connect(d->mFocusObject->object(), SIGNAL(destroyed(QObject *)), this, SLOT(editorDeleted(QObject *)));
   535 
   538 
   536     d->setFocusCommon();
   539     d->setFocusCommon();
   537 
   540 
   538     // The focus jumped from one editor to another. Make sure that vkb host
   541     // The focus jumped from one editor to another. Make sure that vkb host
   539     // updates the situation correctly.
   542     // updates the situation correctly.
   591 
   594 
   592 /*!
   595 /*!
   593 The framework calls this method every time the input state changes. This is an empty default
   596 The framework calls this method every time the input state changes. This is an empty default
   594 implementation and the inheriting class should override it.
   597 implementation and the inheriting class should override it.
   595 */
   598 */
   596 void HbInputMethod::inputStateActivated(const HbInputState& newState)
   599 void HbInputMethod::inputStateActivated(const HbInputState &newState)
   597 {
   600 {
   598     Q_UNUSED(newState);
   601     Q_UNUSED(newState);
   599     // Empty default implementation.
   602     // Empty default implementation.
   600     if (this != HbInputMethodNull::Instance()) {
   603     if (this != HbInputMethodNull::Instance()) {
   601         qWarning("WARNING: inputStateActivated() default implementation called: Is that ok?");
   604         qWarning("WARNING: inputStateActivated() default implementation called: Is that ok?");
   641 instance may occur.
   644 instance may occur.
   642 
   645 
   643 \sa activateNextState
   646 \sa activateNextState
   644 \sa InputState
   647 \sa InputState
   645 */
   648 */
   646 bool HbInputMethod::activateState(const HbInputState& state)
   649 bool HbInputMethod::activateState(const HbInputState &state)
   647 {
   650 {
   648     Q_D(HbInputMethod);
   651     Q_D(HbInputMethod);
   649 
   652 
   650     if (!d->stateAllowedInEditor(state)) {
   653     if (!d->stateAllowedInEditor(state)) {
   651         return false;
   654         return false;
   652     }
   655     }
   653 
   656 
   654     d->mStateChangeInProgress = true;
   657     d->mStateChangeInProgress = true;
   655 
   658 
   656     HbInputMethod* stateHandler = HbInputModeCache::instance()->findStateHandler(state);
   659     HbInputMethod *stateHandler = HbInputModeCache::instance()->findStateHandler(state);
   657 
   660 
   658     if (!stateHandler) {
   661     if (!stateHandler) {
   659         stateHandler = HbInputMethodNull::Instance();
   662         stateHandler = HbInputMethodNull::Instance();
   660     }
   663     }
   661 
   664 
   697     if (currentTextCase == HbTextCaseAutomatic) {
   700     if (currentTextCase == HbTextCaseAutomatic) {
   698         if (!autoCaseNeeded) {
   701         if (!autoCaseNeeded) {
   699             currentTextCase = HbTextCaseLower;
   702             currentTextCase = HbTextCaseLower;
   700             refresh = true;
   703             refresh = true;
   701         }
   704         }
   702     } else if (autoCaseNeeded && currentTextCase != HbTextCaseUpper ) {
   705     } else if (autoCaseNeeded && currentTextCase != HbTextCaseUpper) {
   703         if (!d->isFixedCaseEditor()) {
   706         if (!d->isFixedCaseEditor()) {
   704             currentTextCase = HbTextCaseAutomatic;
   707             currentTextCase = HbTextCaseAutomatic;
   705             refresh = true;
   708             refresh = true;
   706         } else {
   709         } else {
   707             return;
   710             return;
   719 Receives the screen orientation signal. Will determine correct input state for new
   722 Receives the screen orientation signal. Will determine correct input state for new
   720 orientation and find state handler for it.
   723 orientation and find state handler for it.
   721 */
   724 */
   722 void HbInputMethod::orientationChanged(Qt::Orientation orientation)
   725 void HbInputMethod::orientationChanged(Qt::Orientation orientation)
   723 {
   726 {
       
   727     Q_D(HbInputMethod);
   724     Q_UNUSED(orientation);
   728     Q_UNUSED(orientation);
   725 
   729 
   726     if (isActiveMethod()) {
   730     if (d->mOldFocusObject) {
   727         // Make sure that if there was an editor focus before the orientation change,
   731         setFocusObject(d->mOldFocusObject);
   728         // it will re-focus.
   732         d->mOldFocusObject = 0;
   729         QInputContext *ic = qApp->inputContext();
   733     }
   730         if (ic) {
   734 
   731             QEvent *event = new QEvent(QEvent::RequestSoftwareInputPanel);
       
   732             ic->filterEvent(event);
       
   733             delete event;
       
   734         }
       
   735     }
       
   736 }
   735 }
   737 
   736 
   738 /*!
   737 /*!
   739 This slot is connected to setting proxy's orientation change warning signal. The default
   738 This slot is connected to setting proxy's orientation change warning signal. The default
   740 base class implementation is empty.
   739 base class implementation is empty.
   741 
   740 
   742 \sa HbInputSettingProxy
   741 \sa HbInputSettingProxy
   743 */
   742 */
   744 void HbInputMethod::orientationAboutToChange()
   743 void HbInputMethod::orientationAboutToChange()
   745 {
   744 {
       
   745     Q_D(HbInputMethod);
       
   746     reset();
       
   747     d->inputStateToEditor(d->mInputState);
       
   748     if (d->mFocusObject) {
       
   749         d->mOldFocusObject = d->mFocusObject;
       
   750         d->mFocusObject = 0;
       
   751     }
       
   752     HbVkbHostBridge::instance()->closeKeypad(true);
   746 }
   753 }
   747 
   754 
   748 /*!
   755 /*!
   749 Returns active input language. Unlike setting proxy's global input language,
   756 Returns active input language. Unlike setting proxy's global input language,
   750 this method takes into account input state language and possible editor local language,
   757 this method takes into account input state language and possible editor local language,
   802 }
   809 }
   803 \endcode
   810 \endcode
   804 */
   811 */
   805 void HbInputMethod::forceUnfocus()
   812 void HbInputMethod::forceUnfocus()
   806 {
   813 {
   807     HbInputMethod* active = activeInputMethod();
   814     HbInputMethod *active = activeInputMethod();
   808 
   815 
   809     if (active) {
   816     if (active) {
   810         active->focusLost(false);       
   817         active->focusLost(false);
   811         delete active->d_ptr->mFocusObject;
   818         delete active->d_ptr->mFocusObject;
   812         active->d_ptr->mFocusObject = 0;
   819         active->d_ptr->mFocusObject = 0;
   813     }
   820     }
   814 }
   821 }
   815 
   822 
   823 }
   830 }
   824 
   831 
   825 /*!
   832 /*!
   826 Deep copies the input state back to editor interface.
   833 Deep copies the input state back to editor interface.
   827 */
   834 */
   828 void HbInputMethod::inputStateToEditor(const HbInputState& source)
   835 void HbInputMethod::inputStateToEditor(const HbInputState &source)
   829 {
   836 {
   830     Q_D(HbInputMethod);
   837     Q_D(HbInputMethod);
   831     d->inputStateToEditor(source);
   838     d->inputStateToEditor(source);
   832 }
   839 }
   833 
   840 
   852 {
   859 {
   853     Q_D(HbInputMethod);
   860     Q_D(HbInputMethod);
   854     Q_UNUSED(obj);
   861     Q_UNUSED(obj);
   855 
   862 
   856     focusLost();
   863     focusLost();
   857 	d->hideMainWindow();
   864     d->hideMainWindow();
   858     delete d->mFocusObject;
   865     delete d->mFocusObject;
   859     d->mFocusObject = 0;
   866     d->mFocusObject = 0;
   860 
   867 
   861     reset();
   868     reset();
   862 }
   869 }