src/hbplugins/inputmethods/common/hbinputpredictionhandler.cpp
branchGCC_SURGE
changeset 15 f378acbc9cfb
parent 7 923ff622b8b9
child 21 4633027730f5
child 34 ed14f46c0e55
equal deleted inserted replaced
9:730c025d4b77 15:f378acbc9cfb
    37 #include "../touchinput/virtualqwerty.h"
    37 #include "../touchinput/virtualqwerty.h"
    38 
    38 
    39 #include "hbinputpredictionhandler_p.h"
    39 #include "hbinputpredictionhandler_p.h"
    40 #include "hbinputabstractbase.h"
    40 #include "hbinputabstractbase.h"
    41 
    41 
    42 #define HbDeltaHeight 3.0
    42 static const qreal HbDeltaHeight = 3.0;
    43 
    43 
    44 HbInputPredictionHandlerPrivate::HbInputPredictionHandlerPrivate()
    44 HbInputPredictionHandlerPrivate::HbInputPredictionHandlerPrivate()
    45     :mEngine(0),
    45     :mEngine(0),
    46     mCandidates(0),
    46     mCandidates(0),
    47     mBestGuessLocation(0),
    47     mBestGuessLocation(0),
    48     mShowTail(true),
    48     mShowTail(true),
    49     mTailShowing(false),
       
    50     mAutoAddedSpace(true),
    49     mAutoAddedSpace(true),
    51     mCanContinuePrediction(true),
    50     mCanContinuePrediction(true),
    52     mShowTooltip(true)
    51     mShowTooltip(true),
       
    52     mSpellQueryDialog(0)
    53 {
    53 {
    54 }
    54 }
    55 
    55 
    56 HbInputPredictionHandlerPrivate::~HbInputPredictionHandlerPrivate()
    56 HbInputPredictionHandlerPrivate::~HbInputPredictionHandlerPrivate()
    57 {
    57 {
    61     }
    61     }
    62 }
    62 }
    63 
    63 
    64 void HbInputPredictionHandlerPrivate::deleteOneCharacter()
    64 void HbInputPredictionHandlerPrivate::deleteOneCharacter()
    65 {
    65 {
       
    66     if (!mEngine && !mInputMethod->focusObject()) {
       
    67         return;
       
    68     }
    66     mShowTail = true;
    69     mShowTail = true;
    67     mShowTooltip = true;
    70     mShowTooltip = true;
    68     // A backspace in predictive means updating the engine for the delete key press
    71     // A backspace in predictive means updating the engine for the delete key press
    69     // and get the new candidate list from the engine.
    72     // and get the new candidate list from the engine.
    70     if ( mEngine->inputLength() >= 1 ) {
    73     if ( mEngine->inputLength() >= 1 ) {
    71         //Only autocomplition part should be deleted when autocompliton part is enable and user pressed a delete key
    74         int tailLength =  mInputMethod->focusObject()->preEditString().length() - mEngine->inputLength();
    72         if(false == mTailShowing) {
    75         //Only autocomplition part should be deleted when autocompliton part is shown and user pressed a delete key
       
    76         if(tailLength <= 0) { // no autocompletion part displayed
    73             mEngine->deleteKeyPress( this );
    77             mEngine->deleteKeyPress( this );
    74         }
    78         }
    75         //To prevent showing autocompletion part while deleting the characters using backspace key
    79         //To prevent showing autocompletion part while deleting the characters using backspace key
    76         mShowTail = false;
    80         mShowTail = false;
    77         mShowTooltip = false;
    81         mShowTooltip = false;
   110         return;
   114         return;
   111     }
   115     }
   112 
   116 
   113     QString commitString;
   117     QString commitString;
   114     if (mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   118     if (mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   115         if(mCandidates->count() <= mBestGuessLocation) {
   119         commitString = getCommitString();
   116             commitString = mCandidates->at(0);
   120         mEngine->addUsedWord(commitString);
   117             mEngine->addUsedWord(mCandidates->at(0));
       
   118         } else if (mShowTail == false) {
       
   119             commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength());
       
   120             mEngine->addUsedWord(mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()));
       
   121         } else {
       
   122             commitString = mCandidates->at(mBestGuessLocation);
       
   123             mEngine->addUsedWord(mCandidates->at(mBestGuessLocation));
       
   124         }
       
   125         if (character == QChar(' ') || character == QChar('\n')) {
   121         if (character == QChar(' ') || character == QChar('\n')) {
   126             mAutoAddedSpace = true;
   122             mAutoAddedSpace = true;
   127         }
   123         }
   128         commit(commitString);
   124         commit(commitString);
   129     } else {
   125     } else {
   165 /*!
   161 /*!
   166 This function shows the exact popup if needed.
   162 This function shows the exact popup if needed.
   167 */
   163 */
   168 void HbInputPredictionHandlerPrivate::showExactWordPopupIfNeeded()
   164 void HbInputPredictionHandlerPrivate::showExactWordPopupIfNeeded()
   169 {
   165 {
   170     Q_Q(HbInputPredictionHandler);
       
   171     if (mShowTooltip && mBestGuessLocation > 0 && mCandidates->at(0).mid(0, mEngine->inputLength()) \
       
   172         != mCandidates->at(mBestGuessLocation).mid(0, mEngine->inputLength())) {                
       
   173         q->processExactWord(mCandidates->at(0));
       
   174     } else {
       
   175         QString empty;
       
   176         q->processExactWord(empty);
       
   177     }
       
   178 }
   166 }
   179 
   167 
   180 QList<HbKeyPressProbability> HbInputPredictionHandlerPrivate::probableKeypresses()
   168 QList<HbKeyPressProbability> HbInputPredictionHandlerPrivate::probableKeypresses()
   181 {
   169 {
   182     if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   170     if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   220                 // TODO: Color from skin should be used
   208                 // TODO: Color from skin should be used
   221 				QColor col = HbColorScheme::color("qtc_input_hint_normal");
   209 				QColor col = HbColorScheme::color("qtc_input_hint_normal");
   222                 QBrush brush(col);
   210                 QBrush brush(col);
   223                 QTextCharFormat gray;
   211                 QTextCharFormat gray;
   224                 gray.setForeground(brush);
   212                 gray.setForeground(brush);
   225                 list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, mEngine->inputLength(), taillength, gray));
   213                 if((focusedObject->object())->inherits("QGraphicsWebView") || (focusedObject->object())->inherits("QWebView")) {
       
   214                     //QGraphicsWebView does not handle partial input length formatting well. Causes crash, a temporary fix provided,
       
   215                     //This makes the whole text field grey insted of just the auto-completion part. Anyways, it does not cause crash.
       
   216                     //This should be treated as a work around till QGraphicsWebView is fixed.
       
   217                     list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, 0, QInputMethodEvent::TextFormat, gray));
       
   218                 } else {
       
   219                     list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, mEngine->inputLength(), taillength, gray));
       
   220                 }
   226 				list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mEngine->inputLength(), 0, 0));
   221 				list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mEngine->inputLength(), 0, 0));
   227                 QInputMethodEvent event(mCandidates->at(mBestGuessLocation), list);
   222                 QInputMethodEvent event(mCandidates->at(mBestGuessLocation), list);
   228                 focusedObject->sendEvent(event);
   223                 focusedObject->sendEvent(event);
   229                 mTailShowing = true;
       
   230             } else {
   224             } else {
   231 				list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mCandidates->at(mBestGuessLocation).length(), 0, 0));
   225 				list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mCandidates->at(mBestGuessLocation).length(), 0, 0));
   232                 QInputMethodEvent event(mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()), list);
   226                 QInputMethodEvent event(mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()), list);
   233                 focusedObject->sendEvent(event);
   227                 focusedObject->sendEvent(event);
   234                 mTailShowing = false;
       
   235             }
   228             }
   236             if (mShowTooltip && mBestGuessLocation > 0 && mCandidates->at(0).mid(0, mEngine->inputLength()) \
   229             if (mShowTooltip && mBestGuessLocation > 0 && mCandidates->at(0).mid(0, mEngine->inputLength()) \
   237                 != mCandidates->at(mBestGuessLocation).mid(0, mEngine->inputLength())) {                
   230                 != mCandidates->at(mBestGuessLocation).mid(0, mEngine->inputLength())) {                
   238                     q->processExactWord(mCandidates->at(0));
   231                     q->processExactWord(mCandidates->at(0));
   239             } else {
   232             } else {
   250 bool HbInputPredictionHandlerPrivate::filterEvent(const QKeyEvent * event)
   243 bool HbInputPredictionHandlerPrivate::filterEvent(const QKeyEvent * event)
   251 {
   244 {
   252     HbInputFocusObject* focusObject = 0;
   245     HbInputFocusObject* focusObject = 0;
   253     focusObject = mInputMethod->focusObject();
   246     focusObject = mInputMethod->focusObject();
   254     //If the focused object is NULL or the key event is improper, can not continue
   247     //If the focused object is NULL or the key event is improper, can not continue
   255     if(!focusObject || (event->key()<0)) {
   248     if(!focusObject || event->key() < 0 ||
       
   249         event->key() == HbInputButton::ButtonKeyCodeCustom) {
   256         return false;
   250         return false;
   257     }
   251     }
   258 
   252 
   259     Q_Q(HbInputPredictionHandler);
   253     Q_Q(HbInputPredictionHandler);
   260     if (!mEngine) {
   254     if (!mEngine) {
   278                 deleteOneCharacter();
   272                 deleteOneCharacter();
   279             }
   273             }
   280 		}
   274 		}
   281         ret = true;
   275         ret = true;
   282         break;
   276         break;
   283     case Qt::Key_Period: // TODO: better handling for punctuation
   277     
   284     case Qt::Key_Comma: { // Need to take fn, shift etc. in account
       
   285             HbModifier modifier = HbModifierNone;
       
   286             int currentTextCase = focusObject->editorInterface().textCase();
       
   287             if ( HbTextCaseUpper == currentTextCase || HbTextCaseAutomatic == currentTextCase ) {
       
   288                 modifier = HbModifierShiftPressed;
       
   289             }
       
   290             QString qc;
       
   291             const HbMappedKey* mappedKey = mKeymap->keyForKeycode(mInputMethod->inputState().keyboard(), event->key());
       
   292 
       
   293             if (mappedKey) {
       
   294                 if (modifier == HbModifierNone) {
       
   295                     qc = mappedKey->characters(HbModifierNone).left(1);
       
   296                 } else if (modifier == HbModifierShiftPressed) {
       
   297                     qc = mappedKey->characters(HbModifierShiftPressed).left(1);
       
   298                 }
       
   299             }
       
   300 
       
   301             if (mEngine->inputLength() == 0) {
       
   302                 QList<QInputMethodEvent::Attribute> list;
       
   303                 QInputMethodEvent event(QString(), list);
       
   304                 if (mAutoAddedSpace) {
       
   305                     int cursorPos = mInputMethod->focusObject()->inputMethodQuery(Qt::ImCursorPosition).toInt();
       
   306                     QString text = mInputMethod->focusObject()->inputMethodQuery(Qt::ImSurroundingText).toString();
       
   307                     if (cursorPos > 0 && text.at(cursorPos-1).isSpace()) {
       
   308                         event.setCommitString(qc, -1, 1);
       
   309                     } else {
       
   310                         event.setCommitString(qc);
       
   311                     }
       
   312                 } else {
       
   313                     event.setCommitString(qc);
       
   314                 }
       
   315                 mAutoAddedSpace = false;
       
   316                 q->sendAndUpdate(event);
       
   317             } else {
       
   318                 // Fix for input stopping after ,. keys in qwerty predictive
       
   319                 commitAndAppendCharacter(qc.at(0));
       
   320                 QString empty;
       
   321                 q->processExactWord(empty);
       
   322             }
       
   323             ret = true;
       
   324         }
       
   325         break;
       
   326     case HbInputButton::ButtonKeyCodeEnter:
   278     case HbInputButton::ButtonKeyCodeEnter:
   327     case HbInputButton::ButtonKeyCodeSpace:
   279     case HbInputButton::ButtonKeyCodeSpace:
   328     case Qt::Key_0: {//Space
   280     
       
   281         {
   329             // A space means we have to commit the candidates when we are in predictive mode.
   282             // A space means we have to commit the candidates when we are in predictive mode.
   330             QChar qc(event->key());
   283             QChar qc(event->key());
   331             if (qc == Qt::Key_Enter) {
   284             if (qc == Qt::Key_Enter) {
   332                 qc = QChar('\n');  // Editor expects normal line feed.
   285                 qc = QChar('\n');  // Editor expects normal line feed.
   333             } else if (qc == Qt::Key_0) {
   286             } 
   334                 qc = QChar(' ');
       
   335             }
       
   336             commitAndAppendCharacter(qc);
   287             commitAndAppendCharacter(qc);
   337             // if exact word popup functionality is on then we should inform exact word popup
   288             // if exact word popup functionality is on then we should inform exact word popup
   338             // about the space.//++TODO
   289             // about the space.//++TODO
   339             QString empty;
   290             QString empty;
   340             q->processExactWord(empty);
   291             q->processExactWord(empty);
   413     if (mouseEvent->type() != QEvent::MouseButtonPress) {
   364     if (mouseEvent->type() != QEvent::MouseButtonPress) {
   414         return;
   365         return;
   415     }
   366     }
   416 
   367 
   417     //The mouse has been clicked outside of the pre-editing word and hence need to commit the word.
   368     //The mouse has been clicked outside of the pre-editing word and hence need to commit the word.
   418     if ( cursorPosition < 0 || (mCandidates->size()>0 && cursorPosition >= mCandidates->at(mBestGuessLocation).length())) {
   369     if ( cursorPosition < 0 || cursorPosition >= mInputMethod->focusObject()->preEditString().length()) {
   419         if (mEngine->inputLength() > 0 && mCandidates->count() > 0 && mBestGuessLocation < mCandidates->count()) {
   370         commit();
   420             commit(mCandidates->at(mBestGuessLocation),true);
       
   421         }
       
   422     } else if (mCandidates->size() > 0) {
   371     } else if (mCandidates->size() > 0) {
   423         if(!mCanContinuePrediction && (*mCandidates)[mBestGuessLocation].endsWith('?')) {
   372         if(!mCanContinuePrediction && (*mCandidates)[mBestGuessLocation].endsWith('?')) {
   424 			// mouse has been clicked on the pre-editing string ends with "?"
   373             // mouse has been clicked on the pre-editing string ends with "?"
   425             //Remove the "?" mark
   374             //Remove the "?" mark
   426             (*mCandidates)[mBestGuessLocation].chop(1);
   375             (*mCandidates)[mBestGuessLocation].chop(1);
   427             updateEditor();
   376             updateEditor();
   428             q->processCustomWord((*mCandidates)[mBestGuessLocation]);
   377             q->launchSpellQueryDialog();
   429             mCanContinuePrediction = true;
       
   430         } else {
   378         } else {
   431 
   379 
   432         //The mouse has been clicked on the pre-editing word, launch candidate list
   380         //The mouse has been clicked on the pre-editing word, launch candidate list
   433         mInputMethod->launchCandidatePopup(*mCandidates);
   381         mInputMethod->launchCandidatePopup(*mCandidates);
   434         }	
   382         }	
   435     }
   383     }
   436 }
   384 }
   437 
   385 
   438 void HbInputPredictionHandlerPrivate::init()
   386 void HbInputPredictionHandlerPrivate::init()
   439 {
   387 {
   440     mEngine = NULL;
   388     mEngine = 0;
   441     HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage();
   389     HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage();
   442     mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language());
   390     mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language());
   443     if (mEngine && !mCandidates) {
   391     if (mEngine && !mCandidates) {
   444         mCandidates = new QStringList();
   392         mCandidates = new QStringList();
   445     }
   393     }
   451         mEngine->clear();
   399         mEngine->clear();
   452     }
   400     }
   453     if (mCandidates) {
   401     if (mCandidates) {
   454         mCandidates->clear();
   402         mCandidates->clear();
   455     }
   403     }
   456 
       
   457     mTailShowing = false;
       
   458 }
   404 }
   459 
   405 
   460 void HbInputPredictionHandlerPrivate::commit()
   406 void HbInputPredictionHandlerPrivate::commit()
   461 {
   407 {
   462     if (mEngine && mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   408     if (mEngine && mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   463         if(!mCanContinuePrediction) {
       
   464             //Remove the "?" mark
       
   465             (*mCandidates)[mBestGuessLocation].chop(1);
       
   466         }
       
   467 		
   409 		
   468 		// Close exact word pop up in qwerty when the word is committed
   410 		// Close exact word pop up in qwerty when the word is committed
   469 		if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   411 		if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   470 			mInputMethod->closeExactWordPopup();
   412 			mInputMethod->closeExactWordPopup();
   471 		}
   413 		}
   472 		
   414 		
   473         QString commitString;
   415         QString commitString = getCommitString();
       
   416 
       
   417         // need to update the freq information
       
   418         mEngine->commit(commitString);
       
   419         commit(commitString,false);
       
   420     }
       
   421 }
       
   422 
       
   423 QString HbInputPredictionHandlerPrivate::getCommitString()
       
   424 {
       
   425     QString commitString;
       
   426     if(mCandidates->count()) {
       
   427         if(!mCanContinuePrediction) {
       
   428            //Remove the "?" mark
       
   429            (*mCandidates)[mBestGuessLocation].chop(1);
       
   430         }
   474         if(mCandidates->count() <= mBestGuessLocation) {
   431         if(mCandidates->count() <= mBestGuessLocation) {
   475             commitString = mCandidates->at(0);
   432             commitString = mCandidates->at(0);
   476         } else if (mShowTail == false) {
   433         } else if (mShowTail == false) {
   477             commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength());
   434             commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength());
   478         } else {
   435         } else {
   479             commitString = mCandidates->at(mBestGuessLocation);
   436             commitString = mCandidates->at(mBestGuessLocation);
   480         }
   437         }
   481         // need to update the freq information
   438     }
   482         mEngine->commit(commitString);
   439     return commitString;
   483         commit(commitString,false);
       
   484     }
       
   485 }
   440 }
   486 
   441 
   487 /*!
   442 /*!
   488 This function accepts a Qstring and commits the string to editor. This also clears all the key presses and
   443 This function accepts a Qstring and commits the string to editor. This also clears all the key presses and
   489 candidates from prediction engine
   444 candidates from prediction engine
   490 */
   445 */
   491 void HbInputPredictionHandlerPrivate::commit(const QString& string, bool addToUsedWordDict, bool isAsync)
   446 void HbInputPredictionHandlerPrivate::commit(const QString& string, bool addToUsedWordDict, bool isAsync)
   492 {
   447 {
   493     Q_Q(HbInputPredictionHandler);
   448     Q_Q(HbInputPredictionHandler);
   494     if(!mCanContinuePrediction) {
   449 
   495         //Remove the "?" mark
   450     // Close exact word pop up in qwerty when the word is committed
   496         (*mCandidates)[mBestGuessLocation].chop(1);
       
   497     }
       
   498 
       
   499 	// Close exact word pop up in qwerty when the word is committed
       
   500 	if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   451 	if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   501 		mInputMethod->closeExactWordPopup();
   452 		mInputMethod->closeExactWordPopup();
   502 	}
   453 	}
   503 
   454 
   504     q->commitAndUpdate(string, 0, 0, isAsync);
   455     q->commitAndUpdate(string, 0, 0, isAsync);
   505 
   456 
   506     if(mEngine) {
   457     if(mEngine) {
   507         if(addToUsedWordDict && !string.isEmpty()) {
   458         if(addToUsedWordDict && !string.isEmpty()) {
   508             QString separator = " ";
   459             QChar spaceChar(' ');
   509             QStringList stringList = string.split(separator, QString::SkipEmptyParts);
   460             QStringList stringList = string.split(spaceChar, QString::SkipEmptyParts);
   510             foreach (QString str, stringList) {
   461             foreach (const QString str, stringList) {
   511                 mEngine->addUsedWord(str);
   462                 mEngine->addUsedWord(str);
   512             }
   463             }
   513         }
   464         }
   514         mEngine->clear();
   465         mEngine->clear();
   515     }
   466     }
   516 
   467 
   517     //Enable the flag after commit
   468     //Enable the flag after commit
   518     mCanContinuePrediction = true;
   469     mCanContinuePrediction = true;
   519 	mTailShowing = false;
       
   520 }
   470 }
   521 
   471 
   522 /*!
   472 /*!
   523 This function accepts a QInputMethodEvent and commits the event to editor. This also clears all the key presses and
   473 This function accepts a QInputMethodEvent and commits the event to editor. This also clears all the key presses and
   524 candidates from prediction engine
   474 candidates from prediction engine
   543         mEngine->clear();
   493         mEngine->clear();
   544     }
   494     }
   545 
   495 
   546     //Enable the flag after commit
   496     //Enable the flag after commit
   547     mCanContinuePrediction = true;
   497     mCanContinuePrediction = true;
   548 	mTailShowing = false;
       
   549 
       
   550 }
   498 }
   551 
   499 
   552 void HbInputPredictionHandlerPrivate::commitExactWord()
   500 void HbInputPredictionHandlerPrivate::commitExactWord()
   553 {
   501 {
   554     if (mEngine && mEngine->inputLength() /*> 0 && mCandidates->count() > 0*/) {
   502     if (mEngine && mEngine->inputLength() /*> 0 && mCandidates->count() > 0*/) {
   599     } else {
   547     } else {
   600         mCanContinuePrediction = true;
   548         mCanContinuePrediction = true;
   601     }
   549     }
   602 }
   550 }
   603 
   551 
       
   552 void HbInputPredictionHandlerPrivate::setPreEditTextToEditor(QString string, bool showAutocompletionPart)
       
   553 {
       
   554     //update the editor with pre-edit text
       
   555     mEngine->setWord(string);
       
   556     bool used = false;	 
       
   557     mEngine->updateCandidates(mBestGuessLocation, used);
       
   558     if(showAutocompletionPart) {
       
   559         mShowTail = true;
       
   560     } else {
       
   561         mShowTail =  false;
       
   562     }
       
   563     updateEditor();
       
   564 
       
   565 }
       
   566 
   604 HbInputPredictionHandler::HbInputPredictionHandler(HbInputPredictionHandlerPrivate &dd, HbInputAbstractMethod* inputMethod)
   567 HbInputPredictionHandler::HbInputPredictionHandler(HbInputPredictionHandlerPrivate &dd, HbInputAbstractMethod* inputMethod)
   605 :HbInputModeHandler(dd, inputMethod)
   568 :HbInputModeHandler(dd, inputMethod)
   606 {
   569 {
   607     Q_D(HbInputPredictionHandler);
   570     Q_D(HbInputPredictionHandler);
   608     d->q_ptr = this;
   571     d->q_ptr = this;
   629 bool HbInputPredictionHandler::actionHandler(HbInputModeAction action)
   592 bool HbInputPredictionHandler::actionHandler(HbInputModeAction action)
   630 {
   593 {
   631     Q_D(HbInputPredictionHandler);
   594     Q_D(HbInputPredictionHandler);
   632     bool ret = true;
   595     bool ret = true;
   633     switch (action) {
   596     switch (action) {
   634         case HbInputModeActionReset: {
   597         case HbInputModeActionReset:
   635             //At the moment we are commiting the text with the autocompletion part as it needs to be committed on clicking outside the editor. 
   598         case HbInputModeActionCommit:
       
   599         case HbInputModeActionFocusLost: {
       
   600             //At the moment we are committing the text with the autocompletion part as it needs to be committed on clicking outside the editor. 
   636             //TO DO : When We back to the application by pressing Application key the inline word should not commit and remain in the inline editing
   601             //TO DO : When We back to the application by pressing Application key the inline word should not commit and remain in the inline editing
   637             //d->mShowTail = false;
   602             //d->mShowTail = false;
   638             d->commit();
   603             d->commit();
   639             d->reset();
   604             d->reset();
   640         }
       
   641         break;
       
   642         case HbInputModeActionFocusLost: {
       
   643             // if focus lost happens and before that if toolitip is available then typing line word should be committed in the editor 
       
   644             // if tooltip and autocompletion part is available then typing line word should be committed in the editor along with the autocompletion part            
       
   645             // Focus change should commit the auto-completed part as well.
       
   646             d->commit();
       
   647         }
       
   648             break;
       
   649         case HbInputModeActionCommit: {
       
   650             d->commit();
       
   651         }
   605         }
   652         break;
   606         break;
   653         case HbInputModeActionDeleteAndCommit: {
   607         case HbInputModeActionDeleteAndCommit: {
   654             deleteOneCharacter();
   608             deleteOneCharacter();
   655             d->commit();
   609             d->commit();
   692             }
   646             }
   693             break;
   647             break;
   694         case HbInputModeActionHideTail:
   648         case HbInputModeActionHideTail:
   695             d->mShowTail = false;
   649             d->mShowTail = false;
   696             break;
   650             break;
       
   651         case HbInputModeActionCloseSpellQuery:
       
   652             closeSpellQueryDialog();
       
   653             break;
   697         default:
   654         default:
   698             ret = HbInputModeHandler::actionHandler(action);
   655             ret = HbInputModeHandler::actionHandler(action);
   699         break;
   656             break;
   700     }
   657     }
   701     
   658     
   702     return ret;
   659     return ret;
   703 }
   660 }
   704 
   661 
   811 void HbInputPredictionHandler::processExactWord(QString exactWord)
   768 void HbInputPredictionHandler::processExactWord(QString exactWord)
   812 {
   769 {
   813     Q_UNUSED(exactWord);
   770     Q_UNUSED(exactWord);
   814 }
   771 }
   815 
   772 
   816 void HbInputPredictionHandler::processCustomWord(QString customWord)
       
   817 {
       
   818     Q_UNUSED(customWord);
       
   819 }
       
   820 
       
   821 void HbInputPredictionHandler::showExactWordPopupIfNeeded()
   773 void HbInputPredictionHandler::showExactWordPopupIfNeeded()
   822 {
   774 {
   823     Q_D(HbInputPredictionHandler);
   775     Q_D(HbInputPredictionHandler);
   824     d->showExactWordPopupIfNeeded();
   776     d->showExactWordPopupIfNeeded();
   825 }
   777 }
       
   778 
       
   779 // Launch spell query dialog in responce to launchSpellQueryDialog signal
       
   780 void HbInputPredictionHandler::launchSpellQueryDialog()
       
   781 {
       
   782     Q_D(HbInputPredictionHandler);
       
   783     HbInputFocusObject *focusedObject = d->mInputMethod->focusObject();
       
   784     if(!focusedObject) {
       
   785         return;
       
   786     }
       
   787 
       
   788     // As of now we need to delete and create mSpellQueryDialog every time 
       
   789     // we launch it. If we launch the same dialog, keypad does not open sometimes. 
       
   790     // Will take sometime to find out the root cause of this, and will fix this. 
       
   791     if(d->mSpellQueryDialog) {
       
   792         delete d->mSpellQueryDialog;
       
   793         d->mSpellQueryDialog =0;
       
   794     }
       
   795     if(!d->mSpellQueryDialog) {
       
   796         d->mSpellQueryDialog = new HbInputSpellQuery(d->mInputMethod,this); 
       
   797         d->mSpellQueryDialog->setParent(this);
       
   798     }
       
   799 
       
   800     QString string;
       
   801     if(d->mCandidates && (*(d->mCandidates)).size() >= d->mBestGuessLocation + 1) {
       
   802         string = (*(d->mCandidates))[d->mBestGuessLocation].left(d->mEngine->inputLength());
       
   803     }
       
   804     d->reset();
       
   805     d->mSpellQueryDialog->launch(string);
       
   806 
       
   807 }
       
   808 
       
   809 // To force the spell query dialog to close.
       
   810 void HbInputPredictionHandler::closeSpellQueryDialog()
       
   811 {    
       
   812     Q_D(HbInputPredictionHandler);
       
   813     if (d->mSpellQueryDialog && d->mSpellQueryDialog->isVisible()) {
       
   814         d->mSpellQueryDialog->close();
       
   815     }
       
   816 }
       
   817 
       
   818 //
       
   819 void HbInputPredictionHandler::spellQueryDialogClosed(QObject *savedFocusObject
       
   820                                                       ,HbInputSpellQuery::HbSpellCloseReason closeReason,const QString &string)
       
   821 {
       
   822     if(!savedFocusObject) {
       
   823         return;
       
   824     }
       
   825 
       
   826     Q_D(HbInputPredictionHandler);
       
   827     // set the focus back to the editor which caused the launch of spell dialog.
       
   828     HbInputFocusObject *newFocusObject = new HbInputFocusObject(savedFocusObject);
       
   829     newFocusObject->releaseFocus();
       
   830     newFocusObject->setFocus();
       
   831     HbAbstractEdit *abstractEdit = qobject_cast<HbAbstractEdit*>(savedFocusObject);
       
   832     if(abstractEdit) {
       
   833         abstractEdit->setCursorPosition(abstractEdit->cursorPosition());
       
   834     }
       
   835     d->mInputMethod->setFocusObject(newFocusObject);
       
   836 
       
   837     if (closeReason == HbInputSpellQuery::HbOkPressed) {
       
   838         d->commit(string,true);
       
   839     } else if(closeReason == HbInputSpellQuery::HbCancelPressed) {
       
   840         //update the editor with pre-edit text
       
   841         d->setPreEditTextToEditor(string, d->mCanContinuePrediction);
       
   842         // This update is need for below usecase
       
   843         // Editor is empty => enter some data till their is no match => click on word
       
   844         // to launch spell query => now press cancel => testcase of keypad is uppercase,
       
   845         // but it should be lower case
       
   846         d->mInputMethod->updateState();
       
   847     } else if (closeReason == HbInputSpellQuery::HbForceClose) {
       
   848         // Force spell query close happens when oriantation is about to change.
       
   849         // In this case nomal commit() on input method does not seems to work.
       
   850         // So we are directly sending commit even to editor.
       
   851         QList<QInputMethodEvent::Attribute> list;
       
   852         QInputMethodEvent event(QString(), list);
       
   853         event.setCommitString(string);
       
   854         QApplication::sendEvent(savedFocusObject, &event);
       
   855     }
       
   856     // Enable the flag
       
   857     d->mCanContinuePrediction = true;
       
   858 }
       
   859 
       
   860 
       
   861 void HbInputPredictionHandler::setAutocompletionStatus(bool status)
       
   862 {
       
   863     Q_D(HbInputPredictionHandler);
       
   864     d->mAutocompletionEnabled = status;
       
   865     if(!d->mEngine) {
       
   866         return;
       
   867     }
       
   868     if(!status) {
       
   869         d->mEngine->disableFeature(HbPredFeatureWordCompletion);
       
   870     } else {
       
   871         d->mEngine->enableFeature(HbPredFeatureWordCompletion);
       
   872     }
       
   873 
       
   874 }
   826 // EOF
   875 // EOF