--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textinput/ptienginev2/src/PtiDefaultCore.cpp Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,1134 @@
+/*
+* Copyright (c) 2003-2007 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: Default core for predective text input engine.
+* Implements basic qwerty & multitapping input.
+*
+*/
+
+
+#include <e32property.h>
+#include "PtiDefaultCore.h"
+#include "PtiLanguage.h"
+#include "PtiEngine.h"
+#include "PtiKeyMappings.h"
+#include <PtiEngine.rsg>
+#include "PtiDefaultNumberModeMappingdata.h"
+
+#include <data_caging_path_literals.hrh>
+
+// CONSTANTS
+const TInt KMultiTapTimeoutMS = 1000000;
+//const TInt KPtiKeymappingsDefaultImplementation = 0x10281897;
+
+_LIT(KDefaultCoreVendor, "Default core");
+
+#ifdef _DEBUG
+_LIT(KPtiEnginePanic, "CPtiDefaultCore");
+#endif
+
+// lam with alef ligatures are entered as one press but are actually two symbols
+// These four arabic characters are handled as a special case.
+const TUint16 KArarbicLigatureLamWithAlefWithMaddaAboveIsolatedForm = 0xFEF5;
+const TUint16 KArarbicLigatureLamWithAlefWithHamzaAboveIsolatedForm = 0xFEF7;
+const TUint16 KArarbicLigatureLamWithAlefWithHamzaBelowIsolatedForm = 0xFEF9;
+const TUint16 KArarbicLigatureLamWithAlefIsolatedForm = 0xFEFB;
+
+_LIT(KArarbicLigatureLamWithAlefWithMaddaAboveIsolatedSequence, "\x0644\x622");
+_LIT(KArarbicLigatureLamWithAlefWithHamzaAboveIsolatedSequence, "\x0644\x623");
+_LIT(KArarbicLigatureLamWithAlefWithHamzaBelowIsolatedSequence, "\x0644\x625");
+_LIT(KArarbicLigatureLamWithAlefIsolatedSequence, "\x0644\x627");
+
+
+//
+// CMultiTapTimer
+//
+
+// ---------------------------------------------------------------------------
+// CMultiTapTimer::NewL
+//
+// ---------------------------------------------------------------------------
+//
+CMultiTapTimer* CMultiTapTimer::NewL(TCallBack aCallback)
+ {
+ CMultiTapTimer* self = new(ELeave)CMultiTapTimer(aCallback);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(); // self
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CMultiTapTimer::CMultitapTimer
+//
+// ---------------------------------------------------------------------------
+//
+CMultiTapTimer::CMultiTapTimer(TCallBack aCallback)
+:CTimer(EPriorityStandard), iCallback(aCallback)
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CMultiTapTimer::ConstructL
+//
+// ---------------------------------------------------------------------------
+//
+void CMultiTapTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ CActiveScheduler::Add(this);
+ }
+
+// ---------------------------------------------------------------------------
+// CMultiTapTimer::After
+//
+// ---------------------------------------------------------------------------
+//
+void CMultiTapTimer::After(TTimeIntervalMicroSeconds32 aInterval)
+ {
+ if (IsActive())
+ {
+ Cancel();
+ }
+ CTimer::After(aInterval);
+ }
+
+// ---------------------------------------------------------------------------
+// CMultiTapTimer::RunL
+//
+// ---------------------------------------------------------------------------
+//
+void CMultiTapTimer::RunL()
+ {
+ iCallback.CallBack();
+ }
+
+
+//
+// CPtiDefaultCore
+//
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::NewL
+//
+// ---------------------------------------------------------------------------
+//
+CPtiDefaultCore* CPtiDefaultCore::NewL(CPtiEngine* aOwner, TDes* aTextBuffer)
+ {
+ CPtiDefaultCore *core = new (ELeave) CPtiDefaultCore(aOwner, aTextBuffer);
+ CleanupStack::PushL( core );
+ core->ConstructL();
+ CleanupStack::Pop(); // core
+ return core;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::CPtiDefaultCore
+// .
+// ---------------------------------------------------------------------------
+//
+CPtiDefaultCore::CPtiDefaultCore()
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::CPtiDefaultCore
+//
+// ---------------------------------------------------------------------------
+//
+CPtiDefaultCore::CPtiDefaultCore(CPtiEngine* aOwner, TDes* aTextBuffer) : iOwner(aOwner), iTextBuffer(aTextBuffer)
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::~CPtiDefaultCore
+//
+// ---------------------------------------------------------------------------
+//
+CPtiDefaultCore::~CPtiDefaultCore()
+ {
+ if (iTimer)
+ {
+ iTimer->Cancel();
+ }
+
+ ShutDownKeymapFactory();
+
+ delete iTimer;
+ delete iNumericMappings;
+ delete iNumericData;
+
+ iFactoryBindings.Close();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::ConstructL
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::ConstructL()
+ {
+ FillCoreInfo();
+ TCallBack timerExpire(TimerExpire, this);
+ iTimer = CMultiTapTimer::NewL(timerExpire);
+ iNumericData = CPtiNumberModeDataImpl::NewL();
+ iNumericMappings = CPtiKeyMappings::NewL(iNumericData);
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::InitializeL
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::InitializeL(CPtiEngine* aOwner, TDes* aTextBuffer, CArrayPtrFlat<CPtiCoreLanguage>* aLanguageList, TBool /*aUseDefautUserDictionary*/)
+ {
+ iOwner = aOwner;
+ iTextBuffer = aTextBuffer;
+ iLanguageList = aLanguageList;
+
+ TInt count = 0;
+ TInt err = RProperty::Get(KPtiEnginePSUid, EKeyMapPropertyCount, count);
+ if (err == KErrNone && count > 0)
+ {
+ // PS key found, keymap implementation list has been created and can be read
+ TBuf16<256> dataBuffer;
+ err = RProperty::Get(KPtiEnginePSUid, EKeyMapPropertyData, dataBuffer);
+
+ if( err == KErrNone )
+ {
+ TInt langId;
+ TInt factoryUid;
+ for(TInt i = 0; i < count; i++ )
+ {
+ langId = dataBuffer[3*i];
+ factoryUid = (dataBuffer[3*i+1] << 16) + dataBuffer[3*i+2];
+
+ CPtiCoreLanguage* language = CPtiCoreLanguage::NewL();
+ language->SetLanguageCode(langId);
+ language->SetCore(this, EPtiEngineNumeric);
+
+ CleanupStack::PushL( language );
+ aLanguageList->AppendL( language );
+ CleanupStack::Pop(); // language
+
+ TPtiDataFactoryBinding newBind(langId, factoryUid);
+ iFactoryBindings.AppendL(newBind);
+ }
+ return;
+ }
+ }
+
+ // PS key not defined or error, we need to fetch the data from dll:s
+ RArray<TInt> dataImpl;
+ CleanupClosePushL(dataImpl);
+ CPtiKeyMapDataFactory::ListImplementationsL(dataImpl);
+
+ for (TInt i = 0; i < dataImpl.Count(); i++)
+ {
+ ShutDownKeymapFactory();
+ iKeyMapDataFactory = CPtiKeyMapDataFactory::CreateImplementationL(TUid::Uid(dataImpl[i]));
+ ListDataFactoryLanguagesL(iKeyMapDataFactory, dataImpl[i], aLanguageList);
+ }
+
+ if (!iFactoryBindings.Count())
+ {
+ // Cannot function without keymapping data.
+ User::Leave(KErrCorrupt);
+ }
+
+ // Write language->dll mapping data to P/S-key so we don't need to load every dll later
+ TBuf16<256> dataBuffer;
+ for(TInt i = 0; i < iFactoryBindings.Count(); i++)
+ {
+ dataBuffer.Append(iFactoryBindings[i].iLanguage); // Language id should fit in 16 bits
+ dataBuffer.Append(iFactoryBindings[i].iFactoryImplUid >> 16); // 32-bit Uid is appended in two parts
+ dataBuffer.Append(iFactoryBindings[i].iFactoryImplUid);
+ }
+
+ // If these fail, then they just fail.
+ RProperty::Set(KPtiEnginePSUid, EKeyMapPropertyCount, iFactoryBindings.Count());
+ RProperty::Set(KPtiEnginePSUid, EKeyMapPropertyData, dataBuffer);
+
+ CleanupStack::PopAndDestroy(); // dataImpl
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::OpenLanguageL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::OpenLanguageL(CPtiCoreLanguage* aLanguage)
+ {
+ TRAPD(err, LoadFactoryForLanguageL(aLanguage->LanguageCode()));
+
+ ClearFlag(EPtiFlagVowelSeq);
+
+ return err;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::CloseLanguageL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::CloseLanguageL()
+ {
+ if (iOwner->CurrentLanguage())
+ {
+ CPtiCoreLanguage* curLang = static_cast<CPtiCoreLanguage*>(iOwner->CurrentLanguage());
+ curLang->SetKeyMapDataFactory(NULL);
+ }
+
+ ClearFlag(EPtiFlagVowelSeq);
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::GetCurrentWord
+//
+// ---------------------------------------------------------------------------
+//
+TPtrC CPtiDefaultCore::GetCurrentWord() const
+ {
+ __ASSERT_DEBUG(iTextBuffer, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ return TPtrC(iTextBuffer->Ptr());
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::CommitCurrentWord
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::CommitCurrentWord()
+ {
+ ClearBuffer();
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::NumberOfCandidates
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::NumberOfCandidates()
+ {
+ __ASSERT_DEBUG(iTextBuffer, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ if (iTextBuffer->Length() == 0)
+ {
+ return 0;
+ }
+
+ return 1;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::FillCoreInfo
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::FillCoreInfo()
+ {
+ iCoreInfo.SetCapsBits(0);
+ iCoreInfo.SetMaxWordLength(KDefaulCoreMaximumWordLength);
+ iCoreInfo.SetVendorString( KDefaultCoreVendor );
+ iCoreInfo.SetMaxNumberOfCandidates(1);
+ iCoreInfo.SetUid(KDefaultCoreUid);
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::SetReordering
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::SetReordering(TBool aStatus)
+ {
+ if (aStatus)
+ {
+ return KErrNotSupported;
+ }
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::AppendKeyPress
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::AppendKeyPress(TPtiKey aKey)
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ CPtiCoreLanguage* lang = static_cast<CPtiCoreLanguage*>(iOwner->CurrentLanguage());
+ const TPtiEngineInputMode inputMode = iOwner->InputMode();
+ const TBool qwerty = iOwner->IsQwertyBasedMode(inputMode);
+ TBool append = ETrue;
+ TUint16 overridingDeadKey = 0;
+
+ ClearFlag(EPtiGetAllFlag);
+
+ __ASSERT_DEBUG(lang, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ MPtiKeyMappings* maps = NULL;
+
+ if (inputMode == EPtiEngineNumeric)
+ {
+ maps = iNumericMappings;
+ }
+ else if (inputMode == EPtiEngineHalfQwerty)
+ {
+ if (lang->HasInputMode(EPtiEngineHalfQwerty))
+ {
+ maps = lang->GetHalfQwertyKeymappings();
+ }
+ }
+ else if (qwerty)
+ {
+ if (lang->HasInputMode(EPtiEngineQwerty))
+ {
+ maps = lang->GetQwertyKeymappings();
+ }
+ }
+ else
+ {
+ if (lang->HasInputMode(EPtiEngineMultitapping))
+ {
+ maps = lang->GetKeymappings();
+ }
+ }
+
+ if (!maps)
+ {
+ iTimer->Cancel();
+ return;
+ }
+
+ if (iTimer->IsActive())
+ {
+ TUint16 chr = maps->NextKey(aKey, append, iOwner->Case());
+ if (chr && (!append) && (iTextBuffer->Length() > 0))
+ {
+ iTextBuffer->SetLength(iTextBuffer->Length() - 1);
+ }
+ if (iTextBuffer->Length() < iTextBuffer->MaxLength())
+ {
+ if (chr)
+ {
+ iTextBuffer->Append(chr);
+ }
+ }
+ }
+ else
+ {
+ if (iTextBuffer->Length() < iTextBuffer->MaxLength())
+ {
+ if (qwerty)
+ {
+ CPtiQwertyKeyMappings* qmap = static_cast<CPtiQwertyKeyMappings*>(maps);
+ if (lang->LanguageCode() == ELangVietnamese)
+ {
+ qmap->SetFlag(CPtiQwertyKeyMappings::ETrackVietnameseToneMarksAndVowels);
+ }
+ else
+ {
+ qmap->ResetFlag(CPtiQwertyKeyMappings::ETrackVietnameseToneMarksAndVowels);
+ }
+
+ if (qmap->DeadKey() && (aKey == qmap->CurrentKey()))
+ {
+ overridingDeadKey = qmap->DeadKeyRootChar();
+ }
+ }
+
+ TUint16 chr = maps->StartMapping(aKey, iOwner->Case(), inputMode);
+
+ if (chr == KPtiGetAllMarker)
+ {
+ if (lang->LanguageCode() == ELangHindi)
+ {
+ TPtrC ptr = maps->GetAll(iOwner->Case());
+ iTextBuffer->Append(ptr.Left(iTextBuffer->MaxLength() - iTextBuffer->Length()));
+ SetFlag(EPtiGetAllFlag);
+ }
+ }
+ else if (chr)
+ {
+ switch (chr)
+ {
+ case KArarbicLigatureLamWithAlefWithMaddaAboveIsolatedForm:
+ iTextBuffer->Append(KArarbicLigatureLamWithAlefWithMaddaAboveIsolatedSequence);
+ SetFlag(EPtiDoubleWideEntry);
+ break;
+ case KArarbicLigatureLamWithAlefWithHamzaAboveIsolatedForm:
+ iTextBuffer->Append(KArarbicLigatureLamWithAlefWithHamzaAboveIsolatedSequence);
+ SetFlag(EPtiDoubleWideEntry);
+ break;
+ case KArarbicLigatureLamWithAlefWithHamzaBelowIsolatedForm:
+ iTextBuffer->Append(KArarbicLigatureLamWithAlefWithHamzaBelowIsolatedSequence);
+ SetFlag(EPtiDoubleWideEntry);
+ break;
+ case KArarbicLigatureLamWithAlefIsolatedForm:
+ iTextBuffer->Append(KArarbicLigatureLamWithAlefIsolatedSequence);
+ SetFlag(EPtiDoubleWideEntry);
+ break;
+ default:
+ iTextBuffer->Append(chr);
+ }
+ }
+
+ if (qwerty)
+ {
+ // There was dead key press waiting, but last key press didn't
+ // contain dead key data, so both keys will be inserted.
+ CPtiQwertyKeyMappings* qmap = static_cast<CPtiQwertyKeyMappings*>(maps);
+
+ if (overridingDeadKey != 0)
+ {
+ qmap->ClearDeadKey();
+ }
+ else if (qmap->DeadKeyRootFlag())
+ {
+ if (iTextBuffer->Length() < iTextBuffer->MaxLength())
+ {
+ SetFlag(EPtiDeadKeyRootFlag); // This will indicate PtiEngine that extra character
+ // was added to buffer.
+ iTextBuffer->Append(maps->StartMapping(aKey, iOwner->Case()));
+ }
+ }
+ else if ((qmap->VowelSequenceFlag()) &&
+ (lang->LanguageCode() == ELangVietnamese))
+ {
+ // This was Vietnamese vowel sequence, remove first vowel
+ // component from buffer.
+ TInt numRemove = (iTextBuffer->Length() > 1 ? 2 : 1);
+ iTextBuffer->SetLength(iTextBuffer->Length() - numRemove);
+ iTextBuffer->Append(qmap->VowelSequenceResult());
+ SetFlag(EPtiFlagVowelSeq);
+ }
+ }
+ }
+ }
+
+ const TPtiTextCase textCase = iOwner->Case();
+// In Querty mode . default core always get called.
+// When Fn key is pressed its not in multitap its not in multitapmode
+// multitap timer should be canceled.
+
+ if (qwerty &&
+ ((textCase == EPtiCaseLower) || (textCase == EPtiCaseUpper) ||(textCase == EPtiCaseFnLower) || (textCase == EPtiCaseFnUpper)||
+ ((inputMode == EPtiEngineZhuyinQwerty || inputMode ==EPtiEnginePinyinQwerty ||
+ inputMode == EPtiEngineStrokeQwerty ||inputMode == EPtiEngineZhuyinPhraseQwerty ||
+ inputMode == EPtiEngineStrokePhraseQwerty ||inputMode == EPtiEnginePinyinPhraseQwerty ) &&
+ (textCase == EPtiCaseChrUpper ||
+ textCase == EPtiCaseChrLower))))
+ {
+ iTimer->Cancel();
+ }
+ else
+ {
+ iTimer->After(KMultiTapTimeoutMS);
+ }
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::DeleteKeyPress
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::DeleteKeyPress()
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ ClearFlag(EPtiGetAllFlag | EPtiFlagVowelSeq);
+
+ if (iTimer->IsActive())
+ {
+ iTimer->Cancel();
+ }
+
+ if (iTextBuffer->Length() > 0)
+ {
+ // Delete last character.
+ iTextBuffer->SetLength(iTextBuffer->Length() - 1);
+ }
+
+ ClearVowelSequence();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::ClearBuffer
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::ClearBuffer()
+ {
+ __ASSERT_DEBUG(iTimer, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ iTimer->Cancel();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::ClearVowelSequence
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::ClearVowelSequence()
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ if (iOwner->IsQwertyBasedMode(iOwner->InputMode()))
+ {
+ CPtiCoreLanguage* lang = static_cast<CPtiCoreLanguage*>(iOwner->CurrentLanguage());
+ __ASSERT_DEBUG(lang, User::Panic(KPtiEnginePanic, KErrCorrupt));
+ CPtiQwertyKeyMappings* qMap = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (qMap)
+ {
+ qMap->ClearVowelSequence();
+ qMap->ClearLastChar();
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::SetCurrentInputSequence
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::SetCurrentInputSequence(TPtrC8 /*aInput*/)
+ {
+ __ASSERT_DEBUG(iTimer, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ if (iTimer->IsActive())
+ {
+ iTimer->Cancel();
+ }
+
+ ClearVowelSequence();
+
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::TimerExpire
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::TimerExpire(TAny* aPtr)
+ {
+ return reinterpret_cast<CPtiDefaultCore*>(aPtr)->DoTimerExpire();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::DoTimerExpire
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::DoTimerExpire()
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ if (iOwner->Observer())
+ {
+ iOwner->Observer()->KeyTimerExpired();
+ }
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::DropLanguages
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::DropLanguages(CArrayPtrFlat<CPtiCoreLanguage>* aLanguageList)
+ {
+ for (TInt i = 0; i < aLanguageList->Count(); i++)
+ {
+ if (aLanguageList->At(i)->HasInputMode(EPtiEngineMultitapping))
+ {
+ aLanguageList->At(i)->ClearMultitapping();
+ if (aLanguageList->At(i)->GetCore(EPtiEngineMultitapping) == this)
+ {
+ aLanguageList->At(i)->SetCore(NULL, EPtiEngineMultitapping);
+ }
+ }
+ if (aLanguageList->At(i)->HasInputMode(EPtiEngineQwerty))
+ {
+ aLanguageList->At(i)->ClearQwerty();
+ if (aLanguageList->At(i)->GetCore(EPtiEngineQwerty) == this)
+ {
+ aLanguageList->At(i)->SetCore(NULL, EPtiEngineQwerty);
+ }
+ }
+ if (aLanguageList->At(i)->HasInputMode(EPtiEngineHalfQwerty))
+ {
+ aLanguageList->At(i)->ClearHalfQwerty();
+ if (aLanguageList->At(i)->GetCore(EPtiEngineHalfQwerty) == this)
+ {
+ aLanguageList->At(i)->SetCore(NULL, EPtiEngineHalfQwerty);
+ }
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::GetCoreInfo
+//
+// ---------------------------------------------------------------------------
+//
+MPtiCoreInfo* CPtiDefaultCore::GetCoreInfo()
+ {
+ return &iCoreInfo;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::Convert
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::Convert(TPtiCharConversion /*aType*/,
+ TAny* /*aInput*/,
+ TInt /*aInputLength*/,
+ TAny* /*aOutput*/)
+ {
+ return KErrNotSupported;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::SetExternalKeyMapL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::SetExternalKeyMapL(TPtiEngineInputMode aMode,
+ TPtiKey aKey,
+ TDesC& aKeyMap,
+ TPtiTextCase aCase)
+ {
+ if (aMode == EPtiEngineNumeric)
+ {
+ __ASSERT_DEBUG(iNumericMappings, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ // Always available. Case doesn't apply for numeric mode,
+ // so both cases are always updated.
+ TInt ret = iNumericMappings->ReplaceKeyMapL(aKey, aKeyMap, EPtiCaseLower);
+ if (ret != KErrNone)
+ {
+ return ret;
+ }
+ return iNumericMappings->ReplaceKeyMapL(aKey, aKeyMap, EPtiCaseUpper);
+ }
+ else
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ CPtiCoreLanguage* lang = static_cast<CPtiCoreLanguage*>(iOwner->CurrentLanguage());
+ if (!lang)
+ {
+ return KErrCorrupt;
+ }
+
+ MPtiKeyMappings* maps = NULL;
+ if (aMode == EPtiEngineMultitapping)
+ {
+ maps = lang->GetKeymappings();
+ }
+ else if (aMode == EPtiEngineQwerty)
+ {
+ maps = lang->GetQwertyKeymappings();
+ }
+ else if (aMode == EPtiEngineHalfQwerty)
+ {
+ maps = lang->GetHalfQwertyKeymappings();
+ }
+
+ if (maps)
+ {
+ return maps->ReplaceKeyMapL(aKey, aKeyMap, aCase);
+ }
+ }
+
+
+ return KErrNotSupported;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::GetSpelling
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::GetSpelling(TUint16 /*aInput*/, TDes& /*aOutput*/,
+ TPtiSpelling /*aType*/)
+ {
+ return KErrNotSupported;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::CancelTimerActivity
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::CancelTimerActivity()
+ {
+ __ASSERT_DEBUG(iTimer, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ iTimer->Cancel();
+ return KErrNone;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::HandleCommandL
+//
+// ---------------------------------------------------------------------------
+//
+TInt CPtiDefaultCore::HandleCommandL(TPtiEngineCommand aCommand, TAny* aParams)
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ CPtiCoreLanguage* lang = static_cast<CPtiCoreLanguage*>(iOwner->CurrentLanguage());
+ TBool qwerty = EFalse;
+ if (lang)
+ {
+ qwerty = lang->HasInputMode(EPtiEngineQwerty);
+ }
+
+ switch (aCommand)
+ {
+ case EPtiCommandPollQwertyDeadKeyRootFlag:
+ {
+ if (IsFlagSet(EPtiDeadKeyRootFlag))
+ {
+ ClearFlag(EPtiDeadKeyRootFlag);
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+ case EPtiCommandGetAndClearDeadKeyRootChar:
+ {
+ TUint16 ret = 0;
+
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps->DeadKey())
+ {
+ maps->ClearDeadKey();
+ ret = maps->DeadKeyRootChar();
+ }
+ }
+
+ return ret;
+ }
+ case EPtiCommandDeadKeyWaiting:
+ {
+ TUint16 ret = 0;
+
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps->DeadKey())
+ {
+ ret = 1;
+ }
+ }
+
+ return ret;
+ }
+
+ case EPtiCommandQueryAndClearGetAllFlag:
+ {
+ TBool ret = IsFlagSet(EPtiGetAllFlag);
+ ClearFlag(EPtiGetAllFlag);
+ return ret;
+ }
+
+ case EPtiCommandGetAndClearVowelSequence:
+ {
+ if (IsFlagSet(EPtiFlagVowelSeq))
+ {
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ ClearFlag(EPtiFlagVowelSeq);
+ return maps->VowelSequenceResult();
+ }
+ }
+
+ return 0;
+ }
+ case EPtiCommandVowelSeqFlag:
+ return IsFlagSet(EPtiFlagVowelSeq);
+ case EPtiCommandClearVowelSeq:
+ {
+ ClearFlag(EPtiFlagVowelSeq);
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ maps->ClearVowelSequence();
+ }
+ }
+ }
+ return 0;
+ case EPtiCommandGetAndClearLastVietnameseChar:
+ {
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ TInt ret = maps->GetLastChar();
+ maps->ClearLastChar();
+ return ret;
+ }
+ }
+ }
+ return 0;
+ case EPtiCommandSetVietnameseLastChar:
+ {
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ maps->SetLastChar((TInt)aParams);
+ }
+ }
+ }
+ return 0;
+ case EPtiCommandQueryReplacePrevious:
+ {
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ TChar rep = maps->ReplacedCharacter();
+ if (maps->VowelCase() == EPtiCaseUpper ||
+ maps->VowelCase() == EPtiCaseChrUpper)
+ {
+ rep.UpperCase();
+ }
+ else
+ {
+ rep.LowerCase();
+ }
+
+ return rep;
+ }
+ }
+ }
+ return 0;
+ case EPtiCommandSetLastKeyForVietnamese:
+ {
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ TPtiKey key = (TPtiKey)((TInt)aParams);
+ maps->SetLastKey(key);
+ }
+ }
+ }
+ return 0;
+
+ case EPtiCommandResetVietnameseVowelSeqAndToneMark:
+ ClearFlag(EPtiFlagVowelSeq);
+ if (lang && qwerty)
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ maps->ResetVietnameseVowelSequenceAndToneMarks();
+ }
+ }
+ return 0;
+
+ case EPtiCommandGetVietnameseLastKey:
+ if ((lang) && (lang->HasInputMode(EPtiEngineQwerty)))
+ {
+ CPtiQwertyKeyMappings* maps = static_cast<CPtiQwertyKeyMappings*>(lang->GetQwertyKeymappings());
+ if (maps)
+ {
+ return (TInt)maps->LastKey();
+ }
+ }
+ return 0;
+ case EPtiCommandDoubleWideEntry:
+ {
+ TInt ret = IsFlagSet(EPtiDoubleWideEntry);
+ ClearFlag(EPtiDoubleWideEntry);
+ return ret;
+ }
+ default:
+ break;
+ }
+
+ return KErrNotSupported;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::ListDataFactoryLanguagesL
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::ListDataFactoryLanguagesL(CPtiKeyMapDataFactory* aDataFactory,
+ TInt aImplUid,
+ CArrayPtrFlat<CPtiCoreLanguage>* aLanguageList)
+ {
+ __ASSERT_DEBUG(aDataFactory, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ RArray<TInt> langs;
+ aDataFactory->ListLanguagesL(langs);
+ CleanupClosePushL(langs);
+
+ for (TInt i = 0; i < langs.Count(); i++)
+ {
+ CPtiCoreLanguage* language = NULL;
+
+ for (TInt j = 0; j < iFactoryBindings.Count(); j++)
+ {
+ // Remove possible earlier bindings for this language (ie.
+ // newly installed dlls will replace old languages).
+ if (iFactoryBindings[j].iLanguage == langs[i])
+ {
+ iFactoryBindings.Remove(j);
+ break;
+ }
+ }
+
+ if (!language)
+ {
+ language = CPtiCoreLanguage::NewL();
+ CleanupStack::PushL( language );
+ aLanguageList->AppendL( language );
+ CleanupStack::Pop(); // language
+ }
+
+ language->SetLanguageCode(langs[i]);
+ language->SetCore(this, EPtiEngineNumeric);
+ language->SetKeyMapDataFactory(aDataFactory);
+ language->GetKeymappings(); // Force core list to be updated.
+ language->SetKeyMapDataFactory(NULL);
+
+ TPtiDataFactoryBinding newBind(langs[i], aImplUid);
+ iFactoryBindings.AppendL(newBind);
+ }
+
+ CleanupStack::PopAndDestroy(); // langs
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::LoadFactoryForLanguageL
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::LoadFactoryForLanguageL(TInt aLanguage)
+ {
+ __ASSERT_DEBUG(iOwner, User::Panic(KPtiEnginePanic, KErrCorrupt));
+
+ TInt currentUid = 0;
+ if (iKeyMapDataFactory)
+ {
+ currentUid = iKeyMapDataFactory->ImplementationUid();
+ }
+
+ CPtiCoreLanguage* coreLang = static_cast<CPtiCoreLanguage*>(iOwner->GetLanguage(aLanguage));
+ if (!coreLang)
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ coreLang->SetKeyMapDataFactory(NULL);
+ for (TInt i = 0; i < iFactoryBindings.Count(); i++)
+ {
+ if (iFactoryBindings[i].iLanguage == aLanguage)
+ {
+ if (iFactoryBindings[i].iFactoryImplUid == currentUid)
+ {
+ coreLang->SetKeyMapDataFactory(iKeyMapDataFactory);
+ return;
+ }
+
+ // Factory is about to change. Clear references to old one.
+ ShutDownKeymapFactory();
+
+ iKeyMapDataFactory = CPtiKeyMapDataFactory::CreateImplementationL(TUid::Uid(iFactoryBindings[i].iFactoryImplUid));
+ coreLang->SetKeyMapDataFactory(iKeyMapDataFactory);
+
+ return;
+ }
+ }
+
+ User::Leave(KErrNotFound);
+ }
+
+
+// ---------------------------------------------------------------------------
+// CPtiDefaultCore::ShutDownKeymapFactory
+//
+// ---------------------------------------------------------------------------
+//
+void CPtiDefaultCore::ShutDownKeymapFactory()
+ {
+ if (iLanguageList)
+ {
+ CPtiCoreLanguage* lang = NULL;
+ for (TInt i = 0; i < iLanguageList->Count(); i++)
+ {
+ lang = static_cast<CPtiCoreLanguage*>(iLanguageList->At(i));
+ if (lang && lang->DataFactory() == iKeyMapDataFactory)
+ {
+ lang->SetKeyMapDataFactory(NULL);
+ }
+ }
+
+ delete iKeyMapDataFactory;
+ iKeyMapDataFactory = NULL;
+ }
+ }
+
+// End of file