diff -r 000000000000 -r eb1f2e154e89 fep/aknfep/src/AknFepCaseManager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fep/aknfep/src/AknFepCaseManager.cpp Tue Feb 02 01:02:04 2010 +0200 @@ -0,0 +1,1062 @@ +/* +* Copyright (c) 2002-2004 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: +* +*/ + + + + + + + + + + + + +#include "AknFepCaseManager.h" +#include "AknFepPanic.h" +#include "aknfeppeninputenums.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +const TText KSpaceCharacter=' '; +const TText KInvertedExclamationMarkCharacter = 0x00A1; +const TText KInvertedQuestionMarkCharacter = 0x00BF; + +/* Teleca change begin, 18.08.2009 ssal */ +const TInt KSBase = 0xac00; // base address for hangul syllables +const TInt KCBase = 0x3131; // base address for hangul compatibility jamo + +const TInt KLCount = 19; // count of L-jamos +const TInt KVCount = 21; // count of V-jamos +const TInt KTCount = 28; // count of T-jamos +const TInt KNCount = KVCount * KTCount; // count of V&T-jamo combinations +const TInt KSCount = KLCount * KNCount; // total count of hangul syllables + +// Conversion table for hangul compatibility jamo +const TUint16 conversionTableFromCompatibilityJamoToJamo[] = { +0x1100, +0x1101, +0x11AA, +0x1102, +0x11AC, +0x11AD, +0x1103, +0x1104, +0x1105, +0x11B0, +0x11B1, +0x11B2, +0x11B3, +0x11B4, +0x11B5, +0x11B6, +0x1106, +0x1107, +0x1108, +0x11B9, +0x1109, +0x110A, +0x110B, +0x110C, +0x110D, +0x110E, +0x110F, +0x1110, +0x1111, +0x1112, +0x1161, +0x1162, +0x1163, +0x1164, +0x1165, +0x1166, +0x1167, +0x1168, +0x1169, +0x116A, +0x116B, +0x116C, +0x116D, +0x116E, +0x116F, +0x1170, +0x1171, +0x1172, +0x1173, +0x1174, +0x1175, +}; + +#define KCCount (sizeof(conversionTableFromCompatibilityJamoToJamo) / sizeof(TUint16)) +/* Teleca change end, 18.08.2009 ssal */ + +// 0x2029 is the paragraph seperator. When the user inputs a +// new line character, 0x2029 is inserted. +const TText KParagraphSeperator = 0x2029; +// 0x000A is line feed character +const TText KLineFeed = 0x000A; + +//for chinese unicode ox4E00 to 0x9FA5 +const TText KChineseLowerUnicode = 0x4E00; +const TText KChineseUpperUnicode = 0x9FA5; +CAknFepCaseManager* CAknFepCaseManager::NewL(CAknFepManager& aFep) + { + CAknFepCaseManager* self = new (ELeave) CAknFepCaseManager(aFep); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); //self + return self; + } + + +CAknFepCaseManager::~CAknFepCaseManager() + { + delete iPictoInterface; + } + + + + +void CAknFepCaseManager::ConfigureCaseStateFromEditorState() + { + CAknEdwinState* editorState = iFep.EditorState(); + if (!editorState) + { + return; + } + + iCurrentCase = editorState->CurrentCase(); + iPreviousCase = editorState->CaseState().PreviousCase(); + + SetFixedCase(editorState->Flags() & EAknEditorFlagFixedCase); + + iPreviousCase = iCurrentCase; + + if (CurrentEditorIsFixedCase()) + { + SetCurrentCase(editorState->DefaultCase()); + iPreviousCase = iCurrentCase; + __ASSERT_DEBUG(IsCasePermitted(iCurrentCase), + AknFepPanic(EAknFepPanicNonPermittedEditorMode)); + } + + //determine it based on position + UpdateCase(ENullNaviEvent); + + // if still there is no current case set - use the default + if (!iCurrentCase) + { + SetCurrentCase(editorState->DefaultCase()); + if (!IsCasePermitted(iCurrentCase)) + { + SetCurrentCase(editorState->CurrentCase()); + } + + iPreviousCase = iCurrentCase; + __ASSERT_DEBUG(IsCasePermitted(iCurrentCase), + AknFepPanic(EAknFepPanicNonPermittedEditorMode)); + } + + // if the current is not allowed stay where we are + else if (!IsCasePermitted(iCurrentCase)) + { + if (!iPreviousCase) + { + SetCurrentCase(editorState->DefaultCase()); + iPreviousCase = iCurrentCase; + __ASSERT_DEBUG(IsCasePermitted(iCurrentCase), + AknFepPanic(EAknFepPanicNonPermittedEditorMode)); + } + else + { + if (IsCasePermitted(iPreviousCase)) + { + SetCurrentCase(iPreviousCase); + } + else + { + SetCurrentCase(editorState->DefaultCase()); + iPreviousCase = iCurrentCase; + __ASSERT_DEBUG(IsCasePermitted(iCurrentCase), + AknFepPanic(EAknFepPanicNonPermittedEditorMode)); + } + } + } + } + + +void CAknFepCaseManager::UpdateCase(TWesternNaviEvent aNaviEvent) + { + TBool applyCaseNeeded = ETrue; + if ( iFep.IsFlagSet(CAknFepManager::EFlagSupressAutoUpdate) ) + { + return; + } + CAknEdwinState* editorState = iFep.EditorState(); + if (!CurrentEditorIsFixedCase() && editorState + && editorState->PermittedCases() & EAknEditorTextCase) + { + // lets figure out where the cursor will be when the case needs to be checked + TInt cursorPos = FindCursorPositionAtCaseCheck(aNaviEvent); + + if (!(cursorPos == 0 + && iFep.IsFlagSet(CAknFepManager::EFlagSupressAutoUpdateAtEditorStart) )) + { + TInt defaultCase = editorState->DefaultCase(); + if ( cursorPos == 0 && + (defaultCase == EAknEditorLowerCase || defaultCase == EAknEditorUpperCase )) + { + SetCurrentCase(defaultCase); + } + // UPPER CASE : If in upper case & inside sentence, stay in upper. + else if (!(iCurrentCase == EAknEditorUpperCase && + CapsLockRequired(cursorPos, iCurrentCase) && + aNaviEvent != EBackspaceEvent)) + { + const TBool textCaseRequired = TextCaseRequired(cursorPos); + // UPPER CASE : If upper case & inside sentence & backspace event, stay in upper. + if (!(iCurrentCase == EAknEditorUpperCase && aNaviEvent == EBackspaceEvent && + !textCaseRequired && cursorPos != 0)) + { + // TEXT CASE : set if at start of editor or following a full stop / text case character + if (cursorPos == 0 || textCaseRequired) + { + TInt inputMode = iFep.InputMode(); + if (iFep.IsChineseInputLanguage() && + inputMode != ELatin && + iCurrentCase != EAknEditorLowerCase) + { + SetCurrentCase(iCurrentCase); + } +#ifdef RD_HINDI_PHONETIC_INPUT + + else if(iFep.IsIndicPhoneticInputLanguage()) + { + if(CurrentCase() != EAknEditorUpperCase) + SetCurrentCase(EAknEditorLowerCase); + } +#endif + else + { + /* Teleca change begin, 27.08.2008 ssal + original code: + SetCurrentCase(EAknEditorTextCase); */ + + if(iFep.IsKoreanInputLanguage() && inputMode == EHangul ) + { + SetCurrentCase(EAknEditorLowerCase); + } + else + { + SetCurrentCase(EAknEditorTextCase); + } + /* Teleca change end, 27.08.2008 ssal */ + } + applyCaseNeeded = EFalse; + } + else // OTHERWISE LOWER + { + SetCurrentCase(EAknEditorLowerCase); + applyCaseNeeded = EFalse; + } + } + } + } + else + { + iFep.ClearFlag(CAknFepManager::EFlagSupressAutoUpdateAtEditorStart); + } + } + if (applyCaseNeeded) + { + ApplyCase(); + } + } + + +void CAknFepCaseManager::ManualCaseUpdate() + { + if (!CurrentEditorIsFixedCase()) + { + if (IsCasePermitted(iCurrentCase)) + { + DoManualCaseUpdate(); + iFep.ClearFlag(CAknFepManager::EFlagSupressAutoUpdate); + } + } + } + + +void CAknFepCaseManager::RevertCaseChange() + { + if (!CurrentEditorIsFixedCase()) + { + if (IsCasePermitted(iPreviousCase)) + { + SetCurrentCase(iPreviousCase); + } + } + } + + +void CAknFepCaseManager::SetCurrentCase(TInt aCase, TBool aOverrideNumericTest) + { + if ( ( iFep.InputMode() == ENumber || iFep.InputMode() == ENativeNumber ) && + !aOverrideNumericTest) + { + if ( iFep.EditorState() && + (iFep.EditorState()->NumericKeymap() == EAknEditorConverterNumberModeKeymap) ) + { + // Converter number mode keymap for '*' key requires upper case 'E'. + iCurrentCase = EAknEditorUpperCase; + } + else + { + // Number mode keymappings for '*' -key uses lower case letters (pw). + iCurrentCase = EAknEditorLowerCase; + } + } + else + { + if ( aCase == ECaseInverseText ) + { + iCurrentCase = ECaseUpper; + iInverseCase = ETrue; + } + else + { + iCurrentCase = aCase; + iInverseCase = EFalse; + } + } + ApplyCase(); + } + + +TInt CAknFepCaseManager::CurrentCase() const + { + return iCurrentCase; + } + +TBool CAknFepCaseManager::IsAbleChangeCase() const + { + TBool isable = ETrue; + + CAknEdwinState* editorState = iFep.EditorState(); + if (editorState) + { + const TInt permittedCases = editorState->PermittedCases(); + + if (permittedCases == EAknEditorUpperCase || + permittedCases == EAknEditorLowerCase ) + { + isable = EFalse; + } + else if ((editorState->Flags() & EAknEditorFlagForceTransparentFepModes) + && iFep.IsChineseInputLanguage()) + { + isable = EFalse; + } + else if ( editorState->Flags() & EAknEditorFlagFixedCase ) + { + isable = EFalse; + } + else if (!iFep.InputLanguageSupportsCaseChanges()) + { + isable = EFalse; + } + } + else + { + isable = EFalse; + } + return isable; + } + +CAknFepCaseManager::CAknFepCaseManager(CAknFepManager& aFep) : + iFep(aFep) + { + } + + +void CAknFepCaseManager::ConstructL() + { + // Set text case character set from resource + TResourceReader reader; + CCoeEnv::Static()->CreateResourceReaderLC(reader, R_AKNFEP_TEXT_CASE_CHARACTER_SET); + iTextCaseCharacters=reader.ReadTPtrC(); + + // Create PictographInterface + CCoeControl* control = NULL; + MAknPictographAnimatorCallBack* callback = NULL; + iPictoInterface = CAknPictographInterface::NewL(*control,*callback); + + CleanupStack::PopAndDestroy(); // reader*/ + } + + +TInt CAknFepCaseManager::FindCursorPositionAtCaseCheck(TWesternNaviEvent aNaviEvent) + { + TCursorSelection curCursSel; + iFep.FepAwareTextEditor()->GetCursorSelectionForFep(curCursSel); + + TInt docLength = iFep.FepAwareTextEditor()->DocumentLengthForFep(); + TInt returnedPosition = -1; + + TCursorSelection uncommittedText = iFep.UncommittedText(); + + switch (aNaviEvent) + { + case ENullNaviEvent: + if (iFep.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) + { + returnedPosition = uncommittedText.HigherPos(); + } + else + { + // In case of non-predictive mode, following condition + // check text is selceted mode or not? + // In selected mode, character always being inserted + // anchor position + if( curCursSel.Length() >0 ) + { + returnedPosition = curCursSel.LowerPos(); + } + else + { + returnedPosition = curCursSel.HigherPos(); + } + } + break; + case ERightNaviEvent: + if (iFep.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) + { + returnedPosition = uncommittedText.HigherPos(); + } + else + { + if (curCursSel.Length()) + { + returnedPosition = curCursSel.HigherPos(); + } + else + { + if (curCursSel.iCursorPos == docLength) + { + returnedPosition = 0; + } + else + { + returnedPosition = curCursSel.HigherPos() + 1; + } + } + } + break; + case ELeftNaviEvent: + if (iFep.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) + { + returnedPosition = uncommittedText.LowerPos(); + } + else + { + if (curCursSel.Length()) + { + returnedPosition = curCursSel.LowerPos(); + } + else + { + if (curCursSel.iCursorPos == 0) + { + returnedPosition = docLength; + } + else + { + returnedPosition = curCursSel.LowerPos() - 1; + } + } + } + break; + case EBackspaceEvent: + if (iFep.IsFlagSet(CAknFepManager::EFlagInsideInlineEditingTransaction)) + { + returnedPosition = uncommittedText.HigherPos(); + } + else + { + if (curCursSel.Length()) + { + returnedPosition = curCursSel.LowerPos(); + } + else + { + returnedPosition = curCursSel.LowerPos() - 1; + } + } + break; + default: + break; + } + + if (returnedPosition < 0) + { + returnedPosition = 0; + } + else if (returnedPosition > docLength) + { + returnedPosition = docLength; + } + return returnedPosition; + } + + +TBool CAknFepCaseManager::TextCaseRequired(TInt aCursorPos) + { + TBool textCaseRequired = EFalse; + TInt charPosToCheck = aCursorPos - 1; + TChar ch = KSpaceCharacter; + TBuf editorText; + TInt nonEnterSpaceCharCount = 0; + + if (charPosToCheck >= 0) + { + // Get the character just before the cursor. + iFep.FepAwareTextEditor()->GetEditorContentForFep(editorText, + charPosToCheck, CAknFepManager::ESingleCharacter); + ch = editorText[0]; + if ( ch == KInvertedQuestionMarkCharacter || ch == KInvertedExclamationMarkCharacter ) + { + // Text case is required imediatelly after 'spanich' question and exclamation mark that begins a sentence. + textCaseRequired = ETrue; + } + // for chinese uncode limit + if ( ch >= KChineseLowerUnicode && ch<= KChineseUpperUnicode) + { + textCaseRequired = ETrue; + } + + if( ( TUint )ch == KParagraphSeperator || ( TUint )ch == KLineFeed ) + { + // When we have enter key, we need to decide the case after: + // we reach some non space characters (OR) + // we reach the beginning of the editor + while (charPosToCheck > 0 && !textCaseRequired) + { + charPosToCheck--; + iFep.FepAwareTextEditor()->GetEditorContentForFep(editorText, + charPosToCheck, CAknFepManager::ESingleCharacter); + ch = editorText[0]; + + // IsSpace returns true for ParagraphSeperator. + if (!(ch.IsSpace() || ch == EKeyEnter) && nonEnterSpaceCharCount <= 1) + { + if (IsTextCaseCharacter(ch)) + { + textCaseRequired = ETrue; + } + break; + } + else + { + if(!( ( TUint )ch == KParagraphSeperator || ( TUint )ch == EKeyEnter || ( TUint )ch == KLineFeed ) ) + { + // Incrementing the count if we have + // IsSpace() returns True AND + // the character is not a ParagraphSeparator or Enter or Line Feed + nonEnterSpaceCharCount++; + } + if (charPosToCheck <= 0 && !nonEnterSpaceCharCount) + { + //Reached the beginning of the Editor. Text case should be ON + textCaseRequired = ETrue; + } + } + } + charPosToCheck = aCursorPos - 1; + + if (charPosToCheck <= 0 && !nonEnterSpaceCharCount) + { + // If Enter is pressed as the first character. Text case is ON + textCaseRequired = ETrue; + } + + } + + /* Teleca change begin, 27.08.2008 ssal */ + if (IsKoreanCharacter(ch)) + { + textCaseRequired = ETrue; + } + /* Teleca change end, 27.08.2008 ssal */ + } + + + if (charPosToCheck > 0 && !textCaseRequired) + { + if (iFep.IsFeatureSupportedJapanese()) + { + // The character case is changed to text case when the left side + // character is Japanese character. + if (IsJapaneseCharacter(ch)) + { + textCaseRequired = ETrue; + } + else if (ch.IsSpace() || ch == EKeyEnter || + ch == (TUint)KPuaCodeSpaceSymbol) + { + while (charPosToCheck > 0) + { + charPosToCheck--; + // Get the character before the previous character. + iFep.FepAwareTextEditor()->GetEditorContentForFep(editorText, + charPosToCheck, CAknFepManager::ESingleCharacter); + ch = editorText[0]; + if (!(ch.IsSpace() || ch == EKeyEnter || ch == (TUint)KPuaCodeSpaceSymbol)) + { + if (IsTextCaseCharacter(ch)) + { + // One space between the cursor and the punctuation character => text case needed + textCaseRequired = ETrue; + } + break; + } + else if (charPosToCheck <= 0) + { + // reached the start of the editor => text case needed + textCaseRequired = ETrue; + } + } + } + } + else + { + if ( charPosToCheck > 0 && !textCaseRequired && !nonEnterSpaceCharCount) + { + if ( ch.IsSpace() || ch == EKeyEnter || + ch == ( TUint )KPuaCodeSpaceSymbol ) + { + while ( charPosToCheck > 0 ) + { + charPosToCheck--; + + // Get the character before the previous character. + iFep.FepAwareTextEditor()->GetEditorContentForFep(editorText, + charPosToCheck, CAknFepManager::ESingleCharacter); + + ch = editorText[0]; + + // This condition is added to keep Text case ON when space is + // entered after a "New line" character. + if( ( TUint )ch == KParagraphSeperator ) + { + textCaseRequired = ETrue; + break; + } + + if ( !( ch == EKeyEnter || + ch == ( TUint )KPuaCodeSpaceSymbol ) ) + { + if ( IsTextCaseCharacter( ch ) ) + { + textCaseRequired = ETrue; + } + break; + } + else if ( charPosToCheck <= 0 ) + { + // reached the start of the editor => text case needed + textCaseRequired = ETrue; + } + } + } + } + } + } + else if (charPosToCheck < 0) + { + // reached the start of the editor => text case needed + textCaseRequired = ETrue; + } + else // if (charPosToCheck == 0) + { + if (!textCaseRequired && iFep.IsFeatureSupportedJapanese()) + { + if (IsJapaneseCharacter(ch) + || ch.IsSpace() + || ch == EKeyEnter + || ch == (TUint)KPuaCodeSpaceSymbol) + { + // reached the start of the editor => text case needed + textCaseRequired = ETrue; + } + } + } + + return textCaseRequired; + } + + +TBool CAknFepCaseManager::CapsLockRequired(TInt aCursorPos, TInt aCurCase) + { + TBool capsLocked = iForceUpperCase; + TInt charPosToCheck = aCursorPos - 1; + TChar ch = KSpaceCharacter; + TBuf editorText; + + // is the previous character alphabetical? + if (charPosToCheck >= 0) + { + iFep.FepAwareTextEditor()->GetEditorContentForFep(editorText, + charPosToCheck, CAknFepManager::ESingleCharacter); + if( editorText.Length()>0 ) + { + ch = editorText[0]; + } + + if (IsAlpha(ch) || + ((aCurCase == EAknEditorUpperCase || aCurCase == ECaseInverseText) && + !TextCaseRequired(aCursorPos))) + { + // Caps lock (upper case mode) is kept up if we are currently in upper case mode + // and previous character is alpha character or for example full stop. + // If the cursor and full stop is separated with space, text case is restored. + capsLocked = ETrue; + } + } + + return capsLocked; + } + + +void CAknFepCaseManager::DoManualCaseUpdate() + { + TBool applyCaseNeeded = ETrue; + iPreviousCase = iCurrentCase; + TCursorSelection currentSelection; + iFep.FepAwareTextEditor()->GetCursorSelectionForFep(currentSelection); + + switch (iCurrentCase) + { + case EAknEditorLowerCase: + if (CapsLockRequired(currentSelection.iCursorPos, iCurrentCase) + && IsCasePermitted(EAknEditorUpperCase)) + { + SetCurrentCase(EAknEditorUpperCase); + } + else if (!IsCasePermitted(EAknEditorTextCase) +#ifdef RD_HINDI_PHONETIC_INPUT + + || iFep.IsIndicPhoneticInputLanguage() +#endif + ) + { + if( IsCasePermitted(EAknEditorUpperCase) ) + SetCurrentCase(EAknEditorUpperCase); + } + else + { + SetCurrentCase(EAknEditorTextCase); + } + applyCaseNeeded = EFalse; + break; + case EAknEditorTextCase: + if (iForceUpperCase && IsCasePermitted(EAknEditorUpperCase)) + { + SetCurrentCase(EAknEditorUpperCase); + applyCaseNeeded = EFalse; + break; + } + case EAknEditorUpperCase: + SetCurrentCase(EAknEditorLowerCase); + applyCaseNeeded = EFalse; + break; + default: + break; + } + + if (!(IsCasePermitted(iCurrentCase))) + { + DoManualCaseUpdate(); + } + else + { + if (applyCaseNeeded) + { + ApplyCase(); + } + } + } + + +void CAknFepCaseManager::ApplyCase() + { + // update engine... + switch (iCurrentCase) + { + case EAknEditorUpperCase: // fall through + case EAknEditorTextCase: + iFep.SetCase(EUpperCase); + break; + case EAknEditorLowerCase: // fall through + default: + iFep.SetCase(ELowerCase); + break; + } + if(iFep.EditorState()) + { + iFep.EditorState()->SetCurrentCase(iCurrentCase); + } + iFep.UpdateIndicators(); + +#ifdef RD_SCALABLE_UI_V2 + iFep.UpdateTouchCaseMode(); +#endif + } + + +void CAknFepCaseManager::SetFixedCase(TBool aFixedCase) + { + iFixedCase = aFixedCase; + } + + +TBool CAknFepCaseManager::CurrentEditorIsFixedCase() const + { + return iFixedCase; + } + + +TBool CAknFepCaseManager::IsCasePermitted(TInt aCase) const + { + // if current is permitted or current is lower and text is permitted + CAknEdwinState* editorState = iFep.EditorState(); + return ( editorState && ( !editorState->PermittedCases() || + (aCase & editorState->PermittedCases() || + (aCase == EAknEditorLowerCase && + (EAknEditorTextCase & editorState->PermittedCases())))) ); + } + +TBool CAknFepCaseManager::IsTextCaseCharacter(TChar aChar) const + { + TBool ret = EFalse; + if (iTextCaseCharacters.Locate(aChar)!=KErrNotFound) + { + ret = ETrue; + } + else if (JPLangUtil::IsKanji((TText)aChar) + || JPLangUtil::IsHiragana((TText)aChar) + || JPLangUtil::IsKatakana((TText) aChar)) + { + ret = ETrue; + } + return ret; + } + +TBool CAknFepCaseManager::IsAlpha(TChar aChar) const + { + TBool ret = EFalse; + TBool isPicto = EFalse; + + if (iPictoInterface && iPictoInterface->Interface()) + { + isPicto = iPictoInterface->Interface()->IsPictograph((TText)aChar); + } + + if (!( JPLangUtil::IsHiragana((TText)aChar) + || JPLangUtil::IsKanji((TText)aChar) + || JPLangUtil::IsKatakana((TText)aChar) + /* Teleca change begin, 18.08.2009 ssal */ + || IsKoreanCharacter(aChar) + /* Teleca change end, 18.08.2009 ssal */ + || isPicto )) + { + TChar ch = aChar; + if (iFep.IsFeatureSupportedJapanese() && + JPLangUtil::IsFullWidth((TText) ch)) + { + TBuf fullChar; + TBuf halfChar; + fullChar.Append(ch); + if (JPLangUtil::ConvertFullToHalfWidth(fullChar, halfChar)) + { + ch = halfChar[0]; + ret = ch.IsAlpha(); + } + } + else + { + ret = ch.IsAlpha(); + } + } + return ret; + } + +TInt CAknFepCaseManager::PluginPermittedCases() + { + TInt allowedCases = ECaseInvalide; + if ( !(iFep.EditorState()) ) + { + return allowedCases; + } + + TInt editorCases = iFep.EditorState()->PermittedCases(); + + if( editorCases == 0 ) + { + allowedCases = ECaseUpper | ECaseLower | ECaseText | ECaseInverseText; + } + else + { + allowedCases = editorCases; + + if( (editorCases & EAknEditorUpperCase) && + (editorCases & EAknEditorTextCase) ) + { + allowedCases |= ECaseInverseText; + } + } + + return allowedCases; + } + + +// ----------------------------------------------------------------------------- +// CAknFepCaseManager::CapsLockRequired +// +// +// ----------------------------------------------------------------------------- +// +TBool CAknFepCaseManager::CapsLockRequired(TInt aCurrentCase) + { + TCursorSelection currentSelection; + + if (iFep.FepAwareTextEditor()) + { + iFep.FepAwareTextEditor()->GetCursorSelectionForFep(currentSelection); + return CapsLockRequired(currentSelection.iCursorPos, aCurrentCase); + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CAknFepCaseManager::IsJapaneseCharacter +// Determines whether a character is one of Japanese characters +// ----------------------------------------------------------------------------- +// +TBool CAknFepCaseManager::IsJapaneseCharacter(TChar aChar) const + { + TBool ret = EFalse; + // The character case is changed to text case when the left side + // character is Japanese character (Hiragana, Katakana, Kanji, + // Full-width Symbol). + if (JPLangUtil::IsKanji((TText)aChar) + || JPLangUtil::IsHiragana((TText)aChar) + || JPLangUtil::IsKatakana((TText)aChar)) + { + // Hiragana, Katakana, Kanji + ret = ETrue; + } + else if (JPLangUtil::IsFullWidth((TText)aChar) + && aChar != KPuaCodeSpaceSymbol + && aChar != KPuaCodeLineFeedSymbol) + { + if (iFep.InputMode() == ELatin + && iFep.CharacterWidth() == EFullWidthChar) + { + TBuf fullChar; + TBuf halfChar; + fullChar.Append(aChar); + if (JPLangUtil::ConvertFullToHalfWidth(fullChar, halfChar)) + { + TChar ch2 = halfChar[0]; + if (!ch2.IsAlpha()) + { + // Full width Symbol or Number + ret = ETrue; + } + } + else + { + // The character which isn't converted to half is + // special Japanese Symbols. + ret = ETrue; + } + } + else + { + ret = ETrue; + } + } + return ret; + } + +/* Teleca change begin, 18.08.2009 ssal */ +// ----------------------------------------------------------------------------- +// CAknFepCaseManager::IsKoreanCharacter +// Determines whether a character is one of Korean characters +// ----------------------------------------------------------------------------- +// +TBool CAknFepCaseManager::IsKoreanCharacter(TChar aChar) const + { + if ( IsHangulSyllable( aChar) || IsHangulCompatibilityJamo( aChar ) ) + { + return ETrue; + } + return EFalse; + } + +// --------------------------------------------------------------------------- +// Checks that is given character hangul syllable or not. +// --------------------------------------------------------------------------- +// +TBool CAknFepCaseManager::IsHangulSyllable( TChar aChar ) const + { + // Character is 'hangul syllable' + // if it's numeric value is between KSBase and KSBase + KSCount. + TInt index = static_cast ( aChar ) - KSBase; + if ( index < 0 || index >= KSCount ) + { + return EFalse; + } + return ETrue; + } + +// --------------------------------------------------------------------------- +// Checks that is given character hangul syllable or not. +// --------------------------------------------------------------------------- +// +TBool CAknFepCaseManager::IsHangulCompatibilityJamo( TChar aChar ) const + { + // Character is 'hangul compatibility jamo' + // if it's numeric value is between KCBase and KCBase + KCCount. + TInt index = static_cast ( aChar ) - KCBase; + if ( index < 0 || index >= KCCount ) + { + return EFalse; + } + return ETrue; + } + +/* Teleca change end, 18.08.2009 ssal */ +// End of file