src/hbplugins/inputmethods/common/hbinputpredictionhandler.cpp
changeset 6 c3690ec91ef8
parent 5 627c4a0fd0e7
child 7 923ff622b8b9
equal deleted inserted replaced
5:627c4a0fd0e7 6:c3690ec91ef8
    32 #include <hbaction.h>
    32 #include <hbaction.h>
    33 #include <hbinputvkbhost.h>
    33 #include <hbinputvkbhost.h>
    34 #include <hbcolorscheme.h>
    34 #include <hbcolorscheme.h>
    35 #include <hbinpututils.h>
    35 #include <hbinpututils.h>
    36 #include <hbinputbutton.h>
    36 #include <hbinputbutton.h>
    37 #include "hbinputspellquerydialog.h"
       
    38 #include "../touchinput/virtualqwerty.h"
    37 #include "../touchinput/virtualqwerty.h"
    39 
    38 
    40 #include "hbinputpredictionhandler_p.h"
    39 #include "hbinputpredictionhandler_p.h"
    41 #include "hbinputabstractbase.h"
    40 #include "hbinputabstractbase.h"
    42 
    41 
    43 #define HbDeltaHeight 3.0
    42 static const qreal HbDeltaHeight = 3.0;
    44 
    43 
    45 HbInputPredictionHandlerPrivate::HbInputPredictionHandlerPrivate()
    44 HbInputPredictionHandlerPrivate::HbInputPredictionHandlerPrivate()
    46     :mEngine(0),
    45     :mEngine(0),
    47     mCandidates(0),
    46     mCandidates(0),
    48     mBestGuessLocation(0),
    47     mBestGuessLocation(0),
   112         return;
   111         return;
   113     }
   112     }
   114 
   113 
   115     QString commitString;
   114     QString commitString;
   116     if (mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   115     if (mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   117         if(mCandidates->count() <= mBestGuessLocation) {
   116         commitString = getCommitString();
   118             commitString = mCandidates->at(0);
   117         mEngine->addUsedWord(commitString);
   119             mEngine->addUsedWord(mCandidates->at(0));
       
   120         } else if (mShowTail == false) {
       
   121             commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength());
       
   122             mEngine->addUsedWord(mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()));
       
   123         } else {
       
   124             commitString = mCandidates->at(mBestGuessLocation);
       
   125             mEngine->addUsedWord(mCandidates->at(mBestGuessLocation));
       
   126         }
       
   127         if (character == QChar(' ') || character == QChar('\n')) {
   118         if (character == QChar(' ') || character == QChar('\n')) {
   128             mAutoAddedSpace = true;
   119             mAutoAddedSpace = true;
   129         }
   120         }
   130         commit(commitString);
   121         commit(commitString);
   131     } else {
   122     } else {
   167 /*!
   158 /*!
   168 This function shows the exact popup if needed.
   159 This function shows the exact popup if needed.
   169 */
   160 */
   170 void HbInputPredictionHandlerPrivate::showExactWordPopupIfNeeded()
   161 void HbInputPredictionHandlerPrivate::showExactWordPopupIfNeeded()
   171 {
   162 {
   172     Q_Q(HbInputPredictionHandler);
       
   173     if (mShowTooltip && mBestGuessLocation > 0 &&  mCandidates->count() > 0
       
   174     	&& mCandidates->at(0).mid(0, mEngine->inputLength()) \
       
   175         != mCandidates->at(mBestGuessLocation).mid(0, mEngine->inputLength())) {                
       
   176         q->processExactWord(mCandidates->at(0));
       
   177     } else {
       
   178         QString empty;
       
   179         q->processExactWord(empty);
       
   180     }
       
   181 }
   163 }
   182 
   164 
   183 QList<HbKeyPressProbability> HbInputPredictionHandlerPrivate::probableKeypresses()
   165 QList<HbKeyPressProbability> HbInputPredictionHandlerPrivate::probableKeypresses()
   184 {
   166 {
   185     if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   167     if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   424     if (mouseEvent->type() != QEvent::MouseButtonPress) {
   406     if (mouseEvent->type() != QEvent::MouseButtonPress) {
   425         return;
   407         return;
   426     }
   408     }
   427 
   409 
   428     //The mouse has been clicked outside of the pre-editing word and hence need to commit the word.
   410     //The mouse has been clicked outside of the pre-editing word and hence need to commit the word.
   429     if ( cursorPosition < 0 || (mCandidates->size()>0 && cursorPosition >= mCandidates->at(mBestGuessLocation).length())) {
   411     if ( cursorPosition < 0 || cursorPosition >= mInputMethod->focusObject()->preEditString().length()) {
   430         if (mEngine->inputLength() > 0 && mCandidates->count() > 0 && mBestGuessLocation < mCandidates->count()) {
   412         commit();
   431             commit(mCandidates->at(mBestGuessLocation),true);
       
   432         }
       
   433     } else if (mCandidates->size() > 0) {
   413     } else if (mCandidates->size() > 0) {
   434         if(!mCanContinuePrediction && (*mCandidates)[mBestGuessLocation].endsWith('?')) {
   414         if(!mCanContinuePrediction && (*mCandidates)[mBestGuessLocation].endsWith('?')) {
   435 			// mouse has been clicked on the pre-editing string ends with "?"
   415             // mouse has been clicked on the pre-editing string ends with "?"
   436             //Remove the "?" mark
   416             //Remove the "?" mark
   437             (*mCandidates)[mBestGuessLocation].chop(1);
   417             (*mCandidates)[mBestGuessLocation].chop(1);
   438             updateEditor();
   418             updateEditor();
   439             q->launchSpellQueryDialog();
   419             q->launchSpellQueryDialog();
   440             mCanContinuePrediction = true;
       
   441         } else {
   420         } else {
   442 
   421 
   443         //The mouse has been clicked on the pre-editing word, launch candidate list
   422         //The mouse has been clicked on the pre-editing word, launch candidate list
   444         mInputMethod->launchCandidatePopup(*mCandidates);
   423         mInputMethod->launchCandidatePopup(*mCandidates);
   445         }	
   424         }	
   446     }
   425     }
   447 }
   426 }
   448 
   427 
   449 void HbInputPredictionHandlerPrivate::init()
   428 void HbInputPredictionHandlerPrivate::init()
   450 {
   429 {
   451     mEngine = NULL;
   430     mEngine = 0;
   452     HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage();
   431     HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage();
   453     mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language());
   432     mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language());
   454     if (mEngine && !mCandidates) {
   433     if (mEngine && !mCandidates) {
   455         mCandidates = new QStringList();
   434         mCandidates = new QStringList();
   456     }
   435     }
   469 }
   448 }
   470 
   449 
   471 void HbInputPredictionHandlerPrivate::commit()
   450 void HbInputPredictionHandlerPrivate::commit()
   472 {
   451 {
   473     if (mEngine && mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   452     if (mEngine && mEngine->inputLength() > 0 && mCandidates->count() > 0) {
   474         if(!mCanContinuePrediction) {
       
   475             //Remove the "?" mark
       
   476             (*mCandidates)[mBestGuessLocation].chop(1);
       
   477         }
       
   478 		
   453 		
   479 		// Close exact word pop up in qwerty when the word is committed
   454 		// Close exact word pop up in qwerty when the word is committed
   480 		if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   455 		if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   481 			mInputMethod->closeExactWordPopup();
   456 			mInputMethod->closeExactWordPopup();
   482 		}
   457 		}
   483 		
   458 		
   484         QString commitString;
   459         QString commitString = getCommitString();
       
   460 
       
   461         // need to update the freq information
       
   462         mEngine->commit(commitString);
       
   463         commit(commitString,false);
       
   464     }
       
   465 }
       
   466 
       
   467 QString HbInputPredictionHandlerPrivate::getCommitString()
       
   468 {
       
   469     QString commitString;
       
   470     if(mCandidates->count()) {
       
   471         if(!mCanContinuePrediction) {
       
   472            //Remove the "?" mark
       
   473            (*mCandidates)[mBestGuessLocation].chop(1);
       
   474         }
   485         if(mCandidates->count() <= mBestGuessLocation) {
   475         if(mCandidates->count() <= mBestGuessLocation) {
   486             commitString = mCandidates->at(0);
   476             commitString = mCandidates->at(0);
   487         } else if (mShowTail == false) {
   477         } else if (mShowTail == false) {
   488             commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength());
   478             commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength());
   489         } else {
   479         } else {
   490             commitString = mCandidates->at(mBestGuessLocation);
   480             commitString = mCandidates->at(mBestGuessLocation);
   491         }
   481         }
   492         // need to update the freq information
   482     }
   493         mEngine->commit(commitString);
   483     return commitString;
   494         commit(commitString,false);
       
   495     }
       
   496 }
   484 }
   497 
   485 
   498 /*!
   486 /*!
   499 This function accepts a Qstring and commits the string to editor. This also clears all the key presses and
   487 This function accepts a Qstring and commits the string to editor. This also clears all the key presses and
   500 candidates from prediction engine
   488 candidates from prediction engine
   501 */
   489 */
   502 void HbInputPredictionHandlerPrivate::commit(const QString& string, bool addToUsedWordDict, bool isAsync)
   490 void HbInputPredictionHandlerPrivate::commit(const QString& string, bool addToUsedWordDict, bool isAsync)
   503 {
   491 {
   504     Q_Q(HbInputPredictionHandler);
   492     Q_Q(HbInputPredictionHandler);
   505     if(!mCanContinuePrediction) {
   493 
   506         //Remove the "?" mark
   494     // Close exact word pop up in qwerty when the word is committed
   507         (*mCandidates)[mBestGuessLocation].chop(1);
       
   508     }
       
   509 
       
   510 	// Close exact word pop up in qwerty when the word is committed
       
   511 	if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   495 	if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) {
   512 		mInputMethod->closeExactWordPopup();
   496 		mInputMethod->closeExactWordPopup();
   513 	}
   497 	}
   514 
   498 
   515     q->commitAndUpdate(string, 0, 0, isAsync);
   499     q->commitAndUpdate(string, 0, 0, isAsync);
   516 
   500 
   517     if(mEngine) {
   501     if(mEngine) {
   518         if(addToUsedWordDict && !string.isEmpty()) {
   502         if(addToUsedWordDict && !string.isEmpty()) {
   519             QString separator = " ";
   503             QChar spaceChar(' ');
   520             QStringList stringList = string.split(separator, QString::SkipEmptyParts);
   504             QStringList stringList = string.split(spaceChar, QString::SkipEmptyParts);
   521             foreach (QString str, stringList) {
   505             foreach (const QString str, stringList) {
   522                 mEngine->addUsedWord(str);
   506                 mEngine->addUsedWord(str);
   523             }
   507             }
   524         }
   508         }
   525         mEngine->clear();
   509         mEngine->clear();
   526     }
   510     }
   610     } else {
   594     } else {
   611         mCanContinuePrediction = true;
   595         mCanContinuePrediction = true;
   612     }
   596     }
   613 }
   597 }
   614 
   598 
   615 void HbInputPredictionHandlerPrivate::setPreEditTextToEditor(QString string)
   599 void HbInputPredictionHandlerPrivate::setPreEditTextToEditor(QString string, bool showAutocompletionPart)
   616 {
   600 {
   617     //update the editor with pre-edit text
   601     //update the editor with pre-edit text
   618     mEngine->setWord(string);
   602     mEngine->setWord(string);
   619     bool used = false;	 
   603     bool used = false;	 
   620     mEngine->updateCandidates(mBestGuessLocation, used);
   604     mEngine->updateCandidates(mBestGuessLocation, used);
   621     mTailShowing = true;
   605     if(showAutocompletionPart) {
       
   606         mShowTail = true;
       
   607     } else {
       
   608         mShowTail =  false;
       
   609     }
   622     updateEditor();
   610     updateEditor();
   623 
   611 
   624 }
   612 }
   625 
   613 
   626 HbInputPredictionHandler::HbInputPredictionHandler(HbInputPredictionHandlerPrivate &dd, HbInputAbstractMethod* inputMethod)
   614 HbInputPredictionHandler::HbInputPredictionHandler(HbInputPredictionHandlerPrivate &dd, HbInputAbstractMethod* inputMethod)
   654     bool ret = true;
   642     bool ret = true;
   655     switch (action) {
   643     switch (action) {
   656         case HbInputModeActionReset:
   644         case HbInputModeActionReset:
   657         case HbInputModeActionCommit:
   645         case HbInputModeActionCommit:
   658         case HbInputModeActionFocusLost: {
   646         case HbInputModeActionFocusLost: {
   659             //At the moment we are commiting the text with the autocompletion part as it needs to be committed on clicking outside the editor. 
   647             //At the moment we are committing the text with the autocompletion part as it needs to be committed on clicking outside the editor. 
   660             //TO DO : When We back to the application by pressing Application key the inline word should not commit and remain in the inline editing
   648             //TO DO : When We back to the application by pressing Application key the inline word should not commit and remain in the inline editing
   661             //d->mShowTail = false;
   649             //d->mShowTail = false;
   662             d->commit();
   650             d->commit();
   663             d->reset();
   651             d->reset();
   664         }
   652         }
   873         d->mSpellQueryDialog->close();
   861         d->mSpellQueryDialog->close();
   874     }
   862     }
   875 }
   863 }
   876 
   864 
   877 //
   865 //
   878 void HbInputPredictionHandler::spellQueryDialogClosed(QObject *savedFocusObject,bool isOk,QString string)
   866 void HbInputPredictionHandler::spellQueryDialogClosed(QObject *savedFocusObject
   879 {
   867                                                       ,HbInputSpellQuery::HbSpellCloseReason closeReason,const QString &string)
   880     Q_D(HbInputPredictionHandler);
   868 {
   881 
   869     if(!savedFocusObject) {
       
   870         return;
       
   871     }
       
   872 
       
   873     Q_D(HbInputPredictionHandler);
   882     // set the focus back to the editor which caused the launch of spell dialog.
   874     // set the focus back to the editor which caused the launch of spell dialog.
   883     if(savedFocusObject) {
   875     HbInputFocusObject *newFocusObject = new HbInputFocusObject(savedFocusObject);
   884         HbInputFocusObject *newFocusObject = new HbInputFocusObject(savedFocusObject);
   876     newFocusObject->releaseFocus();
   885         newFocusObject->releaseFocus();
   877     newFocusObject->setFocus();
   886         newFocusObject->setFocus();
   878     HbAbstractEdit *abstractEdit = qobject_cast<HbAbstractEdit*>(savedFocusObject);
   887         HbAbstractEdit *abstractEdit = qobject_cast<HbAbstractEdit*>(savedFocusObject);
   879     if(abstractEdit) {
   888         if(abstractEdit) {
   880         abstractEdit->setCursorPosition(abstractEdit->cursorPosition());
   889             abstractEdit->setCursorPosition(abstractEdit->cursorPosition());
   881     }
   890         }
   882     d->mInputMethod->setFocusObject(newFocusObject);
   891         d->mInputMethod->setFocusObject(newFocusObject);
   883 
   892     }
   884     if (closeReason == HbInputSpellQuery::HbOkPressed) {
   893 
       
   894     if (isOk) {
       
   895         d->commit(string,true);
   885         d->commit(string,true);
   896     } else {
   886     } else if(closeReason == HbInputSpellQuery::HbCancelPressed) {
   897         //update the editor with pre-edit text
   887         //update the editor with pre-edit text
   898         d->setPreEditTextToEditor(string);
   888         d->setPreEditTextToEditor(string, d->mCanContinuePrediction);
   899         // This update is need for below usecase
   889         // This update is need for below usecase
   900         // Editor is empty => enter some data till their is no match => click on word
   890         // Editor is empty => enter some data till their is no match => click on word
   901         // to lauch spell query => now press cancel => testcase of keypad is uppercase,
   891         // to launch spell query => now press cancel => testcase of keypad is uppercase,
   902         // but it should be lower case
   892         // but it should be lower case
   903         d->mInputMethod->updateState();
   893         d->mInputMethod->updateState();
   904     }
   894     } else if (closeReason == HbInputSpellQuery::HbForceClose) {
       
   895         // Force spell query close happens when oriantation is about to change.
       
   896         // In this case nomal commit() on input method does not seems to work.
       
   897         // So we are directly sending commit even to editor.
       
   898         QList<QInputMethodEvent::Attribute> list;
       
   899         QInputMethodEvent event(QString(), list);
       
   900         event.setCommitString(string);
       
   901         QApplication::sendEvent(savedFocusObject, &event);
       
   902     }
       
   903     // Enable the flag
       
   904     d->mCanContinuePrediction = true;
       
   905 }
       
   906 
       
   907 
       
   908 void HbInputPredictionHandler::setAutocompletionStatus(bool status)
       
   909 {
       
   910     Q_D(HbInputPredictionHandler);
       
   911     d->mAutocompletionEnabled = status;
       
   912     if(!d->mEngine) {
       
   913         return;
       
   914     }
       
   915     if(!status) {
       
   916         d->mEngine->disableFeature(HbPredFeatureWordCompletion);
       
   917     } else {
       
   918         d->mEngine->enableFeature(HbPredFeatureWordCompletion);
       
   919     }
       
   920 
   905 }
   921 }
   906 // EOF
   922 // EOF