textinput/ptienginev2/src/PtiSymbolList.cpp
changeset 0 eb1f2e154e89
child 9 e6a39382bb9c
--- /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 <f32file.h>
+#include <s32file.h>
+
+#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<TPoint>& 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<TPoint>& 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<TPoint>& 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<CSymbol> 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<TPoint>& 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<HBufC>& 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<TInt>& 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<TPoint>& 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<TPoint>( 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<TUint>& 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<TPoint>& 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();
+   }
+
+
+
+
+
+
+