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) |
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 |