diff -r 000000000000 -r 16d8024aca5e src/hbplugins/inputmethods/common/hbinputpredictionhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbplugins/inputmethods/common/hbinputpredictionhandler.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,896 @@ +/**************************************************************************** +** +** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (developer.feedback@nokia.com) +** +** This file is part of the HbPlugins module of the UI Extensions for Mobile. +** +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at developer.feedback@nokia.com. +** +****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../touchinput/virtualqwerty.h" + +#include "hbinputpredictionhandler_p.h" +#include "hbinputabstractbase.h" + +#define HbDeltaHeight 3.0 + +HbInputPredictionHandlerPrivate::HbInputPredictionHandlerPrivate() + :mEngine(0), + mCandidates(0), + mBestGuessLocation(0), + mShowTail(true), + mTailShowing(false), + mAutoAddedSpace(true), + mCanContinuePrediction(true), + mShowTooltip(true) +{ +} + +HbInputPredictionHandlerPrivate::~HbInputPredictionHandlerPrivate() +{ + if (mCandidates) { + delete mCandidates; + mCandidates = 0; + } +} + +void HbInputPredictionHandlerPrivate::deleteOneCharacter() +{ + mShowTail = true; + mShowTooltip = true; + // A backspace in predictive means updating the engine for the delete key press + // and get the new candidate list from the engine. + if ((mEngine->inputLength() >= 1) || selectWord()) { + //Only autocomplition part should be deleted when autocompliton part is enable and user pressed a delete key + if(false == mTailShowing) { + mEngine->deleteKeyPress( this ); + } + //To prevent showing autocompletion part while deleting the characters using backspace key + mShowTail = false; + mShowTooltip = false; + if (mEngine->inputLength() > 0) { + bool unused = false; + mEngine->updateCandidates(mBestGuessLocation, unused); + if (!mCandidates->count()) { + mCandidates->append(mEngine->currentWord()); + } + } + mCanContinuePrediction = true; + // update the editor with the new preedit text. + updateEditor(); + return; + } + + HbInputFocusObject* focusedObject = 0; + focusedObject = mInputMethod->focusObject(); + if (!focusedObject) { + return; + } + + if ((focusedObject->inputMethodQuery(Qt::ImCursorPosition).toInt() >= 0) || focusedObject->preEditString().length()) { + QList list; + QInputMethodEvent event(QString(), list); + event.setCommitString(QString(), -1, 1); + commit(event); + } +} + +void HbInputPredictionHandlerPrivate::commitAndAppendCharacter(QChar character) +{ + if (!mEngine) { + return; + } + + HbInputFocusObject* focusedObject = 0; + focusedObject = mInputMethod->focusObject(); + if (!focusedObject) { + return; + } + + QString commitString; + if (mEngine->inputLength() > 0 && mCandidates->count() > 0) { + if(mCandidates->count() <= mBestGuessLocation) { + commitString = mCandidates->at(0); + mEngine->addUsedWord(mCandidates->at(0)); + } else if (mShowTail == false) { + commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()); + mEngine->addUsedWord(mCandidates->at(mBestGuessLocation).left(mEngine->inputLength())); + } else { + commitString = mCandidates->at(mBestGuessLocation); + mEngine->addUsedWord(mCandidates->at(mBestGuessLocation)); + } + if (character == QChar(' ') || character == QChar('\n')) { + mAutoAddedSpace = true; + } + commit(commitString); + } else { + mAutoAddedSpace = false; + } + commitString = character; + commit(commitString); +} + +/*! +Commits the candidate upon closing of the candidate list. Now can the closing key be anything other than +just selection. Need to evaluate this. When the candidate list is visible, the current implementation of the +candidate list does not allow the virtual keypad to be clicked. +*/ +void HbInputPredictionHandlerPrivate::candidatePopupClosed(int closingKey, const QString& activatedText) +{ + if (!mEngine) { + return; + } + + HbInputFocusObject* focusedObject = 0; + focusedObject = mInputMethod->focusObject(); + if (!focusedObject) { + return; + } + + QString commitString = activatedText; + if (closingKey == Qt::Key_0 || closingKey == Qt::Key_Space) { + commitString = activatedText+' '; + } else if (closingKey == Qt::Key_Enter || closingKey == Qt::Key_Return) { + commitString = activatedText; + commit(commitString); + commitString = '\n'; + } + + commit(commitString,true); +} + +/*! +This function shows the exact popup if needed. +*/ +void HbInputPredictionHandlerPrivate::showExactWordPopupIfNeeded() +{ + Q_Q(HbInputPredictionHandler); + if (mShowTooltip && mBestGuessLocation > 0 && mCandidates->at(0).mid(0, mEngine->inputLength()) \ + != mCandidates->at(mBestGuessLocation).mid(0, mEngine->inputLength())) { + q->processExactWord(mCandidates->at(0)); + } else { + QString empty; + q->processExactWord(empty); + } +} + +QList HbInputPredictionHandlerPrivate::probableKeypresses() +{ + if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) { + //Useof the concrete input method implementations make the modehandlersin flexible. + //Later an intermediate abstract class needsto be introduced. + HbVirtualQwerty * qwertyInputMethod = qobject_cast(mInputMethod); + if(qwertyInputMethod) { + return qwertyInputMethod->probableKeypresses(); + } + } + return QList(); +} + +/*! +This sets the selected candidate from the candidate list as the editor text. +*/ +bool HbInputPredictionHandlerPrivate::selectWord(bool selectFromLeft) +{ + if (!mEngine) { + return false; + } + mShowTail = false; + + HbInputFocusObject* focusedObject = 0; + focusedObject = mInputMethod->focusObject(); + if(!focusedObject) { + return false; + } + // No word selected, if we move next to a word on left side, select it + int cursorPos = focusedObject->inputMethodQuery(Qt::ImCursorPosition).toInt(); + + QString text = focusedObject->inputMethodQuery(Qt::ImSurroundingText).toString(); + if ((cursorPos > 0 && selectFromLeft) || (cursorPos < text.length() && !selectFromLeft)) { + int start; + int end; + if (selectFromLeft && cursorPos>=1 &&!text.at(cursorPos-1).isSpace()) { + // selecting word from left side of cursor + end = cursorPos; + for(start = end; start > 0; start--) { + if (text.at(start-1).isSpace()) { + break; + } + } + } else if (!selectFromLeft && !text.at(cursorPos).isSpace()) { + // selecting word from right side of cursor + start = cursorPos; + for(end = start; end < text.length(); ++end) { + if (text.at(end).isSpace()) { + break; + } + } + } else { + // no word in the direction where cursor is moving + return false; + } + int length = end-start; + // update internal state and editor + if(length > 0){ + mEngine->setWord(text.mid(start, length), this); + } + bool unused = false; + mEngine->updateCandidates(mBestGuessLocation, unused); + //With selection we can always continue predicting, even when the selection + //is not a well predicted word. + if (!mCandidates->count()) { + //Here we are making sure that even if the engine does not return any candidate + //for given input sequence, the candidate list is non-empty. In such a scenario + //the candidate list will contain the actual selection or the exact word. + mCandidates->append(mEngine->currentWord()); + } + // + QTextCharFormat underlined; + QList list; + underlined.setFontUnderline(true); + QInputMethodEvent::Attribute textstyle(QInputMethodEvent::TextFormat, 0, mEngine->inputLength(), underlined); + list.append(textstyle); + QInputMethodEvent event(mCandidates->at(0), list); + event.setCommitString(QString(), (selectFromLeft ? -length : 0), length); + focusedObject->sendEvent(event); + return true; + } else { + return false; + } +} + +/*! +This method updates the editor contents based on the candidates available in the candidate list. +*/ +void HbInputPredictionHandlerPrivate::updateEditor() +{ + Q_Q(HbInputPredictionHandler); + if (!mEngine) { + return; + } + + QList list; + QTextCharFormat underlined; + HbInputFocusObject *focusedObject = 0; + underlined.setFontUnderline(true); + QInputMethodEvent::Attribute textstyle(QInputMethodEvent::TextFormat, 0, mEngine->inputLength(), underlined); + list.append(textstyle); + + focusedObject = mInputMethod->focusObject(); + Q_ASSERT(focusedObject); + + if (mEngine->inputLength() == 0) { + QInputMethodEvent event(QString(), list); + q->sendAndUpdate(event); + } else { + if (mCandidates->count() > mBestGuessLocation) { + int taillength = mCandidates->at(mBestGuessLocation).length() - mEngine->inputLength(); + if (taillength > 0 && mShowTail) { + // TODO: Color from skin should be used + QColor col = HbColorScheme::color("qtc_editor_hint_normal"); + QBrush brush(col); + QTextCharFormat gray; + gray.setForeground(brush); + list.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, mEngine->inputLength(), taillength, gray)); + list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mEngine->inputLength(), 0, 0)); + QInputMethodEvent event(mCandidates->at(mBestGuessLocation), list); + focusedObject->sendEvent(event); + mTailShowing = true; + } else { + list.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, mCandidates->at(mBestGuessLocation).length(), 0, 0)); + QInputMethodEvent event(mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()), list); + focusedObject->sendEvent(event); + mTailShowing = false; + } + if (mShowTooltip && mBestGuessLocation > 0 && mCandidates->at(0).mid(0, mEngine->inputLength()) \ + != mCandidates->at(mBestGuessLocation).mid(0, mEngine->inputLength())) { + q->processExactWord(mCandidates->at(0)); + } else { + QString empty; + q->processExactWord(empty); + } + } else { + QInputMethodEvent event(QString(""), list); + focusedObject->sendEvent(event); + } + } +} + +bool HbInputPredictionHandlerPrivate::filterEvent(const QKeyEvent * event) +{ + HbInputFocusObject* focusObject = 0; + focusObject = mInputMethod->focusObject(); + //If the focused object is NULL or the key event is improper, can not continue + if(!focusObject || (event->key()<0)) { + return false; + } + + Q_Q(HbInputPredictionHandler); + if (!mEngine) { + return false; + } + + bool ret = false; + mModifiers = Qt::NoModifier; + mCanContinuePrediction = true; + switch (event->key()) { + case Qt::Key_Backspace: + case Qt::Key_Delete: + { + QString currentSelection = focusObject->inputMethodQuery(Qt::ImCurrentSelection).toString(); + if(currentSelection.length()) { + QKeyEvent event = QKeyEvent(QEvent::KeyPress, Qt::Key_Backspace, Qt::NoModifier); + q->sendAndUpdate(event); + event = QKeyEvent(QEvent::KeyRelease, Qt::Key_Backspace, Qt::NoModifier); + q->sendAndUpdate(event); + } else { + deleteOneCharacter(); + } + } + ret = true; + break; + case Qt::Key_Period: // TODO: better handling for punctuation + case Qt::Key_Comma: { // Need to take fn, shift etc. in account + HbModifier modifier = HbModifierNone; + int currentTextCase = focusObject->editorInterface().textCase(); + if ( HbTextCaseUpper == currentTextCase || HbTextCaseAutomatic == currentTextCase ) { + modifier = HbModifierShiftPressed; + } + QString qc; + const HbMappedKey* mappedKey = mKeymap->keyForKeycode(mInputMethod->inputState().keyboard(), event->key()); + + if (mappedKey) { + if (modifier == HbModifierNone) { + qc = mappedKey->characters(HbModifierNone).left(1); + } else if (modifier == HbModifierShiftPressed) { + qc = mappedKey->characters(HbModifierShiftPressed).left(1); + } + } + + if (mEngine->inputLength() == 0) { + QList list; + QInputMethodEvent event(QString(), list); + if (mAutoAddedSpace) { + int cursorPos = mInputMethod->focusObject()->inputMethodQuery(Qt::ImCursorPosition).toInt(); + QString text = mInputMethod->focusObject()->inputMethodQuery(Qt::ImSurroundingText).toString(); + if (cursorPos > 0 && text.at(cursorPos-1).isSpace()) { + event.setCommitString(qc, -1, 1); + } else { + event.setCommitString(qc); + } + } else { + event.setCommitString(qc); + } + mAutoAddedSpace = false; + q->sendAndUpdate(event); + } else { + // Fix for input stopping after ,. keys in qwerty predictive + commitAndAppendCharacter(qc.at(0)); + QString empty; + q->processExactWord(empty); + } + ret = true; + } + break; + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Space: + case Qt::Key_0: {//Space + // A space means we have to commit the candidates when we are in predictive mode. + QChar qc(event->key()); + if (qc == Qt::Key_Enter) { + qc = QChar('\n'); // Editor expects normal line feed. + } else if (qc == Qt::Key_0) { + qc = QChar(' '); + } + commitAndAppendCharacter(qc); + // if exact word popup functionality is on then we should inform exact word popup + // about the space.//++TODO + QString empty; + q->processExactWord(empty); + ret = true; + } + break; + default: { + mShowTail = true; + mShowTooltip = true; + mAutoAddedSpace = false; + if (q->HbInputModeHandler::filterEvent(event)) { + return true; + } + if (mEngine) { + int currentTextCase = focusObject->editorInterface().textCase(); + if ( HbTextCaseUpper == currentTextCase || HbTextCaseAutomatic == currentTextCase ) { + mModifiers |= Qt::ShiftModifier; + } + mEngine->appendKeyPress(event->key(), mModifiers, mInputMethod->inputState().textCase(), this); + bool isCustomWord = false; + mEngine->updateCandidates(mBestGuessLocation, isCustomWord); + //The engine can not predict the word, it is a custom word. Now engine returns a + //single candidate entry which is actually the previous properly predicted character. + //TODO: In such a scenario, the prediction should stop and there needs to be some way for + //the user to tell the correct word which he wants (Some query editor). But, such a thing is + //not in place and hence the current implementation just appends a "?" and displays the + //previous word itself. + if (isCustomWord && mCandidates->count()) { + QString replacementText = mCandidates->at(0);//+"?"; + mCandidates->clear(); + mCandidates->append(replacementText); + //Since there is only one candidate, that's the best prediction. + mBestGuessLocation = 0; + } + //We need to check and carry out necessary steps if the engine fails to predict any candidate, + //for the give input sequence. + handleEmptyCandidateList(); + updateEditor(); + mInputMethod->updateState(); + ret = true; + } + } + } + + return ret; +} + +void HbInputPredictionHandlerPrivate::keyHandlerUnicode(const QChar& character) +{ + if (!mEngine) { + return; + } + mEngine->appendCharacter(character, mInputMethod->inputState().textCase(), this); + bool unused = false; + mEngine->updateCandidates(mBestGuessLocation, unused); + //Check if the candidate list is empty and take necessary steps if so. + handleEmptyCandidateList(); + updateEditor(); +} + + + +void HbInputPredictionHandlerPrivate::mouseHandler(int cursorPosition, QMouseEvent* mouseEvent) +{ + Q_Q(HbInputPredictionHandler); + // we are missing something we must get out. + if (!mEngine && !mInputMethod->focusObject()) { + return; + } + + // mouse move / hover events needs to be ignored. + if (mouseEvent->type() != QEvent::MouseButtonPress) { + return; + } + + //The mouse has been clicked outside of the pre-editing word and hence need to commit the word. + if ( cursorPosition < 0 || (mCandidates->size()>0 && cursorPosition >= mCandidates->at(mBestGuessLocation).length())) { + if (mEngine->inputLength() > 0 && mCandidates->count() > 0 && mBestGuessLocation < mCandidates->count()) { + commit(mCandidates->at(mBestGuessLocation),true); + } + } else if (mCandidates->size() > 0) { + if(!mCanContinuePrediction && (*mCandidates)[mBestGuessLocation].endsWith('?')) { + // mouse has been clicked on the pre-editing string ends with "?" + //Remove the "?" mark + (*mCandidates)[mBestGuessLocation].chop(1); + updateEditor(); + q->processCustomWord((*mCandidates)[mBestGuessLocation]); + mCanContinuePrediction = true; + } else { + + //The mouse has been clicked on the pre-editing word, launch candidate list + mInputMethod->launchCandidatePopup(*mCandidates); + } + } +} + +void HbInputPredictionHandlerPrivate::init() +{ + HbInputLanguage language = HbInputSettingProxy::instance()->globalInputLanguage(); + mEngine = HbPredictionFactory::instance()->predictionEngineForLanguage(language.language()); + if (mEngine) { + mCandidates = new QStringList(); + } +} + +void HbInputPredictionHandlerPrivate::reset() +{ + if (mEngine) { + mEngine->clear(); + } + if (mCandidates) { + mCandidates->clear(); + } + + mTailShowing = false; +} + +void HbInputPredictionHandlerPrivate::commit() +{ + if (mEngine && mEngine->inputLength() > 0 && mCandidates->count() > 0) { + if(!mCanContinuePrediction) { + //Remove the "?" mark + (*mCandidates)[mBestGuessLocation].chop(1); + } + + // Close exact word pop up in qwerty when the word is committed + if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) { + mInputMethod->closeExactWordPopup(); + } + + QString commitString; + if(mCandidates->count() <= mBestGuessLocation) { + commitString = mCandidates->at(0); + } else if (mShowTail == false) { + commitString = mCandidates->at(mBestGuessLocation).left(mEngine->inputLength()); + } else { + commitString = mCandidates->at(mBestGuessLocation); + } + // need to update the freq information + mEngine->commit(commitString); + commit(commitString,false); + } +} + +/*! +This function accepts a Qstring and commits the string to editor. This also clears all the key presses and +candidates from prediction engine +*/ +void HbInputPredictionHandlerPrivate::commit(const QString& string, bool addToUsedWordDict, bool isAsync) +{ + Q_Q(HbInputPredictionHandler); + if(!mCanContinuePrediction) { + //Remove the "?" mark + (*mCandidates)[mBestGuessLocation].chop(1); + } + + // Close exact word pop up in qwerty when the word is committed + if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) { + mInputMethod->closeExactWordPopup(); + } + + q->commitAndUpdate(string, 0, 0, isAsync); + + if(mEngine) { + if(addToUsedWordDict && !string.isEmpty()) { + QString separator = " "; + QStringList stringList = string.split(separator, QString::SkipEmptyParts); + foreach (QString str, stringList) { + mEngine->addUsedWord(str); + } + } + mEngine->clear(); + } + + //Enable the flag after commit + mCanContinuePrediction = true; + mTailShowing = false; +} + +/*! +This function accepts a QInputMethodEvent and commits the event to editor. This also clears all the key presses and +candidates from prediction engine +Warning: Use this only when you want to commit some string to editor. If you want to send some formating information +to editor, use sendAndUpdate(QInputMethodEvent & event); The reason is that, this commit function cleans prediction +engine state also. +*/ +void HbInputPredictionHandlerPrivate::commit(QInputMethodEvent & event,bool addToUsedWordDict) +{ + Q_Q(HbInputPredictionHandler); + + // Close exact word pop up in qwerty when the word is committed + if(HbInputUtils::isQwertyKeyboard(mInputMethod->inputState().keyboard())) { + mInputMethod->closeExactWordPopup(); + } + + q->sendAndUpdate(event); + + if(mEngine) { + if(addToUsedWordDict && !event.commitString().isEmpty()) + mEngine->addUsedWord(event.commitString()); + mEngine->clear(); + } + + //Enable the flag after commit + mCanContinuePrediction = true; + mTailShowing = false; + +} + +void HbInputPredictionHandlerPrivate::commitExactWord() +{ + if (mEngine && mEngine->inputLength() /*> 0 && mCandidates->count() > 0*/) { + commit(mCandidates->at(0), true); + } +} + +/*! +This function checks if the constructed candidate list is empty and if so, then +appends a "?" mark to the best guessed candidate with put the current key input. +*/ +void HbInputPredictionHandlerPrivate::handleEmptyCandidateList() +{ + if (!mCandidates->count()) { + QString existingWord(mEngine->currentWord()); + int lastKeyCode = 0; + int lastCharacterCode = 0; + bool isCustomWord = false; + if(existingWord.length()) { + lastCharacterCode = existingWord[existingWord.length()-1].unicode(); + } + const HbKeymap* keymap = HbKeymapFactory::instance()->keymap(HbInputSettingProxy::instance()->globalInputLanguage()); + if(keymap) { + const HbMappedKey* lastKey = keymap->keyForKeycode(mInputMethod->inputState().keyboard(), lastCharacterCode); + if (lastKey) { + lastKeyCode = lastKey->keycode.unicode(); + } + } + //Temporarily delete the key press + mEngine->deleteKeyPress(); + mEngine->updateCandidates(mBestGuessLocation, isCustomWord); + if (mCandidates->count()){ + (*mCandidates)[mBestGuessLocation].append("?"); + } else { + //Should the mBestGuessLocation not be zero. + mBestGuessLocation = 0; + mCandidates->append(mEngine->currentWord()); + (*mCandidates)[mBestGuessLocation].append("?"); + } + //Now again append the same key press + if (lastKeyCode) { + mEngine->appendKeyPress(lastKeyCode, mModifiers, mInputMethod->inputState().textCase(), this); + } else { + mEngine->appendKeyPress(lastCharacterCode, mModifiers, mInputMethod->inputState().textCase(), this); + } + mCanContinuePrediction = false; + } else { + mCanContinuePrediction = true; + } +} + +HbInputPredictionHandler::HbInputPredictionHandler(HbInputPredictionHandlerPrivate &dd, HbInputAbstractMethod* inputMethod) +:HbInputModeHandler(dd, inputMethod) +{ + Q_D(HbInputPredictionHandler); + d->q_ptr = this; + d->init(); +} + + +HbInputPredictionHandler::~HbInputPredictionHandler() +{ +} + +/*! + Mouse handler +*/ +void HbInputPredictionHandler::mouseHandler(int cursorPosition, QMouseEvent* mouseEvent) +{ + Q_D(HbInputPredictionHandler); + d->mouseHandler(cursorPosition, mouseEvent); +} + +/*! + Action Handler +*/ +bool HbInputPredictionHandler::actionHandler(HbInputModeAction action) +{ + Q_D(HbInputPredictionHandler); + bool ret = true; + switch (action) { + case HbInputModeActionReset: { + //At the moment we are commiting the text with the autocompletion part as it needs to be committed on clicking outside the editor. + //TO DO : When We back to the application by pressing Application key the inline word should not commit and remain in the inline editing + //d->mShowTail = false; + d->commit(); + d->reset(); + } + break; + case HbInputModeActionFocusLost: { + // if focus lost happens and before that if toolitip is available then typing line word should be committed in the editor + // if tooltip and autocompletion part is available then typing line word should be committed in the editor along with the autocompletion part + // Focus change should commit the auto-completed part as well. + d->commit(); + } + break; + case HbInputModeActionCommit: { + d->commit(); + } + break; + case HbInputModeActionDeleteAndCommit: { + deleteOneCharacter(); + d->commit(); + } + break; + case HbInputModeActionSetCandidateList: { + if (d->mEngine) { + d->mEngine->setCandidateList(d->mCandidates); + } else { + ret = false; + } + } + break; + case HbInputModeActionSetKeypad: { + if (d->mEngine) { + d->mEngine->setKeyboard(d->mInputMethod->inputState().keyboard()); + } else { + ret = false;; + } + } + break; + case HbInputModeActionLaunchCandidatePopup: + if (d->mEngine && d->mCandidates->size()) { + d->mInputMethod->launchCandidatePopup(*d->mCandidates); + } else { + ret = false; + } + break; + case HbInputModeActionSecondaryLanguageChanged: + if (d->mEngine) { + d->mEngine->setSecondaryLanguage(HbInputSettingProxy::instance()->globalSecondaryInputLanguage()); + } + break; + case HbInputModeActionPrimaryLanguageChanged: + if(!d->mEngine) { + d->init(); + } + if (d->mEngine) { + d->mEngine->setLanguage(HbInputSettingProxy::instance()->globalInputLanguage()); + } + break; + case HbInputModeActionHideTail: + d->mShowTail = false; + break; + default: + ret = HbInputModeHandler::actionHandler(action); + break; + } + + return ret; +} + +/*! + returs the true if we have something in in-line editing. +*/ +bool HbInputPredictionHandler::isComposing() +{ + Q_D(HbInputPredictionHandler); + if (d->mEngine && d->mEngine->inputLength()>0) { + return true; + } + return false; +} + +/*! + SLOT to receive input candidate popup close events. +*/ +void HbInputPredictionHandler::candidatePopupClosed(QString activatedText, int closingKey) +{ + Q_D(HbInputPredictionHandler); + d->candidatePopupClosed(closingKey, activatedText); +} + +/*! + SLOT to receive input qwery dialog box events. +*/ +void HbInputPredictionHandler::inputQueryPopupClosed(QString activatedWord, int closingKey) +{ + Q_UNUSED(activatedWord); + Q_UNUSED(closingKey); +} + +/*! + Appends a unicode character and updates the candidates and editor. +*/ +void HbInputPredictionHandler::appendUnicodeCharacter(QChar character) +{ + Q_D(HbInputPredictionHandler); + d->keyHandlerUnicode(character); +} + +/*! + returns supported languages in current engine. +*/ +QList HbInputPredictionHandler::supportedLanguages() const +{ + Q_D(const HbInputPredictionHandler); + if (d->mEngine) { + return d->mEngine->languages(); + } + + return QList(); +} + +/*! + filterEvent function to handler key events. +*/ +bool HbInputPredictionHandler::filterEvent(const QKeyEvent * event) +{ + Q_D(HbInputPredictionHandler); + return d->filterEvent(event); +} + +/*! + this SLOT is called when a character in sct is selected. +*/ +void HbInputPredictionHandler::sctCharacterSelected(QString character) +{ + Q_D(HbInputPredictionHandler); + //d->mShowTail = false; + d->commit(); + HbInputModeHandler::sctCharacterSelected(character); +} + +void HbInputPredictionHandler::smileySelected(QString smiley) +{ + Q_D(HbInputPredictionHandler); + d->commit(); + HbInputModeHandler::smileySelected(smiley); +} +/*! + this function commits current pre-edit and adds a character at the end. +*/ +void HbInputPredictionHandler::commitAndAppendCharacter(QChar character) +{ + Q_D(HbInputPredictionHandler); + d->commitAndAppendCharacter(character); +} + +/*! + this function deletes one character and updates the engine and editor. +*/ +void HbInputPredictionHandler::deleteOneCharacter() +{ + Q_D(HbInputPredictionHandler); + d->deleteOneCharacter(); +} + +void HbInputPredictionHandler::commitExactWord() +{ + Q_D(HbInputPredictionHandler); + d->commitExactWord(); +} + +/*! + * A virtual function called by the HbInputPredictionHandler when there is a exact word found + * and needs to to handled. Called with an empty string when there is no exact word found. + */ +void HbInputPredictionHandler::processExactWord(QString exactWord) +{ + Q_UNUSED(exactWord); +} + +void HbInputPredictionHandler::processCustomWord(QString customWord) +{ + Q_UNUSED(customWord); +} + +void HbInputPredictionHandler::showExactWordPopupIfNeeded() +{ + Q_D(HbInputPredictionHandler); + d->showExactWordPopupIfNeeded(); +} +// EOF