diff -r 000000000000 -r 4e91876724a2 photosgallery/slideshow/engine/coresrc/shwthumbnailloader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/photosgallery/slideshow/engine/coresrc/shwthumbnailloader.cpp Thu Dec 17 08:45:44 2009 +0200 @@ -0,0 +1,813 @@ +/* +* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Utility that contains HUI related slideshow code + * +*/ + + + + +// INCLUDES +#include "shwthumbnailloader.h" + +// DEPENDENCIES +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "shwslideshowenginepanic.h" +#include "shwthumbnailcontext.h" +#include "shwcallback.h" + +#include "shwconstants.h" // for context priorities + +using namespace NShwSlideshow; + +/** + * CShwThumbnailLoaderImpl + * Implementation dependencies for the thumbnail loading + */ +NONSHARABLE_CLASS( CShwThumbnailLoader::CShwThumbnailLoaderImpl ) + : public CBase, + public MGlxMediaListObserver + { + public: + + /** + * Constructor + * inlined as only ever called inside this cpp + * @param aMedialist the media list + */ + inline CShwThumbnailLoaderImpl( + MGlxMediaList& aMedialist, + MShwThumbnailLoadObserver& aErrorHandler ); + + /** + * Destructor. + * inlined as only ever called inside this cpp + */ + inline ~CShwThumbnailLoaderImpl(); + + /** + * 2nd phase constructor + * inlined as only ever called inside this cpp + */ + inline void ConstructL(); + + /** + * @ref CShwThumbnailLoader::LoadAndNotifyL + * inlined as only ever called inside this cpp + */ + inline void LoadAndNotifyL( TInt aIndex, TSize aSize ); + + /** + * @ref CShwThumbnailLoader::Unload + * inlined as only ever called inside this cpp + */ + inline void Unload( TInt aIndex ); + + /** + * @ref CShwThumbnailLoader::ImageSizeL + * inlined as only ever called inside this cpp + */ + inline TSize ImageSizeL( TInt aIndex ); + + public: // from MGlxMediaListObserver + + /// @ref MGlxMediaListObserver::HandleItemAddedL + void HandleItemAddedL( + TInt aStartIndex, TInt aEndIndex, MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleMediaL + void HandleMediaL( + TInt aListIndex, MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleItemRemovedL + void HandleItemRemovedL( + TInt aStartIndex, TInt aEndIndex, MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleItemModifiedL + void HandleItemModifiedL( + const RArray& aItemIndexes, MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleAttributesAvailableL + void HandleAttributesAvailableL( + TInt aItemIndex, + const RArray& aAttributes, + MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleFocusChangedL + void HandleFocusChangedL( + NGlxListDefs::TFocusChangeType aType, + TInt aNewIndex, + TInt aOldIndex, + MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleItemSelectedL + void HandleItemSelectedL( + TInt aIndex, TBool aSelected, MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleMessageL + void HandleMessageL( + const CMPXMessage& aMessage, MGlxMediaList* aList ); + /// @ref MGlxMediaListObserver::HandleError + void HandleError( TInt aError ); + + private: // Implementation + + // implementation of the error handler + inline void DoHandleErrorL(); + // Helper functions to find an element in the array given an index + // used in three places, load, unload and handleattributes available + // @param the index of the element to find + // @return the index of the element in the array, KErrNotFound otherwise + inline TInt Find( TInt aIndex ); + // @return the context if found, NULL otherwise + inline CShwThumbnailContext* FindContext( TInt aIndex ); + // Helper function to create the size context + inline void AddSizeContextL(); + /// Helper function to notify client of successfull or failed thumbnail load + inline void NofifyClientIfInterestedL( TInt aIndex, TBool aSuccess ); + // Helper function to remove high quality context from given index + inline void RemoveHighQualityContext( TInt aIndex ); + + public: // TCallBack API + + // Helper function to notify thumbnail completion asynchronously + inline TInt CompletedNotifyL(); + // Helper function to notify thumbnail failure asynchronously + inline TInt ErrorNotifyL(); + // Helper function to handle the error + inline TInt AsyncErrorHandleL(); + + private: // Implementation & Data + + /// Ref: the media list + MGlxMediaList& iMedialist; + /// Ref: the error handler + MShwThumbnailLoadObserver& iThumbnailObserver; + /// Own: the array for the thumbnail notifications + RArray< TInt > iNotificationIndexes; + /// Own: the array for already completed indexes + RArray< TInt > iCompletedIndexes; + /// Own: the array for already faulty indexes + RArray< TInt > iErrorIndexes; + /// Own: the array of high quality contexts + RPointerArray< CShwThumbnailContext > iHighQualityContexts; + /// Own: the size context + CGlxDefaultAttributeContext* iSizeContext; + /// Own: async callback needed in case image is already loaded + CAsyncCallBack* iCompletedCallBack; + /// Own: async callback needed in case image had already an error + CAsyncCallBack* iErrorCallBack; + /// Own: async callback for showing the out of memory system dialog + CAsyncCallBack* iErrorHandlerCallBack; + /// Own: the error code + TInt iError; + + }; + +// ----------------------------------------------------------------------------- +// C++ Constructor. Save a few bits of rom with inlining +// ----------------------------------------------------------------------------- +inline CShwThumbnailLoader::CShwThumbnailLoader() + { + } + +// ----------------------------------------------------------------------------- +// NewL. Static construction +// ----------------------------------------------------------------------------- +CShwThumbnailLoader* CShwThumbnailLoader::NewL( + MGlxMediaList& aMedialist, MShwThumbnailLoadObserver& aErrorHandler ) + { + TRACER("CShwThumbnailLoader::NewLs"); + GLX_LOG_INFO( "CShwThumbnailLoader::NewL" ); + CShwThumbnailLoader* self = new( ELeave ) CShwThumbnailLoader; + CleanupStack::PushL( self ); + +// 2nd phase >> + // create implementation + self->iImpl = + new( ELeave ) CShwThumbnailLoaderImpl( aMedialist, aErrorHandler ); + // call 2nd phase + self->iImpl->ConstructL(); +// << 2nd phase + + // pop the stack + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// Destructor +// ----------------------------------------------------------------------------- +CShwThumbnailLoader::~CShwThumbnailLoader() + { + TRACER("CShwThumbnailLoader::~CShwThumbnailLoader"); + GLX_LOG_INFO( "CShwThumbnailLoader::~CShwThumbnailLoader" ); + delete iImpl; + } + +// ----------------------------------------------------------------------------- +// LoadThumbnailAndNotifyL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::LoadAndNotifyL( TInt aIndex, TSize aSize ) + { + TRACER("CShwThumbnailLoader::LoadAndNotifyL"); + GLX_LOG_INFO( "CShwThumbnailLoader::LoadAndNotifyL" ); + // forward + iImpl->LoadAndNotifyL( aIndex, aSize ); + } + +// ----------------------------------------------------------------------------- +// Unload. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::Unload( TInt aIndex ) + { + TRACER("CShwThumbnailLoader::Unload"); + GLX_LOG_INFO( "CShwThumbnailLoader::Unload" ); + // forward + iImpl->Unload( aIndex ); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::ImageSizeL. +// ----------------------------------------------------------------------------- +TSize CShwThumbnailLoader::ImageSizeL( TInt aIndex ) + { + TRACER("CShwThumbnailLoader::ImageSizeL"); + GLX_LOG_INFO( "CShwThumbnailLoader::ImageSizeL" ); + // forward + return iImpl->ImageSizeL( aIndex ); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::C++ Constructor. Save a few bits of rom with inlining +// ----------------------------------------------------------------------------- +inline CShwThumbnailLoader::CShwThumbnailLoaderImpl::CShwThumbnailLoaderImpl( + MGlxMediaList& aMedialist, MShwThumbnailLoadObserver& aErrorHandler ) + : iMedialist( aMedialist ), + iThumbnailObserver( aErrorHandler ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::CShwThumbnailLoaderImpl()"); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::Destructor. +// ----------------------------------------------------------------------------- +inline CShwThumbnailLoader::CShwThumbnailLoaderImpl::~CShwThumbnailLoaderImpl() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::~CShwThumbnailLoaderImpl()"); + GLX_LOG_INFO( "CShwThumbnailLoaderImpl::~CShwThumbnailLoaderImpl" ); + // delete asynch callbacks, delete also cancels them + delete iCompletedCallBack; + delete iErrorCallBack; + delete iErrorHandlerCallBack; + + // size context, remove NULL does nothing + iMedialist.RemoveContext( iSizeContext ); + delete iSizeContext; + + // Remove all contexts from the media list + TInt count = iHighQualityContexts.Count(); + while ( count-- > 0 ) + { + // get the fetch context so that we can remove it from the media list + MGlxFetchContext* context = iHighQualityContexts[ count ]->Context(); + // high quality context, remove NULL does nothing + iMedialist.RemoveContext( context ); + }; + // delete the contexts array, this deletes the CShwThumbnailContexts + iHighQualityContexts.ResetAndDestroy(); + + // remove us from media list observers + iMedialist.RemoveMediaListObserver( this ); + + // close notification indexes array + iNotificationIndexes.Close(); + // close also the already completed indexes array + iCompletedIndexes.Close(); + // close also the errornous indexes array + iErrorIndexes.Close(); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::ConstructL +// ----------------------------------------------------------------------------- +inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::ConstructL() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::ConstructL"); + GLX_LOG_INFO( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::ConstructL" ); + // retrieve the size of images with own context + AddSizeContextL(); + + // add us as media list observer + iMedialist.AddMediaListObserverL( this ); + + // create async callback object to give + // callbacks once scheduler runs, give this high priority so that it + // is faster than the timers we have + iCompletedCallBack = new( ELeave ) CAsyncCallBack( CActive::EPriorityHigh ); + // set the callback + iCompletedCallBack->Set( + TShwCallBack< CShwThumbnailLoaderImpl, CompletedNotifyL >( this ) ); + + // create async callback to give error callbacks once scheduler runs + iErrorCallBack = new( ELeave ) CAsyncCallBack( CActive::EPriorityHigh ); + // set the callback + iErrorCallBack->Set( + TShwCallBack< CShwThumbnailLoaderImpl, ErrorNotifyL >( this ) ); + + // create async callback to give callback once we run onto errors + iErrorHandlerCallBack = new( ELeave ) CAsyncCallBack( CActive::EPriorityHigh ); + // set the callback + iErrorHandlerCallBack->Set( + TShwCallBack< CShwThumbnailLoaderImpl, AsyncErrorHandleL >( this ) ); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::ImageSizeL. +// ----------------------------------------------------------------------------- +inline TSize CShwThumbnailLoader::CShwThumbnailLoaderImpl::ImageSizeL( + TInt aIndex ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::ImageSizeL"); + GLX_LOG_INFO1( "CShwThumbnailLoader::ImageSizeL for index %d", aIndex ); + + // default to KErrNotFound + TSize size( KErrNotFound, KErrNotFound ); + + // get the media item + TGlxMedia item = iMedialist.Item( aIndex ); + // get its dimensions, if they are not available, size is not modified + // if size is not available, GetDimensions returns EFalse + if( !item.GetDimensions( size ) ) + { + // size was not available so try to fetch it with attribute retriever + (void)GlxAttributeRetriever::RetrieveL( + *iSizeContext, iMedialist, + EFalse /*aShowDialog*/ ); + // get the media item again since its just a copy and the old one + // might not have had the CGlxMedia* set + item = iMedialist.Item( aIndex ); + // cast to (void) tells the compiler we ignore + // the fetcher error as there is nothing to do if the fetch fails + // in that case the size will be (KErrNotFound,KErrNotFound) + // try getting the dimensions again + (void)item.GetDimensions( size ); + } + + GLX_LOG_INFO2( + "CShwThumbnailLoader::ImageSizeL (%d,%d)", size.iWidth, size.iHeight ); + + return size; + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::LoadAndNotifyL. +// ----------------------------------------------------------------------------- +inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::LoadAndNotifyL( + TInt aIndex, TSize aSize ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::LoadAndNotifyL"); + GLX_LOG_INFO1( "CShwThumbnailLoader::LoadAndNotifyL %d", aIndex ); + + // check whether a context already exists for this index + CShwThumbnailContext* context = FindContext( aIndex ); + if( !context ) + { + // create new context for the index with the given size + context = CShwThumbnailContext::NewLC( aIndex, aSize ); + iHighQualityContexts.AppendL( context ); + CleanupStack::Pop( context ); + // add the context to the medialist with priority + iMedialist.AddContextL( + context->Context(), KHighQualityContextPriority ); + } + + // add the index to notifications array so that we know to give + // either success or error notification once for the request + // Note that we can have multiple requests for same index + iNotificationIndexes.InsertInOrderAllowRepeatsL( aIndex ); + + // need to check if the thumbnail is already loaded + // when request count is zero (KErrNone) the thumbnail is fully loaded + TInt requestCount = context->RequestCountL( &iMedialist ); + if( requestCount == KErrNone ) + { + // thumbnail is already there + // we cant give the callback right away as the client is expecting + // this method to be always asynchronous + GLX_LOG_INFO1( + "CShwThumbnailLoader::Thumbnail already loaded %d", aIndex ); + // insert index to completed array + // Note that we can have multiple requests for same index + iCompletedIndexes.InsertInOrderAllowRepeatsL( aIndex ); + // cancel the old callback + iCompletedCallBack->Cancel(); + // make the callback + iCompletedCallBack->CallBack(); + } + else if ( requestCount < KErrNone ) + { + // thumbnail had already and error + GLX_LOG_INFO2( + "CShwThumbnailLoader::Thumbnail error %d at index, %d", + requestCount, aIndex ); + // we cant give the callback right away as the client is expecting + // this method to be always asynchronous + // Note that we can have multiple requests for same index + iErrorIndexes.InsertInOrderAllowRepeatsL( aIndex ); + // cancel the old callback + iErrorCallBack->Cancel(); + // make the callback + iErrorCallBack->CallBack(); + } + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::Unload +// ----------------------------------------------------------------------------- +inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::Unload( TInt aIndex ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::Unload"); + GLX_LOG_INFO1( "CShwThumbnailLoader::Unload %d", aIndex ); + + // client is no longer interested on this indes so remove it from the + // notifications + TInt index; + while( ( index = iNotificationIndexes.Find( aIndex ) ) != KErrNotFound ) + { + // remove the index from array + iNotificationIndexes.Remove( index ); + } + + // remove context for this index + RemoveHighQualityContext( aIndex ); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleItemAddedL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemAddedL( + TInt /*aStartIndex*/, TInt /*aEndIndex*/, MGlxMediaList* /*aList*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleMediaL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleMediaL( + TInt /*aListIndex*/, MGlxMediaList* /*aList*/ ) + { + } +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleItemRemovedL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemRemovedL( + TInt /*aStartIndex*/, TInt /*aEndIndex*/, MGlxMediaList* /*aList*/ ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemRemovedL"); + GLX_LOG_INFO( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemRemovedL" ); + // check if we still got some items to show + if( iMedialist.Count() < 1 ) + { + // the media list is empty so call our error handler + iThumbnailObserver.HandleMediaListEmpty(); + } + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleItemModifiedL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemModifiedL( + const RArray& /*aItemIndexes*/, MGlxMediaList* /*aList*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleAttributesAvailableL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleAttributesAvailableL( + TInt aItemIndex, const RArray& aAttributes/**/, + MGlxMediaList* /*aList*/ ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleAttributesAvailableL"); + GLX_LOG_INFO( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleAttributesAvailableL" ); + //done to verify context availability + TInt attributeCount = aAttributes.Count(); + for(TInt i = 0; i < attributeCount; i++ ) + { + TMPXAttribute attr = aAttributes[i]; + } + + GLX_LOG_INFO1( + "CShwThumbnailLoader::HandleAttributesAvailableL %d", aItemIndex ); + // check if the thumbnail was fully loaded, first find the related context + CShwThumbnailContext* context = FindContext( aItemIndex ); + if( context ) + { + // was there an error? + TInt requestCount = context->RequestCountL( &iMedialist ); + if ( requestCount == KErrNone ) + { + // no error, notify client + GLX_LOG_INFO1( + "CShwThumbnailLoader::Thumbnail loaded %d", aItemIndex ); + // notidy client of success if it is interested on this index + NofifyClientIfInterestedL( aItemIndex, ETrue ); + } + else if ( requestCount < 0 ) + { + GLX_LOG_INFO1( + "CShwThumbnailLoader::Thumbnail load failed %d", aItemIndex ); + // remove the context since there is an error in loading it + // need to remove first as error handler may add new contexts + RemoveHighQualityContext( aItemIndex ); + // notidy client of error if it is interested on this index + NofifyClientIfInterestedL( aItemIndex, EFalse ); + } + } + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleFocusChangedL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleFocusChangedL( + NGlxListDefs::TFocusChangeType /*aType*/, TInt /*aNewIndex*/, + TInt /*aOldIndex*/, MGlxMediaList* /*aList*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleItemSelectedL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleItemSelectedL( + TInt /*aIndex*/, TBool /*aSelected*/, MGlxMediaList* /*aList*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleMessageL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleMessageL( + const CMPXMessage& /*aMessage*/, MGlxMediaList* /*aList*/ ) + { + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::HandleError. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleError( + TInt aError ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleError"); + GLX_LOG_INFO1( "CShwThumbnailLoader::CShwThumbnailLoaderImpl::HandleError %d", aError ); + // need to remember the error + iError = aError; + // make asynch callback since we cant leave, this is the perfect way to + // handle error as the real processing will be in RunL so it can leave and + // can show a system error note. It is safe to call CallBack even is previous + // one did not complete + iErrorHandlerCallBack->CallBack(); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::DoHandleErrorL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::DoHandleErrorL() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::DoHandleErrorL"); + GLX_LOG_INFO1( "CShwThumbnailLoader::DoHandleError %d", iError ); + // variable to tell if the error was in some of our fetch contexts + TBool errorInHighQualityContexts = EFalse; + // check if it was any of our high quality fetch contexts + TInt count = iHighQualityContexts.Count(); + // ask all high quality contexts + while ( count-- > 0 ) + { + CShwThumbnailContext* context = iHighQualityContexts[ count ]; + // need to TRAP in case RequestCountL leaves, since if it does + // we need to tell our observer that there is a problem + // requestCount needs to be volatile so that it does get + // optimized to a register and get its initial value returned in leave + volatile TInt requestCount = KErrNone; + TRAPD( error, requestCount = context->RequestCountL( &iMedialist ) ); + // ask if this context had an error or RequestCountL did leave + if( ( requestCount < KErrNone )|| + ( error != KErrNone ) ) + { + // take the index as cant use context once it is removed + TInt index = context->Index(); + // remove the context since there is an error in loading it + // need to remove first as error handler may add new contexts + RemoveHighQualityContext( index ); + // notidy client of error if it is interested on this index + NofifyClientIfInterestedL( index, EFalse ); + // set the flag to tell that there was an error in context + errorInHighQualityContexts = ETrue; + } + } + // check if it was out of memory and in our contexts + if( KErrNoMemory == iError && errorInHighQualityContexts ) + { + // just leave with KErrNoMemory, system will then show the dialog + User::Leave( KErrNoMemory ); + } + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::Find. +// ----------------------------------------------------------------------------- +inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::Find( TInt aIndex ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::Find"); + GLX_LOG_INFO1( "CShwThumbnailLoader::Find %d", aIndex ); + // take the count + TInt index = iHighQualityContexts.Count(); + // browse through all indexes ( count-1 -> 0 ) + while ( index-- > 0 ) + { + // does the index belong to the array? + CShwThumbnailContext* context = iHighQualityContexts[ index ]; + if ( context->Index() == aIndex ) + { + break; + } + } + // if match was not found, index is -1 which is KErrNotFound + return index; + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::FindContext. +// ----------------------------------------------------------------------------- +inline CShwThumbnailContext* + CShwThumbnailLoader::CShwThumbnailLoaderImpl::FindContext( TInt aIndex ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::FindContext"); + GLX_LOG_INFO1( "CShwThumbnailLoader::FindContext %d", aIndex ); + // by default return NULL + CShwThumbnailContext* context = NULL; + // reuse the Find + TInt index = Find( aIndex ); + // if it was found + if( index != KErrNotFound ) + { + // set the context + context = iHighQualityContexts[ index ]; + } + // and return it + return context; + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::AddSizeContextL +// ----------------------------------------------------------------------------- +inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl::AddSizeContextL() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::AddSizeContextL"); + GLX_LOG_INFO( "CShwThumbnailLoader::FindContext "); + // Create the fetch context to retrieve the attribute + iSizeContext = CGlxDefaultAttributeContext::NewL(); + // Set the range offsets relative to the focus item + // e.g. 0, 1, [2], 3, 4. Focus @ 2 => frontOffset = 2, rearOffset = 2 + iSizeContext->SetRangeOffsets( KSizeContextOffset, KSizeContextOffset ); + + // Add the size attribute to the context + iSizeContext->AddAttributeL( KGlxMediaGeneralDimensions ); + + // Add Drm attribute to the context, + // By default Drm attrib would be ETrue if not fetched already and + // shall result in reduced thumbnail size request + iSizeContext->AddAttributeL(KMPXMediaDrmProtected); + + // add the context with its priority + iMedialist.AddContextL( iSizeContext, KSizeContextPriority ); + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::NofifyClientIfInterestedL. +// ----------------------------------------------------------------------------- +void CShwThumbnailLoader::CShwThumbnailLoaderImpl::NofifyClientIfInterestedL( + TInt aIndex, TBool aSuccess ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::NofifyClientIfInterestedL"); + GLX_LOG_INFO1( "CShwThumbnailLoaderImpl::NofifyClientIfInterestedL %d", aIndex ); + // go through all the notification indexes + TInt arrayIndex = iNotificationIndexes.Find( aIndex ); + if( KErrNotFound != arrayIndex ) + { + // need to remove the index first as handle may insert new ones + // remove the index from array so we dont call twice + iNotificationIndexes.Remove( arrayIndex ); + if( aSuccess ) + { + // let the client know that the thumbnail is there + iThumbnailObserver.HandleThumbnailLoadedL( aIndex ); + } + else + { + // let the client know that there was an error + iThumbnailObserver.HandleThumbnailLoadFailureL( aIndex ); + } + } + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::RemoveHighQualityContext +// ----------------------------------------------------------------------------- +inline void CShwThumbnailLoader::CShwThumbnailLoaderImpl:: + RemoveHighQualityContext( TInt aIndex ) + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::RemoveHighQualityContext"); + GLX_LOG_INFO1( "CShwThumbnailLoaderImpl::RemoveHighQualityContext %d", aIndex ); + // Is there a context for this index? + TInt arrayIndex = Find( aIndex ); + if( KErrNotFound != arrayIndex ) + { + // get the context + CShwThumbnailContext* context = iHighQualityContexts[ arrayIndex ]; + // remove the context from the media list + iMedialist.RemoveContext( context->Context() ); + // and remove the context from the array + iHighQualityContexts.Remove( arrayIndex ); + // finally delete the context + delete context; + } + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::CompletedNotifyL +// ----------------------------------------------------------------------------- +inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::CompletedNotifyL() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::CompletedNotifyL"); + GLX_LOG_INFO( "CShwThumbnailLoader::CompletedNotifyL" ); + // then we need to also remove all notifications for the given index + TInt count = iCompletedIndexes.Count(); + while( count-- > 0 ) + { + // take the index + TInt index = iCompletedIndexes[ count ]; + // remove the index from array before calling observer as observer + // may add new indexes to the array + iCompletedIndexes.Remove( count ); + // notidy client of success if it is interested on this index + NofifyClientIfInterestedL( index, ETrue ); + } + // need to return value to please TCallBack API + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::ErrorNotifyL +// ----------------------------------------------------------------------------- +inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::ErrorNotifyL() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::ErrorNotifyL"); + GLX_LOG_INFO( "CShwThumbnailLoader::ErrorNotifyL" ); + // then we need to also remove all notifications for the given index + TInt count = iErrorIndexes.Count(); + while( count-- > 0 ) + { + // take the index + TInt index = iErrorIndexes[ count ]; + // remove the index from array before calling observer as observer + // may add new indexes to the array + iErrorIndexes.Remove( count ); + // remove the context since there is an error in loading it + // need to remove first as error handler may add new contexts + RemoveHighQualityContext( index ); + // notidy client of error if it is interested on this index + NofifyClientIfInterestedL( index, EFalse ); + } + // need to return value to please TCallBack API + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CShwThumbnailLoaderImpl::AsyncErrorHandleL +// ----------------------------------------------------------------------------- +inline TInt CShwThumbnailLoader::CShwThumbnailLoaderImpl::AsyncErrorHandleL() + { + TRACER("CShwThumbnailLoader::CShwThumbnailLoaderImpl::AsyncErrorHandleL"); + GLX_LOG_INFO( "CShwThumbnailLoader::AsyncErrorHandleL" ); + // handle the error + DoHandleErrorL(); + // need to return value to please TCallBack API + return KErrNone; + }