phonebookui/Phonebook2/CommonUI/src/CPbk2TabGroupContainer.cpp
changeset 0 e686773b3f54
--- /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