src/hbplugins/inputmethods/touchinput/hbinputbasicqwertyhandler.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbPlugins module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include <QTimer>
       
    27 #include <hbinputpredictionengine.h>
       
    28 #include <hbinputmethod.h>
       
    29 #include <hbinputkeymap.h>
       
    30 #include <hbinputkeymapfactory.h>
       
    31 
       
    32 #include "hbinputabstractbase.h"
       
    33 #include "hbinputbasicqwertyhandler.h"
       
    34 #include "hbinputbasichandler_p.h"
       
    35 
       
    36 class HbInputBasicQwertyHandlerPrivate: public HbInputBasicHandlerPrivate
       
    37 {
       
    38     Q_DECLARE_PUBLIC(HbInputBasicQwertyHandler)
       
    39 public:
       
    40     HbInputBasicQwertyHandlerPrivate();
       
    41     ~HbInputBasicQwertyHandlerPrivate();
       
    42 
       
    43     void init();
       
    44 
       
    45     // button related operations.
       
    46     bool buttonPressed(const QKeyEvent *event);
       
    47     bool buttonReleased(const QKeyEvent *event);
       
    48     void _q_timeout();
       
    49 
       
    50 public:
       
    51     HbFnState mFnState;
       
    52     int mButton;
       
    53     bool mPreviewAvailable;
       
    54     QChar mPrevDeadKey;
       
    55     HbInputFocusObject *mCurrentlyFocused;
       
    56 };
       
    57 
       
    58 HbInputBasicQwertyHandlerPrivate::HbInputBasicQwertyHandlerPrivate()
       
    59 :mFnState(HbFnOff),
       
    60 mButton(0),
       
    61 mPreviewAvailable(false),
       
    62 mPrevDeadKey(0),
       
    63 mCurrentlyFocused(0)
       
    64 {
       
    65 }
       
    66 
       
    67 HbInputBasicQwertyHandlerPrivate::~HbInputBasicQwertyHandlerPrivate()
       
    68 {
       
    69 }
       
    70 
       
    71 void HbInputBasicQwertyHandlerPrivate::init()
       
    72 {
       
    73 }
       
    74 
       
    75 bool HbInputBasicQwertyHandlerPrivate::buttonPressed(const QKeyEvent * event)
       
    76 {
       
    77     if (!mKeymap->isDeadKey(event->key())) {
       
    78         mButton = event->key();
       
    79         mTimer->start(HbLongPressTimerTimeout);
       
    80         mPreviewAvailable = false;
       
    81     } 
       
    82     return false;
       
    83 }
       
    84 
       
    85 bool HbInputBasicQwertyHandlerPrivate::buttonReleased(const QKeyEvent *event)
       
    86 {
       
    87     Q_Q(HbInputBasicQwertyHandler);
       
    88     int buttonId = event->key();
       
    89     QChar firstChar = 0;
       
    90     QChar secondChar = 0;
       
    91 
       
    92     // If the timer is not active and it is alpha mode, it is a long press
       
    93     // and handled in another function. So just return.
       
    94     if (mTimer->isActive()) {
       
    95         mTimer->stop();
       
    96     } else if (buttonId == Qt::Key_Control) {
       
    97         return false;
       
    98     } else if (!(buttonId & 0xffff0000) && mPreviewAvailable) {
       
    99         return false;
       
   100     }
       
   101 
       
   102     HbInputFocusObject *focusObject = 0;
       
   103     focusObject = mInputMethod->focusObject();
       
   104     if (!focusObject) {
       
   105         qDebug("HbInputBasicQwertyHandler::virtualButtonClicked : no focused editor widget!");
       
   106         return false;
       
   107     }
       
   108     int currentTextCase = focusObject->editorInterface().textCase();
       
   109     const HbMappedKey *mappedKey = mKeymap->keyForKeycode(HbKeyboardVirtualQwerty, event->key());
       
   110     QChar newChar;
       
   111     if (mFnState == HbFnNext) {
       
   112         newChar = (mappedKey->characters(HbModifierFnPressed)).at(0);
       
   113         mFnState = HbFnOff;
       
   114     } else {
       
   115         if (currentTextCase == HbTextCaseLower) {
       
   116             if (mappedKey && mappedKey->characters(HbModifierNone).size() > 0) {
       
   117                 newChar = mappedKey->characters(HbModifierNone).at(0);
       
   118             } else {
       
   119                 newChar = buttonId;
       
   120             }
       
   121         } else {
       
   122             if (mappedKey && mappedKey->characters(HbModifierShiftPressed).size() > 0) {
       
   123                 newChar = mappedKey->characters(HbModifierShiftPressed).at(0);
       
   124             } else {
       
   125                 newChar = buttonId;
       
   126             }
       
   127         }
       
   128     }
       
   129 
       
   130     if (!mPrevDeadKey.isNull()) {
       
   131         if (event->key() != Qt::Key_Shift && event->key() != Qt::Key_Alt) {
       
   132             mKeymap->combineCharacter(mPrevDeadKey, newChar, firstChar, secondChar );
       
   133             mPrevDeadKey = 0;
       
   134             if (firstChar.isNull() && secondChar.isNull()) {
       
   135                 return true;
       
   136             }
       
   137         }
       
   138     } else {
       
   139         if (mKeymap->isDeadKey(newChar.unicode())) {
       
   140             mPrevDeadKey = newChar.unicode();
       
   141             return true;
       
   142         } else {
       
   143             firstChar = newChar;
       
   144         }
       
   145     }
       
   146 
       
   147     bool ret = false;
       
   148     switch(buttonId) {
       
   149     case Qt::Key_Alt:
       
   150         if (mFnState == HbFnOff) {
       
   151             mFnState = HbFnNext;
       
   152         } else if (mFnState == HbFnNext) {
       
   153             mFnState = HbFnOn;
       
   154         } else {
       
   155             mFnState = HbFnOff;
       
   156         }
       
   157         ret = true;
       
   158         break;
       
   159     case Qt::Key_Shift: {
       
   160             HbTextCase currentTextCase = focusObject->editorInterface().textCase();
       
   161             HbInputLanguage language = mInputMethod->inputState().language();
       
   162             
       
   163             // Update the Case Information in HbInputState, it internally updates in HbEditorInterface as well
       
   164             switch(currentTextCase) {
       
   165             case HbTextCaseLower:
       
   166                 // For Case-insensitive languages, Shift Key is used to switch between character sets (i.e lower case characters and shifted characters)
       
   167                 if(!language.isCaseSensitiveLanguage()){
       
   168                     currentTextCase = HbTextCaseUpper; 
       
   169                 }
       
   170                 else {
       
   171                     currentTextCase = HbTextCaseAutomatic;
       
   172                 }                                 
       
   173                 break;
       
   174             case HbTextCaseUpper:
       
   175                 currentTextCase = HbTextCaseLower;                
       
   176                 break;
       
   177             case HbTextCaseAutomatic:
       
   178                 currentTextCase = HbTextCaseUpper;               
       
   179                 break;
       
   180             default:
       
   181                 break;
       
   182             } 
       
   183             HbInputState state = mInputMethod->inputState();
       
   184             state.setTextCase(currentTextCase);            
       
   185             mInputMethod->activateState(state);
       
   186             ret = true;
       
   187         }
       
   188         break;
       
   189     case Qt::Key_Control:   // Ctrl/Chr
       
   190         mInputMethod->switchSpecialCharacterTable();
       
   191         ret = true;
       
   192         break;
       
   193     default:
       
   194 
       
   195         // let's pass non deadkey event to the base class.
       
   196         if (!mKeymap->isDeadKey(firstChar.unicode()) && secondChar.isNull() && q->HbInputBasicHandler::filterEvent(event)) {
       
   197             return true;
       
   198         }
       
   199 
       
   200         if (event->key() == Qt::Key_Delete || event->key() == Qt::Key_Backspace) {
       
   201             return false;
       
   202         }
       
   203 
       
   204         QList<QInputMethodEvent::Attribute> list;
       
   205         QString newText;
       
   206         // If function key is pressed, get the functionized 
       
   207         // character and commit.
       
   208 
       
   209         if (mFnState == HbFnNext) {
       
   210             if (!mappedKey->characters(HbModifierFnPressed).isEmpty() && focusObject && focusObject->characterAllowedInEditor(mappedKey->characters(HbModifierFnPressed).at(0))) {
       
   211                 QInputMethodEvent event(QString(), list);
       
   212                 event.setCommitString(QString(mappedKey->characters(HbModifierFnPressed).at(0)));
       
   213                 focusObject->sendEvent(event);
       
   214             }
       
   215             mFnState = HbFnOff;
       
   216             return true;
       
   217         }
       
   218         
       
   219         if (!firstChar.isNull()){
       
   220             q->commitAndUpdate(firstChar); 
       
   221             if (!secondChar.isNull() ) {
       
   222                 if (!q->HbInputBasicHandler::filterEvent(event)) {
       
   223                     q->commitAndUpdate(secondChar);
       
   224                 }
       
   225             }
       
   226 
       
   227             // Need to refresh the autocompletion list
       
   228             refreshAutoCompleter();
       
   229             ret = true;
       
   230         }
       
   231 
       
   232         break;
       
   233     }
       
   234     return ret;
       
   235 }
       
   236 
       
   237 void HbInputBasicQwertyHandlerPrivate::_q_timeout()
       
   238 {
       
   239     mTimer->stop();
       
   240 
       
   241     //If long key press of shift key is received, just return
       
   242     if (mButton == Qt::Key_Shift) {
       
   243         return;
       
   244     } else if (mButton == Qt::Key_Control) {
       
   245         mInputMethod->selectSpecialCharacterTableMode();
       
   246     }
       
   247     QStringList spellList;
       
   248     //If long key press of shift key, space key and enter key is received, don't
       
   249     if (mButton) {
       
   250         mInputMethod->launchCharacterPreviewPane(mButton);
       
   251     }
       
   252 
       
   253     return;
       
   254 }
       
   255 
       
   256 HbInputBasicQwertyHandler::HbInputBasicQwertyHandler(HbInputAbstractMethod* inputMethod)
       
   257 :HbInputBasicHandler(* new HbInputBasicQwertyHandlerPrivate, inputMethod)
       
   258 {
       
   259     Q_D(HbInputBasicQwertyHandler);
       
   260     d->q_ptr = this;
       
   261     d->init();
       
   262 }
       
   263 
       
   264 
       
   265 /*!
       
   266 This function lists different input modes.
       
   267 */
       
   268 void HbInputBasicQwertyHandler::listInputModes(QVector<HbInputModeProperties>& modes) const
       
   269 {
       
   270     HbInputModeProperties binding;
       
   271     binding.iMode = HbInputModeDefault;
       
   272     binding.iKeyboard = HbKeyboardVirtualQwerty;
       
   273 
       
   274     QList<HbInputLanguage> languages = HbKeymapFactory::availableLanguages();
       
   275     foreach (HbInputLanguage language, languages) {
       
   276         binding.iLanguage = language;
       
   277         modes.push_back(binding);
       
   278     }
       
   279 }
       
   280 
       
   281 HbInputBasicQwertyHandler::~HbInputBasicQwertyHandler()
       
   282 {
       
   283 }
       
   284 
       
   285 /*!
       
   286 filterEvent function key handling.
       
   287 */
       
   288 bool HbInputBasicQwertyHandler::filterEvent(const QKeyEvent* event)
       
   289 {
       
   290     Q_D(HbInputBasicQwertyHandler);
       
   291 
       
   292     if (event->type() == QEvent::KeyRelease) {
       
   293         return d->buttonReleased(event);
       
   294     } else {
       
   295         return d->buttonPressed(event);
       
   296     }
       
   297 }
       
   298 
       
   299 /*!
       
   300 returns true if in inline edit.
       
   301 */
       
   302 bool HbInputBasicQwertyHandler::isComposing() const
       
   303 {   
       
   304     Q_D(const HbInputBasicQwertyHandler);
       
   305     return d->mTimer->isActive();
       
   306 }
       
   307 
       
   308 /*!
       
   309 Action handler
       
   310 */
       
   311 bool HbInputBasicQwertyHandler::actionHandler(HbInputModeAction action)
       
   312 {
       
   313     Q_D(HbInputBasicQwertyHandler);
       
   314     HbInputFocusObject *focusObject = 0;
       
   315     focusObject = d->mInputMethod->focusObject();
       
   316     bool ret = true;
       
   317     switch (action) {
       
   318     case HbInputModeActionCancelButtonPress:
       
   319     case HbInputModeActionReset:
       
   320         if (d->mTimer->isActive()) {
       
   321             d->mTimer->stop();
       
   322         }
       
   323         break;
       
   324     case HbInputModeActionFocusRecieved:
       
   325         if (d->mTimer->isActive()) {
       
   326             d->mTimer->stop(); 
       
   327         }
       
   328         // set up auto completer
       
   329         setUpAutoCompleter();
       
   330     break;
       
   331     case HbInputModeActionFocusLost:
       
   332         // We should add the commit autocompleting text when focus lost happens
       
   333          if (d->mTimer->isActive()) {
       
   334             d->mTimer->stop(); 
       
   335         }
       
   336         if (d->mCurrentlyFocused != focusObject) {
       
   337             d->mCurrentlyFocused = focusObject;
       
   338             addWordInAutoCompleter();
       
   339         } 
       
   340     break;
       
   341     default: {
       
   342         ret = HbInputBasicHandler::actionHandler(action);
       
   343         }
       
   344     }
       
   345     return ret;
       
   346 }
       
   347 
       
   348 /*!
       
   349 this SLOT is called by input plugin when there is a character selected from character preview pane.
       
   350 */
       
   351 void HbInputBasicQwertyHandler::charFromPreviewSelected(QString characters)
       
   352 {
       
   353     Q_D(HbInputBasicQwertyHandler);
       
   354     if(characters.size() > 0) {
       
   355         sctCharacterSelected(characters.at(0));
       
   356         d->mInputMethod->updateState();
       
   357     }
       
   358 }
       
   359 
       
   360 void HbInputBasicQwertyHandler::sctCharacterSelected(QString character)
       
   361 {
       
   362     HbInputModeHandler::sctCharacterSelected(character);
       
   363 }
       
   364 
       
   365 void HbInputBasicQwertyHandler::characterPreviewAvailable(bool available)
       
   366 {
       
   367     Q_D(HbInputBasicQwertyHandler);
       
   368     d->mPreviewAvailable = available;
       
   369 }