diff -r 000000000000 -r 16d8024aca5e src/hbplugins/inputmethods/common/hbinputmodehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hbplugins/inputmethods/common/hbinputmodehandler.cpp Mon Apr 19 14:02:13 2010 +0300 @@ -0,0 +1,429 @@ +/**************************************************************************** +** +** 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 "hbinputmodehandler.h" +#include "hbinputmodehandler_p.h" +#include "hbinputabstractbase.h" + +HbInputModeHandlerPrivate::HbInputModeHandlerPrivate() +:mKeymap(0), +mInputMethod(0), +mTimer(0) +{ +} + +HbInputModeHandlerPrivate::~HbInputModeHandlerPrivate() +{ +} + +void HbInputModeHandlerPrivate::init() +{ + Q_Q(HbInputModeHandler); + mTimer = new QTimer(q); + q->connect(mTimer, SIGNAL(timeout()), q, SLOT(_q_timeout())); +} + +// A virtual timeout function mode handlers should implement this slot. +void HbInputModeHandlerPrivate::_q_timeout() +{ +} + +QString HbInputModeHandlerPrivate::surroundingText() +{ + if (mInputMethod->focusObject()) { + return mInputMethod->focusObject()->editorSurroundingText(); + } + return QString(); +} + +int HbInputModeHandlerPrivate::cursorPosition() +{ + if (mInputMethod->focusObject()) { + return mInputMethod->focusObject()->editorCursorPosition(); + } + + return -1; +} + +void HbInputModeHandlerPrivate::getAndFilterCharactersBoundToKey(QStringList &spellList, Qt::Key key) +{ + HbInputFocusObject *focusObject = mInputMethod->focusObject(); + + spellList.clear(); + // Get the functionized character + const HbMappedKey* mappedKey = mKeymap->keyForKeycode(mInputMethod->inputState().keyboard(), key); + if (!mappedKey) { + return; + } + + if (!mappedKey->characters(HbModifierFnPressed).isNull() && focusObject && focusObject->characterAllowedInEditor(mappedKey->characters(HbModifierFnPressed).at(0))) { + spellList.append(mappedKey->characters(HbModifierFnPressed).at(0)); + } + + // Get the characters mapped to the key. + HbInputState inputState = mInputMethod->inputState(); + HbTextCase textCase = inputState.textCase(); + HbModifiers modifiers = HbModifierNone; + + if (textCase == HbTextCaseUpper || textCase == HbTextCaseAutomatic) { + modifiers |= HbModifierShiftPressed; + } + for (int i=0; i < mappedKey->characters(modifiers).length(); i++) { + if (focusObject && focusObject->characterAllowedInEditor(mappedKey->characters(modifiers).at(i))) { + spellList.append(mappedKey->characters(modifiers).at(i)); + } + } + + // filter characters. + /* if (key < 0x0ff) { + QString charSet = mKeyData->specialCharacterData(mInputMethod->inputState().iKeyboardType); + if (charSet.contains(key, Qt::CaseSensitive)) { + QString mostUsedCharacters; + HbInputSettingProxy::instance()->mostUsedSpecialCharacters(HbMaxSctLineChars, mostUsedCharacters, + mInputMethod->focusObject()->editorInterface().filter()); + spellList.clear(); + if (!mostUsedCharacters.isNull()) { + for (int i=0; iinputState(); + HbTextCase nextCase = HbTextCaseNone; + + switch(nextState.textCase()) { + case HbTextCaseLower: + // In multiline editor, if enter char is input and then shift is pressed twice, + // the case should be reverted to automatic. + if (mInputMethod->automaticTextCaseNeeded()) { + nextCase = HbTextCaseAutomatic; + } else { + nextCase = HbTextCaseUpper; + } + break; + case HbTextCaseUpper: + case HbTextCaseAutomatic: + nextCase = HbTextCaseLower; + break; + default: + break; + } + nextState.setTextCase(nextCase); + mInputMethod->activateState(nextState); +} + +bool HbInputModeHandlerPrivate::isEnterCharacter(QChar character) +{ + if (character == 0x21B2 || character == 0x21b3) { + return true; + } + return false; +} +HbInputModeHandler::HbInputModeHandler(HbInputModeHandlerPrivate &dd, HbInputAbstractMethod* inputMethod) + :d_ptr(&dd) +{ + Q_D(HbInputModeHandler); + d->q_ptr = this; + d->init(); + d->mInputMethod = inputMethod; +} + +HbInputModeHandler::~HbInputModeHandler() +{ + delete d_ptr; +} + +/*! + Gateway for all the mode handlers. +*/ +bool HbInputModeHandler::filterEvent(const QEvent * event) +{ + if (event) { + if (event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease) { + const QKeyEvent *keyEvent = 0; + keyEvent = static_cast(event); + if (keyEvent) { + return filterEvent(keyEvent); + } + } + } + + return false; +} + +/*! + This function handles the most common key events. +*/ +bool HbInputModeHandler::filterEvent(const QKeyEvent * event) +{ + Q_UNUSED(event); + return false; +} + +/*! + Action hanlder. Currently it handles only keymapping loading. +*/ +bool HbInputModeHandler::actionHandler(HbInputModeAction action) +{ + Q_D(HbInputModeHandler); + switch (action) { + case HbInputModeActionInit: + if (d->mKeymap) { + break; + } + case HbInputModeActionPrimaryLanguageChanged: { + HbInputLanguage primaryLanguage = HbInputSettingProxy::instance()->globalInputLanguage(); + d->mKeymap = HbKeymapFactory::instance()->keymap(primaryLanguage); + if (!d->mKeymap) { + qDebug(" HbInputModeHandler::actionHandler --> Failed to get keymapData!!!"); + return false; + } + } + break; + case HbInputModeActionDeleteAndCommit: { + HbInputFocusObject *focusObject = 0; + focusObject = d->mInputMethod->focusObject(); + + if (focusObject && focusObject->editorCursorPosition()) { + QString empty; + QList list; + QInputMethodEvent event(QString(), list); + event.setCommitString(empty, -1, 1); + sendAndUpdate(event); + } + break; + } + default : + return false; + }; + + return true; +} + +/*! +Call-back implementation to indicate that a character was selected from the SCT. With this, the character is committed to the +editor and editor is again made to focus. +*/ +void HbInputModeHandler::sctCharacterSelected(QString aChar) +{ + commitAndUpdate(aChar); +} + +void HbInputModeHandler::smileySelected(QString smiley) +{ + Q_D(HbInputModeHandler); + HbInputFocusObject *focusObject = 0; + focusObject = d->mInputMethod->focusObject(); + if (!focusObject) { + qDebug("HbInputModeHandler::smileySelected no focusObject ... failed!!"); + return ; + } + QStringList patterns = focusObject->editorInterface().smileyTheme().patterns(smiley); + foreach( QString string, patterns) { + QString filtered; + focusObject->filterStringWithEditorFilter(string, filtered); + if (filtered == string) { + focusObject->commitSmiley(smiley); + break; + } + } + d->mInputMethod->updateState(); +} + +void HbInputModeHandler::cursorPositionChanged(int oldPos, int newPos) +{ + Q_D(HbInputModeHandler); + d->mInputMethod->updateState(); + Q_UNUSED(oldPos); + Q_UNUSED(newPos); +} + +/*! + this function commits the first number found in the key. +*/ +void HbInputModeHandler::commitFirstMappedNumber(int key) +{ + Q_D(HbInputModeHandler); + // This is long key press number shortcut functionality. + if (!d->mKeymap) { + d->mKeymap = HbKeymapFactory::instance()->keymap(d->mInputMethod->inputState().language()); + } + QChar numChr = HbInputUtils::findFirstNumberCharacterBoundToKey(d->mKeymap->keyForKeycode(d->mInputMethod->inputState().keyboard(), key), + d->mKeymap->language()); + // when a number is to be entered, it should commit + // the previous string and then append the number to the string + if (numChr != 0) { + commitAndAppendString(numChr); + } +} + +/*! +Gets the character at index in a key and incriments the index by 1. Returns the Zeroth character if +this function finds the index to be out of range and incriments index to 1. +*/ +QChar HbInputModeHandler::getNthCharacterInKey(int &index, int key) +{ + Q_D(HbInputModeHandler); + HbModifiers modifiers = 0; + int textCase = d->mInputMethod->inputState().textCase(); + if (textCase == HbTextCaseUpper || textCase == HbTextCaseAutomatic) { + modifiers |= HbModifierShiftPressed; + } + if (!d->mKeymap) { + d->mKeymap = HbKeymapFactory::instance()->keymap(d->mInputMethod->inputState().language()); + } + const HbMappedKey* mappedKey = d->mKeymap->keyForKeycode(d->mInputMethod->inputState().keyboard(), key); + if (!mappedKey) { + return 0; + } + // We need to see which of the characters in keyData are allowed to the editor. + // this looks like expensive operation, need to find out a better way/place to do it. + QString allowedChars; + HbInputFocusObject *focusedObject = d->mInputMethod->focusObject(); + if(focusedObject) { + focusedObject->filterStringWithEditorFilter(mappedKey->characters(modifiers),allowedChars); + } else { + // we should not come here. Just for saftey. + allowedChars = mappedKey->characters(modifiers); + } + QChar character = 0; + if (!allowedChars.isNull()) { + if (index >= allowedChars.length() || index < 0) { + index = 0; + } + character = allowedChars.at(index); + index++; + } + return character; +} + +/*! + This function gets all the characters bound to a key and filters those character based on the editor. +*/ +void HbInputModeHandler::getAndFilterCharactersBoundToKey(QStringList &spellList, Qt::Key key) +{ + Q_D(HbInputModeHandler); + d->getAndFilterCharactersBoundToKey(spellList, key); +} + +/*! + A virtual function, this should be called from plugin when ever there is mouse event. +*/ +void HbInputModeHandler::mouseHandler(int x, QMouseEvent* mouseEvent) +{ + Q_UNUSED(mouseEvent); + Q_D(HbInputModeHandler); + if(d->cursorPosition() != x) { + actionHandler(HbInputModeActionCommit); + } +} + +/*! + A virtual function, default implementation first commits any inline text by calling actionHandler with + HbInputModeActionCommit. Then commits the string. +*/ +void HbInputModeHandler::commitAndAppendString(const QString& string) +{ + // first commit the pre-edit string if any. + actionHandler(HbInputModeActionCommit); + commitAndUpdate(string); +} + +/*! +Ignores currently active pre-edit text if any and directly commits the passed string in to the editor. This +function also updates the inputmethod state. +*/ +void HbInputModeHandler::commitAndUpdate(const QString& string, int replaceFrom, int replaceLength, bool isAsync) +{ + Q_D(HbInputModeHandler); + HbInputFocusObject *focusObject = 0; + focusObject = d->mInputMethod->focusObject(); + if (!focusObject) { + qDebug("HbInputModeHandler::commitAndUpdate no focusObject ... failed!!"); + return ; + } + + QString filtered; + focusObject->filterStringWithEditorFilter(string, filtered); + + // now commit the string which is passed in. + QList list; + + if(isAsync) { + QInputMethodEvent *event = new QInputMethodEvent(QString(), list); + event->setCommitString(filtered, replaceFrom, replaceLength); + focusObject->postEvent(*event); + } else { + QInputMethodEvent event; + event.setCommitString(filtered, replaceFrom, replaceLength); + focusObject->sendEvent(event); + } + d->mInputMethod->updateState(); +} + +/*! +Sends the passed event to the focused object and upates the inputmethod state. +*/ +void HbInputModeHandler::sendAndUpdate(QEvent& event) +{ + Q_D(HbInputModeHandler); + HbInputFocusObject *focusObject = 0; + focusObject = d->mInputMethod->focusObject(); + if (!focusObject) { + qDebug("HbInputModeHandler::sendAndUpdate no focusObject ... failed!!"); + return; + } + + focusObject->sendEvent(event); + d->mInputMethod->updateState(); +} + +void HbInputModeHandler::setKeymap(const HbKeymap* keymap) +{ + Q_D(HbInputModeHandler); + d->mKeymap = keymap; +} + +void HbInputModeHandler::characterPreviewAvailable(bool available) +{ + Q_UNUSED(available); +} + +#include "moc_hbinputmodehandler.cpp" +// EOF