src/hbplugins/inputmethods/touchinput/hbinputbasic12keyhandler.cpp
changeset 2 06ff229162e9
parent 1 f7ac710697a9
child 5 627c4a0fd0e7
--- a/src/hbplugins/inputmethods/touchinput/hbinputbasic12keyhandler.cpp	Mon May 03 12:48:33 2010 +0300
+++ b/src/hbplugins/inputmethods/touchinput/hbinputbasic12keyhandler.cpp	Fri May 14 16:09:54 2010 +0300
@@ -30,6 +30,7 @@
 #include <hbinputpredictionengine.h>
 #include <hbinputsettingproxy.h>
 #include <hbinputpredictionfactory.h>
+#include <hbinputbutton.h>
 #include "hbinputabstractbase.h"
 #include "hbinputbasic12keyhandler.h"
 #include "hbinputbasic12keyhandler_p.h"
@@ -40,8 +41,8 @@
     mNumChr(0),
     mDownKey(0),
     mCurrentlyFocused(0),
-	mLongPressHappened(false),
-	mShiftKeyDoubleTapped(false)
+    mLongPressHappened(false),
+    mShiftKeyDoubleTapped(false)
 {
 }
 
@@ -50,50 +51,88 @@
 }
 
 // handles the key press events.
-void HbInputBasic12KeyHandlerPrivate::handleAlphaEvent(int buttonId)
+bool HbInputBasic12KeyHandlerPrivate::handleAlphaEvent(int buttonId, HbKeyboardType type)
 {
     Q_Q(HbInputBasic12KeyHandler);
-    HbInputFocusObject *focusObject = 0;
-    focusObject = mInputMethod->focusObject();
+    HbInputFocusObject *focusObject = mInputMethod->focusObject();
     if (!focusObject) {
-        return;
+        return false;
     }
-	//This condition is to avoid get the characters mapped to Asterisk
-	//Especially for Thai language we have mapped character to Asterisk
-	if(buttonId != Qt::Key_Asterisk) {
-		mCurrentChar = q->getNthCharacterInKey(mNumChr, buttonId);
-	}
+
+    int index = mNumChr;
+    do {
+	    //This condition is to avoid get the characters mapped to Asterisk
+	    //Especially for Thai language we have mapped character to Asterisk
+        if (buttonId != HbInputButton::ButtonKeyCodeAsterisk ||
+            mInputMethod->currentKeyboardType() == HbKeyboardSctPortrait) {
+            mCurrentChar = q->getNthCharacterInKey(mNumChr, buttonId, type);
+	    }
 
-    if (mCurrentChar != 0) {
-        QString str;
-        str += mCurrentChar;
-
-        QList<QInputMethodEvent::Attribute> list;
-        QInputMethodEvent event(str, list);
-        focusObject->sendEvent(event);
-    }
+        if (mCurrentChar != 0) {
+            if (focusObject->characterAllowedInEditor(mCurrentChar)) {
+                QString str;
+                str += mCurrentChar;
+                
+                //If the keypad is SCT, we can commit the character immidiately
+                if (mInputMethod->currentKeyboardType() == HbKeyboardSctPortrait) {
+                    focusObject->filterAndCommitCharacter(mCurrentChar);
+                    mCurrentChar = 0;
+                } else {
+                    QList<QInputMethodEvent::Attribute> list;
+                    QInputMethodEvent event(str, list);
+                    focusObject->sendEvent(event);
+                }
+                return true;
+            }
+        } else {
+            break;
+        }
+    } while (index != mNumChr);
+    return false;
 }
 
 bool HbInputBasic12KeyHandlerPrivate::buttonPressed(const QKeyEvent *keyEvent)
 {
-    Q_UNUSED(keyEvent);
+    Q_Q(HbInputBasic12KeyHandler);
     mLongPressHappened = false;
-    HbInputFocusObject *focusObject = 0;
-    focusObject = mInputMethod->focusObject();
+    HbInputFocusObject *focusObject = mInputMethod->focusObject();
     if (!focusObject) {
         return false;
     }
-	int buttonId = keyEvent->key();
-	// mark a shift key double tap. This would be handled when the release event is received.
-	if ( (buttonId == Qt::Key_Shift) && (mLastKey == buttonId) && mTimer->isActive() ) {
-		mShiftKeyDoubleTapped = true;		
-	}
+    int buttonId = keyEvent->key();
+
+    if (keyEvent->isAutoRepeat() && mDownKey == buttonId) {
+        mTimer->stop();
+        if (mDownKey == HbInputButton::ButtonKeyCodeShift) {
+            mLongPressHappened = true;
+            mInputMethod->switchMode(HbInputButton::ButtonKeyCodeShift);                
+        } else if (mDownKey == HbInputButton::ButtonKeyCodeSymbol ||
+            (mDownKey == HbInputButton::ButtonKeyCodeAsterisk &&
+            mInputMethod->currentKeyboardType() != HbKeyboardSctPortrait)) {
+            mLongPressHappened = true;
+            mInputMethod->selectSpecialCharacterTableMode();
+        } else if (mDownKey != HbInputButton::ButtonKeyCodeDelete &&
+                   mInputMethod->currentKeyboardType() != HbKeyboardSctPortrait) {
+            mLongPressHappened = true;
+            q->commitFirstMappedNumber(mDownKey, mInputMethod->currentKeyboardType());
+        }
+        if (mLongPressHappened) {
+            mDownKey = 0;
+            return true;
+        }
+    }
+
+    // mark a shift key double tap. This would be handled when the release event is received.
+    if ((buttonId == HbInputButton::ButtonKeyCodeShift) && (mLastKey == buttonId) && mTimer->isActive()) {
+        mShiftKeyDoubleTapped = true;        
+    }
+
     if (mInputMethod) {
-        if (mLastKey != buttonId)
+        if (mLastKey != buttonId || mInputMethod->currentKeyboardType() == HbKeyboardSctPortrait)
         {
-            if(mCurrentChar != 0) {
+            if (mCurrentChar != 0) {
                 if (!focusObject->characterAllowedInEditor(mCurrentChar)) {
-					focusObject->sendCommitString(QString());			
+                    focusObject->sendCommitString(QString());            
                 } else {
                     if (isEnterCharacter(mCurrentChar)) {
                         focusObject->sendPreEditString(QString("")); // Make sure the enter character is cleared.
@@ -101,15 +140,18 @@
                     }
                     QChar commitChar(mCurrentChar);
                     mCurrentChar = 0;
+                    mNumChr = 0;
                     focusObject->filterAndCommitCharacter(commitChar);
-                }			
-            }			
+                }            
+            }            
         }
 
-		mDownKey = buttonId;
+        mDownKey = buttonId;
         mTimer->stop();
-		mTimer->start(HbMultiTapTimerTimeout);
-	}
+        if (mInputMethod->currentKeyboardType() == HbKeyboardVirtual12Key) {
+            mTimer->start(HbMultiTapTimerTimeout);
+        }
+    }
     return false;
 }
 
@@ -120,57 +162,57 @@
 bool HbInputBasic12KeyHandlerPrivate::buttonReleased(const QKeyEvent *keyEvent)
 {
     HbInputVkbWidget::HbFlickDirection flickDir = static_cast<HbVirtual12Key*>(mInputMethod)->flickDirection();
-	if (mInputMethod && flickDir!=HbInputVkbWidget::HbFlickDirectionDown) {
-		Q_Q(HbInputBasic12KeyHandler);
-		int buttonId = keyEvent->key();
-		HbInputFocusObject *focusObject = 0;
-		focusObject = mInputMethod->focusObject();
-		if (!focusObject || !mDownKey) {
-			return false;
-		}
-		mDownKey = 0;
-		if ( mLongPressHappened ){
-			return false;
-		}
-		if(mTimer->isActive() && mLastKey != buttonId) {
-			mNumChr = 0;
+    if (mInputMethod && flickDir!=HbInputVkbWidget::HbFlickDirectionDown) {
+        Q_Q(HbInputBasic12KeyHandler);
+        int buttonId = keyEvent->key();
+        HbInputFocusObject *focusObject = mInputMethod->focusObject();
+        if (!focusObject || !mDownKey) {
+            return false;
+        }
+        mDownKey = 0;
+        if (mLongPressHappened){
+            mLongPressHappened = false;
+            return false;
+        }
 
+        if (mTimer->isActive() && mLastKey != buttonId) {
+            mNumChr = 0;
 
-			// For QLineEdit it works fine. For HbLineEdit, need to set the state 
-			// to lower by calling activateState().
-			// This is needed for the scenario - When automatic text case is true
-			// click a button and before the multitap timer expires click on
-			// another button.
-			// Need to check for shift key : In empty editor, click on editor
-			// press shift, multitap on a button. The char is entered in upper case.
-			// It should be entered in lower case.
-            if (mLastKey && (Qt::Key_Shift != mLastKey)) {
-			    mInputMethod->updateState();
+            // For QLineEdit it works fine. For HbLineEdit, need to set the state 
+            // to lower by calling activateState().
+            // This is needed for the scenario - When automatic text case is true
+            // click a button and before the multitap timer expires click on
+            // another button.
+            // Need to check for shift key : In empty editor, click on editor
+            // press shift, multitap on a button. The char is entered in upper case.
+            // It should be entered in lower case.
+            if (mLastKey && (HbInputButton::ButtonKeyCodeShift != mLastKey)) {
+                mInputMethod->updateState();
             }
-			refreshAutoCompleter();
-		}
+            refreshAutoCompleter();
+        }
 
-		if (buttonId == Qt::Key_Return) {
-			mInputMethod->closeKeypad();
-			mLastKey = buttonId;
-			return true;
-		} else if (buttonId == Qt::Key_Shift) {
+        if (buttonId == HbInputButton::ButtonKeyCodeEnter) {
+            mInputMethod->closeKeypad();
+            mLastKey = buttonId;
+            return true;
+        } else if (buttonId == HbInputButton::ButtonKeyCodeShift) {
             // single tap of shift key toggles prediction status in case insensitive languages
 			// The Editor should not be Web or URL which allows only Latin Alphabet
             if (!HbInputSettingProxy::instance()->globalInputLanguage().isCaseSensitiveLanguage() &&
-				((HbEditorConstraintLatinAlphabetOnly | HbEditorConstraintAutoCompletingField)!=focusObject->editorInterface().constraints()) &&
+                                ((HbEditorConstraintLatinAlphabetOnly | HbEditorConstraintAutoCompletingField)!=focusObject->editorInterface().inputConstraints()) &&
                 // when the language does not support prediction in that case we should not update the state and prediction
                 HbPredictionFactory::instance()->predictionEngineForLanguage(mInputMethod->inputState().language())) {
                 HbInputSettingProxy::instance()->togglePrediction();
             } else {
                 // For single key press, change the text input case. If the second shift key press is 
-				// received within long key press time out interval, then activate the next state
+                // received within long key press time out interval, then activate the next state
                 if (mShiftKeyDoubleTapped){
                     mShiftKeyDoubleTapped = false;
                     mTimer->stop();
                     if( HbInputSettingProxy::instance()->globalInputLanguage() == mInputMethod->inputState().language() ||
                         HbInputSettingProxy::instance()->globalSecondaryInputLanguage() == mInputMethod->inputState().language() ||
-						((HbEditorConstraintLatinAlphabetOnly | HbEditorConstraintAutoCompletingField)==focusObject->editorInterface().constraints())){
+                                                ((HbEditorConstraintLatinAlphabetOnly | HbEditorConstraintAutoCompletingField)==focusObject->editorInterface().inputConstraints())){
                         // in latin variants , double tap of shift key toggles the prediction status	
                         // revert back to the old case as this is a double tap 
                         // (the case was changed on the single tap)
@@ -180,54 +222,55 @@
                             q->togglePrediction();
                         }
                     } else {
-					    // if the global language is different from the input mode language, we should 
+                        // if the global language is different from the input mode language, we should 
                         // go back to the root state
                         // e.g. double tap of hash/shift key is used to change 
                         // to chinese input mode from latin input mode
                         HbInputState rootState;
                         mInputMethod->editorRootState(rootState);
-                        mInputMethod->activateState(rootState); 		
+                        mInputMethod->activateState(rootState);         
                     }
                 } else {
                     updateTextCase();
-                    mTimer->start(HbLongPressTimerTimeout);
+                    mTimer->start(HbMultiTapTimerTimeout);
                 }
-            }	
-			mLastKey = buttonId;
-			mCurrentChar = 0;
+            }    
+            mLastKey = buttonId;
+            mCurrentChar = 0;
             return true;
-		}
+        }
 
-		// Let's see if we can get the handler for this button in the base class.
-		if (q->HbInputBasicHandler::filterEvent(keyEvent)) {
-			mCurrentChar = 0;
-			return true;
-		}
-		mLastKey = buttonId;
-		handleAlphaEvent(buttonId);
+        // Let's see if we can get the handler for this button in the base class.
+        if (q->HbInputBasicHandler::filterEvent(keyEvent)) {
+            mCurrentChar = 0;
+            return true;
+        }
+        mLastKey = buttonId;
+        if (handleAlphaEvent(buttonId, mInputMethod->currentKeyboardType())) {
+            return true;
+        }
 
-		// it was a long press on sct swith button. so just return form here.
-		if (!mTimer->isActive() && buttonId == Qt::Key_Control) {
-			return true;
-		}
-		if (buttonId == Qt::Key_Asterisk || buttonId == Qt::Key_Control) {
-			//Same asterisk key is used for launching candidate list (long key press)
-			//and also for SCT. So, do not launch SCT if candidate list is already launched.            
-			mInputMethod->switchMode(buttonId);
-			return true;
-		}
-	}
-	return false;
+        // it was a long press on sct swith button. so just return form here.
+        if (!mTimer->isActive() && buttonId == HbInputButton::ButtonKeyCodeSymbol) {
+            return true;
+        }
+        if (buttonId == HbInputButton::ButtonKeyCodeAsterisk || buttonId == HbInputButton::ButtonKeyCodeSymbol ||
+            buttonId == HbInputButton::ButtonKeyCodeAlphabet) {
+            //Same asterisk key is used for launching candidate list (long key press)
+            //and also for SCT. So, do not launch SCT if candidate list is already launched.            
+            mInputMethod->switchMode(buttonId);
+            return true;
+        }
+    }
+    return false;
 }
 
 void HbInputBasic12KeyHandlerPrivate::_q_timeout()
 {
-    Q_Q(HbInputBasic12KeyHandler);
     mTimer->stop();
     mNumChr = 0;
 
-    HbInputFocusObject *focusedObject = 0;
-    focusedObject = mInputMethod->focusObject();
+    HbInputFocusObject *focusedObject = mInputMethod->focusObject();
     if (!focusedObject) {
         qDebug("HbInputBasic12KeyHandler::timeout focusObject == 0");
         return;
@@ -238,23 +281,7 @@
         mCurrentChar = QChar('\n');                    // Convert enter character to line feed.
     }
 
-    //Long key press number key is applicable to all keys
-    if (mDownKey ) {       
-        //switch to numeric mode for long key press of Hash key	
-        if (mDownKey == Qt::Key_Shift) {
-            mInputMethod->switchMode(Qt::Key_Shift);				
-        } else if (mDownKey == Qt::Key_Control ) {
-            mInputMethod->selectSpecialCharacterTableMode();
-            mLongPressHappened = true;
-        } else if (mDownKey == Qt::Key_Asterisk) {
-				//switch to sct mode for long tap of * key
-				mInputMethod->switchMode(mDownKey);
-		} else if (mDownKey != Qt::Key_Delete) {
-            q->commitFirstMappedNumber(mDownKey);
-            mLongPressHappened = true;
-        }
- 	mDownKey = 0;        
-    } else if(mLastKey != Qt::Key_Shift){
+    if (!mDownKey && mLastKey != HbInputButton::ButtonKeyCodeShift) {
         if (!focusedObject->characterAllowedInEditor(mCurrentChar)) {
             focusedObject->sendCommitString(QString());
         } else {
@@ -268,7 +295,7 @@
     }
 
     mCurrentChar = 0;
-    return;	
+    return;    
 }
 
 bool HbInputBasic12KeyHandlerPrivate::actionHandler(HbInputModeHandler::HbInputModeAction action)
@@ -292,7 +319,7 @@
         mDownKey = 0;
         mShiftKeyDoubleTapped = false;
     break;        
-	case HbInputModeHandler::HbInputModeActionCancelButtonPress:
+    case HbInputModeHandler::HbInputModeActionCancelButtonPress:
         mLastKey = 0;
         mNumChr = 0;
         mDownKey = 0;
@@ -313,8 +340,8 @@
                 QInputMethodEvent event(QString(), list);
                 event.setCommitString(empty, -1, 1);
                 focusObject->sendEvent(event);
-				mInputMethod->updateState();            
-			}
+                mInputMethod->updateState();            
+            }
         } else {
             // Close event was originated from a button press, remove the uncommitted character.
             focusObject->sendCommitString(empty);
@@ -343,15 +370,15 @@
             mNumChr = 0;
             mInputMethod->updateState();
         }
-		// We should add the commit autocompleting text when focus lost happens
-		if(HbInputModeHandler::HbInputModeActionFocusLost == action){
-			if (mCurrentlyFocused != focusObject) {
-				mCurrentlyFocused = focusObject;
-				if (mAutoCompleter) {
-					mAutoCompleter->commit();
-				}
-			}
-		}
+        // We should add the commit autocompleting text when focus lost happens
+        if(HbInputModeHandler::HbInputModeActionFocusLost == action){
+            if (mCurrentlyFocused != focusObject) {
+                mCurrentlyFocused = focusObject;
+                if (mAutoCompleter) {
+                    mAutoCompleter->commit();
+                }
+            }
+        }
         break;
     default: {
         ret = false;
@@ -371,7 +398,7 @@
 }
 
 HbInputBasic12KeyHandler::HbInputBasic12KeyHandler(HbInputBasic12KeyHandlerPrivate &dd, HbInputAbstractMethod* inputMethod)
-:HbInputBasicHandler(dd, inputMethod)
+ : HbInputBasicHandler(dd, inputMethod)
 {
     Q_D(HbInputBasic12KeyHandler);
     d->q_ptr = this;