browserui/browser/FavouritesSrc/BrowserFaviconHandler.cpp
branchRCL_3
changeset 48 8e6fa1719340
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/browserui/browser/FavouritesSrc/BrowserFaviconHandler.cpp	Wed Sep 01 12:31:04 2010 +0100
@@ -0,0 +1,405 @@
+/*
+* Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*      Implementation of CBrowserFaviconHandler
+*
+*
+*/
+
+
+// INCLUDES
+#include "BrowserFaviconHandler.h"
+#include "ApiProvider.h"
+#include "BrowserUtil.h"
+#include <e32base.h>
+#include <brctldefs.h>
+#include <fbs.h>
+#include <MdaImageConverter.h>
+#include <favouritesitemlist.h>
+#include <favouritesitem.h>
+
+// number of favicons to get before redrawing
+const TInt KNumFaviconsToRedraw = 3	;
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::CBrowserFaviconHandler()
+// ----------------------------------------------------------------------------
+//
+CBrowserFaviconHandler::CBrowserFaviconHandler( 
+										MApiProvider& aApiProvider,
+										MBrowserFaviconObserver& aObserver,
+										TSize aFaviconSize ) :
+	CActive( CActive::EPriorityIdle ),
+	iApiProvider( aApiProvider ),
+	iObserver( aObserver ),
+	iFaviconSize( aFaviconSize )
+	{
+	CActiveScheduler::Add( this );	
+	}
+
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::~CBrowserFaviconHandler()
+// ----------------------------------------------------------------------------
+//
+CBrowserFaviconHandler::~CBrowserFaviconHandler()
+	{
+	Cancel();
+	if(iBmpScaler!=NULL)
+		{
+			iBmpScaler->Cancel();
+		}
+	delete iBmpScaler;
+	delete iFaviconArrayIndices;
+	delete iFavicon;
+	}
+
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::NewL()
+// ----------------------------------------------------------------------------
+//	
+CBrowserFaviconHandler* CBrowserFaviconHandler::NewL( 
+										MApiProvider& aApiProvider,
+										CArrayPtr<CGulIcon>* aIconArray,
+										MBrowserFaviconObserver& aObserver,
+										TSize aFaviconSize )
+	{
+	CBrowserFaviconHandler* self = 
+					CBrowserFaviconHandler::NewLC( 	aApiProvider, 
+													aIconArray, 
+													aObserver,
+													aFaviconSize );
+    
+    CleanupStack::Pop();
+    return self;	
+	}
+	
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::NewLC()
+// ----------------------------------------------------------------------------
+//	
+CBrowserFaviconHandler* CBrowserFaviconHandler::NewLC(
+										MApiProvider& aApiProvider,
+										CArrayPtr<CGulIcon>* aIconArray,
+										MBrowserFaviconObserver& aObserver,
+										TSize aFaviconSize )
+	{
+	CBrowserFaviconHandler* self = 
+					new ( ELeave ) CBrowserFaviconHandler( 	aApiProvider,
+															aObserver,
+															aFaviconSize );
+	CleanupStack::PushL( self );
+    self->ConstructL( aIconArray );
+    return self;	
+	}
+	
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::ConstructL()
+// ----------------------------------------------------------------------------
+//		
+void CBrowserFaviconHandler::ConstructL( CArrayPtr<CGulIcon>* aIconArray )
+	{
+	iIconArray = aIconArray; // not owned
+	iFaviconArrayIndices = new ( ELeave ) CArrayFixFlat<TFaviconIndex>( 4 );
+		
+	// Construct Favicon Engine
+	iBmpScaler = CBrowserFaviconScaler::NewL(*this);
+	}
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::RequestFavicons()
+// ----------------------------------------------------------------------------
+//      
+void CBrowserFaviconHandler::RequestFavicons( CFavouritesItemList* aFavItems )
+    {
+    TInt count = aFavItems->Count();
+    while(count)
+        {            
+            CFavouritesItem& item = *aFavItems->At( count - 1); // index starts from 0
+            CGulIcon *favIcon = NULL;           
+                        
+            // Request Favicon from Engine  - there should be new API for request, but no har to use it
+            if ( item.Url().Length() )
+                iFavicon = iApiProvider.BrCtlInterface().GetBitmapData(item.Url(), TBrCtlDefs::EBitmapFavicon );
+
+            if ( favIcon )
+                {                
+                delete iFavicon;
+                iFavicon = NULL;
+                }
+            count--;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::StartGetFaviconsL()
+// ----------------------------------------------------------------------------
+//		
+void CBrowserFaviconHandler::StartGetFaviconsL( CFavouritesItemList* aFavItems )
+	{
+	Cancel();
+	iBmpScaler->Cancel();
+		
+	if ( aFavItems->Count() )
+		{
+		// New request for favicons: 
+		iFavItems = aFavItems;
+		
+	    // Initialisation.
+		iFavItemsCurrentIndex = 0;      // will be incremented before favicon getting
+        iFaviconsFound = 0;             // keeps track of favicons found
+		iFaviconArrayIndices->Reset();  // refresh the array mapping uid's to favicons
+		
+		// Initiate the getting of favicons	
+		GetFaviconL();
+		}
+	}
+	
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::GetFaviconL()
+// ----------------------------------------------------------------------------
+//		
+void CBrowserFaviconHandler::GetFaviconL()
+	{	
+	// The whole list has already been checked - we're finished
+	if ( iFavItemsCurrentIndex >= iFavItems->Count() )
+		{
+		iObserver.DrawFavicons();
+		}
+	else
+	    {
+	    // Step through the item array until we find a favicon, or reach the end
+		do
+			{
+			iWasLastItemFavicon = EFalse;
+			
+			CFavouritesItem& item = *iFavItems->At( iFavItemsCurrentIndex );			
+			if ( iFavicon )
+				{
+				// Make sure ongoing scaling is cancelled (if any)
+				Cancel();
+				iBmpScaler->Cancel();
+				
+				delete iFavicon;
+				iFavicon = NULL;
+				}
+						
+			// Get Favicon from Engine
+			if ( item.Url().Length() )
+				{
+				iFavicon = iApiProvider.BrCtlInterface().GetBitmapData(item.Url(), TBrCtlDefs::EBitmapFavicon );
+				}
+
+			// Asynchronously scales the favicon and stores it in an array
+			if ( iFavicon )
+				{
+				iWasLastItemFavicon = ETrue;	
+				RescaleFaviconL();
+				iFaviconsFound++;
+				__ASSERT_DEBUG( !( iFavItemsCurrentIndex > iFavItems->Count() ),
+								Util::Panic( Util::EOutOfRange ) );
+				break;
+				}
+			} while ( ++iFavItemsCurrentIndex < iFavItems->Count() );
+		}
+		
+		// If we exited the 'do' and the last item wasn't a favicon
+		// it means we're finished
+		if ( !iWasLastItemFavicon &&  ( iFaviconsFound %  KNumFaviconsToRedraw ) )
+			{
+			iObserver.DrawFavicons();
+			}
+	}
+	
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::RescaleFaviconL()
+// ----------------------------------------------------------------------------
+//
+void CBrowserFaviconHandler::RescaleFaviconL()
+	{
+	iHasMask = (iFavicon->Mask() != NULL);
+	if (iHasMask)
+		{
+		iBmpScaler->StartScalingL( *iFavicon->Mask(), iFaviconSize, ETrue );
+		}
+	else
+		{
+		iBmpScaler->StartScalingL( *iFavicon->Bitmap(), iFaviconSize, EFalse );
+		}
+	//  Complete two asynchronous requests.
+	iStatus = KRequestPending;
+	SetActive();
+
+	}
+	
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::AppendToIconArray()
+// ----------------------------------------------------------------------------
+//		
+TInt CBrowserFaviconHandler::AppendToIconArray()
+	{
+	TInt err( KErrNone );
+	TInt arrayIndex(-1);
+	
+	// Add the favicon to the icon array
+	TRAP( err, iIconArray->AppendL( iFavicon ); );
+
+	// Favicon was successfully added to the array
+	if ( !err )
+		{		
+		arrayIndex = iIconArray->Count() - 1;
+		
+		// Keep track of the index of the favicon in the icon array
+		if ( arrayIndex > -1 )
+			{
+			TFaviconIndex faviconIndex;			
+			faviconIndex.iFavouritesItemIndex = iFavItems->At( iFavItemsCurrentIndex )->Uid();
+			faviconIndex.iIndex = arrayIndex;		
+			TRAP( err, iFaviconArrayIndices->AppendL( faviconIndex ); )
+			
+			// If there was an error remove the favicon from the icon array
+			if ( err )
+				{
+				iIconArray->Delete( iIconArray->Count() - 1 );				
+				}
+			else
+				{
+				iFavicon = NULL; // favicon ownership passed
+				iFavItemsCurrentIndex++; // we can go to the next item now
+				}
+			}
+		}
+		
+	// Ownership of the favicon was not passed, so we need to delete it
+	if ( err )
+		{
+		iFaviconsFound--; // one less favicon in the array
+		}	
+		
+	return err;
+	}
+	
+	
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::GetFaviconArrayIndex()
+// ----------------------------------------------------------------------------
+//
+TInt CBrowserFaviconHandler::GetFaviconArrayIndex( const CFavouritesItem& aItem )
+	{
+	TInt arrayIndex( KErrNotFound );
+	
+	// Find the index of the favicon in the icon array
+	for ( TInt i=0; i<iFaviconArrayIndices->Count(); i++ )
+		{
+		// if uid is 0 then don't associate with favicon.  for adaptive bookmarks
+		if ( aItem.Uid() && aItem.Uid() == iFaviconArrayIndices->At(i).iFavouritesItemIndex )
+			{
+			arrayIndex = iFaviconArrayIndices->At(i).iIndex;
+			break;
+			}			
+		}	
+	return arrayIndex;
+	}
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::ScalingCompletedL()
+// ----------------------------------------------------------------------------
+//		
+void CBrowserFaviconHandler::ScalingCompletedL(CFbsBitmap* aResult, const TRect& /*aTargetRect*/)
+	{
+	// Check that favicon hasn't already disappeared (i.e. if race cond in which scaler returns 
+	// after you've already left and deleted the icon handle concerned
+	if(NULL == iFavicon)
+		{
+		return;
+		}
+	
+	
+	// Add the favicon to the icon array (which also contains other icons)
+	if (iHasMask)
+		{
+		iFavicon->SetMask(aResult);
+		iHasMask = EFalse;
+		iBmpScaler->StartScalingL( *iFavicon->Bitmap(), iFaviconSize, EFalse );
+		}
+	else
+		{
+		iFavicon->SetBitmap(aResult);
+		iFavicon->SetBitmapsOwnedExternally(EFalse);
+		TInt err = AppendToIconArray();
+		
+		// Complete the AO
+		TRequestStatus* status = &iStatus;
+		User::RequestComplete( status, err );	
+		}
+	}
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::DoCancel()
+// ----------------------------------------------------------------------------
+//	
+void CBrowserFaviconHandler::DoCancel()
+	{
+	TRequestStatus* s = &iStatus;
+	User::RequestComplete( s, KErrNone );
+	}
+	
+		
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::RunL()
+// ----------------------------------------------------------------------------
+//		
+void CBrowserFaviconHandler::RunL()
+	{		
+	TBool drawFavicons( EFalse );
+		
+	// Redraw the favicons at a predefined frequency
+	if ( iFaviconsFound % KNumFaviconsToRedraw == 0 )
+		{
+		drawFavicons = ETrue;
+		}
+	else
+		{
+		// We're not getting any more favicons: draw any undrawn ones
+		if ( iStatus != KErrNone )
+			{
+			// do a final draw
+			drawFavicons = ETrue;
+			}
+		}
+	
+	if ( drawFavicons && iFaviconsFound )
+		{
+		iObserver.DrawFavicons();
+		}
+	
+	// Continue getting favicons if no errors
+	if ( iStatus == KErrNone )
+		{
+		GetFaviconL();
+		}	
+	}
+
+// ----------------------------------------------------------------------------
+// CBrowserFaviconHandler::UpdateIconArray()
+// ----------------------------------------------------------------------------
+//	
+void CBrowserFaviconHandler::UpdateIconArray(CArrayPtr<CGulIcon>* aIconArray)
+    {
+   	iIconArray = aIconArray; 
+    }
+ 
+// End of File