photosgallery/viewframework/views/listview/src/glxpreviewthumbnailbinding.cpp
branchRCL_3
changeset 26 5b3385a43d68
child 27 34937ec34dac
equal deleted inserted replaced
25:8e5f6eea9c9f 26:5b3385a43d68
       
     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 : Class defination for preview thumbnail in list view
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <mglxmedialist.h>
       
    20 #include <glxthumbnailcontext.h>
       
    21 #include <glxfilterfactory.h>                         // For TGlxFilterFactory
       
    22 #include <glxthumbnailattributeinfo.h>
       
    23 #include <glxuiutility.h>                               // For UiUtility instance
       
    24 #include <glxtracer.h>
       
    25 #include <glxlog.h>
       
    26 #include <glxerrormanager.h>             // For CGlxErrormanager
       
    27 #include <glxuistd.h>                    // Fetch context priority def'ns
       
    28 #include <mglxcache.h> 
       
    29 #include <ganes/HgDoubleGraphicList.h>
       
    30 
       
    31 #include "glxpreviewthumbnailbinding.h"
       
    32 #include "glxgeneraluiutilities.h"
       
    33 
       
    34 const TInt KThumbnailsTimeTimeDelay(50000);
       
    35 const TInt KWaitCount(30);
       
    36 const TInt KPreviewThumbnailFetchCount(1);
       
    37 
       
    38 
       
    39 // ----------------------------------------------------------------------------
       
    40 // NewL
       
    41 // ----------------------------------------------------------------------------
       
    42 //
       
    43 CGlxPreviewThumbnailBinding* CGlxPreviewThumbnailBinding::NewL(
       
    44         MPreviewTNObserver& aObserver)
       
    45 	{
       
    46 	TRACER("CGlxPreviewThumbnailBinding::NewL");
       
    47 	CGlxPreviewThumbnailBinding* self = CGlxPreviewThumbnailBinding::NewLC(aObserver);
       
    48 	CleanupStack::Pop(self);
       
    49 	return self;	
       
    50 	}
       
    51 
       
    52 // ----------------------------------------------------------------------------
       
    53 // NewLC
       
    54 // ----------------------------------------------------------------------------
       
    55 //
       
    56 CGlxPreviewThumbnailBinding* CGlxPreviewThumbnailBinding::NewLC(
       
    57         MPreviewTNObserver& aObserver)
       
    58 	{
       
    59 	TRACER("CGlxPreviewThumbnailBinding::NewLC");
       
    60 	CGlxPreviewThumbnailBinding* self = new(ELeave)CGlxPreviewThumbnailBinding(aObserver);
       
    61 	CleanupStack::PushL(self);
       
    62     self->ConstructL();
       
    63 	return self;
       
    64 	}
       
    65 
       
    66 // ----------------------------------------------------------------------------
       
    67 // Constructor
       
    68 // ----------------------------------------------------------------------------
       
    69 //
       
    70 CGlxPreviewThumbnailBinding::CGlxPreviewThumbnailBinding(
       
    71         MPreviewTNObserver& aObserver)
       
    72 : iObserver(aObserver)
       
    73 	{
       
    74 	}
       
    75 
       
    76 // ----------------------------------------------------------------------------
       
    77 // ConstructL
       
    78 // ----------------------------------------------------------------------------
       
    79 //
       
    80 void CGlxPreviewThumbnailBinding::ConstructL()
       
    81     {
       
    82     TRACER("CGlxPreviewThumbnailBinding::ConstructL");
       
    83     iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
    84     CGlxUiUtility* uiUtility = CGlxUiUtility::UtilityL();
       
    85     CleanupClosePushL(*uiUtility);
       
    86     iGridIconSize = uiUtility->GetGridIconSize();
       
    87     CleanupStack::PopAndDestroy(uiUtility);
       
    88     
       
    89     // Filter that filters out any GIF, corrupted images     
       
    90     iPreviewFilter = TGlxFilterFactory::CreatePreviewTNFilterL();
       
    91     iThumbnailIterator.SetRange(KPreviewThumbnailFetchCount);
       
    92     iThumbnailContext = new (ELeave) CGlxAttributeContext(&iThumbnailIterator); 
       
    93     TMPXAttribute tnAttr( KGlxMediaIdThumbnail,
       
    94                         GlxFullThumbnailAttributeId(ETrue,
       
    95                             iGridIconSize.iWidth,iGridIconSize.iHeight) );
       
    96     iThumbnailContext->SetDefaultSpec(iGridIconSize.iWidth,
       
    97                                                 iGridIconSize.iHeight);
       
    98     iThumbnailContext->AddAttributeL(tnAttr);
       
    99     }
       
   100 
       
   101 // ----------------------------------------------------------------------------
       
   102 // Destructor
       
   103 // ----------------------------------------------------------------------------
       
   104 //
       
   105 CGlxPreviewThumbnailBinding::~CGlxPreviewThumbnailBinding()
       
   106 	{
       
   107 	TRACER("CGlxPreviewThumbnailBinding::~CGlxPreviewThumbnailBinding");
       
   108     // close any medialist that exist
       
   109 	if( iMediaList )
       
   110 		{
       
   111         iMediaList->RemoveMediaListObserver( this );
       
   112         iMediaList->RemoveContext(iThumbnailContext);
       
   113         iMediaList->Close();
       
   114         iMediaList = NULL;
       
   115 		}
       
   116     delete iThumbnailContext;
       
   117     delete iPreviewFilter;
       
   118 	// cancel any outstanding request of the timer
       
   119 	if(iTimer->IsActive())
       
   120 	    {
       
   121 	    iTimer->Cancel();
       
   122 	    }
       
   123 	delete iTimer;
       
   124 	iTimer = NULL;	
       
   125 	}
       
   126 
       
   127 // ----------------------------------------------------------------------------
       
   128 // TimerTickedL: we need to update only when required i.e, when the thumbnail count 
       
   129 // has not reached till the max limit to be shown
       
   130 // ----------------------------------------------------------------------------
       
   131 //
       
   132 void CGlxPreviewThumbnailBinding::TimerTickedL()
       
   133     {
       
   134     TRACER("CGlxPreviewThumbnailBinding::TimerTickedL");
       
   135 
       
   136     if (!iMediaList)
       
   137         {
       
   138         GLX_LOG_INFO("TimerTickedL() iMediaList == NULL!");
       
   139         return;
       
   140         }
       
   141 
       
   142     if (iMediaList->IsPopulated())
       
   143         {
       
   144         if (iMediaList->Count())
       
   145             {
       
   146             const TGlxMedia& item = iMediaList->Item(0);
       
   147             TMPXAttribute thumbnailAttribute(KGlxMediaIdThumbnail,
       
   148                     GlxFullThumbnailAttributeId(ETrue, iGridIconSize.iWidth,
       
   149                             iGridIconSize.iHeight));
       
   150 
       
   151             const CGlxThumbnailAttribute* value = item.ThumbnailAttribute(
       
   152                     thumbnailAttribute);
       
   153             if (value)
       
   154                 {
       
   155                 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap;
       
   156                 ScaleBitmapToListSizeL(value->iBitmap, bitmap);
       
   157                 GLX_LOG_INFO1("iObserver.PreviewTNReadyL() iTrialCount=%d", iTrialCount);
       
   158                 iObserver.PreviewTNReadyL(bitmap, NULL);
       
   159                 }
       
   160             else
       
   161                 {
       
   162                 TInt tnError = GlxErrorManager::HasAttributeErrorL(
       
   163                         item.Properties(), KGlxMediaIdThumbnail);
       
   164                 if (tnError != KErrNone || iTrialCount == KWaitCount)
       
   165                     {
       
   166                     GLX_LOG_INFO1("TimerTickedL() tnError(%d) / Max Trialcount reached", tnError);
       
   167                     iObserver.PreviewTNReadyL(NULL, NULL);
       
   168                     iTrialCount = 0;
       
   169                     return;
       
   170                     }
       
   171                 iTrialCount++;
       
   172                 }
       
   173             }
       
   174         else
       
   175             {
       
   176             // Media count is zero, 
       
   177             // Notify immedialtely to jump to the next item in the list 
       
   178             GLX_LOG_INFO("TimerTickedL() iMediaList->Count() = 0");
       
   179             iObserver.PreviewTNReadyL(NULL, NULL);
       
   180             }
       
   181         }
       
   182     }
       
   183 
       
   184 // ----------------------------------------------------------------------------
       
   185 // IsTimeL callback function invoked when timer expires
       
   186 // ----------------------------------------------------------------------------
       
   187 //    
       
   188 TInt CGlxPreviewThumbnailBinding::IsTimeL( TAny* aSelf )
       
   189     {
       
   190     TRACER("CGlxPreviewThumbnailBinding::IsTimeL");
       
   191     if (aSelf)
       
   192         {
       
   193         TRACER("CGlxPreviewThumbnailBinding::IsTimeL");
       
   194         CGlxPreviewThumbnailBinding* self = static_cast<CGlxPreviewThumbnailBinding*>(aSelf);
       
   195         if(self)
       
   196             {
       
   197             self->TimerTickedL();
       
   198            }
       
   199         }
       
   200     return KErrNone;        
       
   201     }
       
   202 
       
   203 
       
   204 // ----------------------------------------------------------------------------
       
   205 // HandleItemChangedL
       
   206 // This function basically closes the old medialist if any for ex. Tags, 
       
   207 // Captured.. and then opens a new medialist with teh required filter.
       
   208 // ----------------------------------------------------------------------------
       
   209 //    
       
   210 void CGlxPreviewThumbnailBinding::HandleItemChangedL(const CMPXCollectionPath& aPath,
       
   211         TBool  aIsRefreshNeeded, TBool aBackwardNavigation)
       
   212     {
       
   213     TRACER("CGlxPreviewThumbnailBinding::HandleItemChangedL");
       
   214     GLX_LOG_INFO("CGlxPreviewThumbnailBinding::HandleItemChangedL()");
       
   215     
       
   216     iTimerTicked = EFalse;
       
   217     iIsRefreshNeeded = aIsRefreshNeeded;
       
   218 
       
   219     // remove and close old medialist   
       
   220     if( iMediaList )
       
   221 	    {
       
   222 	    // Reset the trialCount to 0 while deleting the medialist 
       
   223 	    iTrialCount = 0;
       
   224 	    iMediaList->RemoveMediaListObserver( this );
       
   225         iMediaList->RemoveContext(iThumbnailContext);
       
   226         iMediaList->Close();
       
   227         iMediaList = NULL;
       
   228 	    }
       
   229 	    
       
   230     iMediaList = MGlxMediaList::InstanceL(aPath, KGlxIdNone, iPreviewFilter);
       
   231     iMediaList->AddContextL(iThumbnailContext, KGlxFetchContextPriorityNormal);
       
   232 	// adding the medialist to observ any changes or updates done
       
   233 	iMediaList->AddMediaListObserverL(this);
       
   234 
       
   235 	if(aBackwardNavigation)
       
   236 	    {
       
   237 	    //On backward navigation start the timer manually, since we do not  
       
   238         //get the attribute callback.
       
   239         StartTimer();        
       
   240         }
       
   241     }
       
   242 
       
   243 // ----------------------------------------------------------------------------
       
   244 // StartTimer - Starts the timer based on the flag populateListTN's
       
   245 // where the flag will be true, when initially the first thumbnails in the list
       
   246 // are populated.
       
   247 // ----------------------------------------------------------------------------
       
   248 //    
       
   249 void CGlxPreviewThumbnailBinding::StartTimer()
       
   250     {
       
   251     TRACER("CGlxPreviewThumbnailBinding::StartTimer");
       
   252     
       
   253     if (iTimer)
       
   254         {
       
   255         iTimer->Cancel();
       
   256         }
       
   257         
       
   258     iTimer->Start(KThumbnailsTimeTimeDelay, KThumbnailsTimeTimeDelay,
       
   259             TCallBack(IsTimeL, this));
       
   260     }
       
   261 
       
   262 // ----------------------------------------------------------------------------
       
   263 // StopTimer - Stop the timer
       
   264 // ----------------------------------------------------------------------------
       
   265 //    
       
   266 void CGlxPreviewThumbnailBinding::StopTimer()
       
   267     {
       
   268     TRACER("CGlxPreviewThumbnailBinding::StopTimer");
       
   269         
       
   270     if (iTimer && iTimer->IsActive())
       
   271         {
       
   272         iTimer->Cancel();
       
   273         }
       
   274     }
       
   275 
       
   276 // ----------------------------------------------------------------------------
       
   277 // HandleItemAddedL
       
   278 // ----------------------------------------------------------------------------
       
   279 // 
       
   280 void CGlxPreviewThumbnailBinding::HandleItemAddedL( TInt /*aStartIndex*/, TInt 
       
   281     /*aEndIndex*/, MGlxMediaList* /*aList*/ )
       
   282     {
       
   283     }
       
   284 
       
   285 // ----------------------------------------------------------------------------
       
   286 // HandleItemRemoved
       
   287 // ----------------------------------------------------------------------------
       
   288 //  
       
   289 void CGlxPreviewThumbnailBinding::HandleItemRemovedL( TInt /*aStartIndex*/, TInt 
       
   290     /*aEndIndex*/, MGlxMediaList* /*aList*/ )
       
   291     {
       
   292 
       
   293     }
       
   294 
       
   295 // ----------------------------------------------------------------------------
       
   296 // HandleAttributesAvailableL
       
   297 // Inside this function we are going to append the index for which we have valid 
       
   298 // thumbnails and when the number of available thumbnails become equal to the 
       
   299 // number of slots where thumbnail to be shown we go for updating them to visual
       
   300 // item.
       
   301 // ----------------------------------------------------------------------------
       
   302 //  
       
   303 void CGlxPreviewThumbnailBinding::HandleAttributesAvailableL( TInt aItemIndex, 
       
   304     const RArray<TMPXAttribute>& aAttributes, MGlxMediaList* /*aList*/ )
       
   305     {
       
   306     TRACER("CGlxPreviewThumbnailBinding::HandleAttributesAvailableL");
       
   307 
       
   308     TMPXAttribute thumbnailAttribute(KGlxMediaIdThumbnail, 
       
   309         GlxFullThumbnailAttributeId( ETrue,  iGridIconSize.iWidth, 
       
   310                 iGridIconSize.iHeight ) );
       
   311                                                          
       
   312     TIdentityRelation< TMPXAttribute > match ( &TMPXAttribute::Match );
       
   313     
       
   314     if (KErrNotFound != aAttributes.Find( thumbnailAttribute, match ))
       
   315     	{
       
   316 		const TGlxMedia& item = iMediaList->Item( aItemIndex );
       
   317         const CGlxThumbnailAttribute* value = item.ThumbnailAttribute( 
       
   318                 thumbnailAttribute );
       
   319         if (value)
       
   320 	        {
       
   321 	        GLX_LOG_INFO("CGlxPreviewThumbnailBinding::HandleAttributesAvailableL()");
       
   322            	StartTimer();
       
   323             }
       
   324         }
       
   325     }
       
   326     
       
   327 // ----------------------------------------------------------------------------
       
   328 // HandleFocusChangedL
       
   329 // ----------------------------------------------------------------------------
       
   330 //  
       
   331 void CGlxPreviewThumbnailBinding::HandleFocusChangedL( NGlxListDefs::
       
   332     TFocusChangeType /*aType*/, TInt /*aNewIndex*/, TInt /*aOldIndex*/, 
       
   333     MGlxMediaList* /*aList*/ )
       
   334     {
       
   335     
       
   336     }
       
   337 
       
   338 // ----------   ------------------------------------------------------------------
       
   339 // HandleItemSelected
       
   340 // ----------------------------------------------------------------------------
       
   341 //  
       
   342 void CGlxPreviewThumbnailBinding::HandleItemSelectedL(TInt /*aIndex*/, 
       
   343     TBool /*aSelected*/, MGlxMediaList* /*aList*/ )
       
   344     {
       
   345 
       
   346     }
       
   347 
       
   348 // ----------------------------------------------------------------------------
       
   349 // HandleMessageL
       
   350 // ----------------------------------------------------------------------------
       
   351 //    
       
   352  void CGlxPreviewThumbnailBinding::HandleMessageL( const CMPXMessage& /*aMessage*/, 
       
   353     MGlxMediaList* /*aList*/ )
       
   354     {
       
   355     
       
   356     }
       
   357   
       
   358 // ----------------------------------------------------------------------------
       
   359 // HandleError
       
   360 // ----------------------------------------------------------------------------
       
   361 //
       
   362 void CGlxPreviewThumbnailBinding::HandleError( TInt /*aError*/ ) 
       
   363     {
       
   364     
       
   365     }
       
   366   
       
   367 // ----------------------------------------------------------------------------
       
   368 // HandleCommandCompleteL
       
   369 // ----------------------------------------------------------------------------
       
   370 //  
       
   371 void CGlxPreviewThumbnailBinding::HandleCommandCompleteL( CMPXCommand* 
       
   372         /*aCommandResult*/, 
       
   373     TInt /*aError*/, MGlxMediaList* /*aList*/ )
       
   374     {
       
   375     
       
   376     }
       
   377   
       
   378 // ----------------------------------------------------------------------------
       
   379 // HandleMediaL
       
   380 // ----------------------------------------------------------------------------
       
   381 //  
       
   382 void CGlxPreviewThumbnailBinding::HandleMediaL( TInt /*aListIndex*/, 
       
   383         MGlxMediaList* /*aList*/ )
       
   384     {
       
   385     
       
   386     }
       
   387   
       
   388 // ----------------------------------------------------------------------------
       
   389 // HandleItemModifiedL
       
   390 // ----------------------------------------------------------------------------
       
   391 //  
       
   392 void CGlxPreviewThumbnailBinding::HandleItemModifiedL( const RArray<TInt>& 
       
   393         /*aItemIndexes*/,
       
   394     MGlxMediaList* /*aList*/ )
       
   395     {
       
   396     
       
   397     }
       
   398 
       
   399 // ----------------------------------------------------------------------------
       
   400 // HandlePopulatedL
       
   401 // ----------------------------------------------------------------------------
       
   402 //
       
   403 void CGlxPreviewThumbnailBinding::HandlePopulatedL( MGlxMediaList* /*aList*/ )
       
   404     {
       
   405 	TRACER("CGlxPreviewThumbnailBinding::HandlePopulatedL()");
       
   406     GLX_LOG_INFO("CGlxPreviewThumbnailBinding::HandlePopulatedL()");
       
   407 
       
   408 	// Do cache cleanup. If iIsRefreshNeeded is set,
       
   409 	// then clean up the item at 0th index 
       
   410 	if (iIsRefreshNeeded)
       
   411 		{
       
   412 		if (iMediaList && iMediaList->Count() > 0)
       
   413 			{
       
   414 			GLX_LOG_INFO("**** Cache Cleanup ****");
       
   415 			MGlxCache* cacheManager = MGlxCache::InstanceL();
       
   416 			cacheManager->ForceCleanupMedia(iMediaList->IdSpaceId(0),
       
   417 					iMediaList->Item(0).Id());
       
   418 			cacheManager->Close();
       
   419 			}
       
   420 		}
       
   421 	//Start the timer
       
   422 	StartTimer();
       
   423 	}
       
   424 
       
   425 // ----------------------------------------------------------------------------
       
   426 // ScaleBitmapToListSizeL
       
   427 // ----------------------------------------------------------------------------
       
   428 //
       
   429 void CGlxPreviewThumbnailBinding::ScaleBitmapToListSizeL(
       
   430         CFbsBitmap* aSrcBitmap, CFbsBitmap* aDestBitmap)
       
   431     {
       
   432     TRACER("CGlxPreviewThumbnailBinding::ScaleBitmapToListSizeL()");
       
   433     TSize destSize = CHgDoubleGraphicList::PreferredImageSize();
       
   434     TSize srcSize = aSrcBitmap->SizeInPixels();
       
   435     if (destSize.iHeight * srcSize.iWidth < destSize.iWidth * srcSize.iHeight)
       
   436         {
       
   437         // Source has taller aspect than target so reduce target width
       
   438         destSize.iWidth = ((destSize.iHeight * srcSize.iWidth)
       
   439                 / (srcSize.iHeight));
       
   440         }
       
   441     else
       
   442         {
       
   443         // Source has wider aspect than target so reduce target height
       
   444         destSize.iHeight = (destSize.iWidth * srcSize.iHeight)
       
   445                 / srcSize.iWidth;
       
   446         }
       
   447     aDestBitmap->Create(destSize, aSrcBitmap->DisplayMode());
       
   448     CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(aDestBitmap);
       
   449     CleanupStack::PushL(bitmapDevice);
       
   450     CFbsBitGc* bitmapGc = CFbsBitGc::NewL();
       
   451     CleanupStack::PushL(bitmapGc);
       
   452     bitmapGc->Activate(bitmapDevice);
       
   453     bitmapGc->DrawBitmap(TRect(destSize), aSrcBitmap);
       
   454     CleanupStack::PopAndDestroy(bitmapGc);
       
   455     CleanupStack::PopAndDestroy(bitmapDevice);
       
   456     }