photosgallery/viewframework/medialists/src/glxmedialist.cpp
changeset 0 4e91876724a2
child 1 9ba538e329bd
equal deleted inserted replaced
-1:000000000000 0:4e91876724a2
       
     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 // Cancels a command on the collection
       
   880 // -----------------------------------------------------------------------------
       
   881 void CGlxMediaList::CancelCommand()
       
   882     {
       
   883     TRACER("CGlxMediaList::CancelCommand");
       
   884 
       
   885     // Cancelling a non issued command should not happen
       
   886     __ASSERT_DEBUG( iCommandPending, Panic( EGlxPanicLogicError ) );
       
   887 
       
   888     // Cancel command
       
   889     Collection().CancelRequest();
       
   890     iCommandPending = NULL;
       
   891     }
       
   892 
       
   893 // -----------------------------------------------------------------------------
       
   894 // Specify filter on the media list
       
   895 // -----------------------------------------------------------------------------
       
   896 void CGlxMediaList::SetFilterL(CMPXFilter* aFilter)
       
   897     {
       
   898     TRACER("CGlxMediaList::SetFilterL");
       
   899     
       
   900     // This method now takes a copy of the filter. It does not take ownership of aFilter
       
   901     
       
   902     CMPXFilter* tempFilter = NULL;
       
   903     
       
   904     if (aFilter)
       
   905         {
       
   906         // Create copy of filter
       
   907         tempFilter = CMPXFilter::NewL(*aFilter);
       
   908         CleanupStack::PushL(tempFilter);
       
   909         }
       
   910     
       
   911     // Set filter on the collection
       
   912     Collection().SetFilterL(aFilter);
       
   913 
       
   914     // Re-open collection if filter has been applied and list is already populated
       
   915     if ( iIsPopulated )
       
   916         {
       
   917         ReOpenL();
       
   918 
       
   919         iReorderPending = ETrue;
       
   920         }
       
   921 
       
   922     delete iFilter;
       
   923     iFilter = NULL;
       
   924 
       
   925     if (aFilter)
       
   926         {
       
   927         // SetFilterL did not leave. So take ownership of copy
       
   928         CleanupStack::Pop(tempFilter);
       
   929         iFilter = tempFilter;
       
   930         }
       
   931     }
       
   932 
       
   933 // -----------------------------------------------------------------------------
       
   934 // Returns filter on the media list
       
   935 // -----------------------------------------------------------------------------
       
   936 CMPXFilter* CGlxMediaList::Filter() const
       
   937     {
       
   938     TRACER("CGlxMediaList::Filter");
       
   939     
       
   940     return iFilter;
       
   941     }
       
   942 
       
   943 // ---------------------------------------------------------------------------
       
   944 // IdSpaceId
       
   945 // ---------------------------------------------------------------------------
       
   946 //
       
   947 TGlxIdSpaceId CGlxMediaList::IdSpaceId(TInt aIndex) const
       
   948     {
       
   949     TRACER("CGlxMediaList::IdSpaceId");
       
   950     
       
   951     ///@todo Delegate id space to item list.
       
   952     if (Count() && iItemList->Item(aIndex).IsStatic())
       
   953     	{
       
   954     	return KGlxStaticItemIdSpaceId;
       
   955     	}
       
   956     else
       
   957     	{
       
   958     	return iIdSpaceId;
       
   959     	}
       
   960     }
       
   961 
       
   962 // ---------------------------------------------------------------------------
       
   963 // CGlxMediaList::IsPopulated()
       
   964 // ---------------------------------------------------------------------------
       
   965 //
       
   966 TBool CGlxMediaList::IsPopulated() const
       
   967     {
       
   968     TRACER("CGlxMediaList::IsPopulated");
       
   969     
       
   970     return iIsPopulated;
       
   971     }
       
   972 
       
   973 
       
   974 // -----------------------------------------------------------------------------
       
   975 // Add a static item
       
   976 // -----------------------------------------------------------------------------
       
   977 //
       
   978 void CGlxMediaList::AddStaticItemL( CGlxMedia* aStaticItem, 
       
   979         NGlxListDefs::TInsertionPosition aTargetPosition )
       
   980     {
       
   981     TRACER("CGlxMediaList::AddStaticItemL");    
       
   982     
       
   983     iItemList->AddStaticItemL( aStaticItem, aTargetPosition );
       
   984     }
       
   985 
       
   986 // -----------------------------------------------------------------------------
       
   987 // Remove a static item
       
   988 // -----------------------------------------------------------------------------
       
   989 //
       
   990 void CGlxMediaList::RemoveStaticItem(const TGlxMediaId& aItemId)
       
   991 	{
       
   992 	TRACER("CGlxMediaList::RemoveStaticItem");
       
   993     
       
   994     iItemList->Remove(TGlxIdSpaceId(KGlxStaticItemIdSpaceId), aItemId);
       
   995 	}
       
   996 
       
   997 // -----------------------------------------------------------------------------
       
   998 // Enable/disable static items
       
   999 // -----------------------------------------------------------------------------
       
  1000 //
       
  1001 void CGlxMediaList::SetStaticItemsEnabled( TBool aEnabled )
       
  1002     {
       
  1003     TRACER("CGlxMediaList::SetStaticItemsEnabled");
       
  1004     
       
  1005     iItemList->SetStaticItemsEnabled( aEnabled );
       
  1006     }
       
  1007     
       
  1008 // -----------------------------------------------------------------------------
       
  1009 // return ETrue if static items are enabled
       
  1010 // -----------------------------------------------------------------------------
       
  1011 //
       
  1012 TBool CGlxMediaList::IsStaticItemsEnabled() const
       
  1013     {
       
  1014     TRACER("CGlxMediaList::IsStaticItemsEnabled");
       
  1015         
       
  1016     return iItemList->IsStaticItemsEnabled();
       
  1017     }
       
  1018 
       
  1019 // -----------------------------------------------------------------------------
       
  1020 // Sets the initial focus position
       
  1021 // -----------------------------------------------------------------------------
       
  1022 //
       
  1023 void CGlxMediaList::SetFocusInitialPosition(NGlxListDefs::TFocusInitialPosition aFocusInitialPosition)
       
  1024     {
       
  1025     TRACER("CGlxMediaList::SetFocusInitialPosition");    
       
  1026     
       
  1027     iItemList->SetFocusInitialPosition( aFocusInitialPosition );
       
  1028     }
       
  1029 
       
  1030 // -----------------------------------------------------------------------------
       
  1031 // Resets the focus to the initial position
       
  1032 // -----------------------------------------------------------------------------
       
  1033 //
       
  1034 void CGlxMediaList::ResetFocus()
       
  1035     {
       
  1036     TRACER("CGlxMediaList::ResetFocus");
       
  1037         
       
  1038     iItemList->ResetFocus();
       
  1039     }
       
  1040 
       
  1041 // ---------------------------------------------------------------------------
       
  1042 // From MMPXCollectionObserver
       
  1043 // Handle collection message
       
  1044 // ---------------------------------------------------------------------------
       
  1045 void CGlxMediaList::HandleCollectionMessageL(const CMPXMessage& aMessage)
       
  1046     {
       
  1047     TRACER("CGlxMediaList::HandleCollectionMessageL");
       
  1048     
       
  1049     
       
  1050     if (aMessage.IsSupported(KMPXMessageGeneralId))
       
  1051         {
       
  1052         TInt messageId = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralId);
       
  1053         if ( messageId == KMPXMessageGeneral )
       
  1054             {
       
  1055             if (!aMessage.IsSupported(KMPXMessageGeneralEvent) ||
       
  1056                 !aMessage.IsSupported(KMPXMessageGeneralType))
       
  1057                 {
       
  1058                 return;
       
  1059                 }
       
  1060 
       
  1061             TInt messageEvent = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralEvent);
       
  1062             if (messageEvent == TMPXCollectionMessage::EPathChanged)
       
  1063                 {
       
  1064                 GLX_LOG_INFO("CGlxMediaList::HandleCollectionMessageL() EPathChanged");
       
  1065 
       
  1066                 TInt messageType = aMessage.ValueTObjectL<TInt>(KMPXMessageGeneralType);
       
  1067                 switch (messageType)
       
  1068                     {
       
  1069                     case EMcPathChangedByOpen:
       
  1070                         {
       
  1071                         HandleOpenL();
       
  1072                         break;
       
  1073                         }
       
  1074                     case EMcPathChangedByCollectionChange:
       
  1075                         {
       
  1076                         break;
       
  1077                         }
       
  1078                     default:
       
  1079                         __ASSERT_DEBUG(EFalse, Panic(EGlxPanicLogicError));
       
  1080                         break;
       
  1081                     }
       
  1082                 }
       
  1083             }
       
  1084         else if (messageId == KMPXMessageIdItemChanged)
       
  1085             {
       
  1086             if (!aMessage.IsSupported(KMPXMessageMediaGeneralCategory) ||
       
  1087                 !aMessage.IsSupported(KMPXMessageChangeEventType) ||
       
  1088                 !aMessage.IsSupported(KMPXMessageMediaGeneralId))
       
  1089                 {
       
  1090                 return;
       
  1091                 }
       
  1092 
       
  1093             TMPXChangeEventType messageType = aMessage.ValueTObjectL<TMPXChangeEventType>(KMPXMessageChangeEventType);
       
  1094             switch (messageType)
       
  1095                 {
       
  1096                 case EMPXItemModified:
       
  1097                     {
       
  1098                     RArray<TMPXAttribute> attributes;
       
  1099                     CleanupClosePushL(attributes);
       
  1100                     TMPXItemId itemId = aMessage.ValueTObjectL<TMPXItemId>(KMPXMessageMediaGeneralId);
       
  1101                     HandleItemModifiedL(itemId, attributes);
       
  1102                     CleanupStack::PopAndDestroy(&attributes);
       
  1103                     iManager->HandleWindowChangedL(this);
       
  1104 
       
  1105                     // Drop through to perform sync, in case the order has changed
       
  1106                     }
       
  1107                 case EMPXItemInserted:
       
  1108                 case EMPXItemDeleted:
       
  1109                 default:
       
  1110                     // Items have changed, determine whether to sync now
       
  1111                     // or resync later if a sync is already pending after opening
       
  1112                     if ( iSyncStatus == KNonePending )
       
  1113                         {
       
  1114                         ReOpenL(); // force re-opens
       
  1115 
       
  1116                         iSyncStatus = KSyncPending;
       
  1117                         }
       
  1118                     else
       
  1119                         {
       
  1120                         iSyncStatus = KResyncPending;
       
  1121                         }
       
  1122                     break;
       
  1123                 }
       
  1124             }
       
  1125         else // received message isn't handled by media list
       
  1126             {
       
  1127             // Inform observers of message
       
  1128             TMessageNotificationStrategy strategy( aMessage, *this );
       
  1129             NotifyObservers( strategy );
       
  1130             }
       
  1131         }
       
  1132     }
       
  1133 
       
  1134 // ---------------------------------------------------------------------------
       
  1135 // From MMPXCollectionObserver
       
  1136 // Handles the collection entries being opened. Typically called
       
  1137 // when client has Open()'d a folder
       
  1138 // ---------------------------------------------------------------------------
       
  1139 //
       
  1140 void CGlxMediaList::HandleOpenL(const CMPXMedia& /*aEntries*/, TInt /*aIndex*/,
       
  1141         TBool /*aComplete*/, TInt aError)
       
  1142     {
       
  1143     TRACER("CGlxMediaList::HandleOpenL");
       
  1144     
       
  1145     /// @todo Need to handle errors
       
  1146     __ASSERT_DEBUG(aError == KErrNone, Panic(EGlxPanicLogicError));
       
  1147     HandleOpenL();
       
  1148     }
       
  1149 
       
  1150 // -----------------------------------------------------------------------------
       
  1151 // HandleOpenL
       
  1152 // -----------------------------------------------------------------------------
       
  1153 //
       
  1154 void CGlxMediaList::HandleOpenL()
       
  1155     {
       
  1156     TRACER("CGlxMediaList::HandleOpenL");
       
  1157 
       
  1158     // if we dont have the item list constructed
       
  1159     // dont do anything as it would lead to a crash
       
  1160     if( iItemList )
       
  1161         {
       
  1162         PopulateL();
       
  1163         // Sync (via population) has now occured,
       
  1164         // determine whether to resync if one is pending
       
  1165         if ( iSyncStatus == KResyncPending )
       
  1166             {
       
  1167             ReOpenL();
       
  1168 
       
  1169             iSyncStatus = KSyncPending;
       
  1170             }
       
  1171 
       
  1172         iManager->HandleWindowChangedL(this);
       
  1173         }
       
  1174     }
       
  1175 
       
  1176 // ---------------------------------------------------------------------------
       
  1177 // From MMPXCollectionObserver
       
  1178 // Handles the collection entries being opened. Typically called
       
  1179 // when client has Open()'d an item. Client typically responds by
       
  1180 // 'playing' the item
       
  1181 // ---------------------------------------------------------------------------
       
  1182 //
       
  1183 void CGlxMediaList::HandleOpenL(const CMPXCollectionPlaylist& /*aPlaylist*/,
       
  1184         TInt /*aError*/)
       
  1185     {
       
  1186     TRACER("CGlxMediaList::HandleOpenL" );
       
  1187     __ASSERT_DEBUG(EFalse, Panic(EGlxPanicLogicError));
       
  1188     }
       
  1189 
       
  1190 // ---------------------------------------------------------------------------
       
  1191 // From MMPXCollectionObserver
       
  1192 // Handle extended media properties
       
  1193 // ---------------------------------------------------------------------------
       
  1194 //
       
  1195 void CGlxMediaList::HandleCollectionMediaL(const CMPXMedia& aMedia, TInt aError)
       
  1196     {
       
  1197     TRACER("CGlxMediaList::HandleCollectionMediaL" );
       
  1198 
       
  1199     iManager->HandleCollectionMediaL(iIdSpaceId, aMedia, aError);
       
  1200     }
       
  1201 
       
  1202 // ---------------------------------------------------------------------------
       
  1203 // From MMPXCollectionObserver
       
  1204 // Handle command completion
       
  1205 // ---------------------------------------------------------------------------
       
  1206 //
       
  1207 void CGlxMediaList::HandleCommandComplete(CMPXCommand* aCommandResult, TInt aError)
       
  1208     {
       
  1209     TRACER("CGlxMediaList::HandleCommandComplete" );
       
  1210 
       
  1211     // SessionId is stored in iCommandPending
       
  1212     TAny* sessionId = iCommandPending;
       
  1213 
       
  1214     // Clear command pending flag here, in case an observer issues another command
       
  1215     iCommandPending = NULL;
       
  1216 
       
  1217     TCommandCompletedNotificationStrategy strategy( sessionId, aCommandResult, aError, *this );
       
  1218     NotifyObservers( strategy );
       
  1219     }
       
  1220 
       
  1221 // -----------------------------------------------------------------------------
       
  1222 // NewLC
       
  1223 // -----------------------------------------------------------------------------
       
  1224 //
       
  1225 CGlxMediaList* CGlxMediaList::NewLC(const TGlxHierarchyId& aHierarchyId)
       
  1226     {
       
  1227     TRACER("CGlxMediaList::NewLC" );
       
  1228     
       
  1229     CGlxMediaList* obj = new (ELeave) CGlxMediaList(aHierarchyId);
       
  1230     CleanupStack::PushL(obj);
       
  1231     obj->ConstructL();
       
  1232     return obj;
       
  1233     }
       
  1234 
       
  1235 // -----------------------------------------------------------------------------
       
  1236 // Constructor
       
  1237 // -----------------------------------------------------------------------------
       
  1238 //
       
  1239 CGlxMediaList::CGlxMediaList(const TGlxHierarchyId& aHierarchyId) :
       
  1240     iIdSpaceId(KGlxIdNone),
       
  1241     iHierarchyId(aHierarchyId), iVisibleWindowIndex( 0 )
       
  1242     {
       
  1243     TRACER("CGlxMediaList::CGlxMediaList");
       
  1244     
       
  1245     __ASSERT_DEBUG(KErrNotFound == -1, Panic(EGlxPanicDebugUnexpectedError));
       
  1246     }
       
  1247 
       
  1248 // -----------------------------------------------------------------------------
       
  1249 // Destructor
       
  1250 // -----------------------------------------------------------------------------
       
  1251 //
       
  1252 CGlxMediaList::~CGlxMediaList()
       
  1253     {
       
  1254     TRACER("CGlxMediaList::~CGlxMediaList" );
       
  1255     
       
  1256     if (iCollectionUtility)
       
  1257         {
       
  1258         iCollectionUtility->Close();
       
  1259         }
       
  1260 
       
  1261     iErrorPoster->Close();
       
  1262 
       
  1263     iItemListObservers.Close();
       
  1264     __ASSERT_DEBUG(iContexts.Count() == 0, Panic(EGlxPanicLogicError)); // Release all contexts
       
  1265     iContexts.Close();
       
  1266     iPath.Close();
       
  1267 
       
  1268     delete iItemList;
       
  1269     delete iFilter;
       
  1270     
       
  1271     if (iMediaListArray)
       
  1272     	{
       
  1273     	iMediaListArray->Close();
       
  1274     	}
       
  1275     
       
  1276     iCountAttributes.Close();
       
  1277 
       
  1278     // close the manager last as it may delete the cache and thus the CGlxMedia 
       
  1279     // objects.. item list destructor manipulates those objects so need to do it in this order
       
  1280 	if(iManager)
       
  1281 		{
       
  1282 		iManager->HandleListDeleted( this );
       
  1283 		iManager->Close();
       
  1284 		}    
       
  1285     }
       
  1286 
       
  1287 // -----------------------------------------------------------------------------
       
  1288 // ConstructL
       
  1289 // -----------------------------------------------------------------------------
       
  1290 //
       
  1291 void CGlxMediaList::ConstructL()
       
  1292     {
       
  1293     TRACER("CGlxMediaList::ConstructL" );
       
  1294     
       
  1295     iCollectionUtility = MMPXCollectionUtility::NewL(this, KMcModeIsolated);
       
  1296     iManager = CGlxCacheManager::InstanceL();
       
  1297     iErrorPoster = CGlxErrorPoster::InstanceL();
       
  1298     iMediaListArray = CGlxMediaListArray::InstanceL();
       
  1299     iCountAttributes.AppendL(KGlxMediaCollectionPluginSpecificSubTitle);
       
  1300     iCountAttributes.AppendL(KGlxMediaGeneralSlideshowableContent);
       
  1301     }
       
  1302 
       
  1303 // -----------------------------------------------------------------------------
       
  1304 // Initialize the media list
       
  1305 // -----------------------------------------------------------------------------
       
  1306 //
       
  1307 void CGlxMediaList::OpenL(const CMPXCollectionPath& aPath)
       
  1308     {
       
  1309     TRACER("CGlxMediaList::OpenL" );
       
  1310     
       
  1311     __ASSERT_DEBUG(iPath.Count() == 0, Panic(EGlxPanicAlreadyInitialised));
       
  1312 
       
  1313     // Copy the path's depth dimension
       
  1314     TInt levels = aPath.Levels();
       
  1315 
       
  1316     iPath.ReserveL(levels);
       
  1317     for (TInt level = 0; level < levels; level++) 
       
  1318         {
       
  1319         TGlxMediaId id(aPath.Id(level));
       
  1320         iPath.Append(id); 
       
  1321         }
       
  1322 
       
  1323     
       
  1324 	// Id space ids will no longer be retrieved from the collection framework
       
  1325 	// See ID:  ESLU-7C8CVN Inc9 MP: Error "Program closed: Music player" occurs if 
       
  1326     // user presses Rocker Select key continually in Album art view.
       
  1327     
       
  1328     // Consider the following scenario:
       
  1329     // 1. User launches fetcher dialog
       
  1330     // 2. Fetcher opens a medialist
       
  1331     // 3. MGlxMediaList::InstanceL starts an async wait loop allowing other active objects to run
       
  1332     // 4. User cancels fetcher
       
  1333     // 5. Fetcher does not have a handle to the MGlxMediaList so it cannot cancel or close it.
       
  1334     // --> We leak a medialist and leave an async wait loop in client processes active scheduler.
       
  1335 
       
  1336     if (levels)
       
  1337     	{
       
  1338     	iIdSpaceId = aPath.Id(0);
       
  1339     	}
       
  1340     else
       
  1341     	{
       
  1342     	iIdSpaceId = KGlxIdSpaceIdRoot;
       
  1343     	}
       
  1344     
       
  1345     iItemList = CGlxNavigableList::NewL( iIdSpaceId, *this, *this );
       
  1346 
       
  1347     OpenCollectionL( aPath );
       
  1348     }
       
  1349 
       
  1350 // -----------------------------------------------------------------------------
       
  1351 // AddReference
       
  1352 // -----------------------------------------------------------------------------
       
  1353 //
       
  1354 TInt CGlxMediaList::AddReference()
       
  1355     {
       
  1356     TRACER("CGlxMediaList::AddReference");
       
  1357     
       
  1358     iReferenceCount++;
       
  1359     return iReferenceCount;
       
  1360     }
       
  1361     
       
  1362 // -----------------------------------------------------------------------------
       
  1363 // RemoveReference
       
  1364 // -----------------------------------------------------------------------------
       
  1365 //
       
  1366 TInt CGlxMediaList::RemoveReference()
       
  1367     {
       
  1368     TRACER("CGlxMediaList::RemoveReference");
       
  1369     
       
  1370     __ASSERT_ALWAYS(iReferenceCount > 0, Panic(EGlxPanicLogicError));
       
  1371     iReferenceCount--;
       
  1372     return iReferenceCount;
       
  1373     }
       
  1374     
       
  1375 // -----------------------------------------------------------------------------
       
  1376 // ReferenceCount
       
  1377 // -----------------------------------------------------------------------------
       
  1378 //
       
  1379 TInt CGlxMediaList::ReferenceCount() const
       
  1380     {
       
  1381     TRACER("CGlxMediaList::ReferenceCount");
       
  1382     
       
  1383     return iReferenceCount;
       
  1384     }
       
  1385 
       
  1386 // -----------------------------------------------------------------------------
       
  1387 // Returns ETrue if this media list refers to the path
       
  1388 // -----------------------------------------------------------------------------
       
  1389 //
       
  1390 TBool CGlxMediaList::Equals(const CMPXCollectionPath& aPath) const 
       
  1391     {
       
  1392     TRACER("CGlxMediaList::Equals" );
       
  1393     
       
  1394     TInt myLevels = iPath.Count();
       
  1395     TInt pathLevels = aPath.Levels();
       
  1396     if (myLevels != pathLevels)
       
  1397         {
       
  1398         return EFalse;
       
  1399         }
       
  1400 
       
  1401     // Check if path's match
       
  1402     for (TInt i = 0; i < myLevels; i++) 
       
  1403         {
       
  1404         if (iPath[i] != TGlxMediaId(aPath.Id(i)))
       
  1405             {
       
  1406             return EFalse;
       
  1407             }
       
  1408         }
       
  1409 
       
  1410     return ETrue; // Match		
       
  1411     }
       
  1412 
       
  1413 // -----------------------------------------------------------------------------
       
  1414 // Determines if a filter has been set
       
  1415 // -----------------------------------------------------------------------------
       
  1416 TBool CGlxMediaList::IsFiltered() const
       
  1417     {
       
  1418     TRACER("CGlxMediaList::IsFiltered");
       
  1419     
       
  1420     return iFilter != NULL;
       
  1421     }
       
  1422 
       
  1423 // -----------------------------------------------------------------------------
       
  1424 // Synchronise the media list
       
  1425 // -----------------------------------------------------------------------------
       
  1426 void CGlxMediaList::ReOpenL()
       
  1427     {
       
  1428     TRACER("CGlxMediaList::ReOpenL" );
       
  1429     
       
  1430     // We must not re-open the list before it has been opened the first time
       
  1431     // note - this can happen if update messages are received whilst retreiving
       
  1432     // the id space id
       
  1433     if ( !iItemList )
       
  1434         {
       
  1435         return;
       
  1436         }
       
  1437     
       
  1438     CMPXCollectionPath* path = PathLC( NGlxListDefs::EPathParent );
       
  1439 
       
  1440     OpenCollectionL( *path );
       
  1441 
       
  1442     CleanupStack::PopAndDestroy(path);
       
  1443     }
       
  1444 
       
  1445 // -----------------------------------------------------------------------------
       
  1446 // Populates the list, i.e., opens the collection with the path
       
  1447 // -----------------------------------------------------------------------------
       
  1448 //
       
  1449 void CGlxMediaList::PopulateL()
       
  1450     {
       
  1451     TRACER("CGlxMediaList::PopulateL" );
       
  1452 
       
  1453     // Reserve space for all items in cache, that this media list is a potential user
       
  1454     // This allows SetContentsL to build user links without having to reserve space
       
  1455     iManager->ReserveUsersL( iIdSpaceId, CGlxMediaList::MediaListsL().Count() );
       
  1456 
       
  1457     CMPXCollectionPath* path = Collection().PathL();
       
  1458     CleanupStack::PushL(path);
       
  1459 
       
  1460     if ( iReorderPending )
       
  1461         {
       
  1462         iItemList->ReorderContentsL( *path, *iManager );
       
  1463         iReorderPending = EFalse;
       
  1464         }
       
  1465     else
       
  1466         {
       
  1467         iItemList->SetContentsL( *path, *iManager );
       
  1468 
       
  1469         // Sync has now occured,
       
  1470         // if only a sync was pending, clear sync status
       
  1471         if ( iSyncStatus == KSyncPending )
       
  1472             {
       
  1473             iSyncStatus = KNonePending;
       
  1474             }
       
  1475         }
       
  1476 
       
  1477     CleanupStack::PopAndDestroy(path);
       
  1478 
       
  1479     // The list contents may have changed, so update each used media with the
       
  1480     // current index into the list
       
  1481     UpdateMedia();
       
  1482 
       
  1483     // Inform observers of first time population
       
  1484     if (!iIsPopulated)
       
  1485         {
       
  1486         TListPopulatedNotificationStrategy strategy( *this );
       
  1487         NotifyObservers( strategy );
       
  1488         iIsPopulated = ETrue; // Do this only once.
       
  1489         }
       
  1490     }
       
  1491 
       
  1492 // -----------------------------------------------------------------------------
       
  1493 // Handles item modifications
       
  1494 // -----------------------------------------------------------------------------
       
  1495 void CGlxMediaList::HandleItemModifiedL(TInt aId, const RArray<TMPXAttribute>& aAttributes)
       
  1496     {
       
  1497     TRACER("CGlxMediaList::HandleItemModifiedL");
       
  1498     GLX_LOG_INFO1( "CGlxMediaList::HandleItemModifiedL %d", aId );
       
  1499     TGlxMediaId id(aId);
       
  1500 
       
  1501     /// @todo: Check that the correct IdSpaceId is being used here
       
  1502     
       
  1503     TInt index = Index(iIdSpaceId, id);
       
  1504 
       
  1505     if (index != KErrNotFound)
       
  1506         {
       
  1507         iManager->HandleItemModified(iIdSpaceId, id, aAttributes);
       
  1508 
       
  1509         RArray<TInt> itemIndices;
       
  1510         CleanupClosePushL(itemIndices);
       
  1511         itemIndices.AppendL(index);
       
  1512 
       
  1513         // Inform observers of modified items
       
  1514         TInt obsCount = iItemListObservers.Count();
       
  1515         GLX_DEBUG2("ML:HandleItemModifiedL obsCount=%d", obsCount);
       
  1516         for (TInt obsIdx = 0; obsIdx < obsCount; obsIdx++)
       
  1517             {
       
  1518             MGlxMediaListObserver* obs = iItemListObservers[obsIdx];
       
  1519             obs->HandleItemModifiedL(itemIndices, this);
       
  1520             }
       
  1521 
       
  1522         CleanupStack::PopAndDestroy(&itemIndices);
       
  1523         RPointerArray<CGlxMediaList>& mediaLists = iMediaListArray->Array();
       
  1524         TInt listCount = mediaLists.Count();
       
  1525         GLX_DEBUG2("ML:HandleItemModifiedL listCount=%d", listCount);
       
  1526         if (listCount > 0)
       
  1527             {
       
  1528             CGlxMediaList* mediaList = mediaLists[listCount-1];
       
  1529             // Force a delay to allow TNM to process the modified event
       
  1530             if (mediaList == this)
       
  1531                 {
       
  1532                 GLX_DEBUG3("ML:HandleItemModifiedL(wait) listCount=%d, Id=%d",
       
  1533                                                   listCount, id.Value());
       
  1534                 TTimeIntervalMicroSeconds32 timeout;
       
  1535                 timeout = (mediaList->Count() > KMaxItemsCount ?
       
  1536                   KModifyEventMaxWaitInterval : KModifyEventMinWaitInterval );
       
  1537                 RTimer timer;
       
  1538                 CleanupClosePushL(timer);
       
  1539                 TRequestStatus status;
       
  1540                 timer.CreateLocal();
       
  1541                 timer.After(status, timeout);
       
  1542 			 	// User::WaitForRequest() will add codescanner warning but is necessary 
       
  1543 			 	// as User::WaitForAnyRequest() cannot be used in this case
       
  1544                 User::WaitForRequest(status);
       
  1545                 CleanupStack::PopAndDestroy(&timer);
       
  1546                 }
       
  1547             }
       
  1548         }
       
  1549     }
       
  1550 
       
  1551 // -----------------------------------------------------------------------------
       
  1552 // NotifyObserversOfMediaL
       
  1553 // -----------------------------------------------------------------------------
       
  1554 //
       
  1555 void CGlxMediaList::NotifyObserversOfMediaL(TInt aListIndex)
       
  1556     {
       
  1557     TRACER("CGlxMediaList::NotifyObserversOfMediaL");
       
  1558     GLX_LOG_INFO1( "CGlxMediaList::NotifyObserversOfMediaL %d", aListIndex );
       
  1559     TInt count = iItemListObservers.Count();
       
  1560     for (TInt i = 0; i < count; i++)
       
  1561         {
       
  1562         iItemListObservers[i]->HandleMediaL(aListIndex, this);
       
  1563         }
       
  1564     }
       
  1565         
       
  1566 // -----------------------------------------------------------------------------
       
  1567 // Notify observers of items added
       
  1568 // -----------------------------------------------------------------------------
       
  1569 //
       
  1570 void CGlxMediaList::HandleItemsAdded( TInt aAddedAtIndex, TInt aCount )
       
  1571     {
       
  1572     TRACER("CGlxMediaList::HandleItemsAdded");
       
  1573     
       
  1574     TItemsAddedNotificationStrategy strategy( aAddedAtIndex, aCount, *this );
       
  1575     NotifyObservers( strategy );
       
  1576     }
       
  1577 
       
  1578 // -----------------------------------------------------------------------------
       
  1579 // Notify observers of items removed
       
  1580 // -----------------------------------------------------------------------------
       
  1581 //
       
  1582 void CGlxMediaList::HandleItemsRemoved( TInt aRemovedFromIndex, TInt aCount )
       
  1583     {
       
  1584     TRACER("CGlxMediaList::HandleItemsRemoved");
       
  1585     
       
  1586     TItemsRemovedNotificationStrategy strategy( aRemovedFromIndex, aCount,
       
  1587         *this );
       
  1588     NotifyObservers( strategy );
       
  1589     }
       
  1590 
       
  1591 // -----------------------------------------------------------------------------
       
  1592 // Notify observers of focus change
       
  1593 // -----------------------------------------------------------------------------
       
  1594 //
       
  1595 void CGlxMediaList::HandleFocusChanged( NGlxListDefs::TFocusChangeType aType, 
       
  1596         TInt aNewIndex, TInt aOldIndex )
       
  1597     {
       
  1598     TRACER("CGlxMediaList::HandleFocusChanged");
       
  1599     
       
  1600     TFocusChangedNotificationStrategy strategy( aType, aNewIndex, aOldIndex,
       
  1601         *this );
       
  1602     NotifyObservers( strategy );
       
  1603     }
       
  1604 
       
  1605 // -----------------------------------------------------------------------------
       
  1606 // Notify observers of selection having changed
       
  1607 // -----------------------------------------------------------------------------
       
  1608 //
       
  1609 void CGlxMediaList::HandleItemSelected( TInt aIndex, TBool aSelected )
       
  1610     {
       
  1611     TRACER("CGlxMediaList::HandleItemSelected");
       
  1612     
       
  1613     TItemSelectedNotificationStrategy strategy( aIndex, aSelected, *this );
       
  1614     NotifyObservers( strategy );
       
  1615     }
       
  1616 
       
  1617 // -----------------------------------------------------------------------------
       
  1618 // Call strategy object for each observer
       
  1619 // -----------------------------------------------------------------------------
       
  1620 //
       
  1621 void CGlxMediaList::NotifyObservers( TNotificationStrategy& aStrategy )
       
  1622     {
       
  1623     TRACER("CGlxMediaList::NotifyObservers");
       
  1624     
       
  1625     // Notify all observers, even if some of them leave leave.
       
  1626     // "i" needs to be volatile, so that it does not get optimised into a 
       
  1627     // register. If i were in a register and observer left, i's new value 
       
  1628     // would be lost. 
       
  1629     volatile TInt i = iItemListObservers.Count() - 1;
       
  1630     
       
  1631     // Loop count + 1 times, so that iManager also gets notified if last 
       
  1632     // observer leaves. Iterate backwards in case observes remove themselves
       
  1633     // from the observer array during the callbacks.
       
  1634     while ( i >= -1 ) // usually tested only twice
       
  1635         {
       
  1636         TRAPD( err, 
       
  1637             {
       
  1638             while ( i >= 0 )
       
  1639                 {
       
  1640                 aStrategy.NotifyL( *iItemListObservers[ i ] );
       
  1641                 i--;
       
  1642                 }
       
  1643 
       
  1644             iManager->HandleWindowChangedL( this );
       
  1645             }
       
  1646         );
       
  1647         
       
  1648         if ( err != KErrNone )
       
  1649             {
       
  1650             iErrorPoster->PostError(err);
       
  1651             }
       
  1652 
       
  1653         i--;
       
  1654         }
       
  1655     }
       
  1656 
       
  1657 // -----------------------------------------------------------------------------
       
  1658 // Populates the path with hierarchy to parent
       
  1659 // -----------------------------------------------------------------------------
       
  1660 //
       
  1661 inline void CGlxMediaList::PathPopulateParentL(CMPXCollectionPath& aPath) const
       
  1662     {
       
  1663     TRACER("CGlxMediaList::PathPopulateParentL");
       
  1664     
       
  1665     // Add navigational hierarchy to path
       
  1666     TInt pathCount = iPath.Count();
       
  1667     for (TInt i = 0; i < pathCount; ++i)
       
  1668         {
       
  1669         aPath.AppendL( iPath[ i ].Value() );
       
  1670         }
       
  1671     }
       
  1672 
       
  1673 // -----------------------------------------------------------------------------
       
  1674 // Populates the path with all items and sets the focus
       
  1675 // -----------------------------------------------------------------------------
       
  1676 //
       
  1677 inline void CGlxMediaList::PathPopulateAllL(CMPXCollectionPath& aPath) const
       
  1678     {
       
  1679     TRACER("CGlxMediaList::PathPopulateAllL");
       
  1680     
       
  1681     RArray<TMPXItemId> mpxIds;
       
  1682     CleanupClosePushL( mpxIds );
       
  1683 
       
  1684     // Reserve space for all items
       
  1685     TInt itemCount = iItemList->Count();
       
  1686     mpxIds.ReserveL( itemCount );
       
  1687 
       
  1688     // Obtain TMPXItemId for each item
       
  1689     for (TInt i = 0; i < itemCount; ++i)
       
  1690         {
       
  1691         if ( !iItemList->Item( i ).IsStatic() )
       
  1692             {
       
  1693             mpxIds.AppendL( iItemList->Item( i ).Id().Value() );
       
  1694             }
       
  1695         }
       
  1696 
       
  1697     // Add Ids to current level in path
       
  1698     aPath.AppendL( mpxIds.Array() );
       
  1699 
       
  1700     // Set focused item
       
  1701     TInt focusIndex = FocusIndex();
       
  1702     if ( focusIndex >= 0 )
       
  1703         {
       
  1704         if ( !iItemList->Item( focusIndex ).IsStatic() )
       
  1705             {
       
  1706             aPath.Set( focusIndex - iItemList->Count( NGlxListDefs::ECountPreStatic ) );
       
  1707             }
       
  1708         }
       
  1709 
       
  1710     CleanupStack::PopAndDestroy( &mpxIds );
       
  1711     }
       
  1712 
       
  1713 // -----------------------------------------------------------------------------
       
  1714 // Populates the path with focused item and sets the focus
       
  1715 // -----------------------------------------------------------------------------
       
  1716 //
       
  1717 inline void CGlxMediaList::PathPopulateFocusL(CMPXCollectionPath& aPath) const
       
  1718     {
       
  1719     TRACER("CGlxMediaList::PathPopulateFocusL");
       
  1720     
       
  1721     // Obtain focused item
       
  1722     TInt focusIndex = FocusIndex();
       
  1723     if ( focusIndex >= 0 )
       
  1724         {
       
  1725         const TGlxMedia& item = iItemList->Item( focusIndex );
       
  1726         if ( !item.IsStatic() )
       
  1727             {
       
  1728             // Add focused item to path
       
  1729             aPath.AppendL( item.Id().Value() );
       
  1730             aPath.Set( 0 );
       
  1731             }
       
  1732         }
       
  1733     }
       
  1734 
       
  1735 // -----------------------------------------------------------------------------
       
  1736 // Populates the path with selected items and selects all
       
  1737 // -----------------------------------------------------------------------------
       
  1738 //
       
  1739 inline void CGlxMediaList::PathPopulateSelectionL(CMPXCollectionPath& aPath) const
       
  1740     {
       
  1741     TRACER("CGlxMediaList::PathPopulateSelectionL");
       
  1742     
       
  1743     RArray<TMPXItemId> mpxIds;
       
  1744     CleanupClosePushL( mpxIds );
       
  1745 
       
  1746     // Reserve space for all items
       
  1747     TInt selectionCount = iItemList->SelectedItemIndices().Count();
       
  1748     mpxIds.ReserveL( selectionCount );
       
  1749 
       
  1750     // Obtain TMPXItemId for each item
       
  1751     for (TInt i = 0; i < selectionCount; ++i)
       
  1752         {
       
  1753         TInt selectedItemIndex = iItemList->SelectedItemIndices()[ i ];
       
  1754         mpxIds.AppendL( iItemList->Item( selectedItemIndex ).Id().Value() );
       
  1755         }
       
  1756 
       
  1757     // Add Ids to current level in path
       
  1758     aPath.AppendL( mpxIds.Array() );
       
  1759 
       
  1760     // Set selection
       
  1761     aPath.SelectAllL();
       
  1762 
       
  1763     CleanupStack::PopAndDestroy( &mpxIds );
       
  1764     }
       
  1765 
       
  1766 // -----------------------------------------------------------------------------
       
  1767 // Updates each media used by this media list with the current index
       
  1768 // -----------------------------------------------------------------------------
       
  1769 //
       
  1770 inline void CGlxMediaList::UpdateMedia()
       
  1771     {
       
  1772     TRACER("CGlxMediaList::UpdateMedia");
       
  1773     
       
  1774     TInt count = iItemList->Count();
       
  1775     for (TInt i = 0; i < count; ++i)
       
  1776         {
       
  1777         TGlxMedia& item = iItemList->Item( i );
       
  1778 
       
  1779         // static items should not be updated
       
  1780         if ( !item.IsStatic() )
       
  1781             {
       
  1782             item.UpdateMedia( *this, i );
       
  1783             UpdateMediaInvalidateAttributesChangedByCounts(item);
       
  1784             }
       
  1785         }
       
  1786     }
       
  1787 
       
  1788 // -----------------------------------------------------------------------------
       
  1789 // Updates each media used by this media list with the current index
       
  1790 // -----------------------------------------------------------------------------
       
  1791 //
       
  1792 inline void CGlxMediaList::UpdateMediaInvalidateAttributesChangedByCounts(TGlxMedia& aItem)
       
  1793     {
       
  1794     TRACER("CGlxMediaList::UpdateMediaInvalidateAttributesChangedByCounts");
       
  1795     
       
  1796     iManager->HandleItemModified(iIdSpaceId, aItem.Id(), iCountAttributes);
       
  1797     }
       
  1798     
       
  1799 // -----------------------------------------------------------------------------
       
  1800 // Opens a collection at the appropriate level
       
  1801 // -----------------------------------------------------------------------------
       
  1802 //
       
  1803 void CGlxMediaList::OpenCollectionL(const CMPXCollectionPath& aPath)
       
  1804     {
       
  1805     TRACER("CGlxMediaList::OpenCollectionL");
       
  1806     
       
  1807     // Open the level
       
  1808     if ( aPath.Levels() == 0 )
       
  1809         {
       
  1810         Collection().OpenL( TUid::Uid( EGlxCollectionPluginShowInMainListView ) );
       
  1811         }
       
  1812     else
       
  1813         {
       
  1814         Collection().OpenL( aPath );
       
  1815         }
       
  1816     }
       
  1817 
       
  1818 
       
  1819 // -----------------------------------------------------------------------------
       
  1820 // Compare contexts by pointer
       
  1821 // -----------------------------------------------------------------------------
       
  1822 //
       
  1823 TBool CGlxMediaList::TContext::Match(const TContext& a1, const TContext& a2)
       
  1824     {
       
  1825     TRACER("CGlxMediaList::TContext::Match");
       
  1826     
       
  1827     return a1.iContext == a2.iContext;
       
  1828     }
       
  1829 
       
  1830 // -----------------------------------------------------------------------------
       
  1831 // Compare contexts by priority
       
  1832 // -----------------------------------------------------------------------------
       
  1833 //
       
  1834 TBool CGlxMediaList::TContext::Compare(const TContext& a1, const TContext& a2)
       
  1835     {
       
  1836     TRACER("CGlxMediaList::TContext::Compare");
       
  1837     
       
  1838     return a2.iPriority - a1.iPriority;
       
  1839     }
       
  1840 
       
  1841 // -----------------------------------------------------------------------------
       
  1842 // Set the visible dataWindow index
       
  1843 // -----------------------------------------------------------------------------
       
  1844 //
       
  1845 void CGlxMediaList::SetVisibleWindowIndexL( TInt aIndex )
       
  1846     {
       
  1847     TRACER("CGlxMediaList::SetVisibleWindowIndexL");
       
  1848     __ASSERT_ALWAYS( aIndex <= Count(), Panic( EGlxPanicIllegalArgument ) );
       
  1849     if( aIndex != iVisibleWindowIndex )
       
  1850         {
       
  1851         iVisibleWindowIndex = aIndex;
       
  1852         GLX_DEBUG2("SetVisibleWindowIndexL() iVisibleWindowIndex=%d",
       
  1853                                                         iVisibleWindowIndex);
       
  1854         iManager->HandleWindowChangedL(this);
       
  1855         iManager->RefreshL();
       
  1856         }
       
  1857     }
       
  1858     
       
  1859 // -----------------------------------------------------------------------------
       
  1860 // Returns visible dataWindow index
       
  1861 // -----------------------------------------------------------------------------
       
  1862 //
       
  1863 TInt CGlxMediaList::VisibleWindowIndex() const
       
  1864     {
       
  1865     TRACER("CGlxMediaList::VisibleWindowIndex");
       
  1866     return iVisibleWindowIndex;
       
  1867     }
       
  1868 
       
  1869 // -----------------------------------------------------------------------------
       
  1870 // Cancels the pending attribute/thumbnail requests 
       
  1871 // -----------------------------------------------------------------------------
       
  1872 
       
  1873 void CGlxMediaList::CancelPreviousRequests()
       
  1874 	{
       
  1875 	TRACER("CGlxMediaList::CancelPreviousRequests");	
       
  1876 	
       
  1877 	TInt focusIndex = FocusIndex();
       
  1878 	
       
  1879 	if(focusIndex >= KErrNone)
       
  1880 		{	
       
  1881 		if(!Item(focusIndex).Properties())
       
  1882 			{
       
  1883 			// If media is NULL, cancel the previous pending request.
       
  1884 			// Place a new request for the item in focus, to fetch the media attributes
       
  1885 			iManager->CancelPreviousRequest();		
       
  1886 			}
       
  1887 		}
       
  1888 	}