ui/uiengine/medialists/src/glxmedialist.cpp
branchRCL_3
changeset 59 8e5f6eea9c9f
equal deleted inserted replaced
57:ea65f74e6de4 59:8e5f6eea9c9f
       
     1 /*
       
     2 * Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    List of media items
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 #include "glxmedialist.h"
       
    22 
       
    23 #include <glxcollectionplugintype.hrh>
       
    24 
       
    25 #include <glxassert.h>
       
    26 #include <glxcollectiongeneraldefs.h>
       
    27 #include <glxerrorposter.h>
       
    28 #include <mpxcollectionmessage.h>
       
    29 #include <mpxcollectionmessagedefs.h>
       
    30 #include <mpxcollectionutility.h>
       
    31 #include <mpxcommandgeneraldefs.h>
       
    32 #include <mpxmessagegeneraldefs.h>
       
    33 #include <glxtracer.h>
       
    34 #include <glxlog.h>
       
    35 #include "glxcachemanager.h"
       
    36 #include "glxmedialistarray.h"
       
    37 #include "glxnavigablelist.h"
       
    38 #include "mglxfetchcontext.h"
       
    39 #include "mglxmedialistobserver.h"
       
    40 #include "glxmediastaticitemdefs.h"
       
    41 
       
    42 /**
       
    43  * Min & Max wait interval for a modify event, in microseconds
       
    44  * This is to allow thumbnail manager to procees the event first.
       
    45  */
       
    46 const TInt KModifyEventMinWaitInterval = 2000000;
       
    47 const TInt KModifyEventMaxWaitInterval = 3000000;
       
    48 /**
       
    49  * Maximum items count for minimum wait interval.
       
    50  */
       
    51 const TInt KMaxItemsCount = 500;
       
    52 namespace NGlxMediaList
       
    53     {
       
    54     /**
       
    55      * Interface to notify observers. Allows different notifications to use
       
    56      * the same (complicated) iteration loop
       
    57      */
       
    58     class TNotificationStrategy 
       
    59         {
       
    60         public:
       
    61             TNotificationStrategy( MGlxMediaList& aList )
       
    62                     : iList( aList )
       
    63                 {
       
    64                 }
       
    65                 
       
    66             /** 
       
    67              * Notify observer
       
    68              * @param aObserver Observer to notify 
       
    69              */
       
    70             virtual void NotifyL( MGlxMediaListObserver& aObserver ) = 0;
       
    71         
       
    72         protected:
       
    73             MGlxMediaList& iList;
       
    74         };
       
    75 
       
    76     /**
       
    77      * Notification strategy for items being added
       
    78      */
       
    79     class TItemsAddedNotificationStrategy : public TNotificationStrategy 
       
    80         {
       
    81         public:
       
    82             /**
       
    83              * Constructor 
       
    84              * @param aFirstAddedIndex Index of the first item added
       
    85              * @param aCount number of items added
       
    86              * @param aList Media list that sends the notification
       
    87              */
       
    88             TItemsAddedNotificationStrategy( TInt aFirstAddedIndex, 
       
    89                 TInt aCount, MGlxMediaList& aList )
       
    90                     : TNotificationStrategy( aList )
       
    91                 {
       
    92                 iFirstAddedIndex = aFirstAddedIndex;
       
    93                 iLastAddedIndex = aFirstAddedIndex + aCount - 1;
       
    94                 }
       
    95                 
       
    96             // From MGlxNotificationStrategy
       
    97             void NotifyL( MGlxMediaListObserver& aObserver )
       
    98                 {
       
    99                 aObserver.HandleItemAddedL( iFirstAddedIndex, iLastAddedIndex, 
       
   100                     &iList );
       
   101                 }        
       
   102                 
       
   103         private:
       
   104             /// Index of the first item added
       
   105             TInt iFirstAddedIndex;
       
   106             /// Index of the last item added
       
   107             TInt iLastAddedIndex;
       
   108         };
       
   109 
       
   110     /**
       
   111      * Notification strategy for items being removed
       
   112      */
       
   113     class TItemsRemovedNotificationStrategy : public TNotificationStrategy 
       
   114         {
       
   115         public:
       
   116             /**
       
   117              * Constructor 
       
   118              * @param aFirstRemovedIndex Index of the first item removed
       
   119              * @param aCount number of items removed
       
   120              * @param aList Media list that sends the notification
       
   121              */
       
   122             TItemsRemovedNotificationStrategy( TInt aFirstRemovedIndex, 
       
   123                 TInt aCount, MGlxMediaList& aList )
       
   124                     : TNotificationStrategy( aList )
       
   125                 {
       
   126                 iFirstRemovedIndex = aFirstRemovedIndex;
       
   127                 iLastRemovedIndex = aFirstRemovedIndex + aCount - 1;
       
   128                 }
       
   129                 
       
   130             // From MGlxNotificationStrategy
       
   131             void NotifyL( MGlxMediaListObserver& aObserver )
       
   132                 {
       
   133                 aObserver.HandleItemRemovedL( iFirstRemovedIndex, 
       
   134                     iLastRemovedIndex, &iList );
       
   135                 }        
       
   136                 
       
   137         private:
       
   138             /// Index of the first item removed
       
   139             TInt iFirstRemovedIndex;
       
   140             /// Index of the last item removed
       
   141             TInt iLastRemovedIndex;
       
   142         };
       
   143 
       
   144     /**
       
   145      * Notification strategy for focus being changed
       
   146      */
       
   147     class TFocusChangedNotificationStrategy : public TNotificationStrategy 
       
   148         {
       
   149         public:
       
   150             /**
       
   151              * Constructor 
       
   152              * @param aFirstRemovedIndex Index of the first item removed
       
   153              * @param aCount number of items removed
       
   154              * @param aList Media list that sends the notification
       
   155              */
       
   156             TFocusChangedNotificationStrategy( NGlxListDefs::TFocusChangeType aType, 
       
   157                 TInt aNewIndex, TInt aOldIndex, MGlxMediaList& aList )
       
   158                     : TNotificationStrategy( aList )
       
   159                 {
       
   160                 iType = aType;
       
   161                 iNewIndex = aNewIndex;
       
   162                 iOldIndex = aOldIndex;
       
   163                 }
       
   164                 
       
   165             // From MGlxNotificationStrategy
       
   166             void NotifyL( MGlxMediaListObserver& aObserver )
       
   167                 {
       
   168                 aObserver.HandleFocusChangedL( iType, iNewIndex, iOldIndex, &iList );
       
   169                 }        
       
   170                 
       
   171         private:
       
   172             /// Focus change type
       
   173             NGlxListDefs::TFocusChangeType iType;
       
   174             /// New focus index
       
   175             TInt iNewIndex;
       
   176             /// Old focus index
       
   177             TInt iOldIndex;
       
   178         };
       
   179 
       
   180     /**
       
   181      * Notification strategy for selection being changed
       
   182      */
       
   183     class TItemSelectedNotificationStrategy : public TNotificationStrategy 
       
   184         {
       
   185         public:
       
   186             /**
       
   187              * Constructor 
       
   188              * @param aIndex Index of item being selected/deselected
       
   189              * @param aSelected Selection/deselection info
       
   190              * @param aList Media list that sends the notification
       
   191              */
       
   192             TItemSelectedNotificationStrategy( TInt aIndex, TBool aSelected,
       
   193                 MGlxMediaList& aList )
       
   194                     : TNotificationStrategy( aList )
       
   195                 {
       
   196                 iIndex = aIndex;
       
   197                 iSelected = aSelected;
       
   198                 }
       
   199                 
       
   200             // From MGlxNotificationStrategy
       
   201             void NotifyL( MGlxMediaListObserver& aObserver )
       
   202                 {
       
   203                 aObserver.HandleItemSelectedL( iIndex, iSelected, &iList );
       
   204                 }        
       
   205                 
       
   206         private:
       
   207             /// Index of item being selected/deselected
       
   208             TInt iIndex;
       
   209             /// Selection/deselection info
       
   210             TBool iSelected;
       
   211         };    
       
   212 
       
   213     /**
       
   214      * Notification strategy for command being completed
       
   215      */
       
   216     class TCommandCompletedNotificationStrategy : public TNotificationStrategy 
       
   217         {
       
   218         public:
       
   219             /**
       
   220              * Constructor 
       
   221              * @param aSessionId Session id of client that issued the command
       
   222              * @param aCommand Command which was completed
       
   223              * @param aError Error code from execution of the command
       
   224              * @param aList Media list that sends the notification
       
   225              */
       
   226             TCommandCompletedNotificationStrategy( TAny* aSessionId, 
       
   227                 CMPXCommand* aCommand, TInt aError, MGlxMediaList& aList )
       
   228                     : TNotificationStrategy( aList )
       
   229                 {
       
   230                 iSessionId = aSessionId;
       
   231                 iCommand = aCommand;
       
   232                 iError = aError;
       
   233                 }
       
   234                 
       
   235             // From MGlxNotificationStrategy
       
   236             void NotifyL( MGlxMediaListObserver& aObserver )
       
   237                 {
       
   238                 /// @todo: make this call leaving
       
   239                 aObserver.HandleCommandCompleteL( iSessionId, iCommand, iError, &iList );
       
   240                 }        
       
   241 
       
   242         private:
       
   243             /// Session id of client that issued the command
       
   244             TAny* iSessionId;
       
   245             /// Command which was completed
       
   246             CMPXCommand* iCommand;
       
   247             /// Error code 
       
   248             TBool iError;
       
   249         };            
       
   250         
       
   251         
       
   252 
       
   253     /**
       
   254      * Notification strategy for list population
       
   255      */
       
   256     class TListPopulatedNotificationStrategy : public TNotificationStrategy 
       
   257         {
       
   258         public:
       
   259             /**
       
   260              * Constructor 
       
   261              * @param aList Media list that sends the notification
       
   262              */
       
   263             TListPopulatedNotificationStrategy ( MGlxMediaList& aList )
       
   264                     : TNotificationStrategy( aList )
       
   265                 {
       
   266                 }
       
   267                 
       
   268             // From MGlxNotificationStrategy
       
   269             void NotifyL( MGlxMediaListObserver& aObserver )
       
   270                 {
       
   271                 aObserver.HandlePopulatedL( &iList );
       
   272                 }        
       
   273         }; 
       
   274 
       
   275     /**
       
   276      * Notification strategy for messages
       
   277      */
       
   278     class TMessageNotificationStrategy : public TNotificationStrategy
       
   279         {
       
   280         public:
       
   281             /**
       
   282              * Constructor
       
   283              * @param aList Media list that sends the notification
       
   284              */
       
   285             TMessageNotificationStrategy ( const CMPXMessage& aMessage, MGlxMediaList& aList ) :
       
   286                     TNotificationStrategy( aList ),
       
   287                     iMessage( aMessage )
       
   288                 {
       
   289                 }
       
   290 
       
   291             // From MGlxNotificationStrategy
       
   292             void NotifyL( MGlxMediaListObserver& aObserver )
       
   293                 {
       
   294                 aObserver.HandleMessageL( iMessage, &iList );
       
   295                 }
       
   296 
       
   297         private:
       
   298             /// Message which was received
       
   299             const CMPXMessage& iMessage;
       
   300         };
       
   301     } // namespace NGlxMediaList
       
   302     
       
   303 using namespace NGlxMediaList;
       
   304 
       
   305 // -----------------------------------------------------------------------------
       
   306 // Returns a new/existing media list interface
       
   307 // -----------------------------------------------------------------------------
       
   308 CGlxMediaList* CGlxMediaList::InstanceL(const CMPXCollectionPath& aPath, 
       
   309         const TGlxHierarchyId& aHierarchyId, CMPXFilter* aFilter)
       
   310     {
       
   311     TRACER("CGlxMediaList::InstanceL" );
       
   312     
       
   313     CGlxMediaListArray* mediaListArray = CGlxMediaListArray::InstanceL();
       
   314     CleanupClosePushL(*mediaListArray);
       
   315     
       
   316     RPointerArray<CGlxMediaList>& mediaLists =  mediaListArray->Array();
       
   317 
       
   318     TInt matchIndex = KErrNotFound;
       
   319     CGlxMediaList* mediaListInstance = NULL; // List to return
       
   320 
       
   321     // Try to find an existing media list to return (by matching the path)
       
   322     TInt listCount = mediaLists.Count();
       
   323     for (TInt count = 0; count < listCount; ++count)
       
   324         {
       
   325         CGlxMediaList* mediaList = mediaLists[count];
       
   326 
       
   327         // See if path's and hierarchy id's match
       
   328         // Filter is ignored
       
   329         if (mediaList->Equals(aPath) && (mediaList->iHierarchyId == aHierarchyId))
       
   330             {
       
   331             // Found a match
       
   332             matchIndex = count;
       
   333             mediaListInstance = mediaList;
       
   334             break;
       
   335             }
       
   336         }
       
   337 
       
   338     // Create a new media list if could not use an existing one
       
   339     if (matchIndex == KErrNotFound)
       
   340         {
       
   341         __ASSERT_DEBUG(!mediaListInstance, Panic(EGlxPanicAlreadyInitialised));
       
   342 
       
   343         mediaListInstance = CGlxMediaList::NewLC(aHierarchyId);
       
   344 
       
   345         // Set specified filter (if any) before opening the collection to path
       
   346         mediaListInstance->SetFilterL(aFilter);
       
   347         mediaListInstance->OpenL(aPath);
       
   348 
       
   349         // Insert media list as highest priority
       
   350         mediaLists.InsertL(mediaListInstance, 0);
       
   351         CleanupStack::Pop(mediaListInstance);
       
   352         }
       
   353     else
       
   354         {
       
   355         __ASSERT_DEBUG(mediaListInstance, Panic(EGlxPanicNullPointer));
       
   356 
       
   357         // Match found, set as highest priority
       
   358         mediaLists.InsertL(mediaListInstance, 0);
       
   359         mediaLists.Remove(matchIndex + 1);
       
   360         }
       
   361 
       
   362     mediaListInstance->AddReference(); // Add user
       
   363 
       
   364     CleanupStack::PopAndDestroy(mediaListArray);
       
   365     
       
   366     return mediaListInstance;
       
   367     }
       
   368 
       
   369 // -----------------------------------------------------------------------------
       
   370 // Gives an array of all media lists in current use
       
   371 // -----------------------------------------------------------------------------
       
   372 RPointerArray<CGlxMediaList>& CGlxMediaList::MediaListsL()
       
   373     {
       
   374     TRACER("CGlxMediaList::MediaListsL" );
       
   375     
       
   376     CGlxMediaListArray* mediaListArray = CGlxMediaListArray::InstanceL();
       
   377     RPointerArray<CGlxMediaList>& array = mediaListArray->Array();
       
   378     mediaListArray->Close();
       
   379     return array;
       
   380     }
       
   381 
       
   382 // -----------------------------------------------------------------------------
       
   383 // OfferMedia
       
   384 // -----------------------------------------------------------------------------
       
   385 //
       
   386 void CGlxMediaList::OfferMedia(const TGlxIdSpaceId& aIdSpaceId, CGlxMedia* aMedia) 
       
   387     {
       
   388     TRACER("CGlxMediaList::OfferMedia" );
       
   389 
       
   390     // try to find the matching item in this list
       
   391     TInt index = Index( aIdSpaceId, aMedia->Id() );
       
   392     // if matching item found, link media object
       
   393     if ( KErrNotFound != index )
       
   394         {
       
   395         TGlxMedia& item = iItemList->Item( index );
       
   396 
       
   397         // static items should not be offered
       
   398         if ( !item.IsStatic() )
       
   399             {
       
   400             item.SetMedia( aMedia, *this, index );
       
   401             }
       
   402         }
       
   403     }
       
   404 
       
   405 // -----------------------------------------------------------------------------
       
   406 // NotifyThumbnailAvailableL
       
   407 // -----------------------------------------------------------------------------
       
   408 //
       
   409 void CGlxMediaList::HandleAttributesAvailableL(TInt aIndex, 
       
   410         const RArray<TMPXAttribute>& aAttributes)
       
   411     {
       
   412     TRACER("CGlxMediaList::HandleAttributesAvailableL" );
       
   413 
       
   414     __ASSERT_DEBUG(aIndex >= 0, Panic(EGlxPanicLogicError)); // Must exist
       
   415     // Need to get exact count of iItemListObservers at
       
   416     // every iteration because it is possible that 
       
   417     // RemoveMediaListObserver might call during this iteration
       
   418     for (TInt i = 0; i < iItemListObservers.Count(); i++)
       
   419         {
       
   420         iItemListObservers[i]->HandleAttributesAvailableL(aIndex, aAttributes, this);
       
   421         }
       
   422     }
       
   423 
       
   424 // -----------------------------------------------------------------------------
       
   425 // Ask if the list has any requests to place
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 void CGlxMediaList::AttributeRequestL(RArray<TInt>& aItemIndexes,
       
   429 		RArray<TGlxMediaId>& aItemIds, 
       
   430         RArray<TMPXAttribute>& aAttributes, 
       
   431         CMPXAttributeSpecs*& aDetailedSpecs) const
       
   432     {
       
   433     TRACER("CGlxMediaList::AttributeRequestL" );
       
   434     
       
   435     // Find the highest priority context that has something to request
       
   436     TInt count = iContexts.Count();
       
   437     for (TInt i = 0; i < count; i++)
       
   438         {
       
   439         // Determine items (referenced by index) to request attributes for
       
   440         iContexts[i].iContext->AttributeRequestL(this, aItemIndexes, aAttributes, aDetailedSpecs);
       
   441 
       
   442         // Map item indices to item Ids
       
   443         TInt itemIndicesCount = aItemIndexes.Count();
       
   444         for (TInt itemIndicesCounter = 0; itemIndicesCounter < itemIndicesCount; ++itemIndicesCounter)
       
   445             {
       
   446             const TGlxMedia& item = iItemList->Item( aItemIndexes[itemIndicesCounter] );
       
   447             if (!item.IsStatic())
       
   448                 {
       
   449                 aItemIds.AppendL( item.Id() );
       
   450                 }
       
   451             }
       
   452 
       
   453         // break if context has something to request
       
   454         if (itemIndicesCount > 0)
       
   455             {
       
   456             break;
       
   457             }
       
   458         }
       
   459     }
       
   460 
       
   461 // ---------------------------------------------------------------------------
       
   462 // AllAttributesL
       
   463 // ---------------------------------------------------------------------------
       
   464 //
       
   465 void CGlxMediaList::GetRequiredAttributesL(TInt aIndex, RArray<TMPXAttribute>& aAttributes)
       
   466     {
       
   467     TRACER("CGlxMediaList::GetRequiredAttributesL" );
       
   468     
       
   469     TLinearOrder<TMPXAttribute> orderer (&AttributeOrder);
       
   470 
       
   471     // Determine all attributes to request for an item, for all contexts
       
   472     TInt contextCount = iContexts.Count();
       
   473     for ( TInt contextIndex = 0; contextIndex < contextCount; contextIndex++ )
       
   474         {
       
   475         const MGlxFetchContext* context = iContexts[contextIndex].iContext;
       
   476         if ( context )
       
   477             {
       
   478             // Determine all attributes to request for an item, for this context
       
   479             context->AllAttributesL(this, aIndex, aAttributes);
       
   480 
       
   481             }
       
   482         }
       
   483     }
       
   484 
       
   485 // ---------------------------------------------------------------------------
       
   486 // AttributeOrder
       
   487 // ---------------------------------------------------------------------------
       
   488 //
       
   489 TInt CGlxMediaList::AttributeOrder(const TMPXAttribute& aItem1, 
       
   490         const TMPXAttribute& aItem2) 
       
   491     {
       
   492     TRACER("CGlxMediaList::AttributeOrder");
       
   493             
       
   494     TInt contentId1 = aItem1.ContentId();
       
   495     TInt contentId2 = aItem2.ContentId();
       
   496 
       
   497     if (contentId1 < contentId2) 
       
   498         {
       
   499         return -1;
       
   500         }
       
   501 
       
   502     if (contentId1 > contentId2) 
       
   503         {
       
   504         return 1;
       
   505         }
       
   506 
       
   507     TUint attributeId1 = aItem1.AttributeId();
       
   508     TUint attributeId2 = aItem2.AttributeId();
       
   509 
       
   510     if (attributeId1 < attributeId2) 
       
   511         {
       
   512         return -1;
       
   513         }
       
   514 
       
   515     if (attributeId1 > attributeId2) 
       
   516         {
       
   517         return 1;
       
   518         }
       
   519 
       
   520     return 0;
       
   521     }
       
   522 
       
   523 // ---------------------------------------------------------------------------
       
   524 // AttributeOrderReversed
       
   525 // ---------------------------------------------------------------------------
       
   526 //
       
   527 TInt CGlxMediaList::AttributeOrderReversed(const TMPXAttribute& aItem1, 
       
   528         const TMPXAttribute& aItem2) 
       
   529     {
       
   530     TRACER("CGlxMediaList::AttributeOrderReversed");
       
   531     
       
   532     return -AttributeOrder(aItem1, aItem2);
       
   533     }
       
   534 
       
   535 // ---------------------------------------------------------------------------
       
   536 // Remore references to the media object
       
   537 // ---------------------------------------------------------------------------
       
   538 //
       
   539 void CGlxMediaList::RemoveReference( TInt aIndex )
       
   540     {
       
   541     TRACER( "CGlxMediaList::RemoveReference" );
       
   542     GLX_ASSERT_DEBUG( iItemList, Panic( EGlxPanicNotInitialised ), 
       
   543         "not ready to remove references" );
       
   544     
       
   545     GLX_LOG_INFO1( "CGlxMediaList::RemoveReference %d", aIndex );
       
   546     iItemList->RemoveReference( aIndex );
       
   547     }
       
   548 
       
   549 // ---------------------------------------------------------------------------
       
   550 // HandleError
       
   551 // ---------------------------------------------------------------------------
       
   552 //
       
   553 void CGlxMediaList::HandleError(TInt aError)
       
   554     {
       
   555     TRACER( "CGlxMediaList::HandleError");    
       
   556     GLX_LOG_INFO1( "CGlxMediaList::HandleError %d", aError );
       
   557     TInt obsCount = iItemListObservers.Count();
       
   558     for (TInt obsIdx = 0; obsIdx < obsCount; ++obsIdx)
       
   559         {
       
   560         iItemListObservers[obsIdx]->HandleError(aError);
       
   561         }
       
   562     }
       
   563 
       
   564 // -----------------------------------------------------------------------------
       
   565 // Releases a media list interface
       
   566 // -----------------------------------------------------------------------------
       
   567 void CGlxMediaList::Close()
       
   568     {
       
   569     TRACER( "CGlxMediaList::Close" );
       
   570     
       
   571     RPointerArray<CGlxMediaList>& mediaLists = iMediaListArray->Array();
       
   572 
       
   573     TInt listCount = mediaLists.Count();
       
   574     for (TInt count = 0; count < listCount; ++count)
       
   575         {
       
   576         CGlxMediaList* mediaList = mediaLists[count];
       
   577 
       
   578         if (mediaList == this)
       
   579             {
       
   580             TInt referenceCount = mediaList->RemoveReference();
       
   581             if (referenceCount == 0)
       
   582                 {
       
   583                 mediaLists.Remove(count);
       
   584                 mediaLists.Compress();
       
   585 
       
   586                 delete mediaList;
       
   587                 break;
       
   588                 }
       
   589             }
       
   590         }
       
   591     }
       
   592 
       
   593 // -----------------------------------------------------------------------------
       
   594 // Id
       
   595 // From MGlxMediaList
       
   596 // -----------------------------------------------------------------------------
       
   597 //
       
   598 TGlxMediaListId CGlxMediaList::Id() const
       
   599     {
       
   600     TRACER( "CGlxMediaList::Id" );
       
   601     
       
   602     return TGlxMediaListId((unsigned int)(void*)this);	
       
   603     }
       
   604 
       
   605 // -----------------------------------------------------------------------------
       
   606 // Count
       
   607 // From MGlxMediaList
       
   608 // -----------------------------------------------------------------------------
       
   609 //
       
   610 TInt CGlxMediaList::Count(NGlxListDefs::TCountType aType) const
       
   611     {
       
   612     TRACER("CGlxMediaList::Count");
       
   613     
       
   614     return iItemList->Count( aType );    
       
   615     }
       
   616 
       
   617 // -----------------------------------------------------------------------------
       
   618 // FocusIndex
       
   619 // From MGlxMediaList
       
   620 // -----------------------------------------------------------------------------
       
   621 //
       
   622 TInt CGlxMediaList::FocusIndex() const
       
   623     {
       
   624     TRACER("CGlxMediaList::FocusIndex");
       
   625     
       
   626     return iItemList->FocusIndex();    
       
   627     }
       
   628 
       
   629 // -----------------------------------------------------------------------------
       
   630 // SetFocusL
       
   631 // -----------------------------------------------------------------------------
       
   632 //
       
   633 void CGlxMediaList::SetFocusL(NGlxListDefs::TFocusSetType aType, TInt aValue)
       
   634     {
       
   635     TRACER("CGlxMediaList::SetFocusL");
       
   636     
       
   637     GLX_LOG_INFO1( "CGlxMediaList::SetFocusL %d", aValue );
       
   638     iItemList->SetFocus( aType, aValue );
       
   639     }
       
   640 
       
   641 // -----------------------------------------------------------------------------
       
   642 // Item
       
   643 // From MGlxMediaList
       
   644 // -----------------------------------------------------------------------------
       
   645 //
       
   646 const TGlxMedia& CGlxMediaList::Item(TInt aIndex) const
       
   647     {
       
   648     TRACER("CGlxMediaList::Item");
       
   649     
       
   650     return iItemList->Item( aIndex );    
       
   651     }
       
   652 
       
   653 // -----------------------------------------------------------------------------
       
   654 // Index
       
   655 // From MGlxMediaList
       
   656 // -----------------------------------------------------------------------------
       
   657 //
       
   658 TInt CGlxMediaList::Index(const TGlxIdSpaceId& aIdSpaceId, const TGlxMediaId& aId) const
       
   659     {
       
   660     TRACER("CGlxMediaList::Index");
       
   661     
       
   662     return iItemList->Index( aIdSpaceId, aId );    
       
   663     }
       
   664 
       
   665 // -----------------------------------------------------------------------------
       
   666 // AddMediaListObserverL
       
   667 // From MGlxMediaList
       
   668 // -----------------------------------------------------------------------------
       
   669 //
       
   670 void CGlxMediaList::AddMediaListObserverL(MGlxMediaListObserver* aObserver)
       
   671     {
       
   672     TRACER("CGlxMediaList::AddMediaListObserverL");    
       
   673     GLX_LOG_INFO1( "CGlxMediaList::AddMediaListObserverL(0x%x)", aObserver );
       
   674 
       
   675     // Make sure the observer is not already in the array
       
   676     __ASSERT_DEBUG(iItemListObservers.Find(aObserver) == -1, Panic(EGlxPanicIllegalArgument)); // Observer already added
       
   677 
       
   678     iItemListObservers.AppendL(aObserver);
       
   679     }
       
   680 
       
   681 // -----------------------------------------------------------------------------
       
   682 // RemoveMediaListObserver
       
   683 // From MGlxMediaList
       
   684 // -----------------------------------------------------------------------------
       
   685 //	
       
   686 void CGlxMediaList::RemoveMediaListObserver(MGlxMediaListObserver* aObserver)
       
   687     {
       
   688     TRACER("CGlxMediaList::RemoveMediaListObserver");    
       
   689     GLX_LOG_INFO1( "CGlxMediaList::RemoveMediaListObserver(0x%x)", aObserver );
       
   690 
       
   691     TInt index = iItemListObservers.Find(aObserver);
       
   692 
       
   693     // Make sure the observer is in the array
       
   694     // LOG THIS! __ASSERT_DEBUG(index != -1, Panic(EGlxPanicIllegalArgument)); // No such observer
       
   695 
       
   696     if (index != KErrNotFound) 
       
   697         {
       
   698         iItemListObservers.Remove(index);	
       
   699         }
       
   700     }
       
   701 
       
   702 // -----------------------------------------------------------------------------
       
   703 // AddContextL
       
   704 // From MGlxMediaList
       
   705 // -----------------------------------------------------------------------------
       
   706 //	
       
   707 void CGlxMediaList::AddContextL(const MGlxFetchContext* aContext, 
       
   708         TInt aPriority)
       
   709     {
       
   710     TRACER("CGlxMediaList::AddContextL");    
       
   711     GLX_LOG_INFO1( "CGlxMediaList::AddContextL(0x%x)", aContext );
       
   712 
       
   713     if (!aContext)
       
   714         {
       
   715         return;
       
   716         }
       
   717 
       
   718     // Add the new context in priority order
       
   719     TContext context;
       
   720     context.iContext = aContext;
       
   721     context.iPriority = aPriority;
       
   722 
       
   723 #ifdef _DEBUG
       
   724 
       
   725     // Make sure no duplicate entries
       
   726     TIdentityRelation<CGlxMediaList::TContext> match (&CGlxMediaList::TContext::Match);
       
   727     __ASSERT_DEBUG(iContexts.Find(context, match) == KErrNotFound, Panic(EGlxPanicAlreadyAdded));
       
   728 
       
   729 #endif // _DEBUG
       
   730 
       
   731     TLinearOrder<CGlxMediaList::TContext> orderer (&CGlxMediaList::TContext::Compare);
       
   732     TInt ret = iContexts.InsertInOrderAllowRepeats(context, orderer); 
       
   733     User::LeaveIfError(ret);
       
   734 
       
   735     iManager->HandleWindowChangedL(this);
       
   736     }
       
   737 
       
   738 // -----------------------------------------------------------------------------
       
   739 // RemoveContext
       
   740 // From MGlxMediaList
       
   741 // -----------------------------------------------------------------------------
       
   742 //	
       
   743 void CGlxMediaList::RemoveContext(const MGlxFetchContext* aContext)
       
   744     {
       
   745     TRACER("CGlxMediaList::RemoveContext");    
       
   746     GLX_LOG_INFO1( "CGlxMediaList::RemoveContext(0x%x)", aContext );
       
   747 
       
   748     if (!aContext)
       
   749         {
       
   750         return;
       
   751         }
       
   752 
       
   753     TIdentityRelation<CGlxMediaList::TContext> match (&CGlxMediaList::TContext::Match);
       
   754     TContext context;
       
   755     context.iContext = aContext;
       
   756     context.iPriority = 0;
       
   757     TInt index = iContexts.Find(context, match);
       
   758 
       
   759     // remove the context if it was found, just ignore if its not found
       
   760     if (index != KErrNotFound) 
       
   761         {
       
   762         iContexts.Remove(index);
       
   763         // notify cache manager: garbage collection needs to be run to free the 
       
   764         // items that the removed context required
       
   765         TRAP_IGNORE( iManager->HandleWindowChangedL( this ) );
       
   766         }
       
   767     }
       
   768 
       
   769 // -----------------------------------------------------------------------------
       
   770 // Returns the isolated collection, that is used by this media list
       
   771 // -----------------------------------------------------------------------------
       
   772 //
       
   773 MMPXCollection& CGlxMediaList::Collection() const
       
   774     {
       
   775     TRACER("CGlxMediaList::Collection");
       
   776     __ASSERT_DEBUG(iCollectionUtility != NULL, Panic(EGlxPanicNullPointer));
       
   777     return iCollectionUtility->Collection();
       
   778     }
       
   779 
       
   780 // -----------------------------------------------------------------------------
       
   781 // Returns the current path
       
   782 // -----------------------------------------------------------------------------
       
   783 CMPXCollectionPath* CGlxMediaList::PathLC(NGlxListDefs::TPathType aType) const
       
   784     {
       
   785     TRACER("CGlxMediaList::PathLC");  
       
   786 
       
   787     CMPXCollectionPath* path = CMPXCollectionPath::NewL();
       
   788     CleanupStack::PushL(path);
       
   789 
       
   790     // Add navigation to parent
       
   791     PathPopulateParentL( *path );
       
   792 
       
   793     if ( aType == NGlxListDefs::EPathAllOrSelection ||
       
   794          aType == NGlxListDefs:: EPathFocusOrSelection )
       
   795         {
       
   796         // If selection exists, add only selection
       
   797         // Otherwise add all items or focused item
       
   798         if ( iItemList->SelectedItemIndices().Count() > 0 )
       
   799             {
       
   800             PathPopulateSelectionL( *path );
       
   801             }
       
   802         else
       
   803             {
       
   804             if ( aType == NGlxListDefs::EPathAllOrSelection )
       
   805                 {
       
   806                 PathPopulateAllL( *path );
       
   807                 }
       
   808             else if ( aType == NGlxListDefs:: EPathFocusOrSelection )
       
   809                 {
       
   810                 PathPopulateFocusL( *path );
       
   811                 }
       
   812             }
       
   813         }
       
   814 
       
   815     return path;
       
   816     }
       
   817 
       
   818 // -----------------------------------------------------------------------------
       
   819 // Determines if an item has been selected
       
   820 // -----------------------------------------------------------------------------
       
   821 TBool CGlxMediaList::IsSelected(TInt aIndex) const
       
   822     {
       
   823     TRACER("CGlxMediaList::IsSelected");    
       
   824     GLX_LOG_INFO1( "CGlxMediaList::IsSelected %d", aIndex );
       
   825     return iItemList->IsSelected( aIndex );
       
   826     }
       
   827 
       
   828 // -----------------------------------------------------------------------------
       
   829 // Handles item selection/deselection
       
   830 // -----------------------------------------------------------------------------
       
   831 void CGlxMediaList::SetSelectedL(TInt aIndex, TBool aSelected)
       
   832     {
       
   833     TRACER("CGlxMediaList::SetSelectedL");    
       
   834     GLX_LOG_INFO2( "CGlxMediaList::SetSelectedL %d:%d", aIndex, aSelected );
       
   835     iItemList->SetSelectedL( aIndex, aSelected );
       
   836     }
       
   837 
       
   838 // -----------------------------------------------------------------------------
       
   839 // Returns selection count
       
   840 // -----------------------------------------------------------------------------
       
   841 TInt CGlxMediaList::SelectionCount() const
       
   842     {
       
   843     TRACER("CGlxMediaList::SelectionCount");
       
   844     
       
   845     return iItemList->SelectedItemIndices().Count();
       
   846     }
       
   847 
       
   848 // -----------------------------------------------------------------------------
       
   849 // Returns selected item index from selection
       
   850 // -----------------------------------------------------------------------------
       
   851 TInt CGlxMediaList::SelectedItemIndex(TInt aSelectionIndex) const
       
   852     {
       
   853     TRACER("CGlxMediaList::SelectedItemIndex");    
       
   854     GLX_LOG_INFO1( "CGlxMediaList::SelectedItemIndex %d", aSelectionIndex );
       
   855     return iItemList->SelectedItemIndices()[ aSelectionIndex ];
       
   856     }
       
   857 
       
   858 // -----------------------------------------------------------------------------
       
   859 // Sends a command to the collection
       
   860 // -----------------------------------------------------------------------------
       
   861 void CGlxMediaList::CommandL(CMPXCommand& aCommand)
       
   862     {
       
   863     TRACER("CGlxMediaList::CommandL");
       
   864 
       
   865     // Multiple commands should not happen
       
   866     __ASSERT_DEBUG( !iCommandPending, Panic( EGlxPanicLogicError ) );
       
   867 
       
   868     // Send the command
       
   869     Collection().CommandL( aCommand );
       
   870 
       
   871     // Use the sessionId to indicate that a command is pending
       
   872     __ASSERT_DEBUG( aCommand.IsSupported( KMPXCommandGeneralSessionId ), 
       
   873                     Panic( EGlxPanicLogicError ) );
       
   874 
       
   875     iCommandPending = aCommand.ValueTObjectL<TAny*>( KMPXCommandGeneralSessionId );
       
   876     }
       
   877 
       
   878 // -----------------------------------------------------------------------------
       
   879 // Checks if a command is active or not
       
   880 // -----------------------------------------------------------------------------
       
   881 TBool CGlxMediaList::IsCommandActive()
       
   882     {
       
   883     TRACER("CGlxMediaList::IsCommandActive");
       
   884 
       
   885     if(iCommandPending)
       
   886         {
       
   887          return ETrue;  
       
   888         }
       
   889     else
       
   890         {
       
   891          return EFalse;
       
   892         }
       
   893     }
       
   894 
       
   895 
       
   896 // -----------------------------------------------------------------------------
       
   897 // Cancels a command on the collection
       
   898 // -----------------------------------------------------------------------------
       
   899 void CGlxMediaList::CancelCommand()
       
   900     {
       
   901     TRACER("CGlxMediaList::CancelCommand");
       
   902 
       
   903     // Cancelling a non issued command should not happen
       
   904     __ASSERT_DEBUG( iCommandPending, Panic( EGlxPanicLogicError ) );
       
   905 
       
   906     // Cancel command
       
   907     Collection().CancelRequest();
       
   908     iCommandPending = NULL;
       
   909     }
       
   910 
       
   911 // -----------------------------------------------------------------------------
       
   912 // Specify filter on the media list
       
   913 // -----------------------------------------------------------------------------
       
   914 void CGlxMediaList::SetFilterL(CMPXFilter* aFilter)
       
   915     {
       
   916     TRACER("CGlxMediaList::SetFilterL");
       
   917     
       
   918     // This method now takes a copy of the filter. It does not take ownership of aFilter
       
   919     
       
   920     CMPXFilter* tempFilter = NULL;
       
   921     
       
   922     if (aFilter)
       
   923         {
       
   924         // Create copy of filter
       
   925         tempFilter = CMPXFilter::NewL(*aFilter);
       
   926         CleanupStack::PushL(tempFilter);
       
   927         }
       
   928     
       
   929     // Set filter on the collection
       
   930     Collection().SetFilterL(aFilter);
       
   931 
       
   932     // Re-open collection if filter has been applied and list is already populated
       
   933     if ( iIsPopulated )
       
   934         {
       
   935         ReOpenL();
       
   936 
       
   937         iReorderPending = ETrue;
       
   938         }
       
   939 
       
   940     delete iFilter;
       
   941     iFilter = NULL;
       
   942 
       
   943     if (aFilter)
       
   944         {
       
   945         // SetFilterL did not leave. So take ownership of copy
       
   946         CleanupStack::Pop(tempFilter);
       
   947         iFilter = tempFilter;
       
   948         }
       
   949     }
       
   950 
       
   951 // -----------------------------------------------------------------------------
       
   952 // Returns filter on the media list
       
   953 // -----------------------------------------------------------------------------
       
   954 CMPXFilter* CGlxMediaList::Filter() const
       
   955     {
       
   956     TRACER("CGlxMediaList::Filter");
       
   957     
       
   958     return iFilter;
       
   959     }
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // IdSpaceId
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 TGlxIdSpaceId CGlxMediaList::IdSpaceId(TInt aIndex) const
       
   966     {
       
   967     TRACER("CGlxMediaList::IdSpaceId");
       
   968     
       
   969     ///@todo Delegate id space to item list.
       
   970     if (Count() && iItemList->Item(aIndex).IsStatic())
       
   971     	{
       
   972     	return KGlxStaticItemIdSpaceId;
       
   973     	}
       
   974     else
       
   975     	{
       
   976     	return iIdSpaceId;
       
   977     	}
       
   978     }
       
   979 
       
   980 // ---------------------------------------------------------------------------
       
   981 // CGlxMediaList::IsPopulated()
       
   982 // ---------------------------------------------------------------------------
       
   983 //
       
   984 TBool CGlxMediaList::IsPopulated() const
       
   985     {
       
   986     TRACER("CGlxMediaList::IsPopulated");
       
   987     
       
   988     return iIsPopulated;
       
   989     }
       
   990 
       
   991 
       
   992 // -----------------------------------------------------------------------------
       
   993 // Add a static item
       
   994 // -----------------------------------------------------------------------------
       
   995 //
       
   996 void CGlxMediaList::AddStaticItemL( CGlxMedia* aStaticItem, 
       
   997         NGlxListDefs::TInsertionPosition aTargetPosition )
       
   998     {
       
   999     TRACER("CGlxMediaList::AddStaticItemL");    
       
  1000     
       
  1001     iItemList->AddStaticItemL( aStaticItem, aTargetPosition );
       
  1002     }
       
  1003 
       
  1004 // -----------------------------------------------------------------------------
       
  1005 // Remove a static item
       
  1006 // -----------------------------------------------------------------------------
       
  1007 //
       
  1008 void CGlxMediaList::RemoveStaticItem(const TGlxMediaId& aItemId)
       
  1009 	{
       
  1010 	TRACER("CGlxMediaList::RemoveStaticItem");
       
  1011     
       
  1012     iItemList->Remove(TGlxIdSpaceId(KGlxStaticItemIdSpaceId), aItemId);
       
  1013 	}
       
  1014 
       
  1015 // -----------------------------------------------------------------------------
       
  1016 // Enable/disable static items
       
  1017 // -----------------------------------------------------------------------------
       
  1018 //
       
  1019 void CGlxMediaList::SetStaticItemsEnabled( TBool aEnabled )
       
  1020     {
       
  1021     TRACER("CGlxMediaList::SetStaticItemsEnabled");
       
  1022     
       
  1023     iItemList->SetStaticItemsEnabled( aEnabled );
       
  1024     }
       
  1025     
       
  1026 // -----------------------------------------------------------------------------
       
  1027 // return ETrue if static items are enabled
       
  1028 // -----------------------------------------------------------------------------
       
  1029 //
       
  1030 TBool CGlxMediaList::IsStaticItemsEnabled() const
       
  1031     {
       
  1032     TRACER("CGlxMediaList::IsStaticItemsEnabled");
       
  1033         
       
  1034     return iItemList->IsStaticItemsEnabled();
       
  1035     }
       
  1036 
       
  1037 // -----------------------------------------------------------------------------
       
  1038 // Sets the initial focus position
       
  1039 // -----------------------------------------------------------------------------
       
  1040 //
       
  1041 void CGlxMediaList::SetFocusInitialPosition(NGlxListDefs::TFocusInitialPosition aFocusInitialPosition)
       
  1042     {
       
  1043     TRACER("CGlxMediaList::SetFocusInitialPosition");    
       
  1044     
       
  1045     iItemList->SetFocusInitialPosition( aFocusInitialPosition );
       
  1046     }
       
  1047 
       
  1048 // -----------------------------------------------------------------------------
       
  1049 // Resets the focus to the initial position
       
  1050 // -----------------------------------------------------------------------------
       
  1051 //
       
  1052 void CGlxMediaList::ResetFocus()
       
  1053     {
       
  1054     TRACER("CGlxMediaList::ResetFocus");
       
  1055         
       
  1056     iItemList->ResetFocus();
       
  1057     }
       
  1058 
       
  1059 // ---------------------------------------------------------------------------
       
  1060 // From MMPXCollectionObserver
       
  1061 // Handle collection message
       
  1062 // ---------------------------------------------------------------------------
       
  1063 void CGlxMediaList::HandleCollectionMessageL(const CMPXMessage& aMessage)
       
  1064     {
       
  1065     TRACER("CGlxMediaList::HandleCollectionMessageL");
       
  1066     
       
  1067     
       
  1068     if (aMessage.IsSupported(KMPXMessageGeneralId))
       
  1069         {
       
  1070         TInt messageId = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralId);
       
  1071         if ( messageId == KMPXMessageGeneral )
       
  1072             {
       
  1073             if (!aMessage.IsSupported(KMPXMessageGeneralEvent) ||
       
  1074                 !aMessage.IsSupported(KMPXMessageGeneralType))
       
  1075                 {
       
  1076                 return;
       
  1077                 }
       
  1078 
       
  1079             TInt messageEvent = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralEvent);
       
  1080             if (messageEvent == TMPXCollectionMessage::EPathChanged)
       
  1081                 {
       
  1082                 GLX_LOG_INFO("CGlxMediaList::HandleCollectionMessageL() EPathChanged");
       
  1083 
       
  1084                 TInt messageType = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralType);
       
  1085                 switch (messageType)
       
  1086                     {
       
  1087                     case EMcPathChangedByOpen:
       
  1088                         {
       
  1089                         HandleOpenL();
       
  1090                         break;
       
  1091                         }
       
  1092                     case EMcPathChangedByCollectionChange:
       
  1093                         {
       
  1094                         break;
       
  1095                         }
       
  1096                     default:
       
  1097                         __ASSERT_DEBUG(EFalse, Panic(EGlxPanicLogicError));
       
  1098                         break;
       
  1099                     }
       
  1100                 }
       
  1101             }
       
  1102         else if (messageId == KMPXMessageIdItemChanged)
       
  1103             {
       
  1104             if (!aMessage.IsSupported(KMPXMessageMediaGeneralCategory) ||
       
  1105                 !aMessage.IsSupported(KMPXMessageChangeEventType) ||
       
  1106                 !aMessage.IsSupported(KMPXMessageMediaGeneralId))
       
  1107                 {
       
  1108                 return;
       
  1109                 }
       
  1110 
       
  1111             TMPXChangeEventType messageType = aMessage.ValueTObjectL<TMPXChangeEventType>(KMPXMessageChangeEventType);
       
  1112             switch (messageType)
       
  1113                 {
       
  1114                 case EMPXItemModified:
       
  1115                     {
       
  1116                     RArray<TMPXAttribute> attributes;
       
  1117                     CleanupClosePushL(attributes);
       
  1118                     TMPXItemId itemId = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaGeneralId);
       
  1119                     HandleItemModifiedL(itemId, attributes);
       
  1120                     CleanupStack::PopAndDestroy(&attributes);
       
  1121                     iManager->HandleWindowChangedL(this);
       
  1122                     //Fix for Bug 'ESLM-827JU8 Vasco w03':Dont 'ReOpenL()' in any case
       
  1123 	      			//Side Effect: Does not reorder album list in case of renaming album (To be handled later).
       
  1124 	      			break;
       
  1125                     // Drop through to perform sync, in case the order has changed
       
  1126                     }
       
  1127                 case EMPXItemInserted:
       
  1128                 case EMPXItemDeleted:
       
  1129                 default:
       
  1130                     // Items have changed, determine whether to sync now
       
  1131                     // or resync later if a sync is already pending after opening
       
  1132                     if ( iSyncStatus == KNonePending )
       
  1133                         {
       
  1134                         ReOpenL(); // force re-opens
       
  1135 
       
  1136                         iSyncStatus = KSyncPending;
       
  1137                         }
       
  1138                     else
       
  1139                         {
       
  1140                         iSyncStatus = KResyncPending;
       
  1141                         }
       
  1142                     break;
       
  1143                 }
       
  1144             }
       
  1145         else // received message isn't handled by media list
       
  1146             {
       
  1147             // Inform observers of message
       
  1148             TMessageNotificationStrategy strategy( aMessage, *this );
       
  1149             NotifyObservers( strategy );
       
  1150             }
       
  1151         }
       
  1152     }
       
  1153 
       
  1154 // ---------------------------------------------------------------------------
       
  1155 // From MMPXCollectionObserver
       
  1156 // Handles the collection entries being opened. Typically called
       
  1157 // when client has Open()'d a folder
       
  1158 // ---------------------------------------------------------------------------
       
  1159 //
       
  1160 void CGlxMediaList::HandleOpenL(const CMPXMedia& /*aEntries*/, TInt /*aIndex*/,
       
  1161         TBool /*aComplete*/, TInt aError)
       
  1162     {
       
  1163     TRACER("CGlxMediaList::HandleOpenL");
       
  1164     
       
  1165     /// @todo Need to handle errors
       
  1166     __ASSERT_DEBUG(aError == KErrNone, Panic(EGlxPanicLogicError));
       
  1167     HandleOpenL();
       
  1168     }
       
  1169 
       
  1170 // -----------------------------------------------------------------------------
       
  1171 // HandleOpenL
       
  1172 // -----------------------------------------------------------------------------
       
  1173 //
       
  1174 void CGlxMediaList::HandleOpenL()
       
  1175     {
       
  1176     TRACER("CGlxMediaList::HandleOpenL");
       
  1177 
       
  1178     // if we dont have the item list constructed
       
  1179     // dont do anything as it would lead to a crash
       
  1180     if( iItemList )
       
  1181         {
       
  1182         PopulateL();
       
  1183         // Sync (via population) has now occured,
       
  1184         // determine whether to resync if one is pending
       
  1185         if ( iSyncStatus == KResyncPending )
       
  1186             {
       
  1187             ReOpenL();
       
  1188 
       
  1189             iSyncStatus = KSyncPending;
       
  1190             }
       
  1191 
       
  1192         iManager->HandleWindowChangedL(this);
       
  1193         }
       
  1194     }
       
  1195 
       
  1196 // ---------------------------------------------------------------------------
       
  1197 // From MMPXCollectionObserver
       
  1198 // Handles the collection entries being opened. Typically called
       
  1199 // when client has Open()'d an item. Client typically responds by
       
  1200 // 'playing' the item
       
  1201 // ---------------------------------------------------------------------------
       
  1202 //
       
  1203 void CGlxMediaList::HandleOpenL(const CMPXCollectionPlaylist& /*aPlaylist*/,
       
  1204         TInt /*aError*/)
       
  1205     {
       
  1206     TRACER("CGlxMediaList::HandleOpenL" );
       
  1207     __ASSERT_DEBUG(EFalse, Panic(EGlxPanicLogicError));
       
  1208     }
       
  1209 
       
  1210 // ---------------------------------------------------------------------------
       
  1211 // From MMPXCollectionObserver
       
  1212 // Handle extended media properties
       
  1213 // ---------------------------------------------------------------------------
       
  1214 //
       
  1215 void CGlxMediaList::HandleCollectionMediaL(const CMPXMedia& aMedia, TInt aError)
       
  1216     {
       
  1217     TRACER("CGlxMediaList::HandleCollectionMediaL" );
       
  1218 
       
  1219     iManager->HandleCollectionMediaL(iIdSpaceId, aMedia, aError);
       
  1220     }
       
  1221 
       
  1222 // ---------------------------------------------------------------------------
       
  1223 // From MMPXCollectionObserver
       
  1224 // Handle command completion
       
  1225 // ---------------------------------------------------------------------------
       
  1226 //
       
  1227 void CGlxMediaList::HandleCommandComplete(CMPXCommand* aCommandResult, TInt aError)
       
  1228     {
       
  1229     TRACER("CGlxMediaList::HandleCommandComplete" );
       
  1230 
       
  1231     // SessionId is stored in iCommandPending
       
  1232     TAny* sessionId = iCommandPending;
       
  1233 
       
  1234     // Clear command pending flag here, in case an observer issues another command
       
  1235     iCommandPending = NULL;
       
  1236 
       
  1237     TCommandCompletedNotificationStrategy strategy( sessionId, aCommandResult, aError, *this );
       
  1238     NotifyObservers( strategy );
       
  1239     }
       
  1240 
       
  1241 // -----------------------------------------------------------------------------
       
  1242 // NewLC
       
  1243 // -----------------------------------------------------------------------------
       
  1244 //
       
  1245 CGlxMediaList* CGlxMediaList::NewLC(const TGlxHierarchyId& aHierarchyId)
       
  1246     {
       
  1247     TRACER("CGlxMediaList::NewLC" );
       
  1248     
       
  1249     CGlxMediaList* obj = new (ELeave) CGlxMediaList(aHierarchyId);
       
  1250     CleanupStack::PushL(obj);
       
  1251     obj->ConstructL();
       
  1252     return obj;
       
  1253     }
       
  1254 
       
  1255 // -----------------------------------------------------------------------------
       
  1256 // Constructor
       
  1257 // -----------------------------------------------------------------------------
       
  1258 //
       
  1259 CGlxMediaList::CGlxMediaList(const TGlxHierarchyId& aHierarchyId) :
       
  1260     iIdSpaceId(KGlxIdNone),
       
  1261     iHierarchyId(aHierarchyId), iVisibleWindowIndex( 0 )
       
  1262     {
       
  1263     TRACER("CGlxMediaList::CGlxMediaList");
       
  1264     
       
  1265     __ASSERT_DEBUG(KErrNotFound == -1, Panic(EGlxPanicDebugUnexpectedError));
       
  1266     }
       
  1267 
       
  1268 // -----------------------------------------------------------------------------
       
  1269 // Destructor
       
  1270 // -----------------------------------------------------------------------------
       
  1271 //
       
  1272 CGlxMediaList::~CGlxMediaList()
       
  1273     {
       
  1274     TRACER("CGlxMediaList::~CGlxMediaList" );
       
  1275     
       
  1276     if (iCollectionUtility)
       
  1277         {
       
  1278         iCollectionUtility->Close();
       
  1279         }
       
  1280 
       
  1281     iErrorPoster->Close();
       
  1282 
       
  1283     iItemListObservers.Close();
       
  1284     __ASSERT_DEBUG(iContexts.Count() == 0, Panic(EGlxPanicLogicError)); // Release all contexts
       
  1285     iContexts.Close();
       
  1286     iPath.Close();
       
  1287 
       
  1288     delete iItemList;
       
  1289     delete iFilter;
       
  1290     
       
  1291     if (iMediaListArray)
       
  1292     	{
       
  1293     	iMediaListArray->Close();
       
  1294     	}
       
  1295     
       
  1296     iCountAttributes.Close();
       
  1297 
       
  1298     // close the manager last as it may delete the cache and thus the CGlxMedia 
       
  1299     // objects.. item list destructor manipulates those objects so need to do it in this order
       
  1300 	if(iManager)
       
  1301 		{
       
  1302 		iManager->HandleListDeleted( this );
       
  1303 		iManager->Close();
       
  1304 		}    
       
  1305     }
       
  1306 
       
  1307 // -----------------------------------------------------------------------------
       
  1308 // ConstructL
       
  1309 // -----------------------------------------------------------------------------
       
  1310 //
       
  1311 void CGlxMediaList::ConstructL()
       
  1312     {
       
  1313     TRACER("CGlxMediaList::ConstructL" );
       
  1314     
       
  1315     iCollectionUtility = MMPXCollectionUtility::NewL(this, KMcModeIsolated);
       
  1316     iManager = CGlxCacheManager::InstanceL();
       
  1317     iErrorPoster = CGlxErrorPoster::InstanceL();
       
  1318     iMediaListArray = CGlxMediaListArray::InstanceL();
       
  1319     iCountAttributes.AppendL(KGlxMediaCollectionPluginSpecificSubTitle);
       
  1320     iCountAttributes.AppendL(KGlxMediaGeneralSlideshowableContent);
       
  1321     }
       
  1322 
       
  1323 // -----------------------------------------------------------------------------
       
  1324 // Initialize the media list
       
  1325 // -----------------------------------------------------------------------------
       
  1326 //
       
  1327 void CGlxMediaList::OpenL(const CMPXCollectionPath& aPath)
       
  1328     {
       
  1329     TRACER("CGlxMediaList::OpenL" );
       
  1330     
       
  1331     __ASSERT_DEBUG(iPath.Count() == 0, Panic(EGlxPanicAlreadyInitialised));
       
  1332 
       
  1333     // Copy the path's depth dimension
       
  1334     TInt levels = aPath.Levels();
       
  1335 
       
  1336     iPath.ReserveL(levels);
       
  1337     for (TInt level = 0; level < levels; level++) 
       
  1338         {
       
  1339         TGlxMediaId id(aPath.Id(level));
       
  1340         iPath.AppendL(id); 
       
  1341         }
       
  1342 
       
  1343     
       
  1344 	// Id space ids will no longer be retrieved from the collection framework
       
  1345 	// See ID:  ESLU-7C8CVN Inc9 MP: Error "Program closed: Music player" occurs if 
       
  1346     // user presses Rocker Select key continually in Album art view.
       
  1347     
       
  1348     // Consider the following scenario:
       
  1349     // 1. User launches fetcher dialog
       
  1350     // 2. Fetcher opens a medialist
       
  1351     // 3. MGlxMediaList::InstanceL starts an async wait loop allowing other active objects to run
       
  1352     // 4. User cancels fetcher
       
  1353     // 5. Fetcher does not have a handle to the MGlxMediaList so it cannot cancel or close it.
       
  1354     // --> We leak a medialist and leave an async wait loop in client processes active scheduler.
       
  1355 
       
  1356     if (levels)
       
  1357     	{
       
  1358     	iIdSpaceId = aPath.Id(0);
       
  1359     	}
       
  1360     else
       
  1361     	{
       
  1362     	iIdSpaceId = KGlxIdSpaceIdRoot;
       
  1363     	}
       
  1364     
       
  1365     iItemList = CGlxNavigableList::NewL( iIdSpaceId, *this, *this );
       
  1366 
       
  1367     OpenCollectionL( aPath );
       
  1368     }
       
  1369 
       
  1370 // -----------------------------------------------------------------------------
       
  1371 // AddReference
       
  1372 // -----------------------------------------------------------------------------
       
  1373 //
       
  1374 TInt CGlxMediaList::AddReference()
       
  1375     {
       
  1376     TRACER("CGlxMediaList::AddReference");
       
  1377     
       
  1378     iReferenceCount++;
       
  1379     return iReferenceCount;
       
  1380     }
       
  1381     
       
  1382 // -----------------------------------------------------------------------------
       
  1383 // RemoveReference
       
  1384 // -----------------------------------------------------------------------------
       
  1385 //
       
  1386 TInt CGlxMediaList::RemoveReference()
       
  1387     {
       
  1388     TRACER("CGlxMediaList::RemoveReference");
       
  1389     
       
  1390     __ASSERT_ALWAYS(iReferenceCount > 0, Panic(EGlxPanicLogicError));
       
  1391     iReferenceCount--;
       
  1392     return iReferenceCount;
       
  1393     }
       
  1394     
       
  1395 // -----------------------------------------------------------------------------
       
  1396 // ReferenceCount
       
  1397 // -----------------------------------------------------------------------------
       
  1398 //
       
  1399 TInt CGlxMediaList::ReferenceCount() const
       
  1400     {
       
  1401     TRACER("CGlxMediaList::ReferenceCount");
       
  1402     
       
  1403     return iReferenceCount;
       
  1404     }
       
  1405 
       
  1406 // -----------------------------------------------------------------------------
       
  1407 // Returns ETrue if this media list refers to the path
       
  1408 // -----------------------------------------------------------------------------
       
  1409 //
       
  1410 TBool CGlxMediaList::Equals(const CMPXCollectionPath& aPath) const 
       
  1411     {
       
  1412     TRACER("CGlxMediaList::Equals" );
       
  1413     
       
  1414     TInt myLevels = iPath.Count();
       
  1415     TInt pathLevels = aPath.Levels();
       
  1416     if (myLevels != pathLevels)
       
  1417         {
       
  1418         return EFalse;
       
  1419         }
       
  1420 
       
  1421     // Check if path's match
       
  1422     for (TInt i = 0; i < myLevels; i++) 
       
  1423         {
       
  1424         if (iPath[i] != TGlxMediaId(aPath.Id(i)))
       
  1425             {
       
  1426             return EFalse;
       
  1427             }
       
  1428         }
       
  1429 
       
  1430     return ETrue; // Match		
       
  1431     }
       
  1432 
       
  1433 // -----------------------------------------------------------------------------
       
  1434 // Determines if a filter has been set
       
  1435 // -----------------------------------------------------------------------------
       
  1436 TBool CGlxMediaList::IsFiltered() const
       
  1437     {
       
  1438     TRACER("CGlxMediaList::IsFiltered");
       
  1439     
       
  1440     return iFilter != NULL;
       
  1441     }
       
  1442 
       
  1443 // -----------------------------------------------------------------------------
       
  1444 // Synchronise the media list
       
  1445 // -----------------------------------------------------------------------------
       
  1446 void CGlxMediaList::ReOpenL()
       
  1447     {
       
  1448     TRACER("CGlxMediaList::ReOpenL" );
       
  1449     
       
  1450     // We must not re-open the list before it has been opened the first time
       
  1451     // note - this can happen if update messages are received whilst retreiving
       
  1452     // the id space id
       
  1453     if ( !iItemList )
       
  1454         {
       
  1455         return;
       
  1456         }
       
  1457     
       
  1458     CMPXCollectionPath* path = PathLC( NGlxListDefs::EPathParent );
       
  1459 
       
  1460     OpenCollectionL( *path );
       
  1461 
       
  1462     CleanupStack::PopAndDestroy(path);
       
  1463     }
       
  1464 
       
  1465 // -----------------------------------------------------------------------------
       
  1466 // Populates the list, i.e., opens the collection with the path
       
  1467 // -----------------------------------------------------------------------------
       
  1468 //
       
  1469 void CGlxMediaList::PopulateL()
       
  1470     {
       
  1471     TRACER("CGlxMediaList::PopulateL" );
       
  1472 
       
  1473     // Reserve space for all items in cache, that this media list is a potential user
       
  1474     // This allows SetContentsL to build user links without having to reserve space
       
  1475     iManager->ReserveUsersL( iIdSpaceId, CGlxMediaList::MediaListsL().Count() );
       
  1476 
       
  1477     CMPXCollectionPath* path = Collection().PathL();
       
  1478     CleanupStack::PushL(path);
       
  1479 
       
  1480     if ( iReorderPending )
       
  1481         {
       
  1482         iItemList->ReorderContentsL( *path, *iManager );
       
  1483         iReorderPending = EFalse;
       
  1484         }
       
  1485     else
       
  1486         {
       
  1487         iItemList->SetContentsL( *path, *iManager );
       
  1488 
       
  1489         // Sync has now occured,
       
  1490         // if only a sync was pending, clear sync status
       
  1491         if ( iSyncStatus == KSyncPending )
       
  1492             {
       
  1493             iSyncStatus = KNonePending;
       
  1494             }
       
  1495         }
       
  1496 
       
  1497     CleanupStack::PopAndDestroy(path);
       
  1498 
       
  1499     // The list contents may have changed, so update each used media with the
       
  1500     // current index into the list
       
  1501     UpdateMedia();
       
  1502 
       
  1503     // Inform observers of first time population
       
  1504     if (!iIsPopulated)
       
  1505         {
       
  1506         TListPopulatedNotificationStrategy strategy( *this );
       
  1507         iIsPopulated = ETrue; // Do this only once.
       
  1508         NotifyObservers( strategy );
       
  1509         }
       
  1510     }
       
  1511 
       
  1512 // -----------------------------------------------------------------------------
       
  1513 // Handles item modifications
       
  1514 // -----------------------------------------------------------------------------
       
  1515 void CGlxMediaList::HandleItemModifiedL(TInt aId, const RArray<TMPXAttribute>& aAttributes)
       
  1516     {
       
  1517     TRACER("CGlxMediaList::HandleItemModifiedL");
       
  1518     GLX_LOG_INFO1( "CGlxMediaList::HandleItemModifiedL %d", aId );
       
  1519     TGlxMediaId id(aId);
       
  1520 
       
  1521     /// @todo: Check that the correct IdSpaceId is being used here
       
  1522     
       
  1523     TInt index = Index(iIdSpaceId, id);
       
  1524 
       
  1525     if (index != KErrNotFound)
       
  1526         {
       
  1527         iManager->HandleItemModified(iIdSpaceId, id, aAttributes);
       
  1528 
       
  1529         RArray<TInt> itemIndices;
       
  1530         CleanupClosePushL(itemIndices);
       
  1531         itemIndices.AppendL(index);
       
  1532 
       
  1533         // Inform observers of modified items
       
  1534         TInt obsCount = iItemListObservers.Count();
       
  1535         GLX_DEBUG2("ML:HandleItemModifiedL obsCount=%d", obsCount);
       
  1536         for (TInt obsIdx = 0; obsIdx < obsCount; obsIdx++)
       
  1537             {
       
  1538             MGlxMediaListObserver* obs = iItemListObservers[obsIdx];
       
  1539             obs->HandleItemModifiedL(itemIndices, this);
       
  1540             }
       
  1541 
       
  1542         CleanupStack::PopAndDestroy(&itemIndices);
       
  1543         RPointerArray<CGlxMediaList>& mediaLists = iMediaListArray->Array();
       
  1544         TInt listCount = mediaLists.Count();
       
  1545         GLX_DEBUG2("ML:HandleItemModifiedL listCount=%d", listCount);
       
  1546         if (listCount > 0)
       
  1547             {
       
  1548             CGlxMediaList* mediaList = mediaLists[listCount-1];
       
  1549             if (mediaList == this)
       
  1550                 {
       
  1551                 GLX_DEBUG3("ML:HandleItemModifiedL(wait) listCount=%d, Id=%d",
       
  1552                                                   listCount, id.Value());
       
  1553                 TTimeIntervalMicroSeconds32 timeout;
       
  1554                 timeout = (mediaList->Count() > KMaxItemsCount ?
       
  1555                   KModifyEventMaxWaitInterval : KModifyEventMinWaitInterval );
       
  1556                 RTimer timer;
       
  1557                 CleanupClosePushL(timer);
       
  1558                 TRequestStatus status;
       
  1559                 timer.CreateLocal();
       
  1560                 timer.After(status, timeout);
       
  1561                 User::WaitForRequest(status);
       
  1562                 CleanupStack::PopAndDestroy(&timer);
       
  1563                 }
       
  1564             }
       
  1565         }
       
  1566     }
       
  1567 
       
  1568 // -----------------------------------------------------------------------------
       
  1569 // NotifyObserversOfMediaL
       
  1570 // -----------------------------------------------------------------------------
       
  1571 //
       
  1572 void CGlxMediaList::NotifyObserversOfMediaL(TInt aListIndex)
       
  1573     {
       
  1574     TRACER("CGlxMediaList::NotifyObserversOfMediaL");
       
  1575     GLX_LOG_INFO1( "CGlxMediaList::NotifyObserversOfMediaL %d", aListIndex );
       
  1576     TInt count = iItemListObservers.Count();
       
  1577     for (TInt i = 0; i < count; i++)
       
  1578         {
       
  1579         iItemListObservers[i]->HandleMediaL(aListIndex, this);
       
  1580         }
       
  1581     }
       
  1582         
       
  1583 // -----------------------------------------------------------------------------
       
  1584 // Notify observers of items added
       
  1585 // -----------------------------------------------------------------------------
       
  1586 //
       
  1587 void CGlxMediaList::HandleItemsAdded( TInt aAddedAtIndex, TInt aCount )
       
  1588     {
       
  1589     TRACER("CGlxMediaList::HandleItemsAdded");
       
  1590     
       
  1591     TItemsAddedNotificationStrategy strategy( aAddedAtIndex, aCount, *this );
       
  1592     NotifyObservers( strategy );
       
  1593     }
       
  1594 
       
  1595 // -----------------------------------------------------------------------------
       
  1596 // Notify observers of items removed
       
  1597 // -----------------------------------------------------------------------------
       
  1598 //
       
  1599 void CGlxMediaList::HandleItemsRemoved( TInt aRemovedFromIndex, TInt aCount )
       
  1600     {
       
  1601     TRACER("CGlxMediaList::HandleItemsRemoved");
       
  1602     
       
  1603     TItemsRemovedNotificationStrategy strategy( aRemovedFromIndex, aCount,
       
  1604         *this );
       
  1605     NotifyObservers( strategy );
       
  1606     }
       
  1607 
       
  1608 // -----------------------------------------------------------------------------
       
  1609 // Notify observers of focus change
       
  1610 // -----------------------------------------------------------------------------
       
  1611 //
       
  1612 void CGlxMediaList::HandleFocusChanged( NGlxListDefs::TFocusChangeType aType, 
       
  1613         TInt aNewIndex, TInt aOldIndex )
       
  1614     {
       
  1615     TRACER("CGlxMediaList::HandleFocusChanged");
       
  1616     
       
  1617     TFocusChangedNotificationStrategy strategy( aType, aNewIndex, aOldIndex,
       
  1618         *this );
       
  1619     NotifyObservers( strategy );
       
  1620     }
       
  1621 
       
  1622 // -----------------------------------------------------------------------------
       
  1623 // Notify observers of selection having changed
       
  1624 // -----------------------------------------------------------------------------
       
  1625 //
       
  1626 void CGlxMediaList::HandleItemSelected( TInt aIndex, TBool aSelected )
       
  1627     {
       
  1628     TRACER("CGlxMediaList::HandleItemSelected");
       
  1629     
       
  1630     TItemSelectedNotificationStrategy strategy( aIndex, aSelected, *this );
       
  1631     NotifyObservers( strategy );
       
  1632     }
       
  1633 
       
  1634 // -----------------------------------------------------------------------------
       
  1635 // Call strategy object for each observer
       
  1636 // -----------------------------------------------------------------------------
       
  1637 //
       
  1638 void CGlxMediaList::NotifyObservers( TNotificationStrategy& aStrategy )
       
  1639     {
       
  1640     TRACER("CGlxMediaList::NotifyObservers");
       
  1641     
       
  1642     // Notify all observers, even if some of them leave leave.
       
  1643     // "i" needs to be volatile, so that it does not get optimised into a 
       
  1644     // register. If i were in a register and observer left, i's new value 
       
  1645     // would be lost. 
       
  1646     volatile TInt i = iItemListObservers.Count() - 1;
       
  1647     
       
  1648     // Loop count + 1 times, so that iManager also gets notified if last 
       
  1649     // observer leaves. Iterate backwards in case observes remove themselves
       
  1650     // from the observer array during the callbacks.
       
  1651     while ( i >= -1 ) // usually tested only twice
       
  1652         {
       
  1653         TRAPD( err, 
       
  1654             {
       
  1655             while ( i >= 0 )
       
  1656                 {
       
  1657                 aStrategy.NotifyL( *iItemListObservers[ i ] );
       
  1658                 i--;
       
  1659                 }
       
  1660 
       
  1661             iManager->HandleWindowChangedL( this );
       
  1662             }
       
  1663         );
       
  1664         
       
  1665         if ( err != KErrNone )
       
  1666             {
       
  1667             iErrorPoster->PostError(err);
       
  1668             }
       
  1669 
       
  1670         i--;
       
  1671         }
       
  1672     }
       
  1673 
       
  1674 // -----------------------------------------------------------------------------
       
  1675 // Populates the path with hierarchy to parent
       
  1676 // -----------------------------------------------------------------------------
       
  1677 //
       
  1678 inline void CGlxMediaList::PathPopulateParentL(CMPXCollectionPath& aPath) const
       
  1679     {
       
  1680     TRACER("CGlxMediaList::PathPopulateParentL");
       
  1681     
       
  1682     // Add navigational hierarchy to path
       
  1683     TInt pathCount = iPath.Count();
       
  1684     for (TInt i = 0; i < pathCount; ++i)
       
  1685         {
       
  1686         aPath.AppendL( iPath[ i ].Value() );
       
  1687         }
       
  1688     }
       
  1689 
       
  1690 // -----------------------------------------------------------------------------
       
  1691 // Populates the path with all items and sets the focus
       
  1692 // -----------------------------------------------------------------------------
       
  1693 //
       
  1694 inline void CGlxMediaList::PathPopulateAllL(CMPXCollectionPath& aPath) const
       
  1695     {
       
  1696     TRACER("CGlxMediaList::PathPopulateAllL");
       
  1697     
       
  1698     RArray<TMPXItemId> mpxIds;
       
  1699     CleanupClosePushL( mpxIds );
       
  1700 
       
  1701     // Reserve space for all items
       
  1702     TInt itemCount = iItemList->Count();
       
  1703     mpxIds.ReserveL( itemCount );
       
  1704 
       
  1705     // Obtain TMPXItemId for each item
       
  1706     for (TInt i = 0; i < itemCount; ++i)
       
  1707         {
       
  1708         if ( !iItemList->Item( i ).IsStatic() )
       
  1709             {
       
  1710             mpxIds.AppendL( iItemList->Item( i ).Id().Value() );
       
  1711             }
       
  1712         }
       
  1713 
       
  1714     // Add Ids to current level in path
       
  1715     aPath.AppendL( mpxIds.Array() );
       
  1716 
       
  1717     // Set focused item
       
  1718     TInt focusIndex = FocusIndex();
       
  1719     if ( focusIndex >= 0 )
       
  1720         {
       
  1721         if ( !iItemList->Item( focusIndex ).IsStatic() )
       
  1722             {
       
  1723             aPath.Set( focusIndex - iItemList->Count( NGlxListDefs::ECountPreStatic ) );
       
  1724             }
       
  1725         }
       
  1726 
       
  1727     CleanupStack::PopAndDestroy( &mpxIds );
       
  1728     }
       
  1729 
       
  1730 // -----------------------------------------------------------------------------
       
  1731 // Populates the path with focused item and sets the focus
       
  1732 // -----------------------------------------------------------------------------
       
  1733 //
       
  1734 inline void CGlxMediaList::PathPopulateFocusL(CMPXCollectionPath& aPath) const
       
  1735     {
       
  1736     TRACER("CGlxMediaList::PathPopulateFocusL");
       
  1737     
       
  1738     // Obtain focused item
       
  1739     TInt focusIndex = FocusIndex();
       
  1740     if ( focusIndex >= 0 )
       
  1741         {
       
  1742         const TGlxMedia& item = iItemList->Item( focusIndex );
       
  1743         if ( !item.IsStatic() )
       
  1744             {
       
  1745             // Add focused item to path
       
  1746             aPath.AppendL( item.Id().Value() );
       
  1747             aPath.Set( 0 );
       
  1748             }
       
  1749         }
       
  1750     }
       
  1751 
       
  1752 // -----------------------------------------------------------------------------
       
  1753 // Populates the path with selected items and selects all
       
  1754 // -----------------------------------------------------------------------------
       
  1755 //
       
  1756 inline void CGlxMediaList::PathPopulateSelectionL(CMPXCollectionPath& aPath) const
       
  1757     {
       
  1758     TRACER("CGlxMediaList::PathPopulateSelectionL");
       
  1759     
       
  1760     RArray<TMPXItemId> mpxIds;
       
  1761     CleanupClosePushL( mpxIds );
       
  1762 
       
  1763     // Reserve space for all items
       
  1764     TInt selectionCount = iItemList->SelectedItemIndices().Count();
       
  1765     mpxIds.ReserveL( selectionCount );
       
  1766 
       
  1767     // Obtain TMPXItemId for each item
       
  1768     for (TInt i = 0; i < selectionCount; ++i)
       
  1769         {
       
  1770         TInt selectedItemIndex = iItemList->SelectedItemIndices()[ i ];
       
  1771         mpxIds.AppendL( iItemList->Item( selectedItemIndex ).Id().Value() );
       
  1772         }
       
  1773 
       
  1774     // Add Ids to current level in path
       
  1775     aPath.AppendL( mpxIds.Array() );
       
  1776 
       
  1777     // Set selection
       
  1778     aPath.SelectAllL();
       
  1779 
       
  1780     CleanupStack::PopAndDestroy( &mpxIds );
       
  1781     }
       
  1782 
       
  1783 // -----------------------------------------------------------------------------
       
  1784 // Updates each media used by this media list with the current index
       
  1785 // -----------------------------------------------------------------------------
       
  1786 //
       
  1787 inline void CGlxMediaList::UpdateMedia()
       
  1788     {
       
  1789     TRACER("CGlxMediaList::UpdateMedia");
       
  1790     
       
  1791     TInt count = iItemList->Count();
       
  1792     GLX_DEBUG2("CGlxMediaList::UpdateMedia() count=%d", count);    
       
  1793     for (TInt i = 0; i < count; ++i)
       
  1794         {
       
  1795         TGlxMedia& item = iItemList->Item( i );
       
  1796 
       
  1797         // static items should not be updated
       
  1798         if ( !item.IsStatic() )
       
  1799             {
       
  1800             item.UpdateMedia( *this, i );
       
  1801             UpdateMediaInvalidateAttributesChangedByCounts(item);
       
  1802             }
       
  1803         }
       
  1804     }
       
  1805 
       
  1806 // -----------------------------------------------------------------------------
       
  1807 // Updates each media used by this media list with the current index
       
  1808 // -----------------------------------------------------------------------------
       
  1809 //
       
  1810 inline void CGlxMediaList::UpdateMediaInvalidateAttributesChangedByCounts(TGlxMedia& aItem)
       
  1811     {
       
  1812     TRACER("CGlxMediaList::UpdateMediaInvalidateAttributesChangedByCounts");
       
  1813     
       
  1814     iManager->HandleItemModified(iIdSpaceId, aItem.Id(), iCountAttributes);
       
  1815     }
       
  1816     
       
  1817 // -----------------------------------------------------------------------------
       
  1818 // Opens a collection at the appropriate level
       
  1819 // -----------------------------------------------------------------------------
       
  1820 //
       
  1821 void CGlxMediaList::OpenCollectionL(const CMPXCollectionPath& aPath)
       
  1822     {
       
  1823     TRACER("CGlxMediaList::OpenCollectionL");
       
  1824     
       
  1825     // Open the level
       
  1826     if ( aPath.Levels() == 0 )
       
  1827         {
       
  1828         Collection().OpenL( TUid::Uid( EGlxCollectionPluginShowInMainListView ) );
       
  1829         }
       
  1830     else
       
  1831         {
       
  1832         Collection().OpenL( aPath );
       
  1833         }
       
  1834     }
       
  1835 
       
  1836 
       
  1837 // -----------------------------------------------------------------------------
       
  1838 // Compare contexts by pointer
       
  1839 // -----------------------------------------------------------------------------
       
  1840 //
       
  1841 TBool CGlxMediaList::TContext::Match(const TContext& a1, const TContext& a2)
       
  1842     {
       
  1843     TRACER("CGlxMediaList::TContext::Match");
       
  1844     
       
  1845     return a1.iContext == a2.iContext;
       
  1846     }
       
  1847 
       
  1848 // -----------------------------------------------------------------------------
       
  1849 // Compare contexts by priority
       
  1850 // -----------------------------------------------------------------------------
       
  1851 //
       
  1852 TBool CGlxMediaList::TContext::Compare(const TContext& a1, const TContext& a2)
       
  1853     {
       
  1854     TRACER("CGlxMediaList::TContext::Compare");
       
  1855     
       
  1856     return a2.iPriority - a1.iPriority;
       
  1857     }
       
  1858 
       
  1859 // -----------------------------------------------------------------------------
       
  1860 // Set the visible dataWindow index
       
  1861 // -----------------------------------------------------------------------------
       
  1862 //
       
  1863 void CGlxMediaList::SetVisibleWindowIndexL( TInt aIndex )
       
  1864     {
       
  1865     TRACER("CGlxMediaList::SetVisibleWindowIndexL");
       
  1866     __ASSERT_ALWAYS( aIndex <= Count(), Panic( EGlxPanicIllegalArgument ) );
       
  1867     if( aIndex != iVisibleWindowIndex )
       
  1868         {
       
  1869         iVisibleWindowIndex = aIndex;
       
  1870         GLX_DEBUG2("SetVisibleWindowIndexL() iVisibleWindowIndex=%d",
       
  1871                                                         iVisibleWindowIndex);
       
  1872         iManager->HandleWindowChangedL(this);
       
  1873         iManager->RefreshL();
       
  1874         }
       
  1875     }
       
  1876     
       
  1877 // -----------------------------------------------------------------------------
       
  1878 // Returns visible dataWindow index
       
  1879 // -----------------------------------------------------------------------------
       
  1880 //
       
  1881 TInt CGlxMediaList::VisibleWindowIndex() const
       
  1882     {
       
  1883     TRACER("CGlxMediaList::VisibleWindowIndex");
       
  1884     return iVisibleWindowIndex;
       
  1885     }
       
  1886 
       
  1887 // -----------------------------------------------------------------------------
       
  1888 // Cancels the pending attribute/thumbnail requests 
       
  1889 // -----------------------------------------------------------------------------
       
  1890 
       
  1891 void CGlxMediaList::CancelPreviousRequests()
       
  1892 	{
       
  1893 	TRACER("CGlxMediaList::CancelPreviousRequests");	
       
  1894 	
       
  1895 	
       
  1896 			// If media is NULL, cancel the previous pending request.
       
  1897 			// Place a new request for the item in focus, to fetch the media attributes
       
  1898 			iManager->CancelPreviousRequest();		
       
  1899 			}