browserui/browser/FavouritesSrc/BrowserFaviconHandler.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 21 Jun 2010 15:43:41 +0300
branchRCL_3
changeset 60 b149f0820e5a
parent 31 868cceedabd3
permissions -rw-r--r--
Revision: 201023 Kit: 2010125

/*
* 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