--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneuis/dialer/src/cdialerkeypadlabelmanager.cpp Fri Feb 19 22:50:26 2010 +0200
@@ -0,0 +1,659 @@
+/*
+* Copyright (c) 2009, 2010 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: Helper class to handle virtual keypad text labels
+*
+*/
+
+#include <AknUtils.h>
+#include <bautils.h>
+#include <barsread.h>
+#include <avkon.rsg>
+#include <dialer.rsg>
+#include <dialerkeypad.rsg>
+#include <e32const.h>
+#include <e32lang.h>
+#include <PtiEngine.h>
+#include <AknFepInternalCRKeys.h>
+#include <AvkonInternalCRKeys.h>
+#include <bacntf.h>
+
+#include "cdialerkeypadlabelmanager.h"
+#include "dialercommon.h"
+
+// CONSTANTS
+const TInt KKeyCount( 12 );
+
+_LIT( KDialerButton1NumLabel, "1" );
+_LIT( KDialerButton2NumLabel, "2" );
+_LIT( KDialerButton3NumLabel, "3" );
+_LIT( KDialerButton4NumLabel, "4" );
+_LIT( KDialerButton5NumLabel, "5" );
+_LIT( KDialerButton6NumLabel, "6" );
+_LIT( KDialerButton7NumLabel, "7" );
+_LIT( KDialerButton8NumLabel, "8" );
+_LIT( KDialerButton9NumLabel, "9" );
+_LIT( KDialerButton10NumLabel, "*+" );
+_LIT( KDialerButton11NumLabel, "0" );
+_LIT( KDialerButton12NumLabel, "#" );
+
+_LIT( KDialerKeypadResourceFile, "z:\\resource\\dialerkeypad" );
+_LIT( KDialerKeypadResourceFileExt, ".rsc" );
+_LIT( KDialerKeypadVariantExtSeparator, "_" );
+
+_LIT( KScriptLatin, "latin" );
+_LIT( KScriptCyrillic, "cyrillic" );
+_LIT( KScriptGreek, "greek" );
+_LIT( KScriptHebrew, "hebrew" );
+_LIT( KScriptArabic, "arabic" );
+_LIT( KScriptFarsi, "farsi" );
+_LIT( KScriptUrdu, "urdu" );
+_LIT( KScriptThai, "thai" );
+_LIT( KScriptDevanagari, "devanagari" );
+_LIT( KScriptChnPinyin, "chn_pinyin" );
+_LIT( KScriptChnZhuyin, "chn_zhuyin" );
+_LIT( KScriptChnStroke, "chn_stroke" );
+_LIT( KScriptChnCangjie, "chn_cangjie" );
+
+enum TScript
+ {
+ EScriptLatin = 0,
+ EScriptCyrillic,
+ EScriptGreek,
+ EScriptHebrew,
+ EScriptArabic,
+ EScriptFarsi,
+ EScriptUrdu,
+ EScriptThai,
+ EScriptDevanagari,
+ EScriptChinese, // generic value for all Chinese input modes
+ EScriptChnPinyin,
+ EScriptChnZhuyin,
+ EScriptChnStroke,
+ EScriptChnCangjie
+ };
+
+struct TLanguageScriptMapping
+ {
+ TLanguage iLang;
+ TScript iScript;
+ };
+
+// Following table maps non-Latin languages to corresponding scripts.
+// Rest of the languages are asumed to use Latin script.
+// The data of the table has been extracted from the header
+// \sf\mw\inputmethods\textinput\peninputgenericitut\inc\peninputgenericitutdata.h
+const TLanguageScriptMapping KScriptMap[] =
+ {
+ {ELangRussian, EScriptCyrillic},
+ {ELangBulgarian, EScriptCyrillic},
+ {ELangUkrainian, EScriptCyrillic},
+
+ {ELangGreek, EScriptGreek},
+ {ELangCyprusGreek, EScriptGreek},
+
+ {ELangHebrew, EScriptHebrew},
+
+ {ELangArabic, EScriptArabic},
+
+ {ELangFarsi, EScriptFarsi},
+
+ {ELangUrdu, EScriptUrdu},
+
+ {ELangThai, EScriptThai},
+
+ {ELangHindi, EScriptDevanagari},
+ {ELangMarathi, EScriptDevanagari},
+
+ {ELangTaiwanChinese, EScriptChinese},
+ {ELangHongKongChinese, EScriptChinese},
+ {ELangPrcChinese, EScriptChinese}
+ };
+const TInt KScriptMapCount = sizeof( KScriptMap ) / sizeof( TLanguageScriptMapping );
+
+// Values for Chinese adaptive search modes, as documented in AvkonInternalCRKeys.h
+enum TChinesePrcMode
+ {
+ EChnPrcPinyin = 0,
+ EChnPrcStroke = 1
+ };
+enum TChineseTwMode
+ {
+ EChnTwZhuyin = 0,
+ EChnTwStroke = 1
+ };
+enum TChineseHkMode
+ {
+ EChnHkStroke = 0,
+ EChnHkCangjie = 1
+ };
+
+
+// LOCAL FUNCTION DECLARATIONS
+static TScript ScriptForLang( TLanguage aLang );
+static const TDesC& ScriptName( TScript aScriptCode );
+static TBool ScriptCanSubstituteLatin( TScript aScript );
+
+
+// MEMBER FUNCTION DEFINITIONS
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::CDialerKeyPadLabelManager
+//
+// ---------------------------------------------------------------------------
+//
+CDialerKeyPadLabelManager::CDialerKeyPadLabelManager( CCoeEnv& aCoeEnv,
+ MDialerKeyPadLabelManagerCallback& aObserver )
+ : iCoeEnv( aCoeEnv ), iObserver( aObserver )
+ {
+ // No implementation required
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::~CDialerKeyPadLabelManager
+//
+// ---------------------------------------------------------------------------
+//
+CDialerKeyPadLabelManager::~CDialerKeyPadLabelManager()
+ {
+ delete iPtiEngine;
+
+ delete iAknFepRepository;
+ delete iAvkonRepository;
+
+ if ( iEnvChangeNotifier )
+ {
+ iEnvChangeNotifier->Cancel();
+ delete iEnvChangeNotifier;
+ }
+
+ delete iKeypadNumLabelArray;
+ delete iKeypadFirstLabelArray;
+ delete iKeypadSecondLabelArray;
+
+ if ( iResourceOffset )
+ {
+ iCoeEnv.DeleteResourceFile( iResourceOffset );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::NewLC
+//
+// ---------------------------------------------------------------------------
+//
+CDialerKeyPadLabelManager* CDialerKeyPadLabelManager::NewLC( CCoeEnv& aCoeEnv,
+ MDialerKeyPadLabelManagerCallback& aObserver )
+ {
+ CDialerKeyPadLabelManager* self =
+ new (ELeave) CDialerKeyPadLabelManager( aCoeEnv, aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::NewL
+//
+// ---------------------------------------------------------------------------
+//
+CDialerKeyPadLabelManager* CDialerKeyPadLabelManager::NewL( CCoeEnv& aCoeEnv,
+ MDialerKeyPadLabelManagerCallback& aObserver )
+ {
+ CDialerKeyPadLabelManager* self =
+ CDialerKeyPadLabelManager::NewLC( aCoeEnv, aObserver );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::ConstructL
+//
+// ---------------------------------------------------------------------------
+//
+void CDialerKeyPadLabelManager::ConstructL()
+ {
+ iPtiEngine = CPtiEngine::NewL();
+
+ iAknFepRepository = CDialerCenRepWrapper::NewL( *this, KCRUidAknFep );
+ iAvkonRepository = CDialerCenRepWrapper::NewL( *this, KCRUidAvkon );
+
+ TCallBack envChangeCallback( EnvChangeCallback, this );
+ iEnvChangeNotifier = CEnvironmentChangeNotifier::NewL(
+ CActive::EPriorityStandard, envChangeCallback );
+ iEnvChangeNotifier->Start();
+
+ iKeypadNumLabelArray = new ( ELeave ) CDesCArrayFlat( KKeyCount );
+ iKeypadFirstLabelArray = new ( ELeave ) CDesCArrayFlat( KKeyCount );
+ iKeypadSecondLabelArray = new ( ELeave ) CDesCArrayFlat( KKeyCount );
+
+ UpdateNumLabelsL();
+ UpdateTextLabelsL();
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::ButtonNumLabel
+//
+// ---------------------------------------------------------------------------
+//
+TPtrC CDialerKeyPadLabelManager::ButtonNumLabel( TInt aIndex ) const
+ {
+ __ASSERT_DEBUG( aIndex < iKeypadNumLabelArray->Count(), DialerPanic(EDialerPanicLabelNotFound) );
+
+ TPtrC label( KNullDesC );
+ if ( aIndex < iKeypadNumLabelArray->Count() )
+ {
+ label.Set( (*iKeypadNumLabelArray)[ aIndex ] );
+ }
+ return label;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::ButtonFirstAlphaLabel
+//
+// ---------------------------------------------------------------------------
+//
+TPtrC CDialerKeyPadLabelManager::ButtonFirstAlphaLabel( TInt aIndex ) const
+ {
+ __ASSERT_DEBUG( aIndex < iKeypadFirstLabelArray->Count(), DialerPanic(EDialerPanicLabelNotFound) );
+
+ TPtrC label( KNullDesC );
+ if ( aIndex < iKeypadFirstLabelArray->Count() )
+ {
+ label.Set( (*iKeypadFirstLabelArray)[ aIndex ] );
+ }
+ return label;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::ButtonSecondAlphaLabel
+//
+// ---------------------------------------------------------------------------
+//
+TPtrC CDialerKeyPadLabelManager::ButtonSecondAlphaLabel( TInt aIndex ) const
+ {
+ __ASSERT_DEBUG( aIndex < iKeypadSecondLabelArray->Count(), DialerPanic(EDialerPanicLabelNotFound) );
+
+ TPtrC label( KNullDesC );
+ if ( aIndex < iKeypadSecondLabelArray->Count() )
+ {
+ label.Set( (*iKeypadSecondLabelArray)[ aIndex ] );
+ }
+ return label;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::UpdateTextLabelsL
+//
+// ---------------------------------------------------------------------------
+//
+void CDialerKeyPadLabelManager::HandleRepositoryChange(
+ TUid aRepository, TUint32 aId )
+ {
+ if ( (aRepository == KCRUidAknFep && aId == KAknFepInputTxtLang) ||
+ (aRepository == KCRUidAvkon && aId == KAknAdaptiveSearchChinesePRC) ||
+ (aRepository == KCRUidAvkon && aId == KAknAdaptiveSearchChineseTW) ||
+ (aRepository == KCRUidAvkon && aId == KAknAdaptiveSearchChineseHongkong) )
+ {
+ // Check if alpabet labels need to be changed
+ TInt scriptToUse( EScriptLatin );
+ TRAP_IGNORE( scriptToUse = LabelScriptToUseL() );
+ if ( iLabelScriptInUse != scriptToUse )
+ {
+ TRAP_IGNORE( UpdateTextLabelsL() );
+ iObserver.KeyLabelsChanged();
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::HandleEnvChange
+//
+// ---------------------------------------------------------------------------
+//
+void CDialerKeyPadLabelManager::HandleEnvChange()
+ {
+ if ( iEnvChangeNotifier->Change() & EChangesLocale )
+ {
+ TLocale locale;
+ if ( locale.DigitType() != iDigitTypeInUse )
+ {
+ TRAP_IGNORE( UpdateNumLabelsL() );
+ iObserver.KeyLabelsChanged();
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::EnvChangeCallback
+//
+// ---------------------------------------------------------------------------
+//
+TInt CDialerKeyPadLabelManager::EnvChangeCallback( TAny* aSelfPtr )
+ {
+ CDialerKeyPadLabelManager* self =
+ static_cast< CDialerKeyPadLabelManager* >( aSelfPtr );
+ self->HandleEnvChange();
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::UpdateTextLabelsL
+//
+// ---------------------------------------------------------------------------
+//
+void CDialerKeyPadLabelManager::UpdateTextLabelsL()
+ {
+ iKeypadFirstLabelArray->Reset();
+ iKeypadSecondLabelArray->Reset();
+
+ // Load the correct keypad resource file
+ TFileName resourceName;
+ GetResourceFileNameL( resourceName );
+ iResourceOffset = iCoeEnv.AddResourceFileL( resourceName );
+
+ // Read keypad labels from the resource
+ TResourceReader reader;
+ iCoeEnv.CreateResourceReaderLC( reader, R_DIALER_KEYPAD );
+
+ TInt16 count = reader.ReadInt16();
+
+ for ( TInt i = 0 ; i < count ; ++i )
+ {
+ TPtrC firstRow = reader.ReadTPtrC();
+ iKeypadFirstLabelArray->AppendL( firstRow );
+ TPtrC secondRow = reader.ReadTPtrC();
+ iKeypadSecondLabelArray->AppendL( secondRow );
+ }
+
+ CleanupStack::PopAndDestroy(); // reader
+
+ // Free resource as it's not usually needed anymore. Ensure that destructor
+ // won't free it again.
+ iCoeEnv.DeleteResourceFile( iResourceOffset );
+ iResourceOffset = 0;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::UpdateNumLabelsL
+//
+// ---------------------------------------------------------------------------
+//
+void CDialerKeyPadLabelManager::UpdateNumLabelsL()
+ {
+ // Save digit type used. This is to allow us update number labels
+ // only when digit type is changed and not on all locale changes.
+ TLocale locale;
+ iDigitTypeInUse = locale.DigitType();
+
+ iKeypadNumLabelArray->Reset();
+
+ // Fill number labels array
+ iKeypadNumLabelArray->AppendL( KDialerButton1NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton2NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton3NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton4NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton5NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton6NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton7NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton8NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton9NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton10NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton11NumLabel );
+ iKeypadNumLabelArray->AppendL( KDialerButton12NumLabel );
+
+ // Convert num labels to current global number mode
+ for ( TInt i = 0 ; i < iKeypadNumLabelArray->Count() ; ++i )
+ {
+ // A bit of magic is needed to get a modifiable pointer
+ // descriptor which points to string within the array.
+ TPtrC roPtr = (*iKeypadNumLabelArray)[i];
+ TPtr ptr( const_cast<TUint16*>( roPtr.Ptr() ), roPtr.Length(), roPtr.Length() );
+
+ AknTextUtils::LanguageSpecificNumberConversion( ptr );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::GetResourceFileNameL
+//
+// ---------------------------------------------------------------------------
+//
+void CDialerKeyPadLabelManager::GetResourceFileNameL( TDes& aFileName )
+ {
+ TFileName resName;
+
+ iLabelScriptInUse = LabelScriptToUseL();
+ // Try to get variated resource name if necessary
+ if ( iLabelScriptInUse != EScriptLatin )
+ {
+ const TDesC& scriptName = ScriptName( static_cast<TScript>(iLabelScriptInUse) );
+ resName.Copy( KDialerKeypadResourceFile );
+ resName.Append( KDialerKeypadVariantExtSeparator );
+ resName.Append( scriptName );
+ resName.Append( KDialerKeypadResourceFileExt );
+
+ BaflUtils::NearestLanguageFile( iCoeEnv.FsSession(), resName );
+ if ( !BaflUtils::FileExists( iCoeEnv.FsSession(), resName ) )
+ {
+ // resource not found, fall back to Latin
+ iLabelScriptInUse = EScriptLatin;
+ }
+ }
+
+ // Get the default resource name if Latin script was selected or
+ // resource file for the selected script was not found.
+ if ( iLabelScriptInUse == EScriptLatin )
+ {
+ resName.Copy( KDialerKeypadResourceFile );
+ resName.Append( KDialerKeypadResourceFileExt );
+ BaflUtils::NearestLanguageFile( iCoeEnv.FsSession(), resName );
+ }
+
+ aFileName.Copy( resName );
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::LabelScriptToUseL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CDialerKeyPadLabelManager::LabelScriptToUseL() const
+ {
+ TInt lang( ELangEnglish );
+
+ // Get current input language
+ TInt err = iAknFepRepository->Get( KAknFepInputTxtLang, lang );
+ __ASSERT_DEBUG( !err, DialerPanic(err) );
+
+ TInt script = ScriptForLang( static_cast<TLanguage>(lang) );
+
+ // Distinct logic is used to select labels when current input language
+ // is any version of Chinese. PCS uses different algorith for Chinese.
+ if ( script == EScriptChinese )
+ {
+ script = ChineseScriptToUseL();
+ }
+ // If current input language is written in Latin script, then we check
+ // if some other script of the device could also be shown on the labels.
+ // Most variated labels include Latin characters as well.
+ else if ( script == EScriptLatin )
+ {
+ RArray<TInt> availableLanguages;
+ CleanupClosePushL( availableLanguages );
+ iPtiEngine->GetAvailableLanguagesL( availableLanguages );
+
+ // Scirpt of the current UI language is preferred option for
+ // alternative script. Ensure it's considered first.
+ TLanguage uiLang = User::Language();
+ TInt pos = availableLanguages.Find( uiLang );
+ if ( pos != KErrNotFound )
+ {
+ availableLanguages.Remove( pos );
+ availableLanguages.InsertL( uiLang, 0 );
+ }
+
+ TInt langCount = availableLanguages.Count();
+ for ( TInt i = 0 ; i < langCount ; ++i )
+ {
+ TLanguage altLang = static_cast<TLanguage>( availableLanguages[i] );
+ TScript altScript = ScriptForLang( altLang );
+ if ( altScript != EScriptLatin && ScriptCanSubstituteLatin(altScript) )
+ {
+ // Suitable alternative script found. Use its labels
+ // instead of showing only Latin alphabets.
+ script = altScript;
+ i = langCount; // to break out
+ }
+ }
+
+ CleanupStack::PopAndDestroy( &availableLanguages );
+ }
+
+ return script;
+ }
+
+// ---------------------------------------------------------------------------
+// CDialerKeyPadLabelManager::ChineseScriptToUseL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CDialerKeyPadLabelManager::ChineseScriptToUseL() const
+ {
+ TInt script( EScriptLatin );
+
+ TInt lang( ELangPrcChinese );
+ TInt chnSearchMode( 0 );
+
+ TInt err = iAknFepRepository->Get( KAknFepInputTxtLang, lang );
+ __ASSERT_DEBUG( !err, DialerPanic(EDialerPanicChineseScriptError) );
+
+ switch ( lang )
+ {
+ case ELangPrcChinese:
+ {
+ err = iAvkonRepository->Get( KAknAdaptiveSearchChinesePRC, chnSearchMode );
+ script = ( chnSearchMode == EChnPrcPinyin ? EScriptChnPinyin : EScriptChnStroke );
+ }
+ break;
+ case ELangTaiwanChinese:
+ {
+ err = iAvkonRepository->Get( KAknAdaptiveSearchChineseTW, chnSearchMode );
+ script = ( chnSearchMode == EChnTwZhuyin ? EScriptChnZhuyin : EScriptChnStroke );
+ }
+ break;
+ case ELangHongKongChinese:
+ {
+ err = iAvkonRepository->Get( KAknAdaptiveSearchChineseHongkong, chnSearchMode );
+ script = ( chnSearchMode == EChnHkStroke ? EScriptChnStroke : EScriptChnCangjie );
+ }
+ break;
+ default:
+ {
+ err = KErrUnknown;
+ }
+ break;
+ }
+ __ASSERT_DEBUG( !err, DialerPanic(EDialerPanicChineseScriptError) );
+
+ return script;
+ }
+
+
+// LOCAL FUNCTION DEFINITIONS
+
+// ---------------------------------------------------------------------------
+// ScriptForLang
+//
+// ---------------------------------------------------------------------------
+//
+static TScript ScriptForLang( TLanguage aLang )
+ {
+ TScript script( EScriptLatin );
+ for ( TInt i = 0 ; i < KScriptMapCount ; ++i )
+ {
+ if ( aLang == KScriptMap[i].iLang )
+ {
+ script = KScriptMap[i].iScript;
+ i = KScriptMapCount; // to break out
+ }
+ }
+ return script;
+ }
+
+// ---------------------------------------------------------------------------
+// ScriptName
+//
+// ---------------------------------------------------------------------------
+//
+static const TDesC& ScriptName( TScript aScriptCode )
+ {
+ // Convert script ID to script name
+ switch ( aScriptCode )
+ {
+ case EScriptLatin:
+ return KScriptLatin;
+ case EScriptCyrillic:
+ return KScriptCyrillic;
+ case EScriptGreek:
+ return KScriptGreek;
+ case EScriptHebrew:
+ return KScriptHebrew;
+ case EScriptArabic:
+ return KScriptArabic;
+ case EScriptFarsi:
+ return KScriptFarsi;
+ case EScriptUrdu:
+ return KScriptUrdu;
+ case EScriptThai:
+ return KScriptThai;
+ case EScriptDevanagari:
+ return KScriptDevanagari;
+ case EScriptChnPinyin:
+ return KScriptChnPinyin;
+ case EScriptChnZhuyin:
+ return KScriptChnZhuyin;
+ case EScriptChnStroke:
+ return KScriptChnStroke;
+ case EScriptChnCangjie:
+ return KScriptChnCangjie;
+ default:
+ __ASSERT_DEBUG( EFalse, DialerPanic(EDialerPanicUnknownScript) );
+ }
+ return KNullDesC;
+ }
+
+// ---------------------------------------------------------------------------
+// ScriptCanSubstituteLatin
+// Return ETrue if labels of given script can be used instead of Latin labels
+// when current input language is written with Latin script. This requires
+// that the labels include also Latin characters and that labels don't contain
+// any characters which would only make sense in some specific input mode.
+// ---------------------------------------------------------------------------
+//
+static TBool ScriptCanSubstituteLatin( TScript aScript )
+ {
+ // It would be better to figure this out from the resources but that would
+ // require opening and parsing several resource files.
+ return !( aScript == EScriptArabic ||
+ aScript == EScriptUrdu ||
+ aScript == EScriptFarsi ||
+ aScript == EScriptChinese ||
+ aScript == EScriptChnPinyin ||
+ aScript == EScriptChnZhuyin ||
+ aScript == EScriptChnStroke ||
+ aScript == EScriptChnCangjie );
+ }
+
+// end of file
+