phoneuis/BubbleManager/Src/BMBubbleManager.cpp
changeset 0 5f000ab63145
child 3 8871b09be73b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phoneuis/BubbleManager/Src/BMBubbleManager.cpp	Mon Jan 18 20:18:27 2010 +0200
@@ -0,0 +1,3842 @@
+/*
+* Copyright (c) 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:  Manager for the whole subsystem
+*
+*/
+
+
+// INCLUDE FILES
+
+#include    "BMBubbleManager.h"
+#include    "BMBubbleImageManager.h"
+#include    "BMResourceManager.h"
+#include    "BMCustomManager.h"
+#include    "BMBubbleOutlook.h"
+#include    "BMBubbleOutlookMiddle.h"
+#include    "BMBubbleOutlookConference.h"
+#include    "BMBubbleOutlookNE.h"
+#include    "BMCallHeader.h"
+#include    "BMConfHeader.h"
+#include    "BMPanic.h"
+#include    "BMUtils.h"
+#include    "BMLayout.h"
+#include    "BMBubbleImage.h"
+#include    "BubbleManagerPaths.h"
+#include    "BMCallObjectManager.h"
+#include    "BMLayout2.h"
+#include    "BMLayout3.h"
+#include    "BMLayout4.h"
+#include    "BMLayout6.h"
+#include    "BMCallObjectUtils.h"
+#include    "BMVideoController.h"
+#include    "BMTouchPane.h"
+#include    "BMTouchPaneInterface.h"
+#include    "BMMainPaneControl.h"
+#include    <eikimage.h>    // for muted-image
+#include    <coemain.h>
+#include    <PbkFields.hrh> // for field id
+#include    <ConeResLoader.h> 
+#include    <AknsUtils.h>
+#include    <NumberGrouping.h>
+#include    <AknDef.h>
+#include    <layoutmetadata.cdl.h>
+
+#include    <featmgr.h> 
+#include    <telephonyvariant.hrh>
+
+#include <centralrepository.h>
+#include    <NumberGroupingCRKeys.h>
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+#include <gfxtranseffect/gfxtranseffect.h> 
+#include <akntransitionutils.h>
+#endif
+
+#include    "BMBubbleDebug.h"
+
+// ========================= MEMBER FUNCTIONS ================================
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::NewL
+// Symbian OS two phased constructor
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBubbleManager* CBubbleManager::NewL( const CCoeControl& aContainer, 
+                                               const TRect& aRect )
+    {
+    CBubbleManager* self = new( ELeave )CBubbleManager;    
+    CleanupStack::PushL( self );
+    self->ConstructL( aContainer , aRect, EFalse );
+    CleanupStack::Pop();    // self
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::NewL
+// Symbian OS two phased constructor
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBubbleManager* CBubbleManager::NewL( const CCoeControl& aContainer, 
+                                               const TRect& aRect,
+                                               TBool aBigNEInIdle )
+    {
+    CBubbleManager* self = new( ELeave )CBubbleManager;    
+    CleanupStack::PushL( self );
+    self->ConstructL( aContainer , aRect, aBigNEInIdle );
+    CleanupStack::Pop();    // self
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::ConstructL
+// Symbian OS two phased constructor
+// 
+// ---------------------------------------------------------------------------
+//
+
+void CBubbleManager::ConstructL( 
+    const CCoeControl& aContainer, 
+    const TRect& aRect,
+    TBool aBigNEInIdle )
+    {    
+    // Call object display
+    if ( FeatureManager::FeatureSupported( KFeatureIdCallImagetext ) )
+        {
+        iConfigFlags |= EBMCallObjectDisplay;    
+        }
+    
+    // Bigger number entry window in idle    
+    if ( aBigNEInIdle )
+        {
+        iConfigFlags |= EBMBigNEInIdleState;    
+        }
+   
+     // Touch CallHandling.
+    if ( FeatureManager::FeatureSupported( KFeatureIdTouchCallHandling ) )
+        {
+        iConfigFlags |= EBMTouchCallhandling;    
+        }
+               
+    // set window
+    SetContainerWindowL( aContainer );
+    SetParent( const_cast<CCoeControl*>(&aContainer) );
+    iParentControl = &aContainer;
+    
+    // load resource file for animation and number entry component.
+    RConeResourceLoader resourceLoader( *iCoeEnv ); 
+    TFileName fileName; 
+    BubbleUtils::BubbleResourceFileName( fileName ); 
+    resourceLoader.OpenL(fileName); 
+    CleanupClosePushL( resourceLoader );
+    
+    // create image manager
+    iImageManager = CBubbleImageManager::NewL(
+        iConfigFlags & EBMCallObjectDisplay );
+
+    // create resource pool
+    iResourceManager = CBubbleResourceManager::NewL( *this );
+    
+    // create custom manager
+    iCustomManager = CBubbleCustomManager::NewL(*this);
+    
+    // muted image
+    iIsMuted = EFalse;
+    iMutedImage = new( ELeave ) CBubbleImage;
+    iMutedImage->SetContainerWindowL( *this );
+    iMutedImage->SetParent( this );
+    iMutedImage->SetPictureOwnedExternally( ETrue );
+    iMutedImage->MakeVisible( iIsMuted );
+    
+    // create array of call headers
+    CBubbleCallHeader* header;
+    iCallHeaders = new( ELeave ) CArrayPtrFlat<CBubbleCallHeader>( 1 );
+    iCallHeaders->SetReserveL( KBubbleCallMaxAmount );
+    for ( TUint8 i = 0 ; i < KBubbleCallMaxAmount ; i++ )
+        {
+        header = CBubbleCallHeader::NewL( i );
+        iCallHeaders->InsertL( i , header );    // can't leave
+        }
+    
+    // set reserve for active headers
+    iActiveHeaders = new ( ELeave ) CArrayPtrFlat<CBubbleHeader>( 1 );
+    // 1 is for conference
+    iActiveHeaders->SetReserveL( KBubbleCallMaxAmount + 1 ); 
+        
+    // create conference header
+    iConfHeader = CBubbleConfHeader::NewL( KBubbleConferenceId );
+    
+    // create number entry
+    iNumberEntry = new ( ELeave ) CBubbleOutlookNumberEntry( *this, 
+                                                             *iMutedImage );
+    iNumberEntry->SetCallObjectDisplay( 
+        iConfigFlags & EBMCallObjectDisplay );
+    iNumberEntry->SetContainerWindowL( *this );
+    iNumberEntry->SetParent( this );
+    iNumberEntry->ConstructL();
+    iNumberEntry->MakeVisible( EFalse ); //add
+    
+    // create places and their contents ( outlooks )
+    TInt maxAmount = (iConfigFlags & EBMTouchCallhandling) ?
+        KBubblePlaceMaxAmountTouch : KBubblePlaceMaxAmount;
+    CBubblePlace* place;
+    iBubblePlaces = new ( ELeave ) CArrayPtrFlat<CBubblePlace>( 1 );
+    iBubblePlaces->SetReserveL( maxAmount );
+    for ( TUint8 e = 0 ; e < maxAmount ; e++  )
+        {
+        place = new ( ELeave ) CBubblePlace;
+        CleanupStack::PushL( place );
+        place->SetContainerWindowL( *this );
+        place->SetParent( this );
+        place->ConstructL( CBubblePlace::TPhoneBubblePlace ( e ) , *this );
+        place->GetBubbleOutlook().SetCallObjectDisplay( 
+            iConfigFlags & EBMCallObjectDisplay );
+        iBubblePlaces->InsertL( e , place );
+        CleanupStack::Pop(); //place
+        }
+    
+    // reserve space for active places
+    iActivePlaces = 
+        new (ELeave) CArrayPtrFlat<CBubblePlace>( KBubblePlaceMaxVisible );
+    iActivePlaces->SetReserveL( KBubblePlaceMaxVisible );
+    
+    // reserve space for label text
+    iLabelBuf = HBufC::NewMaxL ( KBubbleLabelMaxLength );
+
+    // call object manager
+    if ( iConfigFlags & EBMCallObjectDisplay )
+        {
+        iCallObjectManager = CBubbleCallObjectManager::NewL( *this );
+        
+        // Main pane control is not set as component control,
+        // it just controls the drawing of the call image to
+        // the main pane.
+        iMainPaneControl = CBubbleMainPaneControl::NewL(
+                *this,
+                *iCallObjectManager );
+        iMainPaneControl->ActivateL();
+        iMainPaneControl->SetContainerWindowL( *this );
+        iMainPaneControl->MakeVisible( EFalse );
+        }
+        
+    // Video ringtone
+    iVideoController = CBubbleVideoController::NewL( *this );
+    
+    // Touch pane
+    if ( iConfigFlags & EBMTouchCallhandling )
+        {
+        iTouchPane = CBubbleTouchPane::NewL();
+        iTouchPane->SetContainerWindowL( *this );
+        iTouchPane->SetParent( this );
+        iTouchPane->MakeVisible( EFalse );
+        iTouchPane->ActivateL();
+        }   
+    
+    SetRect( aRect );
+    ActivateL();
+    iResourceManager->ActivateL();
+    iIsReadyToDraw = 0;
+
+    // Resource file isn't needed anymore so it can be closed.
+    CleanupStack::PopAndDestroy(); // resourceLoader   
+    
+    TInt pngErr( KErrNone );
+    TInt pngSupported( 0 );
+    CRepository* repository = CRepository::NewL( KCRUidNumberGrouping );
+    pngErr = repository->Get( KNumberGrouping, pngSupported );
+    delete repository;
+
+    if ( KErrNone == pngErr && pngSupported != 0 )
+        {
+        iNumberGrouping = CPNGNumberGrouping::NewL(KBubbleLabelMaxLength);
+        }
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+    // Register the number entry popup in the transition server
+    GfxTransEffect::Register( iNumberEntry, KGfxNumberEntryPopupUid, EFalse );
+
+    CAknTransitionUtils::SetData( (TInt) this, 0 );
+#endif
+    }
+
+// Destructor
+EXPORT_C CBubbleManager::~CBubbleManager()
+    {
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+    CAknTransitionUtils::RemoveData( (TInt) this );
+    GfxTransEffect::Deregister( iNumberEntry );
+#endif
+    AknsUtils::DeregisterControlPosition( this );
+    
+    delete iMutedImage;
+    
+    if ( iActiveHeaders )
+        {
+        iActiveHeaders->Reset( );
+        delete iActiveHeaders;
+        }
+
+    delete iLabelBuf;
+    
+    if ( iActivePlaces )
+        {
+        iActivePlaces->Reset( );
+        delete iActivePlaces;
+        }
+    
+    if ( iBubblePlaces )
+        {
+        iBubblePlaces->ResetAndDestroy() ;
+        delete iBubblePlaces;
+        }
+    
+    delete iNumberEntry;
+    
+    delete iConfHeader;
+    
+    
+    if ( iCallHeaders )
+        {
+        iCallHeaders->ResetAndDestroy() ;
+        delete iCallHeaders;
+        }
+
+    delete iResourceManager;
+    
+    delete iImageManager;
+    
+    delete iCustomManager;
+    
+    delete iNumberGrouping;
+
+    delete iCallObjectManager;
+    
+    delete iMainPaneControl;
+
+    delete iVideoController;
+    
+    delete iTouchPane;
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::SizeChanged()
+// called by framework when the view size is changed
+//  
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::SizeChanged()
+    {
+    AknsUtils::RegisterControlPosition( this );
+    
+    if ( iConfigFlags & EBMTouchCallhandling )
+        {
+        MBubbleTouchPaneInterface* touchPaneIf =
+            static_cast<MBubbleTouchPaneInterface*> (iTouchPane);             
+        
+        if ( iTouchPane->IsVisible() )
+            {
+            TInt variety = 0;
+            // Popups
+            TAknLayoutRect windowsPane;        
+            windowsPane.LayoutRect( 
+                Rect(), 
+                BubbleLayout6::call6_windows_pane(variety));
+
+            iMainPaneControl->SetRect( windowsPane.Rect() );
+            
+            DoLayoutCall4Bubbles( windowsPane.Rect() );    
+            }
+        else
+            {
+            iMainPaneControl->SetRect( Rect() );
+            
+            DoLayoutCall4Bubbles( Rect() );    
+            }            
+            
+                    
+        // Muted icon
+        AknLayoutUtils::LayoutImage( 
+            iMutedImage, Rect(), 
+            BubbleLayout::main_pane_elements_muted( EFalse ) );    
+        
+        // Touch pane
+
+        TInt variety = 0;
+        AknLayoutUtils::LayoutControl( 
+            iTouchPane, 
+            Rect(), 
+            BubbleLayout6::call6_button_grp_pane(variety) );
+        
+        }
+    else if ( iConfigFlags & EBMCallObjectDisplay )
+        {
+        // call object layout
+        iMainPaneControl->SetRect( Rect() );
+        DoLayoutCall2Bubbles();    
+        }        
+    else
+        {
+        // old thumbnail layout
+        DoLayoutCall1Bubbles();    
+        }
+    
+    // Layout number entry
+    TInt neIndex;
+    switch ( iNumberEntry->Place() )
+        {
+        case CBubbleOutlookNumberEntry::ENEBottomRight:
+            neIndex = 1;
+            break;
+        case CBubbleOutlookNumberEntry::ENEIdleState:
+            neIndex = 4;
+            break;
+        default: // CBubbleOutlookNumberEntry::ENEBottom
+            neIndex = 0;
+            break;                        
+        }
+
+    AknLayoutUtils::LayoutControl( 
+        iNumberEntry, Rect( ), 
+        BubbleLayout::popup_number_entry_window( neIndex ) );        
+    
+    // Layout muted icon
+    if ( !(iConfigFlags & EBMTouchCallhandling) )
+        {
+        AknLayoutUtils::LayoutImage( 
+            iMutedImage, Rect(), 
+            BubbleLayout::main_pane_elements_muted( iNumberEntry->IsUsed() ) );        
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::DoLayoutCall1Bubbles
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::DoLayoutCall1Bubbles()
+    {
+    CBubblePlace* tempBubblePlace = NULL;
+    TUint8 placeCount( TUint8( iBubblePlaces->Count( ) ) );
+    TAknWindowLineLayout placeLayout;
+    
+    for ( TUint8 index = 0 ; index < placeCount ; index++  ) 
+        {
+        tempBubblePlace = iBubblePlaces->At( index );
+        CBubblePlace::TPhoneBubblePlace place = 
+            tempBubblePlace->GetBubblePlace();
+                    
+        switch ( place )
+            {
+            case CBubblePlace::EBottom:
+                placeLayout = BubbleLayout::popup_call_audio_in_window(1);    
+                break;
+                
+            case CBubblePlace::EBottomRightActive:
+                placeLayout = BubbleLayout::popup_call_audio_second_window(1);
+                break;
+                
+            case CBubblePlace::EBottomRightHeld:
+                placeLayout = BubbleLayout::popup_call_audio_second_window(2);
+                break;
+                
+            case CBubblePlace::EMiddleActive:
+                placeLayout = BubbleLayout::popup_call_audio_first_window(3);
+                break;
+                
+            case CBubblePlace::EMiddleHeld:
+                if ( iBubblePlaces->At( CBubblePlace::EBottomCnap )->IsUsed() )
+                    {
+                    placeLayout = BubbleLayout::popup_call_audio_first_window(7);
+                    }
+                else
+                    {
+                    placeLayout = BubbleLayout::popup_call_audio_first_window(2);
+                    }
+                break;
+                
+            case CBubblePlace::ETopLeft:
+                placeLayout = BubbleLayout::popup_call_audio_first_window(4);
+                break;
+                
+            case CBubblePlace::ETopRight:
+                placeLayout = BubbleLayout::popup_call_audio_second_window(3);
+                break;
+                
+            case CBubblePlace::EHide:
+                {
+                TInt v = AknLayoutUtils::ScalableLayoutInterfaceAvailable() ?
+                         5 : 6;
+                placeLayout = BubbleLayout::popup_call_audio_first_window(v);
+                }
+                break;
+                
+            case CBubblePlace::E2InConf:
+                placeLayout = BubbleLayout::popup_call_audio_conf_window(1);
+                break;
+                
+            case CBubblePlace::E3InConf:
+                placeLayout = BubbleLayout::popup_call_audio_conf_window(2);
+                break;
+                
+            case CBubblePlace::E4InConf:
+                placeLayout = BubbleLayout::popup_call_audio_conf_window(3);
+                break;
+                
+            case CBubblePlace::E5InConf:
+                placeLayout = BubbleLayout::popup_call_audio_conf_window(4);
+                break;
+                
+            case CBubblePlace::EBottomCnap:
+                placeLayout = BubbleLayout::popup_call_audio_in_window(3);
+                break;
+                
+            case CBubblePlace::EMiddleCnap:
+                placeLayout = BubbleLayout::popup_call_audio_in_window(4);
+                break;
+                
+            case CBubblePlace::EVideo:
+                placeLayout = BubbleLayout3::popup_call3_audio_in_window(0);
+                break;
+
+            case CBubblePlace::EVideoCnap:
+                placeLayout = BubbleLayout3::popup_call3_audio_in_window(0);
+                break;                                                 
+
+            case CBubblePlace::EBottomText: // not active
+            case CBubblePlace::EBottomImage: // not active
+            case CBubblePlace::EBottomRightCnap: // not active
+            case CBubblePlace::EBottomImageCnap: // not active
+                placeLayout = BubbleLayout::popup_call_audio_in_window(1);
+                break;                 
+                
+            default:
+                Panic( EBMPanicPlaceEnumerationDoesNotExist );
+                break;
+            }
+        
+        AknLayoutUtils::LayoutControl( tempBubblePlace , Rect() , placeLayout );
+        }    
+    }
+    
+// ---------------------------------------------------------------------------
+// CBubbleManager::DoLayoutCall2Bubbles
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::DoLayoutCall2Bubbles()
+    {
+    CBubblePlace* tempBubblePlace = NULL;
+    TUint8 placeCount( TUint8( iBubblePlaces->Count( ) ) );
+    TAknWindowLineLayout placeLayout;
+    
+    for ( TUint8 index = 0 ; index < placeCount ; index++  ) 
+        {
+        tempBubblePlace = iBubblePlaces->At( index );
+        CBubblePlace::TPhoneBubblePlace place = 
+            tempBubblePlace->GetBubblePlace();
+        
+        switch ( place )
+            {
+            case CBubblePlace::EBottom:
+                placeLayout = BubbleLayout2::popup_call2_audio_in_window(0);
+                break;
+                
+            case CBubblePlace::EBottomRightActive:
+                placeLayout = BubbleLayout2::popup_call2_audio_second_window(0);
+                break;
+                
+            case CBubblePlace::EBottomRightHeld:
+                placeLayout = BubbleLayout2::popup_call2_audio_second_window(1);    
+                break;
+                
+            case CBubblePlace::EMiddleActive:
+                placeLayout = BubbleLayout2::popup_call2_audio_first_window(2);    
+                break;
+                
+            case CBubblePlace::EMiddleHeld:
+                if ( iBubblePlaces->At( CBubblePlace::EBottomRightCnap )->IsUsed() )
+                    {
+                    placeLayout = BubbleLayout2::popup_call2_audio_first_window(18);
+                    }
+                else
+                    {
+                    placeLayout = BubbleLayout2::popup_call2_audio_first_window(1);    
+                    }                    
+                break;
+                
+            case CBubblePlace::ETopLeft:
+                placeLayout = BubbleLayout2::popup_call2_audio_first_window(3);    
+                break;
+                
+            case CBubblePlace::ETopRight:
+                placeLayout = BubbleLayout2::popup_call2_audio_second_window(2);    
+                break;
+                
+            case CBubblePlace::EHide:
+                placeLayout = BubbleLayout2::popup_call2_audio_first_window(4);    
+                break;
+                
+            case CBubblePlace::E2InConf:
+                placeLayout = BubbleLayout2::popup_call2_audio_conf_window(0);    
+                break;
+                
+            case CBubblePlace::E3InConf:
+                placeLayout = BubbleLayout2::popup_call2_audio_conf_window(1);       
+                break;
+                
+            case CBubblePlace::E4InConf:
+                placeLayout = BubbleLayout2::popup_call2_audio_conf_window(2);        
+                break;
+                
+            case CBubblePlace::E5InConf:
+                placeLayout = BubbleLayout2::popup_call2_audio_conf_window(3);        
+                break;
+                
+            case CBubblePlace::EBottomCnap:
+                placeLayout = BubbleLayout2::popup_call2_audio_in_window(2);    
+                break;
+                
+            case CBubblePlace::EMiddleCnap:
+                placeLayout = BubbleLayout2::popup_call2_audio_in_window(3);    
+                break;
+                
+            case CBubblePlace::EBottomText:
+                placeLayout = BubbleLayout2::popup_call2_audio_in_window(8);
+                break;                
+
+            case CBubblePlace::EBottomImage:
+                placeLayout = BubbleLayout2::popup_call2_audio_first_window(0);
+                break;                
+                
+            case CBubblePlace::EVideo:
+                placeLayout = BubbleLayout3::popup_call3_audio_in_window(0);
+                break;
+
+            case CBubblePlace::EVideoCnap:
+                placeLayout = BubbleLayout3::popup_call3_audio_in_window(0);
+                break;
+
+            case CBubblePlace::EBottomRightCnap:
+                placeLayout = BubbleLayout2::popup_call2_audio_wait_window(9);    
+                break;
+                
+            case CBubblePlace::EBottomImageCnap:
+                placeLayout = BubbleLayout2::popup_call2_audio_first_window(0);    
+                break;                
+                
+            default:
+                Panic( EBMPanicPlaceEnumerationDoesNotExist );
+                break;
+            }
+       
+        AknLayoutUtils::LayoutControl( tempBubblePlace , Rect() , placeLayout );
+        }    
+    }    
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::DoLayoutCall4Bubbles
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::DoLayoutCall4Bubbles( const TRect& aWindowPane )
+    {
+    CBubblePlace* tempBubblePlace = NULL;
+    TUint8 placeCount( TUint8( iBubblePlaces->Count( ) ) );
+    TAknWindowLineLayout placeLayout;
+    TBool initCall = InitializingCall();
+    
+    for ( TUint8 index = 0 ; index < placeCount ; index++  ) 
+        {
+        tempBubblePlace = iBubblePlaces->At( index );
+        CBubblePlace::TPhoneBubblePlace place = 
+            tempBubblePlace->GetBubblePlace();
+        
+        switch ( place )
+            {
+            case CBubblePlace::EBottom:
+            case CBubblePlace::EBottomCnap:
+                if ( initCall )
+                    {
+                    // in / out
+                    placeLayout = 
+                        BubbleLayout4::popup_call4_audio_in_window(4);
+                    }
+                else
+                    {
+                    // incall
+                    placeLayout =
+                        BubbleLayout6::popup_call6_audio_first_window(0);    
+                    }
+                
+                break;
+                
+            // in / out with text
+            case CBubblePlace::EBottomText:
+                placeLayout = BubbleLayout2::popup_call2_audio_in_window(8);
+                break;                
+
+            // in with video                
+            case CBubblePlace::EVideo:
+            case CBubblePlace::EVideoCnap:
+                placeLayout = BubbleLayout3::popup_call3_audio_in_window(0);
+                break;
+
+            // first
+            case CBubblePlace::EBottomImage:
+            case CBubblePlace::EBottomImageCnap:
+                placeLayout = BubbleLayout6::popup_call6_audio_first_window(0);
+                break;                
+
+            // two calls - active
+            case CBubblePlace::EBottomRightActiveTouch:
+            case CBubblePlace::EBottomRightActiveCnapTouch:                
+                placeLayout = BubbleLayout4::popup_call4_audio_second_window(0);
+                break;
+            // two calls - active                
+            case CBubblePlace::EMiddleHeldTouch:                
+                placeLayout = BubbleLayout4::popup_call4_audio_first_window(1);          
+                break;                
+            
+            // three calls - held
+            case CBubblePlace::ETopRight:
+                placeLayout = BubbleLayout4::popup_call4_audio_second_window(1);    
+                break;
+            // two or three calls - active
+            case CBubblePlace::ETopLeft:
+                placeLayout = BubbleLayout4::popup_call4_audio_first_window(2);    
+                break;
+            // two or three calls - waiting    
+            case CBubblePlace::EBottomRightActive:
+            case CBubblePlace::EBottomRightCnap:
+            case CBubblePlace::EBottomRightHeld:
+                placeLayout = BubbleLayout4::popup_call4_audio_wait_window(0);    
+                break;
+            
+            // conference
+            case CBubblePlace::E2InConf:
+                placeLayout = BubbleLayout4::popup_call4_audio_conference_window(3);    
+                break;
+                
+            case CBubblePlace::E3InConf:
+                placeLayout = BubbleLayout4::popup_call4_audio_conference_window(2);       
+                break;
+                
+            case CBubblePlace::E4InConf:
+                placeLayout = BubbleLayout4::popup_call4_audio_conference_window(1);        
+                break;
+                
+            case CBubblePlace::E5InConf:
+                placeLayout = BubbleLayout4::popup_call4_audio_conference_window(0);        
+                break;
+
+            // not used in touch
+            case CBubblePlace::EMiddleActive:
+            case CBubblePlace::EMiddleHeld:
+            case CBubblePlace::EMiddleCnap:
+            case CBubblePlace::EHide:
+                continue;
+                
+            default:
+                Panic( EBMPanicPlaceEnumerationDoesNotExist );
+                break;
+            }
+       
+        AknLayoutUtils::LayoutControl( tempBubblePlace , aWindowPane , placeLayout );
+        }    
+    }    
+
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::PositionChanged
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::PositionChanged()
+    {
+    AknsUtils::RegisterControlPosition( this );
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::CountComponentControls() const
+//
+//  Controls: NumberEntry, MutedImage and ActivePlaces
+// ---------------------------------------------------------------------------
+//
+TInt CBubbleManager::CountComponentControls() const
+    {
+    if ( ( iConfigFlags & EBMTouchCallhandling ) && 
+         ( iTouchPane->IsVisible() ) )
+        {
+        return 3 + iActivePlaces->Count(); // ne + muted + touchpane + places
+        }
+    else
+        {
+        return 2 + iActivePlaces->Count(); // ne + muted + places
+        }       
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::ComponentControl(TInt aIndex) const
+//
+//  First give active places. Then possible NE, muted-image and AnimStarter
+// ---------------------------------------------------------------------------
+//
+CCoeControl* CBubbleManager::ComponentControl( TInt aIndex ) const
+    {
+    TInt activePlacesCount = iActivePlaces->Count();
+
+    // If too high value, return NULL
+    if ( aIndex >= activePlacesCount + 3 )
+        {
+        return NULL;
+        }
+
+    if ( aIndex < activePlacesCount )
+        {
+        return iActivePlaces->At( aIndex  );
+        }
+
+    if ( aIndex == activePlacesCount )
+        {
+        return iNumberEntry;
+        }
+
+    if ( iConfigFlags & EBMTouchCallhandling )
+        {
+        if ( aIndex == ( activePlacesCount + 1 ) )
+            {
+            return iMutedImage;    
+            }
+
+        return iTouchPane;
+        }
+    else
+        {
+        return iMutedImage;    
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::Draw
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::Draw( const TRect& aRect ) const
+    {
+    // clear the backround area.
+    CWindowGc& gc = SystemGc();
+    gc.SetBrushColor( AKN_LAF_COLOR( BubbleLayout::LayoutColourWhite() ) );
+
+    // Draw just the bitmaps
+    if ( iMainPaneControl &&
+         iMainPaneControl->IsVisible() )
+        {
+        // main pane image
+        iMainPaneControl->DrawBitmaps( aRect );
+        }
+    
+    for ( TInt i = 0 ; i < iActivePlaces->Count() ; i++ )
+        {
+        iActivePlaces->At(i)->GetBubbleOutlook().DrawBitmaps( gc );
+        }
+    
+    if ( iNumberEntry->IsUsed() )
+        {
+        iNumberEntry->DrawBitmaps(  gc );
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::MakeVisible
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::MakeVisible( TBool aVisible )
+    {
+    CCoeControl::MakeVisible( aVisible );
+    
+    if ( aVisible )    
+        {
+        StartAnimations();    
+        }        
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::StartChanges
+//  
+//  Reset all places so there won't be anything wrong left.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::StartChanges( )
+    {
+    BM_TRACE_( "[BUBBLEMANAGER] CBubbleManager::StartChanges" );
+    iIsReadyToDraw++;
+    if ( iIsReadyToDraw > 1 ) // is this called already?
+        {
+        return;
+        }
+    
+    // clear all used areas
+    CBubblePlace* tempBubblePlace = NULL;
+    TInt placeCount = iBubblePlaces->Count();
+    for ( TUint8 index = 0 ; index < placeCount ; index++  ) 
+        {
+        tempBubblePlace = iBubblePlaces->At( index );
+        if ( tempBubblePlace->IsUsed() )
+            {
+            Window().Invalidate( tempBubblePlace->Rect() );
+            tempBubblePlace->SetIsUsed( EFalse );
+            }
+        }
+    
+    iActivePlaces->Delete( 0 , iActivePlaces->Count() ); // do not compress!!
+
+    if ( iTouchPane )
+        {
+        iTouchPane->SetUpdating( ETrue );                
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CBubbleManager::EndChanges
+//  
+//  Check the situation and decide which outlook to take. 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::EndChanges( )
+    {
+    BM_TRACE_( "[BUBBLEMANAGER] CBubbleManager::EndChanges" );
+     
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0 , Panic( EBMPanicErrorInStartAndEndChanges ) );
+
+    iIsReadyToDraw--;
+    if ( iIsReadyToDraw != 0 )
+        {
+        return;
+        }
+
+    if ( iConfHeader->IsExpanded() )
+        {
+        BuildExpandedConference();
+        }
+    else if ( iNumberEntry->IsUsed() && iNumberEntry->IsVisible() )
+        {
+        BuildBubblesWithNE();
+        }
+    else if ( ( iConfigFlags & EBMTouchCallhandling ) )
+        {
+        BuildBubblesForTouch();    
+        }
+    else
+        {
+        BuildBubbles();
+        }
+
+    // Stop video if playing and video bubble is not active.
+    if ( ( iVideoFlags & EBMVideoPlayingVideo ) &&
+         !( iVideoFlags & EBMVideoBubbleActive ) )
+        {
+        StopAndDeleteVideoPlayer();
+        }                
+
+    // Touch pane        
+    if ( iConfigFlags & EBMTouchCallhandling )
+        {
+        if ( iTouchPaneSetVisible &&        // Client sets
+             iActiveHeaders->Count() > 0 && // Incall situation                   
+             !iNumberEntry->IsVisible() )   
+            {
+            iTouchPane->MakeVisible( ETrue );
+            }
+        else
+            {
+            iTouchPane->MakeVisible( EFalse );    
+            }    
+        }
+
+    if ( ( iConfigFlags & EBMCallObjectDisplay ) && 
+         iActiveHeaders->Count() > 0 &&
+         !( iVideoFlags & EBMVideoBubbleActive ) )
+        {
+        // Image is created only for incoming & outgoing
+        // calls, check is inside method.
+        BuildMainPaneImage();
+        }
+    
+    SizeChanged();
+    
+    // Invalidate the new areas.
+    for ( TInt i = 0 ; i < iActivePlaces->Count() ; i++ )
+        {
+        iActivePlaces->At(i)->GetBubbleOutlook().DrawDeferred();
+        }
+    if ( iNumberEntry->IsUsed() )
+        {
+        iNumberEntry->DrawDeferred();
+        iNumberEntry->GetEditor()->DrawDeferred();
+        }
+        
+    if ( iTouchPane )
+        {
+        iTouchPane->SetUpdating( EFalse );
+        }
+            
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+    TBool calledBegin = (TBool) CAknTransitionUtils::GetData( ( TInt ) this );
+    // Only draw parent control if no number entry exists, the number entry is
+    // used or if begin has not been called.
+    if ( !iNumberEntry || iNumberEntry->IsUsed() || !calledBegin )
+        {
+        // Do redraw. Do not use DrawDeferred() here!
+        iParentControl->DrawNow();
+        }
+#else
+    // Do redraw. Do not use DrawDeferred() here!
+    iParentControl->DrawNow();
+#endif
+    // Start animations. 
+    StartAnimations();
+    
+    // Start video if video bubble is active.
+    if ( ( iVideoFlags & EBMVideoBubbleActive ) &&
+         !( iVideoFlags & EBMVideoPlayingVideo ) )
+        {
+        CreateVideoPlayerAndPlay();
+        }
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+    if ( calledBegin )
+        {
+        // Initialize transition effect
+        CAknTransitionUtils::SetAllParents( iNumberEntry );
+        GfxTransEffect::SetDemarcation( iNumberEntry, iNumberEntry->Rect() );
+        GfxTransEffect::End( iNumberEntry );
+
+        // Reset begin call reminder
+        CAknTransitionUtils::SetData( (TInt) this, 0 );
+        }
+    // SetFocus here instead of in SetNumberEntryVisible
+    if ( iNumberEntry->IsVisible() )
+        {
+        iNumberEntry->SetFocus( ETrue );
+        }
+#endif
+    return;
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetActivePlace
+//  
+//  This helps the EndChanges() to make bubble places active.
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::SetActivePlace( 
+    const CBubblePlace::TPhoneBubblePlace& aPlace , 
+    CBubbleHeader& aHeader )
+    {
+    CBubblePlace* place = iBubblePlaces->At( aPlace );
+    place->SetIsUsed( ETrue );
+    CBubbleOutlook& bubbleOutlook = place->GetBubbleOutlook( );
+    bubbleOutlook.ReadBubbleHeader( aHeader );
+    iActivePlaces->InsertL( iActivePlaces->Count( ), place ); // Can't leave
+    }
+
+
+void CBubbleManager::BuildExpandedConference()
+    {
+    iNumberEntry->SetPlace( CBubbleOutlookNumberEntry::ENENone );
+    switch ( iConfHeader->RowCount() )
+        {
+        // Cases mean number of calls in conference.
+        case 2:
+            SetActivePlace( CBubblePlace::E2InConf , *iConfHeader );
+            break;
+        case 3:
+            SetActivePlace( CBubblePlace::E3InConf , *iConfHeader );
+            break;
+        case 4:
+            SetActivePlace( CBubblePlace::E4InConf , *iConfHeader );
+            break;
+        case 5:
+            SetActivePlace( CBubblePlace::E5InConf , *iConfHeader );
+            break;
+        default:
+            Panic( EBMPanicPlaceEnumerationDoesNotExist );
+            break;
+        }
+    return;
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::FindNextDrawableHeader
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::FindNextDrawableHeader( TUint8& aIndex )
+    {
+    while( iActiveHeaders->At( aIndex )->IsInConference() ) 
+        {
+        aIndex++;
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ShownHeaderCount
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CBubbleManager::ShownHeaderCount() const
+    {
+    // We have to find headers that are really shown. 
+    // That means headers which are 
+    // used and are NOT in conference. 
+    TUint8 bubbleAmount = 0;
+    TUint activeCount = iActiveHeaders->Count();
+    for (TUint8 i = 0 ; i < activeCount ; i++ )
+        {
+        if ( !iActiveHeaders->At(i)->IsInConference() )
+            {
+            bubbleAmount++;
+            }
+        }
+    return bubbleAmount;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::BuildBubbles
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::BuildBubbles()
+    { 
+    const TUint8 bubbleAmount = ShownHeaderCount();
+    iVideoFlags &= ~EBMVideoBubbleActive;
+    
+    // Without number entry.
+    switch ( bubbleAmount )
+        {
+        case 0:
+            break;
+        case 1:
+            {
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            CBubbleHeader* header = iActiveHeaders->At( index );
+            TPhoneCallState callState = header->CallState();
+            TBool callObjectText( 
+                  ( iConfigFlags & EBMCallObjectDisplay ) && 
+                  ( header->CallObjectText().Length() > 0) );
+            TBool callObjectImage( 
+                  ( iConfigFlags & EBMCallObjectDisplay ) && 
+                  header->CallObjectImage() );                  
+            
+            TInt cnapLength = header->CNAP().Length();
+
+            // Video
+            if ( callState == EIncoming && 
+                 iVideoFlags & EBMVideoSetAsRingTone )
+                {
+                if ( cnapLength ) // 3-lines
+                    {
+                    SetActivePlace( CBubblePlace::EVideoCnap, 
+                                    *header );
+                                    iVideoFlags |= EBMVideoBubbleActive;
+                    }
+                else
+                    {
+                    SetActivePlace( CBubblePlace::EVideo, 
+                                    *header );
+                                    iVideoFlags |= EBMVideoBubbleActive;    
+                    }                            
+                }
+            // Caller text                    
+            else if ( callObjectText && ( callState == EIncoming || 
+                                          callState == EOutgoing ||
+                                          callState == EAlerting ||
+                                          callState == EAlertToDisconnected ) )
+                {
+                SetActivePlace( CBubblePlace::EBottomText,
+                                *header );                            
+                }
+            // Caller image
+            else if ( callObjectImage && ( callState == EActive ||
+                                           callState == EOnHold ||
+                                           callState == EDisconnected ) )
+                {
+                CBubbleHeader::TBMCallObjectImageType imageType = 
+                    header->CallObjectImageType();
+
+                // Theme image -> use normal bubble                        
+                if ( imageType == CBubbleHeader::EThemeImage ||
+                     imageType == CBubbleHeader::ETextBasedImage )
+                    {
+                    if ( cnapLength ) // 3-lines
+                        {
+                        SetActivePlace( CBubblePlace::EBottomCnap,
+                                        *header );    
+                        }
+                    else
+                        {
+                        SetActivePlace( CBubblePlace::EBottom,
+                                        *header );    
+                        }                                
+                    }
+                // Caller image -> use bigger bubble                                                    
+                else
+                    {
+                    TSize imageSize = header->CallObjectImage()->SizeInPixels();
+                    TSize tinySize = CallObjectImageIncallSize( ETrue );
+                    TBool tiny = imageSize.iHeight < tinySize.iHeight;
+                    iBottomImageVariety = tiny ? 0 : 4;
+                    
+                    if ( cnapLength ) // 3-lines
+                        {
+                        CBubblePlace::TPhoneBubblePlace place = tiny ?
+                            CBubblePlace::EBottomCnap : CBubblePlace::EBottomImageCnap;
+                        
+                        SetActivePlace( place,
+                                        *header );                        
+                        }
+                    else 
+                        {
+                        CBubblePlace::TPhoneBubblePlace place = tiny ?
+                            CBubblePlace::EBottom : CBubblePlace::EBottomImage;
+                        
+                        SetActivePlace( place,
+                                        *header );                        
+                        }                           
+                    }
+                }
+            // Basic
+            else
+                {
+                if ( cnapLength ) // 3-lines
+                    {
+                    SetActivePlace( CBubblePlace::EBottomCnap,
+                                    *header );
+                    }
+                else
+                    {
+                    SetActivePlace( CBubblePlace::EBottom ,
+                                    *header );
+                    }    
+                }
+            break;
+            }
+        case 2:
+            {
+            // first call: middle held/active
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            TPhoneCallState callState = 
+                iActiveHeaders->At( index )->CallState();
+            TInt cnapLength = iActiveHeaders->At( index )->CNAP().Length();                
+
+            // second call: bottom held/active
+            TUint8 index2 = TUint8(index + 1);
+            FindNextDrawableHeader( index2 );
+            TInt cnapLength2 = iActiveHeaders->At( index2 )->CNAP().Length();
+            TPhoneCallState callState2 = 
+                iActiveHeaders->At( index2 )->CallState();
+
+            
+            CBubblePlace::TPhoneBubblePlace place;
+            
+            if ( callState == EOnHold  )
+                {
+                place = CBubblePlace::EMiddleHeld;
+                }
+            else if ( cnapLength  ) // and not held
+                {
+                place = CBubblePlace::EMiddleCnap;    
+                }
+            else
+                {
+                place = CBubblePlace::EMiddleActive;
+                }                
+            
+            CBubblePlace::TPhoneBubblePlace place2 = 
+                CBubblePlace::EBottomRightActive;
+            
+            if ( callState2 == EOnHold )
+                {
+                place2 = CBubblePlace::EBottomRightHeld;
+                }
+            else if ( cnapLength2 ) // and not held
+                {
+                if ( cnapLength == 0 ||
+                     callState2 == EOutgoing ||
+                     callState2 == EAlerting || 
+                     callState2 == EAlertToDisconnected ||
+                     callState2 == EWaiting ||
+                     callState2 == EActive )                
+                    {
+                    // bottom shows 3-lines
+                    place = CBubblePlace::EMiddleHeld;
+                    place2 = CBubblePlace::EBottomRightCnap;
+                    }
+                else
+                    {
+                    place2 = CBubblePlace::EBottomRightHeld;
+                    }                    
+                }
+            else
+                {
+                place2 = CBubblePlace::EBottomRightActive;    
+                }                
+            
+            // set drawing order
+            if ( callState2 > callState )
+                {
+                SetActivePlace( place , *iActiveHeaders->At( index ) );
+                SetActivePlace( place2 , *iActiveHeaders->At( index2 ) );
+                }
+            else
+                {
+                SetActivePlace( place2 , *iActiveHeaders->At( index2 ) );
+                SetActivePlace( place , *iActiveHeaders->At( index ) );
+                }                    
+            }
+            break;
+        case 3:
+            {
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            
+            TUint8 index2 = TUint8( index + 1 );
+            FindNextDrawableHeader( index2 );
+            
+            if ( iActiveHeaders->At( index2 )->CallState( ) 
+                > iActiveHeaders->At( index )->CallState( ) )
+                {
+                SetActivePlace( 
+                    CBubblePlace::ETopLeft , *iActiveHeaders->At( index ) );
+                SetActivePlace( 
+                    CBubblePlace::ETopRight , *iActiveHeaders->At( index2 ) );
+                }
+            else
+                {
+                SetActivePlace( 
+                    CBubblePlace::ETopRight , *iActiveHeaders->At( index2 ) );
+                SetActivePlace( 
+                    CBubblePlace::ETopLeft , *iActiveHeaders->At( index ) );
+                }
+            
+            
+            index = TUint8( index2 + 1 );
+            FindNextDrawableHeader( index );
+            SetActivePlace( 
+                CBubblePlace::EBottom , *iActiveHeaders->At( index ) );
+            break;
+            }
+        default:
+            Panic( EBMPanicInvalidNumberOfHeaders );
+            break;
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::BuildBubblesWithNE
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::BuildBubblesWithNE()
+    { 
+    const TUint8 bubbleAmount = ShownHeaderCount();
+    iVideoFlags &= ~EBMVideoBubbleActive;
+    
+    switch ( bubbleAmount )
+        {
+        case 0:
+            if ( iConfigFlags & EBMBigNEInIdleState )
+                {
+                iNumberEntry->SetPlace(
+                    CBubbleOutlookNumberEntry::ENEIdleState );
+                }
+            else
+                {
+                iNumberEntry->SetPlace(
+                    CBubbleOutlookNumberEntry::ENEBottom );
+                }                
+            break;
+        case 1:
+            {
+            // NE is placed according to it's activation time compared 
+            // to call's activation.
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            TInt cnapLength = iActiveHeaders->At( index )->CNAP().Length();
+            TPhoneCallState callState = 
+                iActiveHeaders->At( index )->CallState();
+
+            CBubbleOutlook& bubbleOutlook = 
+                iBubblePlaces->
+                    At( CBubblePlace::EMiddleHeld )->GetBubbleOutlook( );
+            CBubbleOutlookMiddle& bubbleMiddle =  
+                static_cast< CBubbleOutlookMiddle& >( bubbleOutlook ) ;
+            bubbleMiddle.SetIsUnder( ETrue );
+
+            if ( cnapLength )
+                {
+                SetActivePlace( CBubblePlace::EMiddleCnap ,
+                                *iActiveHeaders->At( index ) );
+                }
+            else
+                {
+                SetActivePlace( CBubblePlace::EMiddleHeld ,
+                                *iActiveHeaders->At( index ) );
+                }
+            iNumberEntry->SetPlace( CBubbleOutlookNumberEntry::ENEBottomRight );
+            break;
+            }
+        case 2:
+            {
+            // NE goes top left. Calls go like second and waiting 
+            // call when there are three calls.
+            iNumberEntry->SetPlace( CBubbleOutlookNumberEntry::ENEBottom );
+                        
+            // first call: middle held/active
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            CBubblePlace::TPhoneBubblePlace place = CBubblePlace::ETopLeft;
+            
+            // second call: bottom held/active
+            TUint8 index2 = TUint8(index + 1);
+            FindNextDrawableHeader( index2 );
+            CBubblePlace::TPhoneBubblePlace place2 = CBubblePlace::ETopRight;
+                        
+            // set drawing order
+            if ( iActiveHeaders->At( index2 )->CallState( ) 
+                > iActiveHeaders->At( index )->CallState( ) )
+                {
+                SetActivePlace( place , *iActiveHeaders->At( index ) );
+                SetActivePlace( place2 , *iActiveHeaders->At( index2 ) );
+                }
+            else
+                {
+                SetActivePlace( place2 , *iActiveHeaders->At( index2 ) );
+                SetActivePlace( place , *iActiveHeaders->At( index ) );
+                }                    
+            
+            break;
+            }
+        case 3:
+            {
+            iNumberEntry->SetPlace( CBubbleOutlookNumberEntry::ENEBottom );
+            
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            
+            TUint8 index2 = TUint8( index + 1 );
+            FindNextDrawableHeader( index2 );
+                        
+            if ( iActiveHeaders->At( index2 )->CallState( ) 
+                > iActiveHeaders->At( index )->CallState( ) )
+                {
+                SetActivePlace( 
+                    CBubblePlace::EHide , *iActiveHeaders->At( index ) );
+                SetActivePlace( 
+                    CBubblePlace::ETopLeft , *iActiveHeaders->At( index2 ) );
+                }
+            else
+                {
+                SetActivePlace( 
+                    CBubblePlace::EHide , *iActiveHeaders->At( index2 ) );
+                SetActivePlace( 
+                    CBubblePlace::ETopLeft , *iActiveHeaders->At( index ) );
+                }
+            
+            index = TUint8( index2 + 1 );
+            FindNextDrawableHeader( index );
+            SetActivePlace( 
+                CBubblePlace::ETopRight , *iActiveHeaders->At( index ) );
+            break;
+            }
+        default:
+            Panic( EBMPanicInvalidNumberOfHeaders );
+            break;
+        }
+    return;           
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::BuildBubblesForTouch
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::BuildBubblesForTouch()
+    {
+    const TUint8 bubbleAmount = ShownHeaderCount();
+    iVideoFlags &= ~EBMVideoBubbleActive;
+    
+    // Without number entry.
+    switch ( bubbleAmount )
+        {
+        case 0:
+            break;
+        case 1:
+            {
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            CBubbleHeader* header = iActiveHeaders->At( index );
+            TPhoneCallState callState = header->CallState();
+            TBool callObjectText( 
+                  ( iConfigFlags & EBMCallObjectDisplay ) && 
+                  ( header->CallObjectText().Length() > 0) );
+            TBool callObjectImage( 
+                  ( iConfigFlags & EBMCallObjectDisplay ) && 
+                  header->CallObjectImage() );                  
+            
+            TInt cnapLength = header->CNAP().Length();
+
+            // Video
+            if ( iVideoFlags & EBMVideoSetAsRingTone &&
+                 ( callState == EIncoming || callState == EAlertToDisconnected ) )
+                {
+                if ( cnapLength ) // 3-lines
+                    {
+                    SetActivePlace( CBubblePlace::EVideoCnap, 
+                                    *header );
+                                    iVideoFlags |= EBMVideoBubbleActive;
+                    }
+                else
+                    {
+                    SetActivePlace( CBubblePlace::EVideo, 
+                                    *header );
+                                    iVideoFlags |= EBMVideoBubbleActive;    
+                    }                            
+                }
+            // Caller text                    
+            else if ( callObjectText && ( callState == EIncoming || 
+                                          callState == EOutgoing ||
+                                          callState == EAlerting ||
+                                          callState == EAlertToDisconnected ) )
+                {
+                SetActivePlace( CBubblePlace::EBottomText,
+                                *header );                            
+                }
+            // Incall
+            else if ( ( callState == EActive ||
+                        callState == EOnHold ||
+                        callState == EDisconnected ) )                
+                {
+                CBubbleHeader::TBMCallObjectImageType imageType = 
+                    header->CallObjectImageType();
+                
+                if ( callObjectImage && 
+                     ( imageType == CBubbleHeader::EGalleryImage ) )
+                    {
+                    TSize imageSize = header->CallObjectImage()->SizeInPixels();
+                    TSize tinySize = CallObjectImageIncallSize( ETrue );
+                    TBool tiny = imageSize.iHeight < tinySize.iHeight;
+                    iBottomImageVariety = tiny ? 0 : 4;
+                    
+                    CBubblePlace::TPhoneBubblePlace place;
+                    place = cnapLength ? CBubblePlace::EBottomImageCnap :
+                                         CBubblePlace::EBottomImage;
+                    
+                    SetActivePlace( place,
+                                    *header );                        
+                    }
+                else
+                    {
+                    CBubblePlace::TPhoneBubblePlace place =
+                        cnapLength ? CBubblePlace::EBottomCnap :
+                                     CBubblePlace::EBottom;
+                    
+                    SetActivePlace( place,
+                                    *header );
+                    }
+                }
+            // Initializing call
+            else
+                {
+                if ( cnapLength ) // 3-lines
+                    {
+                    SetActivePlace( CBubblePlace::EBottomCnap,
+                                    *header );
+                    }
+                else
+                    {
+                    SetActivePlace( CBubblePlace::EBottom ,
+                                    *header );
+                    }    
+                }                
+            break;
+            }
+        case 2:
+            {
+            // first call: middle held/active
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            TPhoneCallState callState = 
+                iActiveHeaders->At( index )->CallState();
+            TInt cnapLength = iActiveHeaders->At( index )->CNAP().Length();                
+
+            // second call: bottom held/active
+            TUint8 index2 = TUint8(index + 1);
+            FindNextDrawableHeader( index2 );
+            TInt cnapLength2 = iActiveHeaders->At( index2 )->CNAP().Length();
+            TPhoneCallState callState2 = 
+                iActiveHeaders->At( index2 )->CallState();
+            TPhoneCallState previousState = 
+                iActiveHeaders->At( index )->PreviousCallState();                
+            TPhoneCallState previousState2 = 
+                iActiveHeaders->At( index2 )->PreviousCallState();                
+
+            CBubblePlace::TPhoneBubblePlace place;
+            CBubblePlace::TPhoneBubblePlace place2;
+            
+            if ( !InitializingCall() ) // Incall
+                {
+                if ( ( callState == EActive  ) ||
+                     ( callState == EDisconnected &&
+                       previousState == EActive ) )
+                    {
+                    // First call shown on bottom
+                    place = cnapLength ? 
+                            CBubblePlace::EBottomRightActiveCnapTouch :
+                            CBubblePlace::EBottomRightActiveTouch;
+                    place2 = CBubblePlace::EMiddleHeldTouch;    
+                    }
+                else if ( ( callState2 == EActive )  ||
+                          ( callState2 == EDisconnected &&
+                            previousState2 == EActive ) )
+                    {
+                    // Second call is shown on bottom
+                    place = CBubblePlace::EMiddleHeldTouch;
+                    place2 = cnapLength2 ? 
+                             CBubblePlace::EBottomRightActiveCnapTouch :
+                             CBubblePlace::EBottomRightActiveTouch;    
+                    }
+                else 
+                    {
+                    // The call that was shown in the held call position
+                    // keeps that position.
+                    if ( previousState == EOnHold )
+                        {
+                        place = CBubblePlace::EMiddleHeldTouch;
+                        place2 = cnapLength2 ? 
+                                 CBubblePlace::EBottomRightActiveCnapTouch :
+                                 CBubblePlace::EBottomRightActiveTouch;    
+                        }
+                    else
+                        {
+                        place = cnapLength ? 
+                                CBubblePlace::EBottomRightActiveCnapTouch :
+                                CBubblePlace::EBottomRightActiveTouch;
+                        place2 = CBubblePlace::EMiddleHeldTouch;    
+                        }
+                    }
+                }
+            else // Initializing call
+                {
+                // the call that is in initializing state is shown in
+                // primary position.
+                place = CBubblePlace::ETopLeft;
+                place2 =  cnapLength2 ? CBubblePlace::EBottomRightCnap :
+                                        CBubblePlace::EBottomRightActive;
+                }                
+            
+            // set drawing order
+            if ( callState2 > callState )
+                {
+                SetActivePlace( place , *iActiveHeaders->At( index ) );
+                SetActivePlace( place2 , *iActiveHeaders->At( index2 ) );
+                }
+            else
+                {
+                SetActivePlace( place2 , *iActiveHeaders->At( index2 ) );
+                SetActivePlace( place , *iActiveHeaders->At( index ) );
+                }                    
+            }
+            break;
+        case 3:
+            {
+            TUint8 index = 0;
+            FindNextDrawableHeader( index );
+            
+            TUint8 index2 = TUint8( index + 1 );
+            FindNextDrawableHeader( index2 );
+            
+            if ( iActiveHeaders->At( index2 )->CallState( ) 
+                > iActiveHeaders->At( index )->CallState( ) )
+                {
+                SetActivePlace( 
+                    CBubblePlace::ETopRight , *iActiveHeaders->At( index ) );
+                SetActivePlace( 
+                    CBubblePlace::ETopLeft , *iActiveHeaders->At( index2 ) );
+                }
+            else
+                {
+                SetActivePlace( 
+                    CBubblePlace::ETopRight , *iActiveHeaders->At( index2 ) );
+                SetActivePlace( 
+                    CBubblePlace::ETopLeft , *iActiveHeaders->At( index ) );
+                }
+            
+            
+            index = TUint8( index2 + 1 );
+            FindNextDrawableHeader( index );
+            SetActivePlace( 
+                CBubblePlace::EBottomRightActive , *iActiveHeaders->At( index ) );
+            break;
+            }
+        default:
+            Panic( EBMPanicInvalidNumberOfHeaders );
+            break;
+        }    
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetPhoneMuted
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetPhoneMuted( const TBool& aIsMuted )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+
+    if ( aIsMuted && iMutedImage->Bitmap() == NULL )
+        {
+        iImageManager->SetBitmapToImage( iMutedImage , 
+                                     EQgn_indi_call_muted , 
+                                     EQgn_indi_call_muted_mask );
+        }
+
+    iIsMuted = aIsMuted;
+    iMutedImage->MakeVisible( iIsMuted );
+    if ( !iIsMuted )
+        {
+        iMutedImage->DrawDeferred();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CreateCallHeader
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBubbleManager::TBubbleId CBubbleManager::CreateCallHeader( )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find unused call header for use.
+    
+    TUint8 index = 0;
+    while ( iCallHeaders->At( index )->IsUsed( ) )
+        {
+        index++;
+        __ASSERT_ALWAYS( index < iCallHeaders->Count( ), 
+                         Panic( EBMPanicInvalidNumberOfHeaders ) );
+        }
+
+    CBubbleCallHeader* header = iCallHeaders->At( index );
+    
+    header->SetIsUsed( ETrue );
+    iActiveHeaders->InsertL( iActiveHeaders->Count( ), header );// Can't leave
+    
+    return header->BubbleId( );
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::RemoveCallHeader
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::RemoveCallHeader( const TBubbleId& aBubbleId )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    if ( header->IsConference() )
+        {
+        __ASSERT_DEBUG( 
+            EFalse , Panic( EBMPanicReferredHeaderIsConferenceHeader ) );
+        return;
+        }
+    
+    if ( header->IsInConference() )
+        {
+        __ASSERT_DEBUG( 
+            EFalse , Panic( EBMPanicReferredCallHeaderIsInConferenceCall ) );
+        return;
+        }
+    
+    header->Reset();
+    
+    
+    // find the active header from array
+    TUint8 index = 0;
+    while ( iActiveHeaders->At( index )->BubbleId( ) != aBubbleId )
+        {
+        index++;
+        }
+        
+    iActiveHeaders->Delete( index );
+    
+    iCustomManager->RemoveCustomElements( aBubbleId );
+    
+    // remove main pane call object
+    if ( iMainPaneControl && 
+         iMainPaneControl->BubbleId() == aBubbleId )
+        {
+        iMainPaneControl->Reset();
+        }
+        
+    if ( ( iConfigFlags & EBMCallObjectDisplay ) && iCallObjectManager )
+        {
+        iCallObjectManager->CancelCallObjectLoading( aBubbleId );            
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetState
+//  
+//  for conf also (active/on hold/ none)
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetState( const TBubbleId& aBubbleId, 
+                                        const TPhoneCallState& aState )
+    {    
+    
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    TPhoneCallState oldstate = header->CallState();
+    header->SetCallState( aState );
+
+    TUint activeCount = iActiveHeaders->Count();
+    
+    //check if we have to change the bubble order
+    if ( (oldstate == EAlerting || oldstate == EOutgoing 
+        || oldstate == EWaiting || oldstate == EIncoming ) 
+        && aState == EActive 
+        && iActiveHeaders->At( activeCount - 1 )->BubbleId() == aBubbleId)
+        {
+        //so we know that the connected call was the last
+        if ( activeCount > 1 )
+            {
+            //we know that there is another call
+            TPhoneCallState previouscallstate = 
+                iActiveHeaders->At( activeCount - 2 )->CallState();
+            
+            if ( previouscallstate == EAlerting 
+                || previouscallstate == EOutgoing 
+                || previouscallstate == EWaiting 
+                || previouscallstate == EIncoming 
+                || previouscallstate == EAlertToDisconnected )
+                {
+                //we know that it's too about to get connection
+                
+                // now we must change the bubble order so active bubble
+                // don't stay under rectangular bubble.
+                
+                CBubbleHeader* tempBubble = 
+                    iActiveHeaders->At( activeCount-2 );
+                iActiveHeaders->At( activeCount-2 ) = 
+                                    iActiveHeaders->At(activeCount-1 );
+                iActiveHeaders->At( activeCount-1 ) = tempBubble;
+                }
+            
+            }
+        
+        }
+
+    // Call collision exception cases:
+
+    // Case: AlertToDisconnected + Waiting
+    // We have change the drawing order:
+    if ( activeCount == 2 )
+        {
+        if ( iActiveHeaders->At(0)->CallState() == EAlertToDisconnected
+            && iActiveHeaders->At(1)->CallState() == EWaiting )
+            {
+            // now we must change the bubble order so waiting bubble
+            // don't stay under alerttodisconnected bubble.
+            CBubbleHeader* tempBubble = iActiveHeaders->At(0);
+            iActiveHeaders->At(0) = iActiveHeaders->At(1);
+            iActiveHeaders->At(1) = tempBubble;
+            }
+        }
+    
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetLabel
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetLabel( 
+    const TBubbleId& aBubbleId, 
+    const TDesC& aText, 
+    const TPhoneClippingDirection& aClipDirection)
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,
+        Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    BubbleUtils::AddTextToHeader( *header, 
+                                  BubbleUtils::EBubbleHeaderLabel , 
+                                  aText , 
+                                  KBubbleLabelMaxLength ,
+                                  aClipDirection ); 
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetLabel
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetLabel( 
+    const TBubbleId& aBubbleId, 
+    const TDesC& aLongText, 
+    const TDesC& aShortText, 
+    const TPhoneClippingDirection& aClipDirection)
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+        Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    // set both text to single buffer. text are cut from the end.
+    TInt shortLength = aShortText.Length();
+    TInt longLength = aLongText.Length();
+    TInt textLength = longLength + shortLength + 1;
+
+    TPtr16 textPtr = iLabelBuf->Des();
+    textPtr.Zero();
+    if ( textPtr.MaxLength() < textLength )
+        {        
+        TRAPD ( err, iLabelBuf = iLabelBuf->ReAllocL( textLength ) );
+        textPtr.Set( iLabelBuf->Des() );
+        textPtr.Zero();
+        if ( longLength > 0 )
+            {
+            if ( err != KErrNone )
+                {
+                longLength = textPtr.MaxLength() - shortLength - 1;
+                textPtr.Append( aLongText.Left( longLength ) );
+                }
+            else
+                {
+                textPtr.Append( aLongText );
+                }
+            }
+        else
+            {
+            textPtr.Append( KNullDesC );
+            }
+        }
+    else
+        {
+        if ( longLength > 0 )
+            {
+            textPtr.Append( aLongText );
+            }
+        else
+            {
+            textPtr.Append( KNullDesC );
+            }
+        }
+
+    textPtr.Append( KBubbleTextSeparator );
+
+    if ( shortLength > 0 )
+        {
+        textPtr.Append( aShortText );
+        }
+    else
+        {
+        textPtr.Append( KNullDesC );
+        }
+
+    header->SetText( textPtr , aClipDirection );
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCLI
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCLI( 
+    const TBubbleId& aBubbleId, 
+    const TDesC& aCLIText, 
+    const TPhoneClippingDirection& aClipDirection  )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+        Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+
+    // We have a number
+    if ( aClipDirection == ELeft )
+        {
+        BubbleUtils::AddTextToHeader( *header, 
+                                  BubbleUtils::EBubbleHeaderCLI , 
+                                  NumberGroup( aCLIText ), 
+                                  KBubbleLabelMaxLength ,
+                                  aClipDirection ); 
+        }
+    else
+        {
+        BubbleUtils::AddTextToHeader( *header, 
+                                  BubbleUtils::EBubbleHeaderCLI , 
+                                  aCLIText , 
+                                  KBubbleLabelMaxLength ,
+                                  aClipDirection ); 
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::UpdateCLI
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::UpdateCLI( 
+    const TBubbleId& aBubbleId, 
+    const TDesC& aCLIText, 
+    const TPhoneClippingDirection& aClipDirection )
+    {
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    BubbleUtils::AddTextToHeader( *header, 
+                                  BubbleUtils::EBubbleHeaderCLI , 
+                                  aCLIText , 
+                                  KBubbleLabelMaxLength ,
+                                  aClipDirection );
+    
+    
+    // Tell active bubbles to update their CLI if it's visible.
+    CBubbleOutlook* outlook = NULL;
+    TInt placeCount = iActivePlaces->Count();
+    for ( TUint8 index = 0 ; index < placeCount ; index++ )
+        {
+        outlook = &iActivePlaces->At( index )->GetBubbleOutlook( );
+        outlook->DrawCLINow();
+        }
+    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallTime
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCallTime( const TBubbleId& aBubbleId, 
+                                           const TDesC& aCallTime )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+        Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+
+    BubbleUtils::AddTextToHeader( *header, 
+                                  BubbleUtils::EBubbleHeaderTimerCost , 
+                                  aCallTime , 
+                                  KBubbleLabelMaxLength ,
+                                  CBubbleManager::ERight );
+
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::UpdateCallTime
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::UpdateCallTime( const TBubbleId& aBubbleId, 
+                                              const TDesC& aCallTime )
+    {
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    BubbleUtils::AddTextToHeader( *header, 
+                                  BubbleUtils::EBubbleHeaderTimerCost , 
+                                  aCallTime , 
+                                  KBubbleLabelMaxLength ,
+                                  CBubbleManager::ERight );
+    
+    // Tell active bubbles to update their timer/cost text if it's visible.
+    CBubbleOutlook* outlook = NULL;
+    TInt placeCount = iActivePlaces->Count();
+    for ( TUint8 index = 0 ; index < placeCount ; index++ )
+        {
+        outlook = &iActivePlaces->At( index )->GetBubbleOutlook( );
+        outlook->DrawTimerCostNow();
+        }
+    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::UpdateCallHeaderText
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::UpdateCallHeaderText( const TBubbleId& aBubbleId, 
+                                            const TDesC& aLongText, 
+                                            const TDesC& aShortText, 
+                                            const TPhoneClippingDirection& aClipDirection )
+    {
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    iIsReadyToDraw++;
+    SetLabel( aBubbleId, aLongText, aShortText, aClipDirection);
+    iIsReadyToDraw--;
+
+    // Tell active bubbles to update call header text if it's visible.
+    CBubbleOutlook* outlook = NULL;
+    TInt placeCount = iActivePlaces->Count();
+    for ( TUint8 index = 0 ; index < placeCount ; index++ )
+        {
+        outlook = &iActivePlaces->At( index )->GetBubbleOutlook( );        
+        outlook->DrawCallHeaderText();
+        }
+    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetThumbnail
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetThumbnail( const TBubbleId& aBubbleId, 
+                                            CFbsBitmap* aTnBitmap, 
+                                            CFbsBitmap* aTnBitmapMask,
+                                            TBool aDataOwnershipTransferred )
+    {
+    if ( !(iConfigFlags & EBMCallObjectDisplay) )
+        {
+        __ASSERT_ALWAYS( 
+            iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+        }
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    header->SetTnBitmap( aTnBitmap );
+    header->SetTnBitmapMask( aTnBitmapMask );
+    header->SetTnDataOwnership( aDataOwnershipTransferred );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallFlags
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCallFlags( const TBubbleId& aBubbleId, 
+                                            const TUint32& aFlags ) 
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    header->SetCallFlags( aFlags );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallFlag
+//  
+//  for conf also 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCallFlag( const TBubbleId& aBubbleId, 
+                                           const TPhoneCallTypeFlags& aFlag, 
+                                           const TBool& aSet )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                                       Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    if ( aSet )
+        {
+        header->SetCallFlag( aFlag );
+        }
+    else 
+        {
+        header->RemoveCallFlag( aFlag );
+        } 
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetNumberType
+//  
+//  
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetNumberType( const TBubbleId& aBubbleId, 
+                                             const TPhoneNumberType& aNumType )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    header->SetNumberType( aNumType );
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetPbkNumberType
+//  
+//  
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetPbkNumberType( const TBubbleId& aBubbleId, 
+                                                const TInt aNumType )
+    {
+    TPhoneNumberType numType = ENotSet;
+    switch ( aNumType )
+        {  
+        case EPbkFieldIdPhoneNumberMobile:
+            numType = EMobile;
+            break;
+        case EPbkFieldIdPhoneNumberStandard:
+        case EPbkFieldIdPhoneNumberHome:
+        case EPbkFieldIdPhoneNumberWork:
+            numType = EPhone;
+            break;
+        case EPbkFieldIdFaxNumber:
+            numType = EFaxNumber;
+            break;
+        case EPbkFieldIdPagerNumber:
+            numType = EPager;
+            break;
+        case EPbkFieldIdCarNumber:
+            numType = ECar;
+            break;            
+        case EPbkFieldIdAssistantNumber:
+            numType = EAssistant;
+            break;            
+        case EPbkFieldIdNone:       // flow through
+        default:
+            numType = ENotSet;
+            break;
+        }
+    SetNumberType( aBubbleId , numType );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetPhCntNumberType
+//  
+//  
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetPhCntNumberType( 
+    const TBubbleId& aBubbleId,
+    const MPhCntMatch::TNumberType aNumberType )    
+    {
+#ifdef RD_VIRTUAL_PHONEBOOK
+    TPhoneNumberType numType = ENotSet;
+    switch( aNumberType ) 
+        {
+        case MPhCntMatch::EMobileNumber:
+            numType = EMobile;
+            break;
+
+        case MPhCntMatch::EVoipNumber:            
+        case MPhCntMatch::EStandardNumber:
+            numType = EPhone;
+            break;
+            
+        case MPhCntMatch::EFaxNumber:
+            numType = EFaxNumber;
+            break;
+            
+        case MPhCntMatch::EPagerNumber:
+            numType = EPager;
+            break;
+        case MPhCntMatch::EAssistantNumber:
+        	numType = EAssistant;
+        	break;
+        case MPhCntMatch::ECarNumber:
+        	numType = ECar;
+        	break;
+        default:
+            break;
+        }
+    SetNumberType( aBubbleId, numType );
+#else
+    (void) aBubbleId;
+    (void) aNumberType;	    
+#endif // RD_VIRTUAL_PHONEBOOK
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CreateConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBubbleManager::TBubbleId CBubbleManager::CreateConference( 
+                                                const TBubbleId& aBubble1, 
+                                                const TBubbleId& aBubble2 )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    __ASSERT_ALWAYS( iActiveHeaders->Count() < KBubblePlaceMaxVisible, 
+                     Panic( EBMPanicInvalidNumberOfHeaders ) );
+    __ASSERT_DEBUG( !iConfHeader->IsUsed() , Panic( EBMPanicConferenceIsUsed ) );
+    
+    iConfHeader->SetIsUsed( ETrue );
+    
+    AddRowToConference( aBubble1 );
+    AddRowToConference( aBubble2 );
+    
+    // Put conference header to first so it will be drawn always on top.
+    iActiveHeaders->InsertL( 0 , iConfHeader ); //Can't leave
+    
+    return iConfHeader->BubbleId( );    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::RemoveConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::RemoveConference( )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    __ASSERT_ALWAYS( iConfHeader->IsUsed( ), Panic( EBMPanicConferenceNotUsed ) );
+    
+    iConfHeader->Reset();
+    
+    
+    // find the active element
+    TUint8 index = 0;
+    __ASSERT_ALWAYS( 
+        iActiveHeaders->Count( ) > 0, Panic( EBMPanicInvalidNumberOfHeaders ) );
+    while ( iActiveHeaders->At( index )->BubbleId( ) != KBubbleConferenceId )
+        {
+        index++;
+        __ASSERT_ALWAYS( index != iActiveHeaders->Count( ), 
+            Panic( EBMPanicInvalidNumberOfHeaders ) );
+        }
+    
+    iActiveHeaders->Delete( index );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::AddRowToConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::AddRowToConference( const TBubbleId& aBubbleId )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    __ASSERT_ALWAYS( header->IsUsed(), Panic( EBMPanicBubbleIdIsNotInUse ) );
+    __ASSERT_ALWAYS( !header->IsConference(), 
+                     Panic( EBMPanicReferredHeaderIsConferenceHeader ) );
+    __ASSERT_ALWAYS( !header->IsInConference(), 
+                     Panic( EBMPanicReferredCallHeaderIsInConferenceCall ) );
+    
+    iConfHeader->AddRow( static_cast<CBubbleCallHeader&>( *header ) ); // type cast downwards
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::RemoveRowFromConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::RemoveRowFromConference( const TBubbleId& aBubbleId )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    iConfHeader->RemoveRow( aBubbleId );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ConferenceRowCount
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUint8 CBubbleManager::ConferenceRowCount( ) const
+    {
+    return iConfHeader->RowCount();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetExpandedConferenceCallHeader
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetExpandedConferenceCallHeader( 
+    const TBool& aIsExpanded )
+    {
+    iConfHeader->SetIsExpanded( aIsExpanded );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::IsConferenceExpanded
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CBubbleManager::IsConferenceExpanded( ) const
+    {
+    return iConfHeader->IsExpanded();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetSelectionInConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetSelectionInConference( 
+    const TRowNumber& aRowNumber )
+    {
+    CBubbleManager::TRowNumber oldrow = iConfHeader->Highlight();
+    iConfHeader->SetHighlight( aRowNumber );
+    CBubbleManager::TRowNumber newrow = iConfHeader->Highlight();
+    
+    UpdateConferenceRows( oldrow , newrow );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetSelectionIdInConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetSelectionIdInConference( 
+    const TBubbleId& aBubbleId )
+    {
+    CBubbleManager::TRowNumber oldrow = iConfHeader->Highlight();
+    iConfHeader->SetHighlightId( aBubbleId );
+    CBubbleManager::TRowNumber newrow = iConfHeader->Highlight();
+    
+    UpdateConferenceRows( oldrow , newrow );
+    }
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SelectionInConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBubbleManager::TRowNumber 
+    CBubbleManager::SelectionInConference() const
+    {
+    return iConfHeader->Highlight();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SelectionIdInConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CBubbleManager::TBubbleId 
+    CBubbleManager::SelectionIdInConference() const
+    {
+    return iConfHeader->HighlightId();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::MoveHighlightOneUpInConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::MoveHighlightOneUpInConference()
+    {
+    CBubbleManager::TRowNumber oldrow = iConfHeader->Highlight();
+    iConfHeader->MoveHighlightOneUp();
+    CBubbleManager::TRowNumber newrow = iConfHeader->Highlight();
+    
+    UpdateConferenceRows( oldrow , newrow );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::MoveHighlightOneDownInConference
+//  
+//  For conference calls only
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::MoveHighlightOneDownInConference()
+    {
+    CBubbleManager::TRowNumber oldrow = iConfHeader->Highlight();
+    iConfHeader->MoveHighlightOneDown();
+    CBubbleManager::TRowNumber newrow = iConfHeader->Highlight();
+    
+    UpdateConferenceRows( oldrow , newrow );
+    }
+
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CreateNumberEntry
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::CreateNumberEntry()
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    __ASSERT_ALWAYS( !iNumberEntry->IsUsed(), Panic( EBMPanicNumberEntryInUse ) );
+
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+    if ( !ShownHeaderCount() ) // Only effects in number entry
+        {
+        // Capture transition begin state
+        GfxTransEffect::Begin( iNumberEntry, KGfxControlAppearAction );
+        // Set reminder that Begin has been called.
+        CAknTransitionUtils::SetData( (TInt) this, (TAny*) 1 );
+        }
+#endif //NOT_RD_UI_TRANSITION_EFFECTS_PHASE2
+    
+    iNumberEntry->SetIsUsed( ETrue );
+    iNumberEntry->MakeVisible( ETrue );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::GetNumberEntry
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CCoeControl* CBubbleManager::GetNumberEntry( ) const
+    {
+    return iNumberEntry->GetEditor();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::IsNumberEntryUsed
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TBool CBubbleManager::IsNumberEntryUsed( ) const
+    {
+    return iNumberEntry->IsUsed();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetNumberEntryVisible
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetNumberEntryVisible( const TBool& aVisibility )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+
+    iNumberEntry->SetPlace( CBubbleOutlookNumberEntry::ENENone );
+    iNumberEntry->MakeVisible( aVisibility );
+    CCoeControl* editor = iNumberEntry->GetEditor();
+    if ( !aVisibility )
+        {
+        editor->SetFocus( EFalse );
+        }
+    else
+        {
+// Don't set focus now ( wait until the screen is redirected )
+// We don't want the cursor to be shown until the transition is finished
+#ifndef RD_UI_TRANSITION_EFFECTS_PHASE2
+        editor->SetFocus( ETrue );
+#endif
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetTextToNumberEntry
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetTextToNumberEntry( const TDesC& aDesC )
+    {
+    iNumberEntry->SetText( aDesC );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::GetTextFromNumberEntry
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::GetTextFromNumberEntry( TDes& aDesC )
+    {
+    iNumberEntry->GetText( aDesC );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::RemoveNumberEntry
+//  
+//  For number entry
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::RemoveNumberEntry( )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    __ASSERT_ALWAYS( 
+        iNumberEntry->IsUsed(), Panic( EBMPanicNumberEntryNotInUse ) );
+    
+#ifdef RD_UI_TRANSITION_EFFECTS_PHASE2
+    if ( !ShownHeaderCount() ) // Only effects in number entry
+        {
+        // Capture transition begin state
+        GfxTransEffect::Begin( iNumberEntry, KGfxControlDisappearAction );
+        // Set reminder that Begin has been called.
+        CAknTransitionUtils::SetData( (TInt) this, (TAny*) 1 );
+        }
+#endif
+
+    iNumberEntry->Reset();
+    iNumberEntry->MakeVisible( EFalse );
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::FindHeader
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CBubbleManager::FindHeader( 
+    const TBubbleId& aBubbleID, 
+    CBubbleHeader*& aHeader ) const
+    {
+    TUint count( TUint8( iCallHeaders->Count() ) );
+    CBubbleHeader* tempHeader = NULL;
+    for ( TUint8 i = 0 ; i < count ; i++ )
+        {
+        tempHeader = iCallHeaders->At( i );
+        if ( aBubbleID == tempHeader->BubbleId() )
+            {
+            aHeader = tempHeader;
+            return ETrue;
+            }
+        }
+    aHeader = NULL;
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::FindActiveHeader
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CBubbleManager::FindActiveHeader( 
+    const TBubbleId& aBubbleID, 
+    CBubbleHeader*& aHeader ) const
+    {
+    TUint count( TUint8( iActiveHeaders->Count() ) );
+    CBubbleHeader* tempHeader = NULL;
+    for ( TUint8 i = 0 ; i < count ; i++ )
+        {
+        tempHeader = iActiveHeaders->At( i );
+        if ( aBubbleID == tempHeader->BubbleId() )
+            {
+            aHeader = tempHeader;
+            return ETrue;
+            }
+        }
+    aHeader = NULL;
+    return EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::UpdateConferenceRows
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::UpdateConferenceRows( CBubbleManager::TRowNumber aRow1, 
+                                          CBubbleManager::TRowNumber aRow2 )
+    {
+    // if the rows are the same or conf is not expanded - nothing to do.
+    if ( aRow1 == aRow2 || !iConfHeader->IsExpanded() )
+        {
+        return;
+        }
+    
+    // if we are surrounded by start-/endchanges, we don't have to
+    // worry about drawing.
+    if ( iIsReadyToDraw > 0 )
+        {
+        return;
+        }
+    
+    // find current control:
+    
+    // There should be only one active place: the expanded conference place
+    if ( iActivePlaces->Count() != 1 )
+        {
+        __ASSERT_DEBUG( EFalse, User::Invariant() );
+        return;
+        }
+    
+    CBubbleOutlookConference* control = 
+        static_cast< CBubbleOutlookConference* >
+            ( &iActivePlaces->At(0)->GetBubbleOutlook() );
+    
+    // make sure it's what we want
+    if ( control == NULL )
+        {
+        __ASSERT_DEBUG( EFalse, User::Invariant() );
+        return;
+        }
+    
+    
+    // Draw row1 first:
+    control->DrawRowNow( aRow1 );
+    
+    // Then second row:
+    control->DrawRowNow( aRow2 );
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::FocusChanged
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::FocusChanged( TDrawNow aDrawNow )
+    {
+    if ( iNumberEntry->IsUsed() && iNumberEntry->IsVisible() )
+        {
+        iNumberEntry->SetFocus( IsFocused(), aDrawNow );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ImageManager
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+CBubbleImageManager& CBubbleManager::ImageManager()
+    {
+    return *iImageManager;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ResourceManager
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+CBubbleResourceManager& CBubbleManager::ResourceManager()
+    {
+    return *iResourceManager;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CustomManager
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+CBubbleCustomManager& CBubbleManager::CustomManager()
+    {
+    return *iCustomManager;
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::HandleResourceChange
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::HandleResourceChange(TInt aType)
+    {
+    if ( aType ==  KEikMessageUnfadeWindows )
+        {
+        if ( iIsReadyToDraw == 0 )
+            {
+            if ( iActivePlaces->Count() > 0 )
+                {
+                iParentControl->DrawNow();
+                }
+            }
+        }
+
+    if ( aType == KAknsMessageSkinChange || 
+         aType == KEikDynamicLayoutVariantSwitch )
+        {
+        StartChanges();
+        
+        if ( aType == KAknsMessageSkinChange )
+            {
+            // Remove muted image. It will be reloaded when 
+            // needed for the next time.
+            iMutedImage->SetPicture( NULL , NULL );
+            iMutedImage->MakeVisible( EFalse );
+
+            // Release all bitmaps from the animations
+            for ( TInt i = 0; i < iBubblePlaces->Count() ; i++ )
+                {
+                iBubblePlaces->At( i )->GetBubbleOutlook().ReleaseBitmaps();
+                }
+
+            // Number entry
+            iNumberEntry->ReleaseBitmaps();
+
+            // Clear all the skinned images from own cache
+            iImageManager->ClearSkinsCache();
+
+            // Set the image back if it was there...
+            SetPhoneMuted( iIsMuted );
+
+            // Recreate all bitmaps from the animations
+            for ( TInt a = 0; a < iBubblePlaces->Count() ; a++ )
+                {
+                iBubblePlaces->At( a )->GetBubbleOutlook().RebuildBitmaps();
+                }
+            
+            // Number entry
+            iNumberEntry->RebuildBitmaps();
+            
+            // Touch pane
+            if ( iTouchPane )
+                {
+                iTouchPane->HandleResourceChange( aType );                    
+                }
+            
+            // Update preloaded theme image
+            if ( iCallObjectManager && 
+                 iCallObjectManager->CallThemeImageIcon() )
+                {
+                iMainPaneControl->Reset();
+                
+                iCallObjectManager->ReleaseCallThemeImage();
+                iCallObjectManager->LoadCallThemeImage( 
+                        *iImageManager, 
+                        MainPaneImageRect().Size() );
+                }
+            }
+        else if ( aType == KEikDynamicLayoutVariantSwitch )
+            {
+            iImageManager->PrepareCachedBitmaps();
+            }            
+        
+        // Call object
+        if ( aType == KEikDynamicLayoutVariantSwitch )
+            {
+            if ( iCallObjectManager && 
+                 iCallObjectManager->CallThemeImageIcon() )
+                {
+                iCallObjectManager->ResizeCallThemeImage( MainPaneImageRect().Size() );
+                }
+                        
+            if ( iMainPaneControl &&
+                 iMainPaneControl->IsUsed() )
+                {
+                ReloadCallObjectImage();
+                }
+            }
+        
+        EndChanges();
+
+        // Relayout video
+        if ( iVideoFlags & EBMVideoPlayingVideo )
+            {
+            iVideoController->HandleLayoutChange();    
+            }
+
+        return;
+        }
+
+    CCoeControl::HandleResourceChange(aType);
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCNAP
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCNAP( 
+    const TBubbleId& aBubbleId, 
+    const TDesC& aCNAPText, 
+    const TPhoneClippingDirection& aClipDirection )
+    {
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+
+    if ( aCNAPText.Length() == 0 )
+        {
+        return;
+        }
+
+    // We have a number        
+    if ( aClipDirection == ELeft )
+        {
+        BubbleUtils::AddTextToHeader( 
+            *header, 
+            BubbleUtils::EBubbleHeaderCNAP, 
+            NumberGroup( aCNAPText ), 
+            KBubbleLabelMaxLength ,
+            aClipDirection );
+        }
+    else
+        {
+        BubbleUtils::AddTextToHeader(
+            *header, 
+            BubbleUtils::EBubbleHeaderCNAP, 
+            aCNAPText, 
+            KBubbleLabelMaxLength ,
+            aClipDirection );    
+        }            
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::NumberGroup
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+const TDesC& CBubbleManager::NumberGroup( const TDesC& aNumber )
+    {
+    if ( iNumberGrouping )
+        {
+        iNumberGrouping->Set( aNumber );
+        return iNumberGrouping->FormattedNumber();
+        }
+    else
+        {
+        return aNumber;
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallObjectImage
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCallObjectImage( 
+    const TBubbleId& aBubbleId,
+    const TDesC& aImageFileName )
+    {
+    __ASSERT_ALWAYS( iCallObjectManager, 
+                     Panic( EBMPanicFeatureNotSupported ) );
+        
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    if ( !header->CallObjectImage() )
+        {
+        if ( !header->IsConference() )        
+            {
+            // load image from file
+            TBool threeLines( header->CNAP().Length() > 0 );
+            CBubbleCallObjectManager::TImageLoadingParams params;
+            params.iPreferredSize = MainPaneImageRect().Size();
+            params.iTinyImageSize = MainPaneImageRect( ETrue, 
+                                                       threeLines ).Size();
+            params.iDisplayMode = Window().DisplayMode();
+            params.iThumbnailSize = CallObjectImageIncallSize( ETrue );
+            iCallObjectManager->LoadImageFromFile( aBubbleId,
+                                                   aImageFileName,
+                                                   params );
+            }
+        else // conference
+            {
+            TAknLayoutRect bubbleRect;
+            bubbleRect.LayoutRect( Rect(),
+                BubbleLayout2::popup_call2_audio_conf_window(3) );
+            
+            TSize imageSize( 
+                CallObjectImageIncallSize().iWidth,
+                bubbleRect.Rect().Size().iHeight );
+            
+            // load image from file
+            CBubbleCallObjectManager::TImageLoadingParams params;
+            params.iPreferredSize = imageSize;
+            params.iDisplayMode = Window().DisplayMode();
+            params.iTinyImageSize = TSize(0,0);
+            params.iThumbnailSize = TSize(0,0);
+            iCallObjectManager->LoadImageFromFile( aBubbleId,
+                                                   aImageFileName,
+                                                   params );    
+            }            
+
+        header->SetCallObjectFileName( aImageFileName.Alloc() );
+        header->SetCallObjectImageType(
+           CBubbleHeader::EGalleryImage );
+        }
+    
+    return;            
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallObjectImage
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CBubbleManager::SetCallObjectImage( const TBubbleId& aBubbleId,
+                                                  CFbsBitmap* aCOBitmap, 
+                                                  CFbsBitmap* aCOBitmapMask,
+                                                  TBool aDataOwnershipTrasferred )
+    {
+    __ASSERT_ALWAYS( ( iConfigFlags & EBMCallObjectDisplay ), 
+                     Panic( EBMPanicFeatureNotSupported ) );
+        
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    header->SetCallObjectImage( aCOBitmap );
+    header->SetCallObjectImageMask( aCOBitmapMask );
+    header->SetCallObjectImageDataOwnership( aDataOwnershipTrasferred );
+    iCallObjectChanged = ETrue;    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallObjectTheme
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::SetCallObjectFromTheme( 
+    const TBubbleId& aBubbleId )
+    {
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    if ( !header->CallObjectImage()  )
+        {
+        CEikImage* themeImage = new CEikImage;
+        if ( themeImage != NULL )
+            {
+            iImageManager->SetBitmapToImage( themeImage,
+                                             EQgn_graf_call_image_1,
+                                             EQgn_graf_call_image_1_mask );
+            SetCallObjectImage( 
+                aBubbleId,
+                const_cast<CFbsBitmap*> ( themeImage->Bitmap() ),
+                const_cast<CFbsBitmap*> ( themeImage->Mask() ),
+                ETrue );
+    
+            themeImage->SetPictureOwnedExternally( ETrue );
+            delete themeImage;
+            header->SetCallObjectImageType( CBubbleHeader::EThemeImage );                
+            }
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetCallObjectText
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CBubbleManager::SetCallObjectText( const TBubbleId& aBubbleId, 
+                                                 const TDesC& aCOText )
+    {
+    __ASSERT_ALWAYS( iCallObjectManager, 
+                     Panic( EBMPanicFeatureNotSupported ) );
+        
+    __ASSERT_ALWAYS( 
+        iIsReadyToDraw > 0, Panic( EBMPanicErrorInStartAndEndChanges ) );
+    
+    // find header
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    
+    if ( !header->CallObjectText().Length() &&
+         !header->IsConference() )
+        {
+        HBufC* text = aCOText.Alloc();    
+        header->SetCallObjectText( text ); // takes ownership
+        iCallObjectChanged = ETrue;
+    
+        CBubbleCallObjectManager::TImageLoadingParams params;
+        params.iPreferredSize = CallObjectImageIncallSize();
+        params.iTinyImageSize = TSize(0,0);
+        params.iThumbnailSize = TSize(0,0);
+        params.iDisplayMode = Window().DisplayMode();
+        iCallObjectManager->LoadImageFromText( aBubbleId,
+                                               aCOText,
+                                               params );
+        header->SetCallObjectImageType(
+           CBubbleHeader::ETextBasedImage );                                               
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ChangeEditorMode
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBubbleManager::ChangeEditorMode( TBool aDefaultMode )
+    {
+    return iNumberEntry->ChangeEditorMode( aDefaultMode );
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::GetEditorMode
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TInt CBubbleManager::GetEditorMode() const
+    {
+    return iNumberEntry->GetEditorMode();
+    }    
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ResetEditorToDefaultValues
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::ResetEditorToDefaultValues()
+    {
+    iNumberEntry->ResetEditorToDefaultValues();
+    }        
+                                                   
+// ---------------------------------------------------------------------------
+//  CBubbleManager::DeactivatepPopupDisplay
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CBubbleManager::FindHeader( const TPhoneCallState& aCallState,
+                                  CBubbleHeader*& aHeader ) const
+    {
+    // lookup outgoing and incoming call headers
+    TInt activeHeaderCount( iActiveHeaders->Count() );
+    for ( TInt i(0); i < activeHeaderCount; i++ )
+        {
+        CBubbleHeader* header = iActiveHeaders->At( i );
+        TPhoneCallState callState( header->CallState() );    
+        if ( callState == aCallState )
+            {
+            aHeader = header;
+            return ETrue;
+            }
+        }
+
+    return EFalse;
+    }
+
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::BuildMainPaneCallObjectL
+//  
+// 
+// ---------------------------------------------------------------------------
+//     
+void CBubbleManager::BuildMainPaneImage()
+    {
+    BM_TRACE_( "[BUBBLEMANAGER] CBubbleManager::BuildMainPaneImage" );
+    
+    CBubbleHeader* incomingHeader = NULL;
+    CBubbleHeader* outgoingHeader = NULL;
+    CBubbleHeader* activeHeader = NULL;
+    CBubbleHeader* holdHeader = NULL;
+    CBubbleHeader* activeConfHeader = NULL;
+    
+    // get incoming and outgoing call headers
+    TInt activeHeaderCount( iActiveHeaders->Count() );
+    for ( TInt i(0); i < activeHeaderCount; i++ )
+        {
+        CBubbleHeader* header = iActiveHeaders->At( i );
+        TPhoneCallState callState( header->CallState() );    
+        if ( callState == EIncoming || callState == EWaiting )
+            {
+            incomingHeader = header;
+            activeHeader = NULL;
+            holdHeader = NULL;
+            activeConfHeader = NULL;
+            break;
+            }
+        else if ( callState == EOutgoing || callState == EAlerting )
+            {
+            outgoingHeader = header;
+            activeHeader = NULL;
+            holdHeader = NULL;
+            activeConfHeader = NULL;
+            break;
+            }
+        else if ( callState == EActive )
+            {
+            holdHeader = NULL;
+            if( header->IsConference() )
+                {
+                // active conference founded, no image to show
+                activeConfHeader = header;
+                activeHeader = NULL;
+                }
+            else if ( !activeConfHeader )
+                {
+                // no conference, single active
+                activeHeader = header;
+                }
+            }
+        else if ( callState == EOnHold )
+            {
+            if( !activeHeader && !activeConfHeader )
+                {                
+                // none active headers, hold need to handle
+                holdHeader = header;
+                }
+            }
+        BM_TRACE_1( "[BUBBLEMANAGER] CBubbleManager::BuildMainPaneImage - callState = %d", callState );
+        }
+    
+   if ( holdHeader && iMainPaneControl->IsUsed() )
+        {
+        // Keep image in mainpane displayed
+        return;
+        }
+    else if ( activeConfHeader || ( !incomingHeader && !outgoingHeader && !activeHeader && !holdHeader ) )
+        {
+        // there are conference call or no incoming, outgoing, active, hold calls , no image
+        // in mainpane is displayed
+        iMainPaneControl->Reset();
+        return;
+        }
+    
+    CBubbleHeader* header = incomingHeader;
+    if ( outgoingHeader )
+        {
+        header = outgoingHeader;
+        }
+    else if ( activeHeader )
+        {
+        // single active
+        header = activeHeader;
+        iCallObjectChanged = ETrue;
+        }
+    else if ( holdHeader )
+        {
+        // single hold and no image yet
+        header = holdHeader;
+        iCallObjectChanged = ETrue;
+        }
+                
+    if ( header->IsInConference() || header->CallObjectText().Length() )
+        {
+        // Conference item or Text is not shown in mainpane.
+        return;            
+        }
+
+    if ( !iMainPaneControl->IsUsed() || iCallObjectChanged )
+        {
+        iMainPaneControl->Reset();
+        iMainPaneControl->ReadBubbleHeader( *header );
+        iCallObjectChanged = EFalse;    
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ReloadCallObjectImage
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::ReloadCallObjectImage()
+    {
+    const TBubbleId bubble = iMainPaneControl->BubbleId();
+
+    iMainPaneControl->Reset();
+    
+    CBubbleHeader* header = NULL;
+    FindActiveHeader( bubble , header );
+
+    if ( header && header->CallObjectFileName().Length() )        
+        {
+        TBool threeLines( header->CNAP().Length() > 0 );
+        
+        CBubbleCallObjectManager::TImageLoadingParams params;
+        params.iPreferredSize = MainPaneImageRect().Size();
+        params.iTinyImageSize = MainPaneImageRect( ETrue, threeLines ).Size();
+        params.iThumbnailSize = CallObjectImageIncallSize( ETrue );
+        params.iDisplayMode = Window().DisplayMode();    
+
+        iCallObjectManager->CancelCallObjectLoading( bubble );
+        
+        iCallObjectManager->LoadImageFromFile( 
+            bubble,
+            header->CallObjectFileName(),
+            params );
+        
+        header->SetCallObjectImage( NULL );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CallIsDroppedByEndKey
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+TBool CBubbleManager::IsCallDroppedByEndKey( 
+    const TPhoneCallState& aState ) const
+    {
+    TUint activeCallCount( iActiveHeaders->Count() );
+    
+    if ( activeCallCount == 1 )
+        {
+        // just one call, it is always dropped by end key
+        return ETrue;            
+        }
+        
+    // Dropping order in multicall state
+    // 1. Disconnected call
+    // 2. Initialising or alerting call
+    // 3. Active call
+    // 4. Held call
+    // 5. Waiting call
+    
+    if ( aState == EWaiting )
+        {
+        // never dropped by end key
+        return EFalse;                
+        }
+    
+    // go through ongoing calls and check if there is a call with
+    // higher dropping priority
+    TBool dropped( ETrue );
+    for ( TInt i(0); i < activeCallCount; i++ )
+        {
+        TPhoneCallState callState = iActiveHeaders->At( i )->CallState();
+        
+        if ( aState == EOnHold && ( callState == EDisconnected ||
+             callState == EOutgoing || callState == EAlerting ||
+             callState == EActive ) )
+            {
+            dropped = EFalse;
+            break;    
+            }
+        else if ( aState == EActive && ( callState == EDisconnected ||
+             callState == EOutgoing || callState == EAlerting ) )
+            {
+            dropped = EFalse;
+            break;        
+            }
+        else if ( ( aState == EOutgoing || aState == EAlerting ) &&
+            ( callState == EDisconnected ) )
+            {
+            dropped = EFalse;
+            break;            
+            }
+        else
+            {
+            // do nothing    
+            }
+        } // for
+    
+    return dropped;       
+    }    
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::ActiveCallCount
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+TUint8 CBubbleManager::ActiveCallCount() const
+    {
+    return iActiveHeaders->Count();    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::MainPaneImageRect
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+const TRect CBubbleManager::MainPaneImageRect( 
+    TBool aTinyImage,
+    TBool aThreeLinesShown ) const
+    {
+    TRect imageRect; // whole main
+    
+    if ( aTinyImage )
+        {
+        TInt variety = aThreeLinesShown ? 1 : 0;
+        
+        if ( iConfigFlags & EBMTouchCallhandling )
+            {
+            // requires call2_image_placing_area to LAF data.
+            TAknLayoutRect callPane;
+            callPane.LayoutRect(
+                Rect(), 
+                BubbleLayout4::call4_windows_pane(2) );    
+            
+            TAknLayoutRect image;
+            image.LayoutRect(
+                callPane.Rect(), 
+                BubbleLayout2::call2_image_placing_area( variety ) );                
+            imageRect = image.Rect();                
+            }
+        else
+            {
+            TAknLayoutRect image;
+            image.LayoutRect(
+                Rect(), 
+                BubbleLayout2::call2_image_placing_area( variety ) );    
+            imageRect = image.Rect();    
+            }
+        }
+    else
+        {
+        if ( iConfigFlags & EBMTouchCallhandling )
+            {
+            TAknLayoutRect image;
+            image.LayoutRect(
+                Rect(), 
+                BubbleLayout4::call4_image_pane( 2 ) );    
+            imageRect = image.Rect();                
+            }
+        else
+            {
+            // mainpane
+            imageRect = Rect();    
+            }            
+        }        
+    
+    return imageRect;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::PrepareIcons
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CBubbleManager::PrepareIcons()
+    {
+    iImageManager->PrepareCachedBitmaps();
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::PreloadCallThemeImage
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::PreloadCallThemeImage( TBool aPreload )
+    {
+    __ASSERT_ALWAYS( ( iConfigFlags & EBMCallObjectDisplay ), 
+                       Panic( EBMPanicFeatureNotSupported ) );
+    if ( aPreload )
+        {
+        iCallObjectManager->LoadCallThemeImage( 
+                *iImageManager,
+                MainPaneImageRect().Size() ); 
+        }
+    else
+        {
+        iCallObjectManager->ReleaseCallThemeImage();
+        }        
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::StartAnimations
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+void CBubbleManager::StartAnimations()
+    {
+    if ( !IsVisible() )
+        {
+        // Animation will be started when this control becomes visible.
+        return;            
+        }
+    
+    for ( TInt i = 0 ; i < iActivePlaces->Count() ; i++ )
+        {
+        TRAP_IGNORE( 
+            iActivePlaces->At(i)->GetBubbleOutlook().HandleAnimationStartL() );
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::HandleBackgroundImageChange
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CBubbleManager::HandleBackgroundImageChange()
+    {
+    // Restart animations to update background frames.
+    StartAnimations();    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetVideoRingTone
+//  
+// 
+// ---------------------------------------------------------------------------
+// 
+EXPORT_C void CBubbleManager::SetVideoRingTone(
+    const TDesC& aFileName,
+    TBubbleVideoPlayMode aPlayMode,
+    TInt aVolumeLevel,
+    TBool aUseArbitraryScaling,
+    MBubbleVideoPlaybackObserver* aObserver )
+    {
+    iVideoController->StopAndDeletePlayer();
+    iVideoController->PrepareToPlayVideo( aFileName,
+                                          aPlayMode,
+                                          aVolumeLevel,
+                                          aUseArbitraryScaling,
+                                          aObserver );
+    
+    iVideoFlags |=  EBMVideoSetAsRingTone;
+    
+    if ( iCallObjectManager )
+        {
+        iCallObjectManager->Suspend();            
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::StopVideoRingTone
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::StopVideoRingTone()
+    {
+    iVideoController->StopPlaying();                
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::MuteVideoRingTone
+//  
+// 
+// ---------------------------------------------------------------------------
+//        
+EXPORT_C void CBubbleManager::MuteVideoRingTone()
+    {
+    iVideoController->MutePlaying();                
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::StopVideoRingTone
+//  
+// 
+// ---------------------------------------------------------------------------
+//        
+EXPORT_C void CBubbleManager::CancelVideoRingTone()
+    {
+    StopAndDeleteVideoPlayer();
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CreateVideoPlayerAndPlay
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::CreateVideoPlayerAndPlay()
+    { 
+    iVideoController->CreatePlayerAndPlay();
+    iVideoFlags |= EBMVideoPlayingVideo;
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::StopAndDeleteVideoPlayer
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+void CBubbleManager::StopAndDeleteVideoPlayer()
+    {
+    iVideoController->StopAndDeletePlayer();
+    iVideoFlags &= ~EBMVideoPlayingVideo;
+    iVideoFlags &= ~EBMVideoSetAsRingTone;
+    if ( iCallObjectManager )
+        {
+        iCallObjectManager->Resume();            
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+//  CBubbleManager::VideoController
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+CBubbleVideoController& CBubbleManager::VideoController() const
+    {
+    return *iVideoController;    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CallState
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+CBubbleManager::TPhoneCallState CBubbleManager::CallState( 
+    const TBubbleId& aBubbleId )
+    {
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    return header->CallState();                         
+    }
+    
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::CallObjectImageIncallSize
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+TSize CBubbleManager::CallObjectImageIncallSize( TBool aBigBubble )
+    {
+    TAknLayoutRect bubbleRect;
+
+    if ( iConfigFlags & EBMTouchCallhandling )
+        {
+        TInt variety = aBigBubble ? 4 : 0;
+        
+        bubbleRect.LayoutRect( Rect(),
+            BubbleLayout4::popup_call4_audio_first_window(variety) );
+        }
+    else
+        {
+        if ( aBigBubble )    
+            {
+            bubbleRect.LayoutRect( Rect(),
+                BubbleLayout2::popup_call2_audio_first_window(0) );
+            }
+        else
+            {
+            bubbleRect.LayoutRect( Rect(),
+               BubbleLayout2::popup_call2_audio_in_window(0) );    
+            }
+        }
+            
+    // image size is half from bubble size
+    TSize imageSize( bubbleRect.Rect().Size() );
+    // Opaque part in bubble approx. 45%.
+    imageSize.iWidth -= (45 * imageSize.iWidth) / 100;
+    return imageSize;  
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetParticipantListCLI
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CBubbleManager::SetParticipantListCLI(
+    const TBubbleId& aBubbleId,
+    TBubbleParticipantListCLI aParticipantCLI )
+    {
+    CBubbleHeader* header = NULL;
+    __ASSERT_ALWAYS( FindActiveHeader( aBubbleId , header ) ,  
+                     Panic( EBMPanicBubbleIdIsNotInUse ) );
+    header->SetParticipantListCLI( aParticipantCLI );
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::TouchPane
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C MBubbleTouchPaneInterface* CBubbleManager::TouchPane()
+    {
+    return iTouchPane;    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::SetTouchPaneVisible
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C void CBubbleManager::SetTouchPaneVisible( TBool aVisible )
+    {
+    iTouchPaneSetVisible = aVisible;   
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::InitializingCall
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+TBool CBubbleManager::InitializingCall() const
+    {
+    TBool initializingCall = EFalse;
+    
+    TInt activeHeaderCount( iActiveHeaders->Count() );
+    for ( TInt i(0); i < activeHeaderCount; i++ )
+        {
+        CBubbleHeader* header = iActiveHeaders->At( i );
+        TPhoneCallState callState( header->CallState() );    
+        if ( callState == EIncoming || callState == EWaiting ||
+             callState == EAlerting || callState == EOutgoing ||
+             callState == EAlertToDisconnected )
+            {
+            initializingCall = ETrue;
+            break;
+            }
+        }
+        
+    return initializingCall;
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::IsTouchCallHandling
+//  
+// 
+// ---------------------------------------------------------------------------
+//    
+TBool CBubbleManager::IsTouchCallHandling() const
+    {
+    return (iConfigFlags & EBMTouchCallhandling);    
+    }
+
+// ---------------------------------------------------------------------------
+//  CBubbleManager::AddCustomElement
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::AddCustomElement( 
+    const TBubbleId& aBubbleId,
+    CTelBubbleCustomElement* aElement,
+    TInt aPriority )
+    {
+    if ( aElement->ElementType() == CTelBubbleCustomElement::ECallImage &&
+         aBubbleId == iMainPaneControl->BubbleId() )
+        {
+        // reset control to get it replaced with this custom element
+        iMainPaneControl->Reset();
+        }
+    
+    iCustomManager->AddCustomElement( aBubbleId, aElement, aPriority );
+    }
+        
+// ---------------------------------------------------------------------------
+//  CBubbleManager::RemoveCustomElement
+//  
+// 
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CBubbleManager::RemoveCustomElement( 
+    const TBubbleId& aBubbleId,
+    CTelBubbleCustomElement* aElement )
+    {
+    if ( aElement->ElementType() == CTelBubbleCustomElement::ECallImage &&
+         aBubbleId == iMainPaneControl->BubbleId() )
+        {
+        // aElement is being used; release it, before removing
+        // it from custom manager.
+        iMainPaneControl->Reset();
+        }
+    
+    iCustomManager->RemoveCustomElement( aBubbleId, aElement );
+    }
+
+// End of File