diff -r 41a7f70b3818 -r 5266b1f337bd phoneapp/phoneuiutils/src/cphoneqwertyhandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phoneapp/phoneuiutils/src/cphoneqwertyhandler.cpp Wed Sep 01 12:30:10 2010 +0100 @@ -0,0 +1,298 @@ +/* +* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Implementation of CPhoneQwertyHandler class. +* +*/ + + +// INCLUDE FILES +#include "cphoneqwertyhandler.h" +#include "cphonelangsettingmonitor.h" +#include "cphoneqwertymodemonitor.h" +#include +#include + +// CONSTANTS +static const TUint32 KNumKeyModifiers( EModifierLeftShift | EModifierRightShift | EModifierShift | + EModifierLeftFunc | EModifierRightFunc | EModifierFunc ); + + +// FORWARD DECLARATIONS + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::CPhoneQwertyHandler +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPhoneQwertyHandler::CPhoneQwertyHandler() + { + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CPhoneQwertyHandler::ConstructL() + { + // Language setting monitor + iLangSettingMonitor = CPhoneLangSettingMonitor::NewL(); + iLangSettingMonitor->AddObserverL( *this ); + + // Qwerty mode + iQwertyModeMonitor = CPhoneQwertyModeMonitor::NewL(); + iQwertyModeMonitor->AddObserverL( *this ); + + // Read current values + iInputLanguageId = iLangSettingMonitor->InputLanguage(); + iQwertyMode = iQwertyModeMonitor->QwertyMode(); + + if ( iQwertyMode ) + { + LoadNumericKeyBindings( iInputLanguageId, iQwertyModeMonitor->Keyboard() ); + } + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CPhoneQwertyHandler* CPhoneQwertyHandler::NewL() + { + CPhoneQwertyHandler* self = + new (ELeave) CPhoneQwertyHandler(); + + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// Destructor +EXPORT_C CPhoneQwertyHandler::~CPhoneQwertyHandler() + { + iLangSettingMonitor->RemoveObserver( *this ); + delete iLangSettingMonitor; + iLangSettingMonitor = NULL; + iQwertyModeMonitor->RemoveObserver( *this ); + delete iQwertyModeMonitor; + iQwertyModeMonitor = NULL; + iNumericKeys.Close(); + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::IsQwertyInput +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CPhoneQwertyHandler::IsQwertyInput() const + { + return iQwertyMode > 0 ? ETrue : EFalse; + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::HandleLanguageSettingChange +// ----------------------------------------------------------------------------- +// +void CPhoneQwertyHandler::HandleInputLanguageSettingChange( TInt aLanguage ) + { + iInputLanguageId = aLanguage; + if ( iQwertyMode ) + { + LoadNumericKeyBindings( iInputLanguageId, iQwertyModeMonitor->Keyboard() ); + } + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::HandleQwertyModeChange +// Loads keybinding with keyboard EPtiKeyboardNone if no keyboeard has been +// defined +// ----------------------------------------------------------------------------- +// +void CPhoneQwertyHandler::HandleQwertyModeChange( TInt aMode ) + { + iQwertyMode = aMode; +#ifndef RD_INTELLIGENT_TEXT_INPUT + if ( iQwertyMode && !iNumericKeys.Count() ) + { + LoadNumericKeyBindings( iInputLanguageId, iQwertyModeMonitor->Keyboard() ); + } +#endif + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::HandleKeyboardLayoutChange +// This event comes after HandleQwertyModeChange +// ----------------------------------------------------------------------------- +// +void CPhoneQwertyHandler::HandleKeyboardLayoutChange() + { + LoadNumericKeyBindings( iInputLanguageId, iQwertyModeMonitor->Keyboard() ); + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::LoadNumericKeyBindings +// ----------------------------------------------------------------------------- +// +void CPhoneQwertyHandler::LoadNumericKeyBindings( TInt aLanguage, TInt aKeyboard ) + { + iNumericKeys.Reset(); + +#ifdef RD_INTELLIGENT_TEXT_INPUT + TPtiKeyboardType keyboard = static_cast( aKeyboard ); + TRAPD( err, + { + CPtiEngine* ptiEngine = CPtiEngine::NewL(); + CleanupStack::PushL( ptiEngine ); + + ptiEngine->GetNumericModeKeysForQwertyL( aLanguage, + iNumericKeys, + keyboard ); + CleanupStack::PopAndDestroy( ptiEngine ); + } ); // TRAP +#else + TRAPD( err, + { + CPtiEngine* ptiEngine = CPtiEngine::NewL(); + CleanupStack::PushL( ptiEngine ); + ptiEngine->GetNumericModeKeysForQwertyL( aLanguage, + iNumericKeys ); + CleanupStack::PopAndDestroy( ptiEngine ); + } ); // TRAP +#endif + + if ( err ) + { + iNumericKeys.Reset(); + iQwertyMode = 0; // To default mode + } + else + { + // remove keys that are not remapped + TInt numericKeysCount = iNumericKeys.Count(); + while ( numericKeysCount-- ) + { + TPtiNumericKeyBinding numKeyBind = iNumericKeys[numericKeysCount]; + + // This is PTI bug? Should not be in numeric keys list. + if ( numKeyBind.iKey == EPtiKeyQwertySpace ) + { + iNumericKeys.Remove( numericKeysCount ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::NumericKeyCode +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt CPhoneQwertyHandler::NumericKeyCode( const TKeyEvent& aKeyEvent ) + { + TInt keyCode( EKeyNull ); + + // It's possible that there are several numeric mode characters in same + // QWERTY key (for example, '2' and 'w' may be on same button) and there must + // be a way to enter each of these. + // Select numeric mode key code for the key event with the following logic: + // 1. If key contains exactly one numeric mode character, return that + // regardless of the current modifiers. + // 2a. If key has two numeric mode characters, then actual numbers are preferred. + // Pressing such key without modifiers will produce the number character. + // 2b. Pressing key with two numeric mode characters together with any modifier + // (Fn, Shift, Chr) will produce the secondary numeric mode character. + // 3. More than two numeric mode characters on one key are not supported. + // Such cases shouldn't ever occur, but if they will, then this algorithm + // must be changed. + + // Check modifier state + TBool modifierActive = ( aKeyEvent.iModifiers & KNumKeyModifiers ); + + TInt numBindIdx = iNumericKeys.Count(); + + while ( numBindIdx-- ) + { + const TPtiNumericKeyBinding& numKeyBind = iNumericKeys[numBindIdx]; + + if ( numKeyBind.iKey == aKeyEvent.iScanCode ) + { + if ( !keyCode ) + { + // first match for this key + keyCode = numKeyBind.iChar; + } + else + { + // Second numeric mode character for this key. Override + // previous code if it was the number character but some + // modifier is active or it was not number character and no + // modifiers are active. + if ( ( IsNumber(keyCode) && modifierActive ) || + ( !IsNumber(keyCode) && !modifierActive ) ) + { + keyCode = numKeyBind.iChar; + } + } + } + } + + return keyCode; + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::ConvertToNumeric +// ----------------------------------------------------------------------------- +// +EXPORT_C TBool CPhoneQwertyHandler::ConvertToNumeric( TKeyEvent& aKeyEvent ) + { + TBool ret( EFalse ); + TInt numericCode = NumericKeyCode( aKeyEvent ); + if ( numericCode ) + { + aKeyEvent.iCode = numericCode; + aKeyEvent.iModifiers &= ~KNumKeyModifiers; + ret = ETrue; + } + return ret; + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::AddQwertyModeObserverL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CPhoneQwertyHandler::AddQwertyModeObserverL( + MPhoneQwertyModeObserver& aObserver ) + { + iQwertyModeMonitor->AddObserverL( aObserver ); + + // Observer need to be notified with a current qwerty status so that + // status dependent objects would get correct initial value. + aObserver.HandleQwertyModeChange( iQwertyMode ); + } + +// ----------------------------------------------------------------------------- +// CPhoneQwertyHandler::IsNumber +// ----------------------------------------------------------------------------- +// +TBool CPhoneQwertyHandler::IsNumber( TText aChar ) const + { + return TChar( aChar ).IsDigit(); + } + + +// End of File