src/hbplugins/inputmethods/touchinput/virtual12key.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hbplugins/inputmethods/touchinput/virtual12key.cpp	Mon Apr 19 14:02:13 2010 +0300
@@ -0,0 +1,807 @@
+/****************************************************************************
+**
+** 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 "virtual12key.h"
+
+//Required Qt headers
+#include <QLocale>
+//Required Hb headers
+#include <hbinputkeymapfactory.h>
+#include <hbinputkeymap.h>
+#include <hbinput12keytouchkeypad.h>
+#include <hbinputsettingproxy.h>
+#include <hbinpututils.h>
+#include <hbinputsctportrait.h>
+#include <hbinputeditorinterface.h>
+#include <hbinputcandidatelist.h>
+#include <hbinputpredictionfactory.h>
+#include <hbinputpredictionengine.h>
+#include <hbmainwindow.h>
+#include <hbaction.h>
+#include <hbview.h>
+#include <hbinputvkbhost.h>
+#include <hbinputcommondialogs.h>
+
+//User includes
+#include "hbinputbasic12keyhandler.h"
+#include "hbinputprediction12keyhandler.h"
+#include "hbinputnumeric12keyhandler.h"
+
+const int HbSmileyNumberOfRows = 5;
+const int HbSmileyNumberOfColumns = 5;
+
+/*!
+\class HbVirtual12Key
+\brief Input method implementations for virtual ITU-T mode in HbInputs framework.
+
+It implements the HbInputMethod interface from HbInput framework. This particular
+input method supports input of predictive and multi-tap input.
+
+\sa HbInputMethod
+*/
+
+HbVirtual12Key::HbVirtual12Key()
+              : mCurrentKeypad(0),
+                mItutKeypad(0),
+                mSctKeypad(0),
+                mKeymap(0),
+                mSctMode(HbInputVkbWidget::HbSctViewSpecialCharacter),
+                mOrientationAboutToChange(false),
+                mCandidatePopup(0),
+                mCurrentlyFocused(0),
+                mVkbHost(0),
+                mKeyboardChangeAlreadyInprogress(false)
+{
+    initializeModeHandlers();
+}
+
+void HbVirtual12Key::initializeModeHandlers()
+{
+    mBasicModeHandler = new HbInputBasic12KeyHandler(this);
+    mPredictionModeHandler = new HbInputPrediction12KeyHandler(this);
+    mNumericModeHandler = new HbInputNumeric12KeyHandler(this);
+    mActiveModeHandler = mBasicModeHandler;
+
+    mBasicModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionInit);
+    mPredictionModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionInit);
+    mNumericModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionInit);
+
+    // let's connect prediction mode handler with latin basic mode handler. It is required incase we Qt::key_0 is pressed in prediction mode
+    // key
+    connect(mPredictionModeHandler, SIGNAL(passFilterEvent(const QKeyEvent *)), mBasicModeHandler, SLOT(filterEvent(const QKeyEvent *)));
+    connect(mPredictionModeHandler, SIGNAL(passActionHandler(HbInputModeAction )), mBasicModeHandler, SLOT(actionHandler(HbInputModeAction )));
+}
+
+bool HbVirtual12Key::isSctModeActive() const
+{
+    return (mCurrentKeypad == mSctKeypad);
+}
+
+/*!
+Destructor for HbVirtual12Key. Responsible for clean up of the class.
+
+\sa HbInputMethod::~HbInputMethod
+*/
+HbVirtual12Key::~HbVirtual12Key()
+{
+    delete mItutKeypad;
+    mItutKeypad = 0;
+    delete mSctKeypad;
+    mSctKeypad = 0;
+    delete mCandidatePopup;
+    mCandidatePopup = 0;
+
+    // free mode handlers
+    delete mBasicModeHandler;
+    mBasicModeHandler = 0;
+    delete mPredictionModeHandler;
+    mPredictionModeHandler = 0;
+    delete mNumericModeHandler;
+    mNumericModeHandler = 0;
+}
+
+/*!
+Implementation of the pure virtual QInputContext::identifierName()
+Returns a string which specifies an identifier for the input method.
+*/
+QString HbVirtual12Key::identifierName()
+{
+    return QString("HbVirtual12Key");
+}
+
+/*!
+Implementation of the pure virtual QInputContext::isComposing()
+*/
+bool HbVirtual12Key::isComposing() const
+{
+    return mActiveModeHandler->isComposing();
+}
+
+/*!
+Implementation of the pure virtual QInputContext::language()
+Returns the currently active language for the input method. The language
+name returned is in the format language-code_country-code e.g. zh_CN.
+*/
+QString HbVirtual12Key::language()
+{
+    QLocale::Language activeLanguage;
+    activeLanguage = (QLocale::Language)HbInputSettingProxy::instance()->globalInputLanguage().language();
+    QLocale locale(activeLanguage);
+    return locale.name();
+}
+
+/*!
+Implementation of the pure virtual QInputContext::reset()
+Resets the input method. This could be called by the widgets for reseting the
+state of the input method.
+*/
+void HbVirtual12Key::reset()
+{
+    mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionReset);
+    mOrientationAboutToChange = false;
+}
+
+/*!
+Construct 12key touchkeypad and make the necessary connections.
+*/
+Hb12KeyTouchKeypad * HbVirtual12Key::construct12Keypad()
+{
+    Hb12KeyTouchKeypad * tempKeypad = 0;
+    tempKeypad = new Hb12KeyTouchKeypad(this, 0);
+    connect(tempKeypad, SIGNAL(keypadCloseEventDetected(HbInputVkbWidget::HbVkbCloseMethod)), this, SLOT(keypadCloseEventDetected(HbInputVkbWidget::HbVkbCloseMethod)));
+    connect(tempKeypad, SIGNAL(rockerDirection(int, HbInputVirtualRocker::RockerSelectionMode)),
+        this, SLOT(rockerDirection(int, HbInputVirtualRocker::RockerSelectionMode)));
+    //FLICKDISABLED connect(tempKeypad, SIGNAL(flickEvent(HbInputVkbWidget::FlickDirection)), this, SLOT(flickEvent(HbInputVkbWidget::FlickDirection)));
+    connect(tempKeypad, SIGNAL(smileySelected(QString)), this, SLOT(smileySelected(QString)));
+    connect(tempKeypad, SIGNAL(mouseMovedOutOfButton()), this, SLOT(mouseMovedOutOfButton()));
+    tempKeypad->setRockerVisible(true);
+    return tempKeypad;
+}
+
+/*!
+Virtual 12-key specific implementation of HbInputMethod::focusReceived().
+Up on reception of focus, the framework switches the input context and calls this
+method indicating the gain of focus to the input method.
+With focus received, the virtual 12-key input method, refreshes the special character
+table as it needs to be based on the focused editor. It also opens the virtual keypad
+and stops the timer which is used for multi tapping and detecting long key press events.
+*/
+void HbVirtual12Key::focusReceived()
+{
+    // load the new keymappings to all keypads and all mode handlers
+    loadKeymap(inputState().language());
+    // After loadKeyMapData call, mKeyData should have keymappings data of the current language
+    if(!mKeymap) {
+        return; // could not get keymappings. Does not make sense to continue
+    }
+
+    //Get vkbhost
+    mVkbHost = focusObject()->editorInterface().vkbHost();
+
+    if(!mItutKeypad){
+        mItutKeypad = construct12Keypad();
+        mItutKeypad->setKeymap(mKeymap);
+    }
+
+    if (!mItutKeypad) {
+        // Something has caused keypad QPointers to zero themselves, no point to go on...
+        return;
+    }
+
+    // inform active mode handler about the focusrecieve event.
+    mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionFocusRecieved);
+
+    if (mCurrentlyFocused != focusObject()) {
+        mCurrentlyFocused = focusObject();
+        // Focus changed from one editor to another.
+        if (mCandidatePopup) {
+            mCandidatePopup->hide();
+        }
+    }
+
+    // We need to check if this focusRecieved call is due to a orientation
+    // switch. If yes we should get the keypad status prior to the orientation
+    // switch and open the keypad in that state only.
+    // For example we have minimized the keypad in Qwerty mode and change the
+    // orientation to portrait then in Itu-T mode also keypad should be in minimized state.
+    if (orientationContextSwitchInProgress()) {
+        HbVkbHost *host = focusObject()->editorInterface().vkbHost();
+        if (host) {
+            // We can get the keypad status prior to the orientation switch from vkbHost it self.
+            HbVkbHost::HbVkbStatus vkbStatus = host->keypadStatusBeforeOrientationChange();
+            if (vkbStatus != HbVkbHost::HbVkbStatusClosed) {
+                openKeypad(mItutKeypad,vkbStatus == HbVkbHost::HbVkbStatusMinimized);
+            }
+        }
+    } else {
+        openKeypad(mItutKeypad);
+    }
+
+    if (focusObject() && mVkbHost) {
+        connect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), mVkbHost, SLOT(ensureCursorVisibility()));
+    }
+
+    if (focusObject()) {
+        disconnect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), mActiveModeHandler, SLOT(cursorPositionChanged(int, int)));
+        connect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), mActiveModeHandler, SLOT(cursorPositionChanged(int, int)));
+    }
+}
+
+/*!
+\reimp
+*/
+void HbVirtual12Key::focusLost(bool focusSwitch)
+{
+    // inform the active mode handler about the focus lost event.
+    mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionFocusLost);
+
+    if (focusObject()) {
+        disconnect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), mActiveModeHandler, SLOT(cursorPositionChanged(int, int)));
+    }
+
+    if (!focusSwitch && mVkbHost && mVkbHost->keypadStatus() != HbVkbHost::HbVkbStatusClosed) {
+        // Context switch has happened but the keypad is still open.
+        // Close it. First notify handler by sending an event and give it changes to
+        // do any closing related things.
+        // Then make sure that keypad closes.
+        closeKeypad();
+        mVkbHost = 0;
+    }
+}
+
+/*!
+Closes the keypad if it is open.
+*/
+void HbVirtual12Key::closeKeypad()
+{
+    if (mVkbHost && mVkbHost->keypadStatus() != HbVkbHost::HbVkbStatusClosed) {
+        mVkbHost->closeKeypad(!stateChangeInProgress());
+        // set mCurrentKeypad to null.
+        mCurrentKeypad = 0;
+        if (mCandidatePopup) {
+            mCandidatePopup->hide();
+        }
+    }
+}
+
+/*!
+Opens the virtual keypad for input.
+*/
+void HbVirtual12Key::openKeypad(HbInputVkbWidget * keypadToOpen,bool inMinimizedMode)
+{
+    mKeyboardChangeAlreadyInprogress = true;
+    HbInputSettingProxy::instance()->setActiveKeyboard(HbKeyboardVirtual12Key);
+    mKeyboardChangeAlreadyInprogress = false;
+
+    // if null is sent, just return.
+    if(!keypadToOpen) {
+        return;
+    }
+    // see if we are trying to open a different keypad than what is already opened.
+    if (mCurrentKeypad != keypadToOpen) {
+        // close currently open keypad. We always close keypad without animation
+        // keypad should be closed with animation only when we loses focus and this is handled
+        // in focusLost function call.
+        if (mVkbHost && mVkbHost->keypadStatus() != HbVkbHost::HbVkbStatusClosed) {
+            mVkbHost->closeKeypad(false);
+        }
+    }
+    // Close candidate popup if open
+    if (mCandidatePopup) {
+        mCandidatePopup->hide();
+    }
+    // assign new keypad to be opened to varable mCurrentKeypad
+    mCurrentKeypad =  keypadToOpen;
+
+    if (mVkbHost && mVkbHost->keypadStatus() != HbVkbHost::HbVkbStatusOpened) {
+        connect(mVkbHost, SIGNAL(keypadClosed()), this, SLOT(keypadClosed()));
+        connect(mVkbHost, SIGNAL(keypadOpened()), this, SLOT(keypadOpened()));
+
+        if (inMinimizedMode) {
+            mVkbHost->openMinimizedKeypad(mCurrentKeypad, this);
+        } else {
+            mVkbHost->openKeypad(mCurrentKeypad, this, !stateChangeInProgress());
+        }
+        connect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), mVkbHost, SLOT(ensureCursorVisibility()));
+    }
+}
+
+/*!
+The mouse event handler for the input method. Launches the candidate list if the mouse is clicked on the
+pre-editing text.
+*/
+void HbVirtual12Key::mouseHandler(int cursorPosition, QMouseEvent* mouseEvent)
+{
+    mActiveModeHandler->mouseHandler(cursorPosition, mouseEvent);
+}
+
+void HbVirtual12Key::predictiveInputStatusChanged(int newStatus)
+{
+    Q_UNUSED(newStatus);
+
+    HbInputFocusObject *focusedObject = focusObject();
+    if (focusedObject) {
+        // Just refresh the situation.
+        inputStateActivated(inputState());
+        return;
+    }
+}
+
+/*!
+Call back indicating that the keypad is closed.
+*/
+void HbVirtual12Key::keypadClosed()
+{
+
+    // commit any character/word which is in inline edit.
+    mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionCommit);
+
+    if (mOrientationAboutToChange) {
+        mOrientationAboutToChange = false;
+    }
+}
+
+/*!
+Call back indicating that the keypad is opened.
+*/
+void HbVirtual12Key::keypadOpened()
+{
+}
+
+/*!
+The call back from the VKB keypad widget before it closes the keypad.
+*/
+void HbVirtual12Key::keypadCloseEventDetected(HbInputVkbWidget::HbVkbCloseMethod vkbCloseMethod)
+{
+    Q_UNUSED(vkbCloseMethod);
+    if (isActiveMethod()) {
+        if (mVkbHost) {
+            if (mVkbHost->keypadStatus() == HbVkbHost::HbVkbStatusOpened) {
+                mVkbHost->minimizeKeypad(!stateChangeInProgress());
+                if (mCandidatePopup) {
+                    mCandidatePopup->hide();
+                }
+            }
+        }
+    }
+}
+
+/*!
+The rocker widget emits the signal rockerDirection when there is any rocker movement. This method catches the emitted
+signal and makes the cursor movements according to the rcker movement.
+*/
+void HbVirtual12Key::rockerDirection(int aDirection, HbInputVirtualRocker::RockerSelectionMode aSelectionMode)
+{
+    Qt::KeyboardModifiers modifiers = 0;
+    if (aSelectionMode == HbInputVirtualRocker::RockerSelectionModeOn) {
+        modifiers = Qt::ShiftModifier;
+    }
+    // commit any character/word which is in inline edit.
+    mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionCommit);
+
+    HbInputLanguage inputlang = HbInputSettingProxy::instance()->globalInputLanguage();
+
+    switch (aDirection) {
+    case HbInputVirtualRocker::HbRockerDirectionLeft:
+        if(inputlang.isRightToLeftLanguage()) {
+            focusObject()->cursorRight(modifiers);
+        } else {
+            focusObject()->cursorLeft(modifiers);
+        }
+        break;
+    case HbInputVirtualRocker::HbRockerDirectionRight:
+        if(inputlang.isRightToLeftLanguage()) {
+            focusObject()->cursorLeft(modifiers);
+        } else {
+            focusObject()->cursorRight(modifiers);
+        }
+        break;
+    case HbInputVirtualRocker::HbRockerDirectionUp: {
+        QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Up, modifiers);
+        focusObject()->sendEvent(keyEvent);
+        }
+        break;
+    case HbInputVirtualRocker::HbRockerDirectionDown: {
+        QKeyEvent keyEvent(QEvent::KeyPress, Qt::Key_Down, modifiers);
+        focusObject()->sendEvent(keyEvent);
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+/*!
+Notification from the generic input method framework indicating a change of input language.
+The VKB keypad needs to refreshed to show the renewed key mapping.
+*/
+void HbVirtual12Key::inputLanguageChanged(const HbInputLanguage &newLanguage)
+{
+    // inform all the mode handler about the language change.
+    mPredictionModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionCommit);
+    // move keypad off screen
+    if (mCurrentKeypad){
+        mCurrentKeypad->keypadLanguageChangeAnimationUpdate(0);
+    }
+    loadKeymap(newLanguage);
+    // inform all the mode handler about the language change.
+    mPredictionModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionPrimaryLanguageChanged);
+    if (mCurrentKeypad){
+        mCurrentKeypad->animKeyboardChange();
+    }
+}
+
+/*!
+Notification from the generic input method framework that there has been a flick event
+*/
+void HbVirtual12Key::flickEvent(HbInputVkbWidget::HbFlickDirection direction)
+{
+    Q_UNUSED(direction);
+}
+
+
+/*!
+Notification from the generic input method framework that the mouse moved out of the button pressed.
+*/
+void HbVirtual12Key::mouseMovedOutOfButton()
+{
+    qDebug("HbVirtual12Key::mouseMovedOutOfButton()");
+    mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionCancelButtonPress);
+}
+
+/*!
+Notification from the generic input method framework to indicate the activation of a state.
+*/
+void HbVirtual12Key::inputStateActivated(const HbInputState& newState)
+{
+    if (!isActiveMethod()
+        || mKeyboardChangeAlreadyInprogress) {
+        return;  // Just to be sure...
+    }
+
+    if (mItutKeypad) {
+        if (newState.inputMode() == HbInputModeNumeric) {
+            // Numeric mode is activated, set numeric mode to itu-t keypad
+            if(mItutKeypad->mode() != EModeNumeric) {
+                // Editor is in numeric mode.
+                mItutKeypad->setMode(EModeNumeric, HbModifierNone);
+            }
+        } else if (newState.inputMode() != HbInputModeNumeric) {
+            if (newState.textCase() == HbTextCaseUpper || newState.textCase() == HbTextCaseAutomatic) {
+                mItutKeypad->setMode(EModeAbc, HbModifierShiftPressed);
+            } else {
+                mItutKeypad->setMode(EModeAbc, HbModifierNone);
+            }
+        }
+    }
+
+    HbInputModeHandler *previousModeHandler = mActiveModeHandler;
+    if (newState.inputMode() == HbInputModeDefault && usePrediction()) {
+        mActiveModeHandler = mPredictionModeHandler;
+        // by passing HbInputModeActionFocusRecieved we will be setting the candidate list and keypad
+        mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionFocusRecieved);
+    } else if (newState.inputMode() == HbInputModeDefault) {
+        mActiveModeHandler = mBasicModeHandler;
+        // Auto completer setup needs following line.
+        mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionFocusRecieved);
+    } else if (newState.inputMode() == HbInputModeNumeric) {
+        mActiveModeHandler = mNumericModeHandler;
+    }
+
+    if (focusObject()) {
+        disconnect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), previousModeHandler, SLOT(cursorPositionChanged(int, int)));
+        connect(&(focusObject()->editorInterface()), SIGNAL(cursorPositionChanged(int, int)), mActiveModeHandler, SLOT(cursorPositionChanged(int, int)));
+    }
+
+    // load the new keymappings to all keypads and all mode handlers
+    loadKeymap(newState.language());
+
+    // if there is a change in the modehandler we need send a commit in previous mode handler.
+    if (previousModeHandler != mActiveModeHandler) {
+        // Auto Completion part needs to be committed as well on mode change.
+
+        previousModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionCommit);
+        if (mActiveModeHandler == mPredictionModeHandler) {
+            // lets set candidate list and keypad type to the engine.
+            mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionSetCandidateList);
+            mActiveModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionSetKeypad);
+        }
+    }
+}
+
+/*!
+This function loads the keymappings data of the given language to all the keypads and to all mode handlers.
+It first checks if we already have keymappings data of given language in mKeyData, if not then gets the
+keymappings,loads them to all avaialble keyboards and to all mode handlers
+*/
+void HbVirtual12Key::loadKeymap(const HbInputLanguage &newLanguage)
+{
+    //dont try to get the keymappings if we ( mKeyData) already have keymappings for newLanguage
+    if(!mKeymap || mKeymap->language().language() != newLanguage.language()){
+        const HbKeymap* keymap = HbKeymapFactory::instance()->keymap(newLanguage);
+        if(keymap){
+            mKeymap = keymap;
+            if(mItutKeypad) {
+                mItutKeypad->setKeymap(mKeymap);
+            }
+            if(mSctKeypad) {
+                mSctKeypad->setKeymap(mKeymap);
+            }
+
+            // inform mode handlers about the language change.
+            if(mBasicModeHandler) {
+                mBasicModeHandler->setKeymap(mKeymap);
+            }
+            if(mPredictionModeHandler) {
+                mPredictionModeHandler->setKeymap(mKeymap);
+            }
+            if(mNumericModeHandler) {
+                mNumericModeHandler->setKeymap(mKeymap);
+            }
+        }
+    }
+}
+
+/*!
+this slot is called by the mode handlers when there is Short Press of Asterisk key.
+*/
+void HbVirtual12Key::starKeySelected(){
+    // if sct is active keypad, then launch itu-t keypad
+    if (isSctModeActive()){
+        switchToAlphaMode();
+    } else {
+        // launch Candidate List
+        bool ret = mPredictionModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionLaunchCandidatePopup);
+        // In case when candidate list is not launched i.e. when the word is not in inlline editing state, launch SCT
+        if (!ret){
+            mSctMode = HbInputVkbWidget::HbSctViewSpecialCharacter;
+            displaySpecialCharacterTable(this);
+        }
+    }
+}
+
+/*!
+this slot is called by the mode handlers when there is sym key or long  press of Asterisk key.
+*/
+void HbVirtual12Key::switchMode(int keyCode)
+{
+    if (keyCode == Qt::Key_Asterisk || keyCode == Qt::Key_Control){
+        if (mCandidatePopup && mCandidatePopup->isVisible()) {
+            return;
+        }
+
+        if (mCurrentKeypad == mSctKeypad){
+            // if sct is active keypad, then launch itu-t keypad
+            switchToAlphaMode();
+        } else {
+            // launch special character keypad
+            mSctMode = HbInputVkbWidget::HbSctViewSpecialCharacter;
+            displaySpecialCharacterTable(this);
+        }
+    } else if ( keyCode == Qt::Key_Shift) {
+           HbInputState inputState = this->inputState();
+        if (inputState.inputMode() != HbInputModeNumeric ) {
+            inputState.setInputMode( HbInputModeNumeric );
+            this->activateState(inputState);
+        } else {
+            HbInputState rootState;
+            editorRootState(rootState);
+            activateState(rootState);
+        }
+        switchToAlphaMode();
+    }
+}
+
+/*!
+Shows the special character table. Re-implements the same method from HbInputMethod.
+*/
+int HbVirtual12Key::displaySpecialCharacterTable(QObject* receiver)
+{
+    Q_UNUSED(receiver);
+
+    if(!mSctKeypad) {
+        mSctKeypad = new HbInputSctPortrait(this,mKeymap,0);
+        connect(mSctKeypad, SIGNAL(keypadCloseEventDetected(HbInputVkbWidget::HbVkbCloseMethod)), this, SLOT(keypadCloseEventDetected(HbInputVkbWidget::HbVkbCloseMethod)));
+        connect(mSctKeypad, SIGNAL(sctCharacterSelected(QString)), this, SLOT(sctCharacterSelected(QString)));
+        connect(mSctKeypad, SIGNAL(smileySelected(QString)), this, SLOT(smileySelected(QString)));
+        mSctKeypad->setRockerVisible(false);
+    }
+
+    mSctKeypad->setSct(mSctMode);
+    //Open the keypad
+    openKeypad(mSctKeypad);
+
+    return 0;
+}
+
+/*!
+Switches the keypad to the alphabetic / normal input mode.
+*/
+void HbVirtual12Key::switchToAlphaMode( bool openAlphaInMinimizedMode)
+{
+    //Open the keypad
+    openKeypad(mItutKeypad,openAlphaInMinimizedMode);
+}
+
+/*!
+The call back from framework to indicate that the orientation is about to change. This closes the keypad
+if it is already open.
+*/
+void HbVirtual12Key::orientationAboutToChange()
+{
+    HbInputMethod::orientationAboutToChange();
+    if (isActiveMethod()) {
+        mOrientationAboutToChange = true;
+    }
+    closeKeypad();
+}
+
+/*!
+Launches the candidate list.
+*/
+void HbVirtual12Key::launchCandidatePopup(const QStringList& candidates)
+{
+    if (!mCandidatePopup) {
+        mCandidatePopup = new HbCandidateList(this);
+    }
+    mCandidatePopup->populateList(candidates);
+    mCandidatePopup->setModal(true);
+
+    QSizeF candListSize = mCandidatePopup->size();
+    QPointF candListPos = mCandidatePopup->pos();
+    getCandidatePositionAndSize(mCandidatePopup, mCurrentKeypad, candListPos,candListSize);
+
+    QRectF geom = mCandidatePopup->geometry();
+    geom.setHeight(candListSize.height());
+    geom.setWidth(candListSize.width());
+    mCandidatePopup->setGeometry(geom);
+
+    mCandidatePopup->setPos(candListPos);
+
+    mCandidatePopup->show();
+}
+
+/*!
+ this slot is called when the candidate popup is closed
+*/
+void HbVirtual12Key::candidatePopupClosed(int closingKey)
+{
+    if (mCandidatePopup) {
+        QString currentCandidate = mCandidatePopup->currentCandidate();
+        if (currentCandidate.size() > 0) {
+            if ((focusObject()->editorInterface().constraints() & HbEditorConstraintAutoCompletingField)) {
+                mBasicModeHandler->autoCompletionPopupClosed(currentCandidate, closingKey);
+            } else {
+                mPredictionModeHandler->candidatePopupClosed(currentCandidate, closingKey);
+            }
+        }
+    }
+}
+
+/*!
+ this function is called whenever there is a hardware keypress Or virtual keypad button is pressed.
+*/
+bool HbVirtual12Key::filterEvent(const QEvent* event)
+{
+    return mActiveModeHandler->filterEvent(event);
+}
+
+void HbVirtual12Key::secondaryInputLanguageChanged(const HbInputLanguage &newLanguage)
+{
+    Q_UNUSED(newLanguage);
+    mPredictionModeHandler->actionHandler(HbInputModeHandler::HbInputModeActionSecondaryLanguageChanged);
+}
+
+/*!
+ this slot is called by sct when a character is selected from sct.
+*/
+void HbVirtual12Key::sctCharacterSelected(QString character)
+{
+    mActiveModeHandler->sctCharacterSelected(character);
+    /* Update the text case */
+    updateState();
+}
+
+void HbVirtual12Key::smileySelected(QString smiley)
+{
+     mActiveModeHandler->smileySelected(smiley);
+}
+
+void HbVirtual12Key::selectSpecialCharacterTableMode()
+{
+    if (mItutKeypad) {
+        mItutKeypad->showSmileyPicker(HbSmileyNumberOfRows, HbSmileyNumberOfColumns);
+    }
+}
+
+/*!
+Slot used by mode handlers to close the candidate popup.
+*/
+void HbVirtual12Key::closeCandidatePopup()
+{
+    if (mCandidatePopup && mCandidatePopup->isVisible()) {
+        mCandidatePopup->hide();
+    }
+}
+
+/*!
+Slot used by mode handlers to close the autocompletion popup.
+*/
+void HbVirtual12Key::closeAutoCompletionPopup()
+{
+    closeCandidatePopup();
+}
+
+/*!
+Launches auto-completion popup if there are candidates available.
+*/
+void HbVirtual12Key::launchAutoCompletionPopup(const QStringList& candidates)
+{
+    if (!mCandidatePopup) {
+        mCandidatePopup = new HbCandidateList(this);
+    }
+
+    if (candidates.count() > 0) {
+        mCandidatePopup->populateList(candidates);
+        mCandidatePopup->setModal(false);
+
+        if (mCandidatePopup->setSizeAndPositionForAutoCompletion(mVkbHost)) {
+            mCandidatePopup->setDismissPolicy(HbPopup::TapInside);
+            mCandidatePopup->setBackgroundFaded(false);
+            mCandidatePopup->show();
+        }
+    } else if (mCandidatePopup->isVisible()) {
+        mCandidatePopup->hide();
+    }
+}
+
+/*!
+Returns true if prediction is on, prediction engine is available and predictions is allowed in current editor.
+*/
+bool HbVirtual12Key::usePrediction() const
+{
+    HbInputFocusObject *fo = focusObject();
+    if (HbInputSettingProxy::instance()->predictiveInputStatus() &&
+        fo &&
+        fo->editorInterface().isPredictionAllowed() &&
+        mPredictionModeHandler->isActive() &&
+        HbPredictionFactory::instance()->predictionEngineForLanguage(inputState().language())) {
+         return true;           
+    }
+
+    return false;
+}
+
+/*!
+This function returns true if the latest mouse release was part of a horizontal flick event
+*/
+HbInputVkbWidget::HbFlickDirection HbVirtual12Key::flickDirection() const
+{
+    if ( mCurrentKeypad ) {
+        return mCurrentKeypad->flickDirection();
+    }else{
+        return HbInputVkbWidget::HbFlickDirectionNone;
+    }
+}
+// End of file