diff -r 000000000000 -r eb1f2e154e89 textinput/ptienginev2/src/PtiSymbolList.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/textinput/ptienginev2/src/PtiSymbolList.cpp Tue Feb 02 01:02:04 2010 +0200 @@ -0,0 +1,577 @@ +/* +* Copyright (c) 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: Predective text input engine core local methods. +* +*/ + + + +#include +#include + +#include "PtiSymbolList.h" + + +//=========== constant definition ============== +_LIT( KSymbolMutexName,"PtiHwrSymbol_101F8610" ); +const TInt KUdmFileHeader = 0x20080808; +const TInt KUdmFileVersion = 0x00001000; +const TInt KInvalidPresetIndex = 0; + + +void CSymbol::InternalizeL(RReadStream& /*aStream*/) + { + } + +void CSymbol::ExternalizeL(RWriteStream& aStream) + { + aStream.WriteInt32L( iHelpLine ); + aStream.WriteInt32L( iBaseLine ); + aStream.WriteInt32L( iRange.iScript ); + aStream.WriteInt32L( iRange.iRange ); + aStream.WriteUint32L( iPresetCode ); + if ( iSymbolName ) + { + aStream.WriteInt32L( iSymbolName->Length() ); + aStream.WriteL( *iSymbolName, iSymbolName->Length() ); + } + else + { + aStream.WriteInt32L( 0 ); + } + + aStream.WriteInt32L( iPointVectorLen ); + aStream.WriteL( reinterpret_cast< TUint8* >( iPointVector ), iPointVectorLen*sizeof( TPoint ) ); + + } + + CSymbol* CSymbol::NewL(RReadStream& aStream) + { + CSymbol* self = new ( ELeave ) CSymbol(); + CleanupStack::PushL( self ); + self->ConstructL( aStream ); + CleanupStack::Pop( self ); + return self; + } + +void CSymbol::ConstructL(RReadStream& aStream) + { + iHelpLine = aStream.ReadInt32L(); + iBaseLine = aStream.ReadInt32L(); + iRange.iScript = aStream.ReadInt32L(); + iRange.iRange = aStream.ReadInt32L(); + iPresetCode = aStream.ReadUint32L(); + + TInt symbolLen = aStream.ReadInt32L(); + iSymbolName = NULL; + if ( symbolLen ) + { + iSymbolName = HBufC::NewL( symbolLen ); + TPtr ptr = iSymbolName->Des(); + aStream.ReadL( ptr, symbolLen ); + } + + iPointVectorLen = aStream.ReadInt32L(); + iPointVector = new ( ELeave ) TPoint[iPointVectorLen]; + aStream.ReadL( reinterpret_cast< TUint8* >( iPointVector ), iPointVectorLen*sizeof( TPoint ) ); + } + +CSymbol::CSymbol() + { + iPresetCode = 0; + } + + CSymbol* CSymbol::NewL(const TDesC& aText, const RArray& aModel, int aHelpLine, int aBaseLine,const THwrUdmRange& aRange) + { + CSymbol* self = new ( ELeave )CSymbol(); + CleanupStack::PushL( self ); + self->ConstructL( aText, aModel, aHelpLine, aBaseLine, aRange ); + CleanupStack::Pop( self ); + return self; + } + +CSymbol::~CSymbol() + { + delete iSymbolName; + delete [] iPointVector; + } + +void CSymbol::ConstructL(const TDesC& aText, const RArray& aModel, int aHelpLine, int aBaseLine,const THwrUdmRange& aRange) + { + iHelpLine = aHelpLine; + iBaseLine = aBaseLine; + iRange = aRange; + iSymbolName = aText.AllocL( ); + iPresetCode = KInvalidPresetIndex; + + iPointVectorLen = aModel.Count(); + iPointVector = new ( ELeave ) TPoint[iPointVectorLen]; + memcpy( iPointVector, &(aModel[0]), iPointVectorLen*sizeof( TPoint ) ); + } + +TInt CSymbol::SymbolOrderDescending(const CSymbol& aFirst, const CSymbol& aSecond) + { + return aFirst.iSymbolName->Compare( *(aSecond.iSymbolName ) ); + } + +TBool CSymbol::Match ( const THwrUdmRange& aRange ) + { + if ( aRange.iScript != EPtiHwrScriptAny ) + { + if ( aRange.iScript != iRange.iScript ) + { + return EFalse; + } + } + + if ( aRange.iRange != EPtiHwrRangeAny ) + { + if ( aRange.iRange != iRange.iRange ) + { + return EFalse; + } + } + + return ETrue; + } + +CSymbolList* CSymbolList::NewL(const TDesC& aFilePath, CSymbolList* aPresetList ) + { + CSymbolList* self = new ( ELeave ) CSymbolList( aPresetList ); + CleanupStack::PushL( self ); + self->ConstructL( aFilePath ); + CleanupStack::Pop( self ); + return self; + } + +void CSymbolList::SetSymbolModelL(const TDesC& aText, const RArray& aModel, TInt aHelpLine , TInt aBaseLine ,const THwrUdmRange& aRange ) + { + if( !aText.Length() || !aModel.Count() ) + User::Leave( KErrGeneral ); + if ( CheckSymbolModel( aText , aRange ) ) + { + User::Leave( KErrAlreadyExists ); + } + + CSymbol* symbol = CSymbol::NewL( aText, aModel, aHelpLine, aBaseLine, aRange ); + CleanupStack::PushL( symbol ); + TLinearOrder order( CSymbol::SymbolOrderDescending ); + // using order insertion later + // iSymbolList.InsertInOrderL( symbol, order ); + iSymbolList.AppendL( symbol ); + CleanupStack::Pop( symbol ); + ExternalizeL(); + } + +TBool CSymbolList::CheckSymbolModel(const TDesC& aChar ,const THwrUdmRange& aRange ) + { + TInt idx = -1; + return GetSymbolIndex( aChar, idx, aRange ) == KErrNone ? ETrue : EFalse ; + } + +void CSymbolList::GetSymbolModelL(const TDesC& aChar, RArray& aModel ,TUint& aUnicode, const THwrUdmRange& aRange ) + { + TInt idx = -1; + if ( GetSymbolIndex( aChar, idx, aRange ) != KErrNone ) + { + User::Leave( KErrNotFound ); + } + // decides which list the idx belongs to + CSymbol* symbol = NULL; + if ( idx >= iSymbolList.Count() && iPresetModels ) + { + symbol = iPresetModels->iSymbolList[ idx - iSymbolList.Count() ]; + } + else + { + symbol = iSymbolList[idx]; + } + + aUnicode = symbol->iPresetCode; + aModel.Reset(); + for ( int i = 0; i < symbol->iPointVectorLen; i++ ) + { + aModel.AppendL( symbol->iPointVector[i] ); + } + } + +void CSymbolList::DeleteSymbolModelL(const TDesC& aChar ,const THwrUdmRange& aRange ) + { + TInt idx = -1; + if ( GetSymbolIndex( aChar, idx, aRange ) != KErrNone ) + { + User::Leave( KErrNotFound ); + } + if ( idx < iSymbolList.Count() ) + { + CSymbol* symbol = iSymbolList[idx]; + iSymbolList.Remove( idx ); + delete symbol; + ExternalizeL(); + } + else if ( iPresetModels ) + { + // modify preset models + TInt presetIdx = idx -iSymbolList.Count(); + CSymbol& symbol = *iPresetModels->iSymbolList[presetIdx]; + delete symbol.iSymbolName; + symbol.iSymbolName = NULL; + iPresetModels->ExternalizeL(); + } + } + +void CSymbolList::GetModelTextListL(RPointerArray& aList ,const THwrUdmRange& /*aRange*/ ) + { + for ( int i = 0; i < iSymbolList.Count(); i++ ) + { + aList.AppendL( (*iSymbolList[i]->iSymbolName).AllocL() ); + } + + // then get preset shortcut models if have + if ( iPresetModels ) + { + for ( int i = 0; i < iPresetModels->iSymbolList.Count(); i++ ) + { + // if the preset model is assigned to a shourtcut, then append it to the list + CSymbol* symbol = iPresetModels->iSymbolList[i]; + if ( symbol->iSymbolName && symbol->iPresetCode ) + { + aList.AppendL( symbol->iSymbolName->AllocL() ); + } + } + } + } + +void CSymbolList::ChangeSymbolTextL(const TDesC& aOldText, const TDesC& aNewText ,const THwrUdmRange& aRange ) + { + TInt idx = -1; + if ( GetSymbolIndex( aOldText, idx, aRange ) != KErrNone ) + { + User::Leave( KErrNotFound ); + } + + if ( aOldText.Compare( aNewText ) == 0 ) + { + return ; + } + + if ( CheckSymbolModel( aNewText, aRange ) ) + { + User::Leave( KErrAlreadyExists ); + } + if ( idx < iSymbolList.Count() ) + { + CSymbol& symbol = *iSymbolList[idx]; + delete symbol.iSymbolName; + symbol.iSymbolName = aNewText.AllocL(); + ExternalizeL(); + } + else if ( iPresetModels ) + { + // modify preset models + TInt presetIdx = idx -iSymbolList.Count(); + + CSymbol& symbol = *iPresetModels->iSymbolList[presetIdx]; + delete symbol.iSymbolName; + symbol.iSymbolName = aNewText.AllocL(); ; + + iPresetModels->ExternalizeL(); + } + } + +void CSymbolList::GetModelIndexListL( RArray& aList, const THwrUdmRange& aRange) + { + aList.Reset(); + for ( int i = 0; i < iSymbolList.Count(); i++ ) + { + if ( iSymbolList[i]->Match( aRange ) ) + { + aList.AppendL( i ); + } + } + + // append the symbols to the array + if ( iPresetModels ) + { + for ( int i = 0; i < iPresetModels->iSymbolList.Count(); i++ ) + { + if ( iPresetModels->iSymbolList[i]->iSymbolName && + iPresetModels->iSymbolList[i]->Match( aRange ) ) + { + aList.AppendL( i + iSymbolList.Count() ); + } + } + } + } + +void CSymbolList::InternalizeL(const TDesC& /*aFile*/) + { + // Read the data file and construct the object + iMutex.Wait(); + CleanupStack::PushL(TCleanupItem(SignalMutex, &iMutex)); + RFile readFile; + TInt errCode = readFile.Open( iRfs, *iFilePath, EFileRead ); + CleanupClosePushL( readFile ); + + if ( errCode == KErrNone ) + { + RFileReadStream readStream( readFile ); + CleanupClosePushL( readStream ); + + // check file Type&Version + TInt fileType = readStream.ReadInt32L(); + TInt fileVersion = readStream.ReadInt32L(); + if ( fileType != KUdmFileHeader || fileVersion != KUdmFileVersion ) + { + User::Leave( KErrGeneral ); + } + + // construct each CSymbol object and add to array + TInt symbolNO = readStream.ReadInt32L(); + for ( int i = 0; i < symbolNO; i++ ) + { + CSymbol* symbol = CSymbol::NewL( readStream ); + iSymbolList.AppendL( symbol ); + } + + // check wether the file is valid. + if ( symbolNO != iSymbolList.Count() ) + { + User::Leave( KErrGeneral ); + } + CleanupStack::PopAndDestroy( &readStream ); + } + CleanupStack::PopAndDestroy( &readFile ); + CleanupStack::PopAndDestroy(); // TCleanupItem(SignalMutex, &iMutex) + } + +void CSymbolList::ExternalizeL() + { + // write a temp file and use replace. + iMutex.Wait(); + CleanupStack::PushL(TCleanupItem(SignalMutex, &iMutex)); + + RFile fileTemp; + CleanupClosePushL( fileTemp ); + + //HBufC* tempFile = HBufC::NewLC( iFilePath->Length() + 3 ); + //TPtr tempFilePtr( tempFile->Des() ); + //tempFilePtr.Copy( *iFilePath ); + //tempFilePtr.Append( KTempPathFix ); + + + TParse fileParse; + fileParse.Set( *iFilePath, NULL, NULL ); + + TFileName tempName; + iRfs.MkDirAll( fileParse.DriveAndPath() ); + User::LeaveIfError ( fileTemp.Temp( iRfs, fileParse.DriveAndPath(), tempName, EFileWrite ) ); + + RFileWriteStream writeStream( fileTemp ); + CleanupClosePushL( writeStream ); + + // write file type&version + writeStream.WriteInt32L( KUdmFileHeader ); + writeStream.WriteInt32L( KUdmFileVersion ); + + writeStream.WriteInt32L( iSymbolList.Count() ); + for ( int i = 0; i < iSymbolList.Count(); i++ ) + { + iSymbolList[i]->ExternalizeL( writeStream ); + } + writeStream.CommitL(); + CleanupStack::PopAndDestroy( &writeStream ); + CleanupStack::PopAndDestroy( &fileTemp ); + + iRfs.Delete( *iFilePath ) ; + User::LeaveIfError( iRfs.Rename( tempName ,*iFilePath ) ); + + CleanupStack::PopAndDestroy(); // TCleanupItem(SignalMutex, &iMutex) + } + +CSymbolList::CSymbolList( CSymbolList* aPresetList ) + { + iPresetModels = aPresetList; + iFilePath = NULL; + } + +void CSymbolList::ConstructL(const TDesC& aFilePath) + { + User::LeaveIfError( iRfs.Connect() ); + iFilePath = aFilePath.AllocL(); + + // create mutex + TInt error( KErrNotFound ); + while( error == KErrNotFound ) + { + error = iMutex.CreateGlobal( KSymbolMutexName ); + if( error != KErrAlreadyExists ) + { + break; + } + error = iMutex.OpenGlobal( KSymbolMutexName ); + } + User::LeaveIfError( error ); + + InternalizeL( aFilePath ); + } + +CSymbolList::~CSymbolList() + { + delete iFilePath; + for ( int i = 0; i < iSymbolList.Count(); i++ ) + { + delete iSymbolList[i]; + } + iSymbolList.Close(); + iRfs.Close(); + iMutex.Close(); + } + +TInt CSymbolList::GetSymbolIndex(const TDesC& aText, TInt& aIndex, const THwrUdmRange& aRange ) + { + // using quick search later. + for ( int i = 0; i < iSymbolList.Count(); i++ ) + { + if ( iSymbolList[i]->iSymbolName->Compare( aText ) == 0 && iSymbolList[i]->Match( aRange )) + { + aIndex = i; + return KErrNone; + } + } + + // then find in preset model + if ( iPresetModels ) + { + for ( int i = 0; i < iPresetModels->iSymbolList.Count(); i++ ) + { + CSymbol& symbol = *iPresetModels->iSymbolList[i]; + // not assigned + if ( !symbol.iSymbolName ) + { + continue; + } + + if ( symbol.iSymbolName->Compare( aText ) == 0 && symbol.Match( aRange )) + { + aIndex = iSymbolList.Count() + i; + return KErrNone; + } + } + } + + return KErrNotFound; + } + +TInt CSymbolList::GetSymbolDataRef( TInt aIndex, TPtrC& aSymbolName,RArray& aModel, TInt& aHelpLine, TInt& aBaseLine ) + { + + CSymbol* symbol = NULL; + if ( aIndex >= 0 && aIndex < iSymbolList.Count() ) + { + symbol = iSymbolList[aIndex]; + } + else if ( iPresetModels && aIndex >= iSymbolList.Count() + && aIndex < iSymbolList.Count() + iPresetModels->iSymbolList.Count() ) + { + symbol = iPresetModels->iSymbolList[ aIndex - iSymbolList.Count() ]; + } + else + { + return KErrNotFound; + } + + aModel.Reset(); + aModel = RArray( sizeof(TPoint), symbol->iPointVector, symbol->iPointVectorLen ); + aHelpLine = symbol->iHelpLine; + aBaseLine = symbol->iBaseLine; + aSymbolName.Set( *symbol->iSymbolName ); + + return KErrNone; + } + + +void CSymbolList::SavePresetShortcutL( TUint aUnicode, const TDesC& aShortcut ) + { + User::LeaveIfNull( iPresetModels ); + + for ( int i = 0; i < iPresetModels->iSymbolList.Count(); i ++ ) + { + CSymbol* sym = iPresetModels->iSymbolList[i]; + if ( aUnicode == sym->iPresetCode ) + { + if ( sym-> iSymbolName ) + { + delete sym->iSymbolName; + sym->iSymbolName = NULL; + } + + if ( aShortcut.Length() > 0 ) + { + sym->iSymbolName = aShortcut.AllocL(); + } + iPresetModels->ExternalizeL(); + return; + } + } + + User::Leave( KErrNotFound ); + } + +void CSymbolList::GetAllPresetSymbolsL( RArray& aPresets ) + { + User::LeaveIfNull( iPresetModels ); + + for ( int i = 0; i < iPresetModels->iSymbolList.Count(); i ++ ) + { + aPresets.AppendL( iPresetModels->iSymbolList[i]->iPresetCode ); + } + } + +void CSymbolList::GetPresetSymbolByUnicodeL( TUint aUnicode, RArray& aModel, TDes& aShortcut ) + { + User::LeaveIfNull( iPresetModels ); + + for ( int i = 0; i < iPresetModels->iSymbolList.Count(); i ++ ) + { + CSymbol* sym = iPresetModels->iSymbolList[i]; + if ( aUnicode == sym->iPresetCode ) + { + aShortcut = KNullDesC; + if ( sym->iSymbolName ) + { + aShortcut.Copy( *sym->iSymbolName ); + } + + for ( int i = 0; i < sym->iPointVectorLen; i++ ) + { + aModel.AppendL( sym->iPointVector[i] ); + } + return; + } + } + User::Leave( KErrNotFound ); + } + +void CSymbolList::SignalMutex(TAny* aMutex) + { + STATIC_CAST( RMutex*, aMutex )->Signal(); + } + + + + + + +