--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/psln/pslnengine/src/PslnSkinStore.cpp Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,381 @@
+/*
+* Copyright (c) 2004-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: Skin store.
+*
+*/
+
+
+// INCLUDE FILES
+
+// Psln specific.
+#include "PslnSkinStore.h"
+#include "PslnModel.h"
+#include "PslnSkinEntry.h"
+#include "PslnDebug.h"
+
+// Repository
+#include <centralrepository.h>
+#include <AknSkinsInternalCRKeys.h>
+#include <AknsSkinUID.h>
+
+#ifdef RD_MULTIPLE_DRIVE
+#include <driveinfo.h>
+#endif //RD_MULTIPLE_DRIVE
+
+void CleanupDeleteArray( TAny* aArray )
+ {
+ static_cast<RPointerArray<CPslnSkinNameEntry>*>
+ (aArray)->ResetAndDestroy();
+ delete aArray;
+ aArray = NULL;
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CPslnSkinStore::CPslnSkinStore()
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPslnSkinStore::ConstructL( CPslnModel* aModel )
+ {
+ iModel = aModel;
+
+ CRepository* repository = CRepository::NewLC( KCRUidPersonalisation );
+ TInt value = KAknsNullPkgID.iNumber;
+ iDefaultSkinPID.Set( KAknsPIDS60DefaultSkin );
+ TBuf<32> buf;
+ TAknsPkgID defaultSkin = KAknsNullPkgID;
+
+ TInt err = repository->Get( KPslnDefaultSkinUID, buf );
+ if ( err != KErrNone || buf.Length() == 0 )
+ {
+ err = repository->Get( KPslnDefaultSkinID, value );
+ if( err == KErrNone )
+ {
+ defaultSkin.Set( TUid::Uid( value ) );
+ }
+ }
+ else
+ {
+ TInt bufLength = buf.Length();
+ // If its 8 characters long, its UID.
+ // PIDs are 16 characters (8 ID + 8 timestamp)
+ if ( bufLength == 8 )
+ {
+ // Let's try to set it directly as Hex.
+ TLex hexLex( buf );
+ TUint pid;
+ err = hexLex.Val( pid, EHex );
+ if (!err)
+ {
+ // UIDs have no timestamp.
+ defaultSkin.Set( 0, pid );
+ }
+ }
+ else
+ {
+ // The skin PID is set in CenRep in format <PID1><PID2> and
+ // values are in hex.
+ TLex lex ( buf.Left( 8 ) );
+ TLex lex2 ( buf.Right( 8 ) );
+ TUint pid;
+ TUint timeStamp;
+ err = lex.Val( pid, EHex );
+ if ( !err )
+ {
+ err = lex2.Val( timeStamp, EHex );
+ }
+ if ( !err )
+ {
+ defaultSkin.Set( timeStamp, pid );
+ }
+ }
+ }
+ iDefaultSkinPID = defaultSkin;
+ CleanupStack::PopAndDestroy( repository );
+ }
+
+// -----------------------------------------------------------------------------
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CPslnSkinStore* CPslnSkinStore::NewL( CPslnModel* aModel )
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::NewL");
+
+ CPslnSkinStore* self = new( ELeave ) CPslnSkinStore;
+ CleanupStack::PushL( self );
+ self->ConstructL( aModel );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CPslnSkinStore::~CPslnSkinStore()
+ {
+ iSkinArray.ResetAndDestroy();
+ }
+
+// -----------------------------------------------------------------------------
+// CPslnSkinStore::UpdateAllSkinsL
+// -----------------------------------------------------------------------------
+//
+void CPslnSkinStore::UpdateAllSkinsL( RFs& aFsSession )
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::UpdateAllSkinsL");
+
+ TInt i = KErrNone;
+
+ // Mark all the existing skins
+ for( ; i < iSkinArray.Count(); i++ )
+ {
+ CPslnSkinEntry* entry = iSkinArray[i];
+ entry->SetDeleteFlag( ETrue );
+ }
+ UpdateAllSkinsL( EAknsSrvAll, aFsSession );
+
+ // Remove any skins that haven't existed (they no longer exist)
+ TInt skinCount = iSkinArray.Count() - 1;
+ for( i = skinCount; i >= 0; i-- )
+ {
+ CPslnSkinEntry* entry = iSkinArray[i];
+ if( entry && entry->IsDeleteFlag() )
+ {
+ delete entry;
+ iSkinArray.Remove( i );
+ }
+ }
+
+ // Then sort the array
+ iSkinArray.Sort( CPslnSkinEntry::LinearOrder );
+
+ // Finally, move default skin as first item in the array.
+ i = KErrNotFound;
+ skinCount = iSkinArray.Count() - 1;
+ CPslnSkinEntry* entry = NULL;
+ for( i = skinCount; i >= 0; i-- )
+ {
+ entry = iSkinArray[i];
+ // move default theme first, if it is not already there.
+ if ( ( entry->PkgID() == iDefaultSkinPID ) && ( i != 0 ) )
+ {
+ // Default skin found.
+ iSkinArray.Remove( i );
+ iSkinArray.Insert( entry, 0 );
+ entry = NULL; // this is not owned by us.
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CPslnSkinStore::Find
+// -----------------------------------------------------------------------------
+//
+CPslnSkinEntry* CPslnSkinStore::Find( const TAknsPkgID& aPID,
+ TAknSkinSrvSkinPackageLocation aLocation )
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::Find");
+ TBool allLocations = ( aLocation == EAknsSrvAll );
+ CPslnSkinEntry* entry = NULL;
+
+ for( TInt i = 0; i < iSkinArray.Count(); i++ )
+ {
+ entry = iSkinArray[i];
+
+ // If PID matches AND
+ // location mathes (or is looking from all locations).
+ if( ( entry && entry->PkgID() == aPID ) &&
+ ( ( allLocations ) ||
+ ( entry->Location() == aLocation ) ) )
+ {
+ // this entry is the one we are looking for.
+ break;
+ }
+ else
+ {
+ entry = NULL;
+ }
+ }
+
+ return entry;
+ }
+
+// -----------------------------------------------------------------------------
+// CPslnSkinStore::UpdateOrAddL
+// -----------------------------------------------------------------------------
+//
+CPslnSkinEntry* CPslnSkinStore::UpdateOrAddL(
+ CAknsSrvSkinInformationPkg* aInfo, RFs& aFsSession )
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::UpdateOrAddL");
+
+ if( !aInfo )
+ {
+ User::Leave( KErrArgument );
+ }
+ CleanupStack::PushL( aInfo );
+
+ CPslnSkinEntry* entry = Find( aInfo->PID(),
+ CPslnSkinEntry::LocationFromPath( aInfo->IniFileDirectory() ) );
+
+#ifdef RD_MULTIPLE_DRIVE
+ TInt drive = EDriveC;
+ TUint driveStatus = 0;
+ TFileName fileName;
+#endif // RD_MULTIPLE_DRIVE
+
+ if( entry )
+ {
+#ifdef RD_MULTIPLE_DRIVE
+ entry->GetSkinPath( fileName );
+ User::LeaveIfError( RFs::CharToDrive( fileName[0], drive ) );
+ User::LeaveIfError( DriveInfo::GetDriveStatus(
+ aFsSession, drive, driveStatus ) );
+ if ( driveStatus & DriveInfo::EDriveExternallyMountable &&
+ driveStatus & DriveInfo::EDriveRemovable )
+ {
+ entry->SetMemoryCardFlag( ETrue );
+ }
+ else if ( driveStatus & DriveInfo::EDriveExternallyMountable )
+ {
+ entry->SetMassDriveFlag( ETrue );
+ }
+#endif // RD_MULTIPLE_DRIVE
+
+ entry->SetProtection( aInfo->ProtectionType() );
+ CleanupStack::PopAndDestroy( aInfo );
+ }
+ else
+ {
+ // Ownership of aInfo is transferred to CPslnSkinEntry.
+ entry = CPslnSkinEntry::NewL( aInfo );
+ CleanupStack::Pop( aInfo );
+ CleanupStack::PushL( entry );
+
+#ifdef RD_MULTIPLE_DRIVE
+ entry->GetSkinPath( fileName );
+ User::LeaveIfError( RFs::CharToDrive( fileName[0], drive ) );
+ User::LeaveIfError( DriveInfo::GetDriveStatus(
+ aFsSession, drive, driveStatus ) );
+ if ( driveStatus & DriveInfo::EDriveExternallyMountable &&
+ driveStatus & DriveInfo::EDriveRemovable )
+ {
+ entry->SetMemoryCardFlag( ETrue );
+ }
+ else if ( driveStatus & DriveInfo::EDriveExternallyMountable )
+ {
+ entry->SetMassDriveFlag( ETrue );
+ }
+#endif // RD_MULTIPLE_DRIVE
+
+ // Using Append instead of InsertInOrderAllowRepeats, since localized
+ // names are not fetched yet for all the items.
+ User::LeaveIfError( iSkinArray.Append( entry ) );
+ CleanupStack::Pop( entry );
+ }
+
+ return entry;
+ }
+
+// -----------------------------------------------------------------------------
+// CPslnSkinStore::CreateNameArray
+// -----------------------------------------------------------------------------
+//
+RPointerArray<CPslnSkinNameEntry>* CPslnSkinStore::CreateNameArrayL()
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::CreateNameArray");
+ RPointerArray<CPslnSkinNameEntry>* array =
+ new RPointerArray<CPslnSkinNameEntry>();
+
+ CleanupStack::PushL( TCleanupItem( CleanupDeleteArray, array ) );
+
+ for( TInt i = 0; i < iSkinArray.Count(); i++ )
+ {
+ AppendEntryL( *array, i );
+ }
+ CleanupStack::Pop(); // TCleanupItem
+
+ return array;
+ }
+
+// -----------------------------------------------------------------------------
+// CPslnSkinStore::UpdateAllSkinsL
+// -----------------------------------------------------------------------------
+//
+void CPslnSkinStore::UpdateAllSkinsL(
+ TAknSkinSrvSkinPackageLocation aLocation, RFs& aFsSession )
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::UpdateAllSkinsL");
+ CArrayPtr<CAknsSrvSkinInformationPkg>* srvArray =
+ iModel->SkinSrvSession().EnumerateSkinPackagesL( aLocation );
+
+ while( srvArray && srvArray->Count() )
+ {
+ CAknsSrvSkinInformationPkg* info = srvArray->At( 0 );
+ TRAP_IGNORE( UpdateOrAddL( info, aFsSession )->SetDeleteFlag( EFalse ) );
+ srvArray->Delete( 0 );
+ }
+
+ if ( srvArray )
+ {
+ srvArray->ResetAndDestroy();
+ }
+ delete srvArray;
+ }
+
+// -----------------------------------------------------------------------------
+// Appends entry to array.
+// -----------------------------------------------------------------------------
+//
+void CPslnSkinStore::AppendEntryL(
+ RPointerArray<CPslnSkinNameEntry>& aArray, const TInt aIndex )
+ {
+ PSLN_TRACE_DEBUG("CPslnSkinStore::AppendEntryL");
+ // Get entry.
+ CPslnSkinEntry* entry = iSkinArray[aIndex];
+
+ // Get name entry.
+ CPslnSkinNameEntry* nameEntry = NULL;
+ nameEntry = CPslnSkinNameEntry::NewL();
+ nameEntry->SetPkgID( entry->PkgID() );
+ nameEntry->SetLocation( entry->Location() );
+ PSLN_TRACE_DEBUG("CPslnSkinStore::AppendEntryL.2");
+
+ // Get name for the entry.
+ HBufC* skinName = HBufC::NewLC( KMaxName );
+ TPtr skinNamePtr = skinName->Des();
+ entry->GetName( skinNamePtr );
+ nameEntry->SetNameL( skinNamePtr );
+ CleanupStack::PopAndDestroy( skinName );
+
+ if( aArray.Append( nameEntry ) )
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+
+// End of File