--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/CommonUI/src/CPbk2TabGroupContainer.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,599 @@
+/*
+* Copyright (c) 2005-2007 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: Phonebook 2 tab group container.
+*
+*/
+
+
+#include "CPbk2TabGroupContainer.h"
+
+// Phonebook 2
+#include <CPbk2ViewGraph.h>
+#include <CPbk2IconInfoContainer.h>
+#include <CPbk2IconFactory.h>
+#include <TPbk2IconId.h>
+#include <MPbk2ViewExplorer.h>
+#include <CPbk2AppUiBase.h>
+#include <CPbk2AppViewBase.h>
+#include <Pbk2UID.h>
+#include <MPbk2TabGroupContainerCallback.h>
+
+// System includes
+#include <barsread.h>
+#include <aknnavide.h>
+#include <akntabgrp.h>
+#include <AknsConstants.h>
+#include <AknsUtils.h>
+#include <eikspane.h>
+#include <aknnavide.h>
+
+// Debugging headers
+#include <Pbk2Profile.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+/**
+ * The maximum amount of visible tabs in the tab group.
+ */
+const TInt KMaxTabsInTabGroup = 4;
+
+/**
+ * Returns the topmost tab group.
+ *
+ * @return Topmost tab group.
+ */
+CAknTabGroup* GetTabGroupOnTop()
+ {
+ CAknTabGroup* result = NULL;
+
+ CAknNavigationControlContainer* naviPane =
+ static_cast<CAknNavigationControlContainer*>
+ ( CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL
+ ( TUid::Uid( EEikStatusPaneUidNavi ) ) );
+
+ if ( naviPane )
+ {
+ CAknNavigationDecorator* topDecorator = naviPane->Top();
+ if ( topDecorator && topDecorator->ControlType() ==
+ CAknNavigationDecorator::ETabGroup )
+ {
+ result = static_cast<CAknTabGroup*>(
+ topDecorator->DecoratedControl() );
+ }
+ }
+ return result;
+ }
+
+} /// namespace
+
+
+/**
+ * Phonebook 2 tab group entry.
+ * Responsible for tab groups. Clients may modify the
+ * tab group through this class.
+ */
+class CPbk2TabGroupContainer::CPbk2TabGroupEntry : public CBase
+ {
+ public: // Construction and destruction
+
+ /**
+ * Creates a new instance of this class.
+ *
+ * @param aTabGroupId Tab group id.
+ * @param aTabGroup Tab group.
+ * @return A new instance of this class.
+ */
+ static CPbk2TabGroupEntry* NewL(
+ TPbk2TabGroupId aTabGroupId,
+ CAknNavigationDecorator* aTabGroup );
+
+ /**
+ * Destructor.
+ */
+ ~CPbk2TabGroupEntry();
+
+ public: // Interface
+
+ /**
+ * Returns the tab group id.
+ *
+ * @return Tab group id.
+ */
+ inline TPbk2TabGroupId TabGroupId() const;
+
+ /**
+ * Returns the tab group.
+ *
+ * @return Tab group.
+ */
+ inline CAknTabGroup* TabGroup() const;
+
+ /**
+ * Returns the navigation decorator.
+ *
+ * @return Navigation decorator.
+ */
+ inline CAknNavigationDecorator* Decorator() const;
+
+ private: // Implementation
+ CPbk2TabGroupEntry(TPbk2TabGroupId aTabGroupId,
+ CAknNavigationDecorator* aTabGroup );
+
+ private: // Data
+ /// Own: Phonebook 2 tab group id
+ TPbk2TabGroupId iTabGroupId;
+ /// Own: Avkon tab group
+ CAknNavigationDecorator* iTabGroup;
+ };
+
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupEntry::CPbk2TabGroupEntry
+// --------------------------------------------------------------------------
+//
+CPbk2TabGroupContainer::CPbk2TabGroupEntry::CPbk2TabGroupEntry
+ ( TPbk2TabGroupId aTabGroupId, CAknNavigationDecorator* aTabGroup ) :
+ iTabGroupId( aTabGroupId ),
+ iTabGroup( aTabGroup )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::CPbk2TabGroupEntry::~CPbk2TabGroupEntry
+// --------------------------------------------------------------------------
+//
+CPbk2TabGroupContainer::CPbk2TabGroupEntry::~CPbk2TabGroupEntry()
+ {
+ delete iTabGroup;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::CPbk2TabGroupEntry::CPbk2TabGroupEntry
+// --------------------------------------------------------------------------
+//
+CPbk2TabGroupContainer::CPbk2TabGroupEntry*
+ CPbk2TabGroupContainer::CPbk2TabGroupEntry::NewL
+ ( TPbk2TabGroupId aTabGroupId, CAknNavigationDecorator* aTabGroup )
+ {
+ CPbk2TabGroupEntry* self = new ( ELeave ) CPbk2TabGroupEntry
+ ( aTabGroupId, aTabGroup );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroupId
+// --------------------------------------------------------------------------
+//
+inline TPbk2TabGroupId
+ CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroupId() const
+ {
+ return iTabGroupId;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroup
+// --------------------------------------------------------------------------
+//
+inline CAknTabGroup*
+ CPbk2TabGroupContainer::CPbk2TabGroupEntry::TabGroup() const
+ {
+ return static_cast<CAknTabGroup*>( iTabGroup->DecoratedControl() );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupEntry::Decorator
+// --------------------------------------------------------------------------
+//
+inline CAknNavigationDecorator*
+ CPbk2TabGroupContainer::CPbk2TabGroupEntry::Decorator() const
+ {
+ return iTabGroup;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::CPbk2TabGroupContainer
+// --------------------------------------------------------------------------
+//
+CPbk2TabGroupContainer::CPbk2TabGroupContainer(
+ MPbk2ViewExplorer& aViewExplorer,
+ MPbk2TabGroupContainerCallback& aCallback ) :
+ iViewExplorer( aViewExplorer ),
+ iCallback ( aCallback )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::~CPbk2TabGroupContainer
+// --------------------------------------------------------------------------
+//
+CPbk2TabGroupContainer::~CPbk2TabGroupContainer()
+ {
+ delete iTabIcons;
+ iViewTabGroups.ResetAndDestroy();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroup::ConstructL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2TabGroupContainer::ConstructL()
+ {
+ iTabIcons = CPbk2IconInfoContainer::NewL();
+
+ PBK2_PROFILE_START(Pbk2Profile::ETabGroupCreateTabGroups);
+ // creates all the tab groups and tabs
+ CreateTabGroupsL();
+ PBK2_PROFILE_END(Pbk2Profile::ETabGroupCreateTabGroups);
+
+ PBK2_PROFILE_START(Pbk2Profile::ETabGroupSkinTabGroups);
+ // skins the created tabs by looping through all of them
+ SkinTabGroupsL();
+ PBK2_PROFILE_END(Pbk2Profile::ETabGroupSkinTabGroups);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::NewL
+// --------------------------------------------------------------------------
+//
+EXPORT_C CPbk2TabGroupContainer* CPbk2TabGroupContainer::NewL(
+ MPbk2ViewExplorer& aViewExplorer,
+ MPbk2TabGroupContainerCallback& aCallback )
+ {
+ CPbk2TabGroupContainer* self =
+ new ( ELeave ) CPbk2TabGroupContainer( aViewExplorer, aCallback );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::TabGroupFromViewId
+// --------------------------------------------------------------------------
+//
+EXPORT_C CAknNavigationDecorator* CPbk2TabGroupContainer::TabGroupFromViewId
+ ( TInt aId ) const
+ {
+ CAknNavigationDecorator* tabGroupDecorator = NULL;
+
+ // Loop through the view tab groups array
+ const TInt tabGroupCount = iViewTabGroups.Count();
+ for (TInt i = 0; i < tabGroupCount; ++i)
+ {
+ CAknTabGroup* tabGroup = iViewTabGroups[i]->TabGroup();
+ if (tabGroup->TabIndexFromId(aId) >= 0)
+ {
+ CAknNavigationDecorator* decorator =
+ iViewTabGroups[i]->Decorator();
+ tabGroupDecorator = decorator;
+ break;
+ }
+ }
+
+ return tabGroupDecorator;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::HandleNavigationKeyEventL
+// --------------------------------------------------------------------------
+//
+EXPORT_C TBool CPbk2TabGroupContainer::HandleNavigationKeyEventL
+ ( const TKeyEvent& aKeyEvent, TEventCode aType )
+ {
+ TBool result = EFalse;
+ CAknTabGroup* topTabGroup = GetTabGroupOnTop();
+
+ if ( topTabGroup )
+ {
+ // Offer key event to be handled to top most tab
+ result = ( topTabGroup->OfferKeyEventL
+ ( aKeyEvent, aType ) == EKeyWasConsumed );
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::TabIcons
+// --------------------------------------------------------------------------
+//
+EXPORT_C CPbk2IconInfoContainer& CPbk2TabGroupContainer::TabIcons() const
+ {
+ return *iTabIcons;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::TabChangedL
+// --------------------------------------------------------------------------
+//
+void CPbk2TabGroupContainer::TabChangedL( TInt aIndex )
+ {
+ CAknTabGroup* topTabGroup = GetTabGroupOnTop();
+ if ( topTabGroup )
+ {
+ // View id is stored in the tab
+ const TInt viewId = topTabGroup->TabIdFromIndex( aIndex );
+
+ MPbk2AppUi* appUi = Phonebook2::Pbk2AppUi();
+
+ CPbk2ViewState* activeViewState =
+ appUi->ActiveView()->ViewStateLC();
+ iViewExplorer.ActivatePhonebook2ViewL( TUid::Uid( viewId ),
+ activeViewState );
+ CleanupStack::PopAndDestroy( activeViewState );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::HandleNaviDecoratorEventL
+// --------------------------------------------------------------------------
+//
+void CPbk2TabGroupContainer::HandleNaviDecoratorEventL( TInt aEventID )
+ {
+ if ( AknLayoutUtils::PenEnabled() )
+ {
+ CAknTabGroup* topTabGroup = GetTabGroupOnTop();
+ if ( topTabGroup )
+ {
+ topTabGroup->HandleNaviDecoratorEventL( aEventID );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::DoCalculateTabGroupWidth
+// --------------------------------------------------------------------------
+//
+TInt CPbk2TabGroupContainer::DoCalculateTabGroupWidth
+ ( TInt aViewCount ) const
+ {
+ TInt width = EAknTabWidthWithOneTab;
+ switch ( aViewCount )
+ {
+ case 1:
+ width = EAknTabWidthWithOneTab;
+ break;
+ case 2:
+ width = EAknTabWidthWithTwoTabs;
+ break;
+ case 3:
+ width = EAknTabWidthWithThreeTabs;
+ break;
+ case 4:
+ width = EAknTabWidthWithFourTabs;
+ break;
+ }
+ if (aViewCount > KMaxTabsInTabGroup)
+ {
+ // n tabs is the maximum amount visible
+ width = EAknTabWidthWithFourTabs;
+ }
+
+ return width;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::DoReadViewNodeTabResourcesL
+// Reads a PBK2_VIEW_NODE_TAB structure, then based on the amount of
+// views in the tab selects the correct substructure and adds an avkon
+// tab from the TAB resource
+// --------------------------------------------------------------------------
+//
+void CPbk2TabGroupContainer::DoReadViewNodeTabResourcesL
+ ( const CPbk2ViewNode& aNode, CAknTabGroup& aAknTabGroup,
+ TInt aViewCount )
+ {
+ // Reads PBK2_VIEW_NODE_TAB structure in the
+ // view graph node
+ TResourceReader resReader;
+ CCoeEnv::Static()->CreateResourceReaderLC
+ ( resReader, aNode.TabResourceId() );
+
+ // Check how many PBK2_VIEW_NODE_TAB elements there are to read
+ const TInt count = resReader.ReadInt16();
+ TBool found = EFalse;
+ // Loop through the resource elements,
+ for ( TInt i = 0; i < count && !found; ++i )
+ {
+ resReader.ReadInt8(); // read version number
+ TInt tabsInGroup = resReader.ReadInt8();
+ TInt tabResourceId = resReader.ReadInt32();
+ TInt iconResId = resReader.ReadInt32();
+ // Check if this resource structure corresponds
+ // to the amount of tabs previously found in the tab group
+ if ( tabsInGroup == aViewCount ||
+ (aViewCount >= KMaxTabsInTabGroup &&
+ tabsInGroup == KMaxTabsInTabGroup))
+ {
+ // Read a TAB structure
+ TResourceReader tabResReader;
+ CCoeEnv::Static()->CreateResourceReaderLC
+ ( tabResReader, tabResourceId );
+ // Feed structure to Avkon tab group
+ aAknTabGroup.AddTabL( tabResReader );
+ CleanupStack::PopAndDestroy(); // tabResReader
+
+ // Read the icons
+ if ( iconResId != 0 )
+ {
+ // Add icon infos associated with the TAB to the
+ // icon info container
+ iTabIcons->AppendIconsFromResourceL(
+ iconResId );
+ }
+ }
+ }
+ CleanupStack::PopAndDestroy(); // resReader
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::CreateTabGroupsL
+// Initializes the tab group from the view graph
+// --------------------------------------------------------------------------
+//
+void CPbk2TabGroupContainer::CreateTabGroupsL()
+ {
+ RArray<TUid> viewIds;
+ CleanupClosePushL( viewIds );
+
+ // Get the number of nodes in the view graph
+ const TInt nodeCount = iViewExplorer.ViewGraph().Count();
+
+ // Travel through all the view graph nodes
+ for ( TInt i = 0; i < nodeCount; ++i )
+ {
+ const CPbk2ViewNode& viewNode = iViewExplorer.ViewGraph()[i];
+
+ // Check the view nodes tab group id and if it exists with
+ // tab resource id, create tabs unless the view has already
+ // been added to some tab group
+ TPbk2TabGroupId tabGroupId = viewNode.TabGroupId();
+ if ( tabGroupId != 0 &&
+ viewNode.TabResourceId() != 0 &&
+ viewIds.Find( viewNode.ViewId() ) == KErrNotFound )
+ {
+ // Get the view graph nodes in the same tab group
+ RPointerArray<CPbk2ViewNode> viewsInTabGroup =
+ iViewExplorer.ViewGraph().FindViewsInTabGroupL(
+ tabGroupId );
+ CleanupClosePushL( viewsInTabGroup );
+
+ // Set up the tab group width
+ const TInt viewsInTabGroupCount = viewsInTabGroup.Count();
+ const TInt tabWidth =
+ DoCalculateTabGroupWidth( viewsInTabGroupCount );
+
+ // Create tab group if it does not already exist
+ CAknTabGroup& aknTabGroup = FindTabGroupWithIdL( tabGroupId );
+ aknTabGroup.SetTabFixedWidthL( tabWidth );
+
+ // Loop through the tab groups' views
+ for ( TInt view = 0; view < viewsInTabGroupCount; ++view )
+ {
+ // Get the tab group view node and add its view id to
+ // the view id array
+ const CPbk2ViewNode& node = *viewsInTabGroup[view];
+ viewIds.AppendL( node.ViewId() );
+
+ // If there is no tabs TabResourceId() returns 0.
+ // tabs -resource defaults to 0.
+ if (node.TabResourceId() != 0)
+ {
+ // Read the view node tab resource structure and
+ // adds the tabs to the tab group
+ DoReadViewNodeTabResourcesL
+ ( node, aknTabGroup, viewsInTabGroupCount );
+ }
+ else
+ {
+ // tab group resource doesnt exits, ask callback to create tab
+ iCallback.CreateViewNodeTabL(
+ node, aknTabGroup, *iTabIcons, viewsInTabGroupCount );
+ }
+
+ }
+ CleanupStack::PopAndDestroy(); // viewInTabGroup
+ }
+ }
+ CleanupStack::PopAndDestroy(); // viewIds
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::FindTabGroupWithIdL
+// --------------------------------------------------------------------------
+//
+CAknTabGroup& CPbk2TabGroupContainer::FindTabGroupWithIdL
+ ( TPbk2TabGroupId aTabGroupId )
+ {
+ CAknTabGroup* result = NULL;
+
+ // Find the tab group from the container
+ const TInt tabGroupCount = iViewTabGroups.Count();
+ for ( TInt i=0; i < tabGroupCount; ++i )
+ {
+ if ( iViewTabGroups[i]->TabGroupId() == aTabGroupId )
+ {
+ result = iViewTabGroups[i]->TabGroup();
+ break;
+ }
+ }
+
+ // If the tab group doesnt exists, it is created
+ if ( !result )
+ {
+ CAknNavigationControlContainer* naviPane =
+ static_cast<CAknNavigationControlContainer*>
+ ( CEikonEnv::Static()->AppUiFactory()->StatusPane()->ControlL
+ ( TUid::Uid( EEikStatusPaneUidNavi ) ) );
+
+ // Create the new tab group
+ CAknNavigationDecorator* newTabGroup =
+ naviPane->CreateTabGroupL( this );
+ CleanupStack::PushL( newTabGroup );
+ CPbk2TabGroupEntry* entry = CPbk2TabGroupEntry::NewL
+ ( aTabGroupId, newTabGroup );
+ CleanupStack::Pop( newTabGroup );
+ CleanupStack::PushL(entry);
+ iViewTabGroups.AppendL(entry);
+ CleanupStack::Pop( entry );
+ result = static_cast<CAknTabGroup*>
+ ( newTabGroup->DecoratedControl() );
+ }
+
+ return *result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2TabGroupContainer::SkinTabGroupsL
+// This function loops all the tabs and overrides then if theres a skin
+// --------------------------------------------------------------------------
+//
+void CPbk2TabGroupContainer::SkinTabGroupsL()
+ {
+ MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+
+ // Travel all the tab groups that have been created
+ const TInt count = iViewTabGroups.Count();
+ for (TInt i = 0; i < count; ++i)
+ {
+ CAknTabGroup& tabGroup = *iViewTabGroups[i]->TabGroup();
+
+ // loop through the tabs in the tab group
+ const TInt tabCount = tabGroup.TabCount();
+ for (TInt j = 0; j < tabCount; ++j)
+ {
+ TInt tabId = tabGroup.TabIdFromIndex(j);
+ // tabId is used as icon id
+ TPbk2IconId iconId( TUid::Uid(KPbk2UID3), tabId );
+ // Find the icon info from the tab icon info container
+ const CPbk2IconInfo* iconInfo = iTabIcons->Find(iconId);
+ if (iconInfo)
+ {
+ CFbsBitmap* bitmap = NULL;
+ CFbsBitmap* mask = NULL;
+ CPbk2IconFactory* factory =
+ CPbk2IconFactory::NewLC( *iTabIcons );
+ // Load the icon and mask
+ factory->CreateIconLC(iconId, *skin, bitmap, mask);
+ // Replace tab with new bitmaps, skin enabled
+ tabGroup.ReplaceTabL(tabId, bitmap, mask);
+ CleanupStack::Pop(2); // mask, bitmap
+ CleanupStack::PopAndDestroy(factory);
+ }
+ }
+ }
+ }
+
+// End of File