psln/pslnengine/src/PslnSkinStore.cpp
changeset 0 2f259fa3e83a
child 38 c52421ed5f07
--- /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