diff -r 6385c4c93049 -r 8e6fa1719340 browserui/browser/FavouritesSrc/BrowserFavouritesListbox.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/browserui/browser/FavouritesSrc/BrowserFavouritesListbox.cpp Wed Sep 01 12:31:04 2010 +0100 @@ -0,0 +1,1187 @@ +/* +* Copyright (c) 2002 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 CBrowserFavouritesListbox. +* +* +*/ + + +// INCLUDE FILES + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BrowserFavouritesListbox.h" +#include "BrowserFavouritesListboxState.h" +#include "BrowserFavouritesListboxModel.h" +#include "BrowserFavouritesListboxView.h" +#include "BrowserFavouritesModel.h" +#include "CommsModel.h" +#include "BrowserFavouritesListboxIconHandler.h" +#include "BrowserFavouritesIconIndexArray.h" +#include "BrowserUtil.h" +#include "BrowserFavouritesListboxCursorObserver.h" +#include "BrowserFavouritesListboxState.h" +#include "BrowserFavouritesListboxItemDrawer.h" +#include "ApiProvider.h" +#include "BrowserAppUi.h" + +#include "BrowserFaviconHandler.h" +#include +#include + +#include "eikon.hrh" + + +// CONSTANTS +/// Granularity of the icon index array. +LOCAL_C const TInt KGranularity = 4; + + +// ================= LOCAL FUNCTIONS ======================= + +/** +* Append elements from aSource to the end of aTarget. +* @param aTarget Array which receives copied elements from aSource. +* @param aSource Elements from this will be appended to aTarget. +*/ +LOCAL_D void AppendArrayL +( CArrayFix& aTarget, const CArrayFix& aSource ) + { + TInt i; + TInt count = aSource.Count(); + for ( i = 0; i < count; i++ ) + { + aTarget.AppendL( aSource.At( i ) ); + } + } + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::NewL +// --------------------------------------------------------- +// +CBrowserFavouritesListbox* CBrowserFavouritesListbox::NewL + ( + MApiProvider& aApiProvider, + const CCoeControl* aParent, + const MBrowserFavouritesListboxIconHandler& aIconHandler + ) + { + CBrowserFavouritesListbox* listbox = + new (ELeave) CBrowserFavouritesListbox( aApiProvider ); + CleanupStack::PushL( listbox ); + listbox->ConstructL( aParent, aIconHandler ); + CleanupStack::Pop(); // listbox + return listbox; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::~CBrowserFavouritesListbox +// --------------------------------------------------------- +// +CBrowserFavouritesListbox::~CBrowserFavouritesListbox() + { + delete iFaviconHandler; + delete iIconIndexes; + delete iItems; + delete iNewState; + if(iIconUpdateCallback) iIconUpdateCallback->Cancel(); + delete iIconUpdateCallback; + + if ( iFontItalic ) + { + CWsScreenDevice& screenDev = *( CEikonEnv::Static()->ScreenDevice() ); + screenDev.ReleaseFont( iFontItalic ); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SetListboxCursorObserver +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::SetListboxCursorObserver +(MBrowserFavouritesListboxCursorObserver* aObserver) + { + iCursorObserver = aObserver; + if ( View() ) + { + STATIC_CAST( CBrowserFavouritesListboxView*, View() )-> + SetCursorObserver( aObserver ); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SetDataL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::SetDataL +( CFavouritesItemList* aItems, /*MCommsModel& aCommsModel,*/ TBool aKeepState ) + { + __ASSERT_DEBUG( aItems, Util::Panic( Util::EUnExpected ) ); + + // Ownership of aItems is taken, and will become a member (but not yet + // that) - push until then. + CleanupStack::PushL( aItems ); + + // Get all favicons asynchronously by iteration on icon array + /* TODO: There should a callback from engine when favIcon are decode + otherwise it takes some redundant calls to engine in order to get + the favIcons to UI. */ +#ifdef BRDO_PERF_IMPROVEMENTS_ENABLED_FF + if(iApiProvider.StartedUp()) + UpdateFavIconsL(); +#else + iFaviconHandler->StartGetFaviconsL( aItems ); +#endif + + + // Get icon indexes into new list. Replace the existing + // data only if successfully gotten. This ensures that they don't go out + // of sync (there cannot be different number of items in the two list). + CBrowserFavouritesIconIndexArray* newIconIndexes = + GetIconIndexesLC( /*aCommsModel,*/ *aItems ); + + if ( aKeepState ) + { + // Calculate new state now, while we still have old items. + CalcNewStateL( *aItems ); + } + + // Got new data. Empty existing data, but keep the empty lists. + ClearSelection(); + iItems->ResetAndDestroy(); + iIconIndexes->Reset(); + SetTopItemIndex(0); + UpdateFilterL(); + HandleItemRemovalL(); + // Replace data with new. + delete iIconIndexes; // Not NULL-ed, because... + delete iItems; // Not NULL-ed, because... + iItems = aItems; // ... this cannot leave + iIconIndexes = newIconIndexes; // ... this cannot leave + + // Let the model know the change. + TheModel()->SetData( *iItems, *iIconIndexes ); // ... this cannot leave + + CleanupStack::Pop( 2 ); // newIconIndexes, aItems: now members. + HandleItemAdditionL(); + UpdateFilterL(); + if ( aKeepState ) + { + // Now set the new state into listbox, then discard it. + __ASSERT_DEBUG( iNewState, Util::Panic( Util::EUnExpected ) ); + SetStateL( *iNewState ); + delete iNewState; + iNewState = NULL; + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::UpdateFavIcons +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::UpdateFavIconsL() + { + if(iIconUpdateCallback) + iIconUpdateCallback->Cancel(); + else + iIconUpdateCallback = CIdle::NewL(CActive::EPriorityIdle); + + iFaviconHandler->RequestFavicons(iItems); + iIconUpdateCallback->Start(TCallBack(UpdateFavIconsCallback, this)); + } + +// ---------------------------------------------------------------------------- +// CBrowserBookmarksView::CompleteAppInitCallback +// ---------------------------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::UpdateFavIconsCallback( TAny* aParam ) + { + CBrowserFavouritesListbox *favListBox = STATIC_CAST(CBrowserFavouritesListbox*, aParam); + TRAP_IGNORE( (favListBox->iFaviconHandler->StartGetFaviconsL(favListBox->iItems)) ) + return EFalse; + } + + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::DrawFavicons +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::DrawFavicons() + { + // We have some favicons to draw + TInt err = KErrNone; + + //Update the icon indices + TRAP( err, + CBrowserFavouritesIconIndexArray* newIconIndexes = + GetIconIndexesLC( /*aCommsModel,*/ *iItems ); + iIconIndexes->Reset(); + delete iIconIndexes; + iIconIndexes = newIconIndexes; + CleanupStack::Pop( newIconIndexes ); + ); + + // Don't draw the favicons if there is a leave + if ( !err ) + { + // Let the model know the change and update the lisbox. + TheModel()->SetData( *iItems, *iIconIndexes ); + DrawNow(); + } + + return err; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SelectionStateL +// --------------------------------------------------------- +// +TBrowserFavouritesSelectionState +CBrowserFavouritesListbox::SelectionStateL() const + { + TBrowserFavouritesSelectionState state; + + // Check marking first. + const CArrayFix* selection = MarkedRealIndexesLC(); + TInt i; + TInt count = selection->Count(); + for ( i = 0; i < count; i++ ) + { + state.iMarkFlags |= + SelectionFlags( *(iItems->At( selection->At( i ) )) ); + if ( iItems->At( selection->At( i ) )->IsItem() ) + { + state.iMarkedItemCount++; + } + else + { + state.iMarkedFolderCount++; + } + } + + if ( count == iItems->Count() ) + { + state.iMarkFlags |= TBrowserFavouritesSelectionState::EAll; + } + + TInt visibleCount; + CAknListBoxFilterItems* filter = TheModel()->Filter(); + visibleCount = filter ? filter->FilteredNumberOfItems() : iItems->Count(); + for ( i = 0; i < visibleCount; i++ ) + { + if ( iItems->At( RealIndex( i ) )->IsItem() ) + { + state.iVisibleItemCount++; + } + else + { + state.iVisibleFolderCount++; + } + } + + TKeyArrayFix key( 0, ECmpTInt32 ); + TInt dummy; + if ( !selection->Find( CurrentItemRealIndex(), key, dummy ) ) + { + state.iMarkFlags |= + TBrowserFavouritesSelectionState::ECurrent; + } + + CleanupStack::PopAndDestroy(); // selection + + // Then comes the current. + const CFavouritesItem* current = CurrentItem(); + if ( current ) + { + state.iCurrentFlags |= SelectionFlags( *current ); + } + + return state; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::CurrentItem +// --------------------------------------------------------- +// +const CFavouritesItem* CBrowserFavouritesListbox::CurrentItem() const + { + TInt index = CurrentItemRealIndex(); + if ( index >= 0 ) + { + return iItems->At( index ); + } + return NULL; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::MarkedItemL +// --------------------------------------------------------- +// +const CFavouritesItem* CBrowserFavouritesListbox::MarkedItemL() const + { + CFavouritesItem* item = NULL; + CArrayFix* marked = MarkedRealIndexesLC(); + if ( marked->Count() == 1 ) + { + item = iItems->At( marked->At( 0 ) ); + } + CleanupStack::PopAndDestroy(); + return item; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::HighlightUidNow +// --------------------------------------------------------- +// +TBool CBrowserFavouritesListbox::HighlightUidNow( TInt aUid ) + { + TInt index = 0; + if (aUid != 0) + { + index = UidToViewIndex( aUid ); + } + + if ( index >= 0 ) + { + SetCurrentItemIndexAndDraw( index ); + return ETrue; + } + return EFalse; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::HandleMarkableListCommandL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::HandleMarkableListCommandL( TInt aCommand ) + { + if ( ListboxFlags() & EAknListBoxMarkableList ) + { + TInt index; + switch ( aCommand ) + { + case EWmlCmdMark: + { + index = CurrentItemIndex(); + if ( index >= 0 ) + { + View()->SelectItemL( index ); + } + break; + } + + case EWmlCmdUnmark: + { + index = CurrentItemIndex(); + if ( index >= 0 ) + { + View()->DeselectItem( index ); + } + break; + } + + case EWmlCmdMarkAll: + { + ClearSelection(); + TInt count = Model()->NumberOfItems(); + if ( count ) + { + TInt i = 0; + CArrayFixFlat* selection = + new(ELeave) CArrayFixFlat( 1 ); + CleanupStack::PushL( selection ); + selection->SetReserveL( count ); + for ( i = 0; i < count; i++ ) + { + selection->AppendL( i ); + } + SetSelectionIndexesL( selection ); + CleanupStack::PopAndDestroy(); // selection + } + break; + } + + case EWmlCmdUnmarkAll: + { + ClearSelection(); + break; + } + + default: + { + Util::Panic( Util::EUnExpected ); + } + } + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::MarkedUidsLC +// --------------------------------------------------------- +// +CArrayFix* CBrowserFavouritesListbox::MarkedUidsLC() const + { + CArrayFix* array = MarkedRealIndexesLC(); + RealIndexesToUids( *array ); + return array; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SelectedUidsLC +// --------------------------------------------------------- +// +CArrayFix* CBrowserFavouritesListbox::SelectedUidsLC() const + { + CArrayFix* array = SelectedRealIndexesLC(); + RealIndexesToUids( *array ); + return array; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SelectedItemsLC +// --------------------------------------------------------- +// +CArrayPtr* +CBrowserFavouritesListbox::SelectedItemsLC(TBool aIncludeSpecialItems) const + { + CArrayPtrFlat* itemPtrs = + new (ELeave) CArrayPtrFlat( KGranularity ); + CleanupStack::PushL( itemPtrs ); + CArrayFix* indexes = SelectedRealIndexesLC(); + TInt i; + TInt count = indexes->Count(); + for ( i = 0; i < count; i++ ) + { + CFavouritesItem* item = iItems->At( indexes->At( i ) ); + + if ( !aIncludeSpecialItems ) + { + // Skip special items: + // folders, homepage, last visited & start page URLs. + // Need a workaround for the start page since CFavouritesItem + // does not provide IsStartPage() or something similar. + if ( (item->Uid() == KFavouritesHomepageUid ) || + (item->Uid() == KFavouritesLastVisitedUid ) || + item->IsFolder() || + item->Uid() == KFavouritesStartPageUid ) + continue; + } + itemPtrs->AppendL( item ); + } + CleanupStack::PopAndDestroy(); // indexes + return itemPtrs; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::ItemByUid +// --------------------------------------------------------- +// +const CFavouritesItem* CBrowserFavouritesListbox::ItemByUid +( TInt aUid ) const + { + return iItems->ItemByUid( aUid ); + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::UnfilteredNumberOfItems +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::UnfilteredNumberOfItems() + { + return iItems->Count(); + } + + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::FilteredNumberOfItems +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::FilteredNumberOfItems() + { + + CAknListBoxFilterItems* filter = TheModel()->Filter(); + return filter->FilteredNumberOfItems(); + } + + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::UpdateFilterL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::UpdateFilterL() + { + CAknListBoxFilterItems* filter = TheModel()->Filter(); + if ( filter ) + { + filter->HandleItemArrayChangeL(); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::AnyFoldersL +// --------------------------------------------------------- +// +TBool CBrowserFavouritesListbox::AnyFoldersL() + { + TInt i; + TInt count = iItems->Count(); + for ( i = 0; i < count; i++ ) + { + if ( iItems->At( i )->IsFolder() ) + { + if (iItems->At( i )->Uid()!=KFavouritesAdaptiveItemsFolderUid) return ETrue; //exclude Adaptive Bookmarks Folder + } + } + return EFalse; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::OfferKeyEventL +// --------------------------------------------------------- +// +TKeyResponse CBrowserFavouritesListbox::OfferKeyEventL +( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + TKeyResponse result = EKeyWasNotConsumed; + + switch ( aKeyEvent.iCode ) + { + case EKeyLeftUpArrow: // Northwest + case EStdKeyDevice10: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyLeftArrow: // West + case EKeyLeftDownArrow: // Southwest + case EStdKeyDevice13: // : Extra KeyEvent supports diagonal event simulator wedge + + case EKeyRightUpArrow: // Northeast + case EStdKeyDevice11: // : Extra KeyEvent supports diagonal event simulator wedge + case EKeyRightArrow: // East + case EKeyRightDownArrow: // Southeast + case EStdKeyDevice12: // : Extra KeyEvent supports diagonal event simulator wedge + { + // This listbox does not consume left/right or diagonal keypresses. + // (The base class always does, even if it doesn't use them ) + break; + } + + default: + { + result = CAknSingleGraphicStyleListBox::OfferKeyEventL + ( aKeyEvent, aType ); + // Call UpdateCBA to update MSK in case of mark/unmark + CBrowserAppUi::Static()->UpdateCbaL(); + } + + } + + return result; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::FocusChanged +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::FocusChanged( TDrawNow aDrawNow ) + { + // Do nothing until the listbox is fully constructed + // The dialogpage sets the focus before calling ConstructL + if ( iView ) + { + CAknSingleGraphicStyleListBox::FocusChanged( aDrawNow ); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::CreateModelL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::CreateModelL() + { + iModel = CBrowserFavouritesListboxModel::NewL( *iItems, *iIconIndexes ); + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::MakeViewClassInstanceL +// --------------------------------------------------------- +// +CListBoxView* CBrowserFavouritesListbox::MakeViewClassInstanceL() + { + return new (ELeave) CBrowserFavouritesListboxView( *this ); + } + + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::CreateItemDrawerL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::CreateItemDrawerL() + { + CAknSingleGraphicStyleListBox::CreateItemDrawerL(); + } + + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::CBrowserFavouritesListbox +// --------------------------------------------------------- +// +CBrowserFavouritesListbox::CBrowserFavouritesListbox + ( MApiProvider& aApiProvider ) : + iApiProvider( aApiProvider ) + { + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::ConstructL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::ConstructL + ( + const CCoeControl* aParent, + const MBrowserFavouritesListboxIconHandler& aIconHandler + ) + { + iSkinUpdated = EFalse; + iIconHandler = &aIconHandler; + iItems = new (ELeave) CFavouritesItemList(); + iIconIndexes = + new (ELeave) CBrowserFavouritesIconIndexArray( KGranularity ); + CAknSingleGraphicStyleListBox::ConstructL( aParent, ListboxFlags() ); + // MUST call this after the listbox has finished; listbox construction + // is buggy and overwrites the model's itemarray ptr. + TheModel()->SetItemArray(); + CreateScrollBarFrameL( ETrue ); + ScrollBarFrame()->SetScrollBarVisibilityL + ( CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); + + // Load icons + ItemDrawer()->ColumnData()->SetIconArray + ( iIconHandler->CreateIconArrayL() ); + + // Store the size of an icon + TAknWindowComponentLayout layout = + AknLayoutScalable_Avkon::list_single_graphic_pane_g1(0); + + TAknLayoutRect naviPaneGraphicsLayoutRect; + TRect listBoxGraphicRect; + TRect rect = iAvkonAppUi->ClientRect(); + + + naviPaneGraphicsLayoutRect.LayoutRect( rect, layout); + listBoxGraphicRect = naviPaneGraphicsLayoutRect.Rect(); + + TSize listBoxGraphicSize( listBoxGraphicRect.iBr.iX - listBoxGraphicRect.iTl.iX, + listBoxGraphicRect.iBr.iY - listBoxGraphicRect.iTl.iY ); + // Favicon handler + iFaviconHandler = CBrowserFaviconHandler::NewL( + iApiProvider, + ItemDrawer()->ColumnData()->IconArray(), + *this, + listBoxGraphicSize ); + + ItemDrawer()->ColumnData()->EnableMarqueeL( ETrue ); + + + // Setup italicized font for use later + const CFont* logicalFont = AknLayoutUtils::FontFromId(EAknLogicalFontPrimaryFont); + + // Note: This font is owned by the application's system font array (where it + // is likely already to have been created) and does not need to be + // released. It can just go out of scope.// Extract font information + TFontSpec fontSpec = logicalFont->FontSpecInTwips();// Desired height, weight, and posture already set in locals + fontSpec.iFontStyle.SetPosture( EPostureItalic );// Obtain new font + CWsScreenDevice& screenDev = *( CEikonEnv::Static()->ScreenDevice() ); + screenDev.GetNearestFontInTwips( ( CFont*& )iFontItalic, fontSpec ); + + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::ListboxFlags +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::ListboxFlags() + { + return AknLayoutUtils::PenEnabled() ? + EAknListBoxStylusMarkableList : EAknListBoxMarkableList; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::GetIconIndexesLC +// --------------------------------------------------------- +// +CBrowserFavouritesIconIndexArray* +CBrowserFavouritesListbox::GetIconIndexesLC +( /*MCommsModel& aCommsModel, */CFavouritesItemList& aItems ) + { + // Create new empty list. + CBrowserFavouritesIconIndexArray* iconIndexes = + new (ELeave) CBrowserFavouritesIconIndexArray( KGranularity ); + CleanupStack::PushL( iconIndexes ); + // Get list of access points. Not copy, owned by the AP model. + // const CApListItemList* apList = aCommsModel.AccessPoints(); + // Fill the list. + TInt i = 0; + TInt count = aItems.Count(); + for ( i = 0; i < count; i++ ) + { + iconIndexes->AppendL + ( iIconHandler->IconIndexes( *(aItems.At( i ))/*, apList*/,this ) ); + } + return iconIndexes; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::CalcNewStateL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::CalcNewStateL +( CFavouritesItemList& aNewItems ) + { + delete iNewState; + iNewState = NULL; + iNewState = new( ELeave ) CBrowserFavouritesListboxState; + + // 1. Check if we have any new item. If yes, highlight goes to first + // new one. + TInt i; + TInt count = aNewItems.Count(); + for ( i = 0; i < count; i++ ) + { + if ( iItems->UidToIndex( aNewItems.IndexToUid( i ) ) == + KErrNotFound ) + { + // New item, not found among the old ones. + // Set highlight to that, and also becomes top item. + iNewState->iHighlightUid = iNewState->iTopItemUid = + aNewItems.IndexToUid( i ); + break; + } + } + + // 2. If there is no new item, get the new highlight. That is the old + // one, if still exists, or the next remaining one after the + // deleted old one(s). + TInt uid; + if ( iNewState->iHighlightUid == KFavouritesNullUid ) + { + i = CurrentItemRealIndex(); + if ( i >= 0 ) + { + // Have current item. + // Now go down the old list, beginning from highlighted one; + // find first item that still exists. + count = iItems->Count(); + for ( /*current highlight index: i*/; i < count; i++ ) + { + uid = iItems->At( i )->Uid(); + if ( aNewItems.UidToIndex( uid ) != KErrNotFound ) + { + iNewState->iHighlightUid = uid; + break; + } + } + // Here we should have higlight uid, unless the deleted element(s) + // were last. In that case, set last item highlighted (if there is + // anything to highlight). + if ( iNewState->iHighlightUid == KFavouritesNullUid && + aNewItems.Count() ) + { + iNewState->iHighlightUid = aNewItems.IndexToUid + ( aNewItems.Count() - 1 ); + } + } + } + + // 3. Get mark uids. Whether these uids exist in the new list or not, is + // not checked here; setting marks to the already changed listbox is + // fool-proof. + iNewState->iMarkUids = MarkedUidsLC(); + CleanupStack::Pop(); // Uid list; ownership is now in the state. + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SetStateL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::SetStateL +( const CBrowserFavouritesListboxState& aState ) + { + TInt topIndex; + + // Set marks. + if ( aState.iMarkUids->Count() ) + { + CArrayFix* marks = new (ELeave) CArrayFixFlat( 4 ); + CleanupStack::PushL( marks ); + marks->AppendL + ( aState.iMarkUids->Back( 0 ), aState.iMarkUids->Count() ); + UidsToViewIndexes( *marks ); + SetSelectionIndexesL( marks ); + CleanupStack::PopAndDestroy(); // marks + } + + // Set top item index. + topIndex = UidToViewIndex ( aState.iTopItemUid ); + if ( topIndex >= 0 ) + { + // Always try to fill the listbox (if there were empty lines below, + // "scroll down", instead of strictly restoring the top item index). + TInt topIndexToSeeLastItem = Model()->NumberOfItems() - + View()->NumberOfItemsThatFitInRect( View()->ViewRect() ); + if ( topIndexToSeeLastItem < 0 ) + { + topIndexToSeeLastItem = 0; + } + topIndex = Min( topIndex, topIndexToSeeLastItem ); + SetTopItemIndex( topIndex ); + } + + // Set higlight. + TInt curIndex = UidToViewIndex ( aState.iHighlightUid ); + if ( curIndex < 0 ) + { + // If cannot restore highlight, set it to top item. + curIndex = topIndex; + } + if ( curIndex >= 0 ) + { + SetCurrentItemIndex( curIndex ); + } + + DrawNow(); + + if ( iCursorObserver ) + { + // Cursor now points to some different item. Let the observer know it. + iCursorObserver->HandleCursorChangedL( this ); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::UidToViewIndex +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::UidToViewIndex( TInt aUid ) const + { + TInt viewIndex = KErrNotFound; + TInt realIndex = iItems->UidToIndex( aUid ); + if ( realIndex >= 0 ) + { + CAknListBoxFilterItems* filter = TheModel()->Filter(); + if ( filter ) + { + // Have filter, do the conversion. + viewIndex = filter->VisibleItemIndex( realIndex ); + } + else + { + // No filter, no conversion necessary. + viewIndex = realIndex; + } + } + return viewIndex; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::UidsToViewIndexes +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::UidsToViewIndexes +( CArrayFix& aList ) const + { + TInt i; + TInt j; + TInt index; + TInt count = aList.Count(); + for ( i = 0, j = 0; i < count; i++ ) + { + index = UidToViewIndex( aList.At ( i ) ); + if ( index != KErrNotFound ) + { + aList.At( j++ ) = index; + } + } + if ( j < count ) + { + // Not all Uids were converted. Delete the trailing rubbish. + aList.Delete( j, count - j ); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::RealIndexesToUids +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::RealIndexesToUids +( CArrayFix& aList ) const + { + TInt i; + TInt uid; + TInt count = aList.Count(); + for ( i = 0; i < count; i++ ) + { + uid = iItems->IndexToUid( aList.At( i ) ); + __ASSERT_DEBUG( uid != KFavouritesNullUid, \ + Util::Panic( Util::EFavouritesBadBookmarkUid ) ); + aList.At( i ) = uid; + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::MarkedRealIndexesLC +// --------------------------------------------------------- +// +CArrayFix* CBrowserFavouritesListbox::MarkedRealIndexesLC() const + { + CListBoxView::CSelectionIndexArray* array = + new (ELeave) CArrayFixFlat( KGranularity ); + CleanupStack::PushL( array ); + if ( iItems->Count() ) + { + const CArrayFix* marked; + CAknListBoxFilterItems* filter = TheModel()->Filter(); + if ( filter ) + { + // Filter knows all. + filter->UpdateSelectionIndexesL(); + marked = filter->SelectionIndexes(); +#if 1 /* TODO remove when AVKON bug fixed*/ + // Overcoming AVKON bug. If filter criteria is empty (i.e. the + // user is not typing in the filter), selection indexes between + // the filter and the listbox are not synchronized! Unfortunately, + // this strange back-way is the only means by we can discover if + // we have criteria or not; CAknListBoxFilterItems has the + // criteria as private; and the CAknSearchField, which holds the + // filter (and has the string) is not accessible here in the + // listbox (it's in the container). + if ( filter->FilteredNumberOfItems() == + filter->NonFilteredNumberOfItems() ) + { + marked = View()->SelectionIndexes(); + } +#endif + } + else + { + // No filter. + marked = View()->SelectionIndexes(); + } + AppendArrayL( /*aTarget=*/*array, /*aSource=*/*marked ); + } + return array; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SelectedRealIndexesLC +// --------------------------------------------------------- +// +CArrayFix* CBrowserFavouritesListbox::SelectedRealIndexesLC() const + { + CListBoxView::CSelectionIndexArray* selection = + MarkedRealIndexesLC(); + if ( selection->Count() == 0 ) + { + // No marks; use the highlighted one. + selection->AppendL( CurrentItemRealIndex() ); + } + return selection; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::CurrentItemRealIndex +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::CurrentItemRealIndex() const + { + return RealIndex( CurrentItemIndex() /*that's view index*/ ); + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::RealIndex +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::RealIndex( TInt aViewIndex ) const + { + TInt index = KErrNotFound; + if ( aViewIndex >= 0 ) + { + CAknListBoxFilterItems* filter = TheModel()->Filter(); + if ( filter ) + { + // If we have the index and the filter also, do the conversion. + index = filter->FilteredItemIndex( aViewIndex ); + } + else + { + index = aViewIndex; + } + } + return index; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::RealIndexes +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::RealIndexes( CArrayFix& aList ) const + { + TInt i; + TInt j; + TInt index; + TInt count = aList.Count(); + for ( i = 0, j = 0; i < count; i++ ) + { + index = RealIndex( aList.At ( i ) ); + if ( index != KErrNotFound ) + { + aList.At( j++ ) = index; + } + } + if ( j < count ) + { + // Not all indexes were converted. Delete the trailing rubbish. + aList.Delete( j, count - j ); + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SelectionFlags +// --------------------------------------------------------- +// +TInt CBrowserFavouritesListbox::SelectionFlags +( const CFavouritesItem& aItem ) const + { + TInt flags = 0; + if ( aItem.IsItem() ) + { + switch ( aItem.Uid() ) + { + case KFavouritesHomepageUid: + { + flags |= + TBrowserFavouritesSelectionState::EAny | + TBrowserFavouritesSelectionState::EHomepage | + TBrowserFavouritesSelectionState::EItem; + break; + } + + case KFavouritesStartPageUid: + { + flags |= + TBrowserFavouritesSelectionState::EAny | + TBrowserFavouritesSelectionState::EStartPage | + TBrowserFavouritesSelectionState::EItem; + break; + } + + case KFavouritesLastVisitedUid: + { + flags |= + TBrowserFavouritesSelectionState::EAny | + TBrowserFavouritesSelectionState::ELastVisited | + TBrowserFavouritesSelectionState::EItem; + break; + } + + default: + { + flags |= + TBrowserFavouritesSelectionState::EAny | + TBrowserFavouritesSelectionState::EPlainItem | + TBrowserFavouritesSelectionState::EItem; + break; + } + } + } + else + { + flags |= + TBrowserFavouritesSelectionState::EAny | + TBrowserFavouritesSelectionState::EFolder; + } + return flags; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::TheModel +// --------------------------------------------------------- +// +CBrowserFavouritesListboxModel* +CBrowserFavouritesListbox::TheModel() const + { + return REINTERPRET_CAST( CBrowserFavouritesListboxModel*, Model() ); + } + + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::HandleResourceChange +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::HandleResourceChange( TInt aType ) + { + CAknSingleGraphicStyleListBox::HandleResourceChange( aType ); + if ( aType == KAknsMessageSkinChange ) + { + CArrayPtr* array = + ItemDrawer()->ColumnData()->IconArray(); + + array->ResetAndDestroy(); + delete array; + + CAknIconArray* iconArray = NULL; + TRAPD( err, + iconArray = iIconHandler->CreateIconArrayL() + ) + + if ( !err ) + { + ItemDrawer()->ColumnData()->SetIconArray( iconArray ); + iFaviconHandler->UpdateIconArray(ItemDrawer()->ColumnData()->IconArray()); + SetSkinUpdated(ETrue); + } + } + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::SetSkinUpdated +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::SetSkinUpdated(TBool aSkinUpdated) + { + iSkinUpdated = aSkinUpdated; + } + +// --------------------------------------------------------- +// CBrowserFavouritesListbox::ItalicizeRowItemL +// --------------------------------------------------------- +// +void CBrowserFavouritesListbox::ItalicizeRowItemL(TInt aRowIndex) + { + if (ItemDrawer() && ItemDrawer()->ColumnData() && iFontItalic) + { + ItemDrawer()->ColumnData()->SetColumnFontForRowL( aRowIndex, 1, iFontItalic ); + } + } + +// End of File