wvuing/wvuiave/AppSrc/CCAChatViewContainer.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuiave/AppSrc/CCAChatViewContainer.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,2747 @@
+/*
+* Copyright (c) 2006 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:  Container class for chat group view
+ *
+*/
+#include "CCAAppSettingsSAPExt.h"
+
+// INCLUDE FILES
+#include "CCAChatViewContainer.h"
+#include "MCAGroupUtilsPC.h"
+#include "CCAAppUi.h"
+#include "CCAApp.h"
+#include "CCAVariantFactory.h"
+#include "CCAUISessionManager.h"
+#include "CCAMessageEditor.h"
+#include "CCAChatViewControl.h"
+#include "CCAInviteEditor.h"
+#include "CCAMessageExtensionsHandler.h"
+#include "CCAGroupUtils.h"
+#include "CCAPicture.h"
+#include "CCAStatusPanehandler.h"
+#include "CCAUiMessageUtils.h"
+#include "cautils.h"
+#include "CCAChatView.h"
+
+#include "MCAConversationMessage.h"
+#include "MCALayoutInfo.h"
+#include "MCASkinVariant.h"
+#include "MCARecipientObserver.h"
+#include "CCAPCUtils.h"
+#include "IMUtils.h"
+#include "IMDialogUtils.h"
+#include "IMNoteMapper.h"
+#include "CAExternalInterface.h"
+#include "chatdebugprint.h"
+#include "chatdebugassert.h"
+#include "CCAContactSelectionDialog.h"
+
+#include "chatngclient.hrh"
+#include "imnginternalcrkeys.h"
+#include "imprivatecrkeys.h"
+#include "imvariant.hrh"
+//added for showing the editing indicator
+#include "CCAEditIndicator.h"
+#include "MCAProcessManager.h"
+#include "MCAGroupPC.h"
+#include "MCAServerContactsArrayPC.h"
+#include <finditemengine.h>
+#include <chatNG.mbg>
+#include <chatNG.rsg>
+#include <csxhelp/imng.hlp.hrh>
+#include <gulicon.h>
+#include <AknBidiTextUtils.h> // KAknBidiExtraSpacePerLine
+#include <AknsUtils.h>
+#include <aknenv.h>
+#include <txtrich.h>
+#include <impsgroupprops.h>
+#include <stringloader.h>
+#include <AknQueryDialog.h>
+#include <AknsConstants.h>
+#include <AppLayout.cdl.h> //cdl
+#include <AknLayoutScalable_Apps.cdl.h>
+#include <AknFepGlobalEnums.h> // for EAknFepSoftkeySpell
+#include <barsread.h>
+
+#include "CATouchUtils.h"
+#include  <AknSettingCache.h>
+// The Settings have been moved to Cenrep (also retained in the Resource file),
+// so the enums for keys and central repository header is added here
+#include 	"VariantKeys.h"
+#ifdef RD_MULTIPLE_DRIVE
+#include <centralrepository.h>
+#include <IMPSServiceSettingsUINGInternalCRKeys.h>
+#include <E32std.h>
+#include <EIKAPP.H>
+#include <eikappui.h>
+#include <eikenv.h>
+#include <eikbtgpc.h>
+#include <CAknMemorySelectionDialogMultiDrive.h>
+//CONSTANTS
+const TInt KErrNotSaved = -999;
+#endif
+
+// ================= MEMBER FUNCTIONS =======================
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::CCAChatViewContainer
+// Default constructor must not leave.
+// ---------------------------------------------------------
+//
+CCAChatViewContainer::CCAChatViewContainer( MCAViewSwitcher& aViewSwitcher,
+                                            MCAGroupPC* aGroupPC,
+                                            MCARecipientObserver& aRecipientObserver,
+                                            CCAMessageExtensionsHandler& aMessageHandler,
+                                            CEikButtonGroupContainer* aCba,
+                                            TInt& aTabId ,
+                                            CCAChatView * aView )
+
+        : iRecipientObserver( aRecipientObserver ),
+        iViewSwitcher( aViewSwitcher ),
+        iGroupPC( aGroupPC ),
+        iMessageExtensionsHandler( aMessageHandler ),
+        iCba( aCba ),
+        iTabId( aTabId ),
+        iView( aView )
+    {
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::NewL
+// Symbian constructor can leave.
+// ---------------------------------------------------------
+//
+CCAChatViewContainer* CCAChatViewContainer::NewL( const TRect& aRect,
+                                                  MCAViewSwitcher& aViewSwitcher,
+                                                  MCAGroupPC* aGroupPC,
+                                                  MCARecipientObserver& aRecipientObserver,
+                                                  MObjectProvider* aParent,
+                                                  CCAMessageExtensionsHandler& aMessageHandler,
+                                                  CEikButtonGroupContainer* aCba,
+                                                  const TBool aActivateFromTabSwitch, TInt& aTabId , CCAChatView * aView )
+    {
+    CCAChatViewContainer* self = new ( ELeave ) CCAChatViewContainer(
+        aViewSwitcher, aGroupPC , aRecipientObserver,
+        aMessageHandler, aCba, aTabId, aView );
+
+    CleanupStack::PushL( self );
+    self->ConstructL( aRect, aParent, aActivateFromTabSwitch );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ConstructL
+// Symbian OS two phased constructor
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ConstructL( const TRect& aRect,
+                                       MObjectProvider* aParent,
+                                       const TBool aActivateFromTabSwitch )
+    {
+    iAppUi = static_cast<CCAAppUi*>( iEikonEnv->AppUi() );
+
+    // This must be done first.
+    SetMopParent( aParent );
+
+    CreateWindowL();
+    CCAApp* app = static_cast<CCAApp*>(
+                      iEikonEnv->EikAppUi()->Application() );
+    iSkinVar = app->VariantFactory()->SkinVariantL();
+
+    iGroupId = iGroupPC->ActiveGroupId().AllocL();
+
+    iGroupUtilsPC = iAppUi->GetProcessManager().GetGroupUtilsInterface() ;
+
+    //Get group interface
+    iIsLoggedIn = iAppUi->UISessionManager().IsLoggedIn();
+
+    AknEditUtils::SAknEditorParameters editorParams;
+    editorParams.iCursorYesNo = ETrue;
+    editorParams.iAllowedToMoveInsertionPoint = ETrue;
+    editorParams.iCharacterCase = EAknEditorTextCase;
+    editorParams.iEditingSpace = IMUtils::MaxMsgLength();
+    editorParams.iEditingWindow = KMaxLines; // max 2 lines in the editor
+    editorParams.iJustification = EAknEditorAlignBidi;
+    editorParams.iOverflowYesNo = EFalse;
+    iEditor = new ( ELeave ) CCAMessageEditor( iMessageExtensionsHandler );
+    iEditor->SetMopParent( this );
+    AknEditUtils::ConstructEditingL( iEditor, editorParams );
+    iEditor->SetContainerWindowL( *this );
+    iEditor->SetAllowPictures( ETrue );
+
+    iEditor->SetEdwinSizeObserver( this );
+    iEditor->SetMessageEditorObserver( this );
+
+    // create chat view control
+
+
+    LoadBitmapsL();
+
+    MCAMsgAddedToRichTxtCtrlObserver* observer = NULL;
+
+    if ( aActivateFromTabSwitch && !iAppUi->FocusFlag() )
+        {
+        observer = this;
+        }
+
+    iChatView = CCAChatViewControl::NewL( aRect, *this,
+                                          *iGroupPC,
+                                          *iAppUi->GetProcessManager().GetSettingsInterface(),
+                                          iMessageExtensionsHandler,
+                                          iPrivIcon, iToMe,
+                                          iUnsupported,
+                                          iCorrupted,
+                                          ETrue,
+                                          observer
+                                        );
+
+    iChatView->SetObserver( this );
+
+
+    iGroupPC->SetGroupEventObserverL( this, *iGroupId  );
+
+    iAppUi->LayoutInfo()->SetLayoutID( TChatListBoxLayout::EWithEditor );
+    iAppUi->LayoutInfo()->SetEditorVisibility( ETrue );
+    SetRect( aRect );
+
+    iEditor->SetupSkinContextL();
+    iEditor->SetCursorPosL( 0, EFalse );
+
+    if ( !aActivateFromTabSwitch )
+        {
+        iEditor->SetFocus( ETrue );
+        iChatView->SetFocus( EFalse );
+        iAppUi->SetFocusFlag( ETrue );
+        }
+    else
+        {
+        iEditor->SetFocus( EFalse );
+        iChatView->SetFocus( ETrue );
+        }
+
+    iEditor->SetObserver( this );
+
+    iRecipients = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+    iSentRecipients = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+
+    iIsEditorStateChanged = EFalse;
+
+    iSendkeyInMsgList = ( IMUtils::CRKeyL( KCRUidIMVariation, KIMVariationKey )
+                          & EIMFeatSendkeyInMsgList );
+
+    ActivateL();
+    TBool tempFlag = aActivateFromTabSwitch;
+    if ( iAppUi->FocusFlag() && aActivateFromTabSwitch )
+        {
+        tempFlag = EFalse;
+        }
+
+    ResetAfterSendL( tempFlag );
+
+    CHAT_DP( D_CHAT_LIT( "CursorPos(): %d" ), iEditor->CursorPos() );
+    CHAT_DP( D_CHAT_LIT( "TextLength(): %d" ), iEditor->TextLength() );
+    iAppUi->AddLayoutChangeObserver( this );
+
+    // Observe tap events
+    iChatView->SetTapObserver( this, EMessageList );
+    iEditor->SetTapObserver( this, EMessageEditor );
+    iEditIndicator = CCAEditIndicator::NewL( *iEditor ) ;
+    ifocusFlag = EFalse;
+    }
+
+// Destructor
+CCAChatViewContainer::~CCAChatViewContainer()
+    {
+
+    delete iEditIndicator;
+    delete iEditor;
+    delete iPrivIcon;
+    delete iToMe;
+    delete iUnsupported;
+    delete iCorrupted;
+    delete iPrivToMany;
+    delete iChatView;
+
+    if ( iRecipients )
+        {
+        iRecipients->Reset();
+        }
+    delete iRecipients;
+
+    if ( iSentRecipients )
+        {
+        iSentRecipients->Reset();
+        }
+    delete iSentRecipients;
+
+    if ( iGroupId && iGroupPC )
+        {
+        TRAP_IGNORE( iGroupPC->SetGroupEventObserverL( NULL, *iGroupId ) );
+        }
+
+    delete iGroupId;
+
+    if ( iAppUi )
+        {
+        if ( !iAppUi->IsUnderDestruction() )
+            {
+            iAppUi->LayoutInfo()->SetEditorVisibility( EFalse );
+            iAppUi->RemoveLayoutChangeObserver( this );
+
+            }
+        }
+
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsObjectSelected
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsObjectSelected( TBool& aIsOpenable ,
+                                              TBool& aSavePossible )
+    {
+    MCAConversationMessage* msg = iChatView->SelectedMessage();
+    if ( !msg )
+        {
+        // Nothing selected
+        return EFalse;
+        }
+
+    TBool object = EFalse;
+
+    if ( msg->ContentType() == TEnumsPC::EContentPicture ||
+         msg->ContentType() == TEnumsPC::EContentOther )
+        {
+        // We have object
+        object = ETrue;
+        }
+
+
+    switch ( msg->ContentProcessState() )
+        {
+        case TEnumsPC::EContentNotSupported:
+        case TEnumsPC::EContentCorrupted:
+        case TEnumsPC::EContentNotSupportedDrm:
+            {
+            // Not supported or corrupted, can't open
+            aIsOpenable = EFalse;
+            break;
+            }
+        case TEnumsPC::EThumbnailReady:
+        default:
+            {
+            if ( msg->ContentData().Length() == 0 )
+                {
+                // No content, don't allow opening
+                aIsOpenable = EFalse;
+                }
+            else
+                {
+                // Allow opening
+                aIsOpenable = ETrue;
+
+                //fix - refer Ui Spec Approved Version 1.0
+                //(Instant Messaging NG 001 151006.pdf)
+                //Section 10.2.10 Pg 131 -
+                //"In case user has saved the image already or sent it
+                //by himself, this option(save) is not available."
+                aSavePossible = ( ( msg->MessagerType() == TEnumsPC::EMessageSent )
+                                  || ( msg->IsImageSaved() ) )
+                                ? EFalse : ETrue ;
+                }
+            }
+        }
+
+    return object;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SelectedMessage
+// ---------------------------------------------------------
+//
+MCAConversationMessage* CCAChatViewContainer::SelectedMessage()
+    {
+    return iChatView->SelectedMessage();
+    }
+
+// -----------------------------------------------------------------------------
+// CCAChatViewContainer::SetItemHighlight
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCAChatViewContainer::SetItemHighlight( TBool aHighlight )
+    {
+    iChatView->SetHighlight( aHighlight );
+    iItemHighlight = aHighlight;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::FetchMessages
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::FetchMessages( TBool aFetch )
+    {
+    iChatView->FetchMessages( aFetch );
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ResizeIcons
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ResizeIcons( TRect aParentRect )
+    {
+    TSize size( aParentRect.Height(), aParentRect.Height() );
+    AknIconUtils::SetSize( iPrivIcon->Bitmap(), size );
+    AknIconUtils::SetSize( iPrivToMany->Bitmap(), size );
+    AknIconUtils::SetSize( iToMe->Bitmap(), size );
+    iMessageExtensionsHandler.SizeChanged( size );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SelectedItem
+// ---------------------------------------------------------
+//
+HBufC* CCAChatViewContainer::SelectedItemL()
+    {
+    return iChatView->SelectedItemL();
+    }
+
+// -----------------------------------------------------------------------------
+// CCAChatViewContainer::SelectedItemType
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+TInt CCAChatViewContainer::SelectedItemType()
+    {
+    return iChatView->SelectedItemType();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsInvitationAllowed
+// Checks if user can invite friends to this group
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsInvitationAllowed() const
+    {
+    return iGroupUtilsPC->IsJoined( *iGroupId );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::InviteFriendsToGroupL
+// Start invite editor for current group
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::InviteFriendsToGroupL()
+    {
+
+    //hide tabs
+    iAppUi->CAStatusPane()->ClearNaviPaneL();
+
+    CCAInviteEditor* editor = CCAInviteEditor::NewLC(
+                                  *iGroupId );
+
+    editor->CreateAndSendInvitation(  *( iAppUi->GroupUtils() ) );
+    CleanupStack::PopAndDestroy( editor );
+
+    //Show tabs
+    iAppUi->CAStatusPane()->RestoreNaviPane();
+
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsStopped
+// This method checks if scroll mode is on or off
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsStopped() const
+    {
+    return iChatView->Highlighted();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::StartScrollingL()
+// This method is called when scrolling is started again
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::StartScrollingL( const TBool aActivateFromTabSwitch/*=EFalse*/ )
+    {
+    // disable highlight and set focus to editor
+    if ( iChatView->Highlighted() )
+        {
+        iChatView->DisableHighlightL();
+        }
+
+    if ( !aActivateFromTabSwitch )
+        {
+        iEditor->SetFocus( ETrue, EDrawNow );
+        iChatView->SetFocus( EFalse, EDrawNow );
+        }
+    else
+        {
+        iEditor->SetFocus( EFalse, EDrawNow );
+        iChatView->SetFocus( ETrue, EDrawNow );
+        }
+    iEditor->DrawDeferred();
+    UpdateCbaL();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::StopScrollingL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::StopScrollingL()
+    {
+    // unfocus editor (highlighting is enabled
+    // automatically in OfferKeyEvent of ChatView)
+    iEditor->SetFocus( EFalse, EDrawNow );
+    iEditor->DrawDeferred();
+    // Set editor cursor pos to end of text
+    iEditor->SetCursorPosL( iEditor->TextLength(), EFalse );
+    iChatView->SetFocus( ETrue );
+    UpdateCbaL();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::UpdateCbaL()
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::UpdateCbaL()
+    {
+    TInt cbaRes( R_CHAT_SOFTKEYS_OPTIONS_CONTINUE__EMPTY );
+
+    if ( !iCba )
+        {
+        return;
+        }
+
+    if ( !iChatView->GetMessageCount() )
+        {
+        //if the message list is empty
+        if ( !iEditor->IsFocused() )
+            {
+            //if editor is not in focus then the rightSK must be "continue"
+            iCba->SetCommandSetL( cbaRes );
+            iCba->DrawNow();
+            return;
+            }
+        }
+
+    if ( iChatView->Highlighted() )
+        {
+        // focus on chatview
+        TBool ignore;
+        TBool dummyArgument( EFalse );
+        HBufC* item = iChatView->SelectedItemL();
+        CleanupStack::PushL( item );
+
+        if ( IsObjectSelected( ignore, dummyArgument ) )
+            {
+            // openable object selected
+            cbaRes = R_CHAT_SOFTKEYS_OPTIONS_CONTINUE__OPEN;
+            }
+        else if ( item && item->Length() > 0 )
+            {
+            // automatic find item selected
+            cbaRes = R_CHAT_SOFTKEYS_OPTIONS_CONTINUE__CONTEXTOPTIONS;
+            }
+
+        CleanupStack::PopAndDestroy( item );
+        }
+    else
+        {
+        // focus on editor
+        cbaRes = iEditor->TextLength() > 0 ?
+                 R_CHAT_SOFTKEYS_OPTIONS_BACK__SEND :
+                 R_CHAT_SOFTKEYS_OPTIONS_BACK__EMPTY;
+        }
+
+    // Check that there is not "Spell" in the left button
+    // ControlOrNull() is needed for 3.0 backport.
+    if ( !( iCba->ControlOrNull( EAknFepSoftkeySpell ) &&
+            iCba->IsCommandVisible( EAknFepSoftkeySpell ) ) )
+        {
+        iCba->SetCommandSetL( cbaRes );
+        iCba->DrawNow();
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SetItemEmphasize( TBool aIsEmphasized )
+// This method sets the item emphasization on
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::SetItemEmphasize( const TBool aIsEmphasized )
+    {
+    iIsEmphasis = aIsEmphasized;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsEmphasized()
+// This method tells if item is emphasized or not
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsEmphasized() const
+    {
+    return iIsEmphasis;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::Editor()
+// This method returns pointer to CEikGlobalTextEditor
+// ---------------------------------------------------------
+//
+CCAMessageEditor& CCAChatViewContainer::Editor() const
+    {
+    return *iEditor;
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsContainer::ForwardToGroupL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ForwardToGroupL()
+    {
+    MCAConversationMessage* message = iChatView->SelectedMessage();
+    if ( !message )
+        {
+        // nothing selected
+        return;
+        }
+
+    MCAServerContactsArrayPC* pairsArray =
+        iGroupPC->GetGroupPairArrayLC();
+
+    HBufC* emptyText = iEikonEnv->AllocReadResourceLC(
+                           R_CHAT_IBOX_FRIENDS_OFFLINE );
+    HBufC* title = iEikonEnv->AllocReadResourceLC(
+                       R_PRIVATE_CHAT_FORWARD_TITLE_GROUP );
+
+    TInt selectedIndex( 0 );
+    TInt retVal( IMDialogUtils::DisplayListQueryDialogL( &selectedIndex,
+                                                         pairsArray,
+                                                         R_PRIVATE_CHAT_LIST_SELECT_RECIP_DLG,
+                                                         *title,
+                                                         *emptyText,
+                                                         ETrue ) );
+    //Note: code scanner warning is ignored for using magic numbers
+    CleanupStack::PopAndDestroy( 2, emptyText ); // title, emptyText
+
+    if ( retVal == EAknSoftkeyOk || retVal == EAknSoftkeyDone
+         || retVal == EAknSoftkeySelect )
+        {
+
+        // Check if there is highlighted item
+        HBufC* item = SelectedItemL();
+        CleanupStack::PushL( item );
+
+        if ( item->Length() > 0 )
+            {
+            // Set forwarded message, ownership is transferred
+            message->SetForwardPartL( item );
+            }
+        else
+            {
+            // Clear previous forward message
+            message->SetForwardPartL( NULL );
+            }
+
+        CleanupStack::PopAndDestroy( item );
+
+        TInt err = iAppUi->GroupUtils()->JoinGroupL(
+                       ETrue,
+                       pairsArray->WVIdL( selectedIndex )->iWVID,
+                       KNullDesC, message );
+
+        if ( err )
+            {
+            CActiveScheduler::Current()->Error( err );
+            }
+        if ( TEnumsPC::EUnregistered == iAppUi->RetForwardTo()  )
+            {
+            iAppUi->SetResetForwardTo( TEnumsPC::ERegister );
+            iAppUi->GroupUtils()->PrepareToSwitchBackL( iGroupId->Des(),
+                                                        KUidChatView,
+                                                        KUidChatView );
+            }
+        else if ( TEnumsPC::ERegister == iAppUi->RetForwardTo() )
+            {
+            iAppUi->SetResetForwardTo( TEnumsPC::EAlreadyRegistered );
+            }
+        }
+    //always dont use CleanupStack::PopAndDestroy(pairsArray)
+    //because there might be a object slicing happening
+    //when the pairsArray is transferred from the creator
+    //to the caller. Hence one will end up deleting the wrong ptr.
+    //Hence it is better to use CleanupStack::PopAndDestroy(), as
+    //we dont know wat the creator has pushed onto the CleanupStack
+    CleanupStack::PopAndDestroy();//pairsArray
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsContainer::ForwardToContactL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ForwardToContactL()
+    {
+    MCAConversationMessage* message = iChatView->SelectedMessage();
+    if ( !message )
+        {
+        // nothing selected
+        return;
+        }
+
+    MCASkinVariant* skinVar = static_cast<CCAApp*>( iAppUi->Application() )
+                              ->VariantFactory()->SkinVariantL();
+
+
+    CDesCArray* selectedContacts = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( selectedContacts );
+
+    CDesCArray* selectedIdentifications = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( selectedIdentifications );
+
+    MCASettingsPC* settingsPC = iAppUi->GetProcessManager().GetSettingsInterface();
+    MCAMainViewArrayPC* mainViewArrayPC = iAppUi->GetProcessManager().GetArrayInterface();
+
+    // show selection dialog
+    TBool contacts( CCAContactSelectionDialog::ShowDialogL( *selectedContacts,
+                                                            *mainViewArrayPC,
+                                                            *skinVar, *settingsPC,
+                                                            iAppUi->MbmFullPath(),
+                                                            TEnumsPC::ESingleSelect,
+                                                            R_CONTACT_SELECTION_DIALOG,
+                                                            *iAppUi->CAStatusPane(),
+                                                            selectedIdentifications ) );
+    if ( !contacts )
+        {
+        // no contacts
+        //Note: code scanner warning is ignored for using magic numbers
+        CleanupStack::PopAndDestroy( 2, selectedContacts ); // selectedContacts, selectedIdentifications
+        return;
+        }
+
+    // allow tabs - suppose user would have received new messages
+    iAppUi->CAStatusPane()->RestoreNaviPane();
+
+    // handle selected contact (if any)
+
+
+    TInt count( selectedContacts->MdcaCount() );
+    CHAT_DP( D_CHAT_LIT( "selection count %d" ), count );
+
+    //if( selectedContacts->Count() == 1 )
+    if ( count == 1 )
+        {
+        TPtrC wvid( selectedContacts->MdcaPoint( 0 ) );
+
+        // User made selection -> set temporary identification for the wv id
+        MCAMainViewArrayPC* mainViewArrayPC =
+            iAppUi->GetProcessManager().GetArrayInterface();
+
+
+        //Add the conversation item to open chats array before switching the view
+        mainViewArrayPC->InsertConversationItemL( wvid,
+                                                  selectedIdentifications->MdcaPoint( 0 ) );
+
+
+        // Check if there is highlighted item
+        HBufC* item = SelectedItemL();
+        CleanupStack::PushL( item );
+
+        if ( item->Length() > 0 )
+            {
+            // Set forwarded message
+            message->SetForwardPartL( item );
+            }
+        else
+            {
+            message->SetForwardPartL( NULL );
+            }
+
+        CleanupStack::PopAndDestroy( item );
+
+        // Store message, in case it gets destroyed.
+        iAppUi->SetForwardMessageL( message );
+
+        if ( TEnumsPC::EUnregistered == iAppUi->RetForwardTo()  )
+            {
+            iAppUi->SetResetForwardTo( TEnumsPC::ERegister );
+            iAppUi->GroupUtils()->PrepareToSwitchBackL( iGroupId->Des(),
+                                                        KUidChatView,
+                                                        KUidConversationsView );
+            }
+        else if ( TEnumsPC::ERegister == iAppUi->RetForwardTo() )
+            {
+            iAppUi->SetResetForwardTo( TEnumsPC::EAlreadyRegistered );
+            }
+        TCADnlConvView dnlConView;
+        dnlConView.iWVID = wvid;
+        dnlConView.iIsForwarded = ETrue;
+        dnlConView.iForwardedMessage = iAppUi->ForwardMessage();
+        dnlConView.iSAPChanged = EFalse;
+        dnlConView.iSwitchTab = EFalse;
+
+        TCADnlConvViewBuf convMsgBuf( dnlConView );
+        CHAT_DP( D_CHAT_LIT( "**forward \"%S\" to contact %S" ),
+                 &dnlConView.iForwardedMessage, &dnlConView.iWVID );
+
+        iAppUi->ActivateLocalViewL( KUidConversationsView, KUidConvViewMsgId, convMsgBuf );
+
+
+        }
+    //Note: code scanner warning is ignored
+    CleanupStack::PopAndDestroy( 2, selectedContacts ); // selectedContacts,selectedIdentifications
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SendMessageL()
+// This method handles message sending to engine
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::SendMessageL()
+    {
+    if ( iAppUi->UISessionManager().IsLoggedIn() )
+        {
+        TInt textLength( iEditor->TextLength() );
+        if ( textLength == 0 )
+            {
+            // setting focus back to editor window
+            iEditor->SetFocus( ETrue );
+            iChatView->SetFocus( EFalse );
+            return;
+            }
+
+        HBufC* msgBuf = iMessageExtensionsHandler.ProcessMessageLC( *iEditor );
+        TPtr msgPtr( msgBuf->Des() );
+        TInt offset( 0 );
+
+        // Check message if there is other than empty chars
+        TInt len( msgPtr.Length() );
+        TBool contaisOnlyEmptyChars( ETrue );
+
+        for ( TInt i( 0 ); ( i < len ) && contaisOnlyEmptyChars; ++i )
+            {
+            TPtrC c = msgPtr.Mid( i, 1 );  // next character
+            TInt position = ( KEmptyCharacters() ).FindC( c );
+
+            if ( position == KErrNotFound )
+                {
+                // c not found from empty characters --> c is not empty char
+                contaisOnlyEmptyChars = EFalse;
+                }
+            }
+
+        if ( contaisOnlyEmptyChars )
+            {
+            // message contains only empty character
+            // don't send message and setting focus back to editor window
+            iEditor->SetFocus( ETrue );
+            iChatView->SetFocus( EFalse );
+            CleanupStack::PopAndDestroy( msgBuf );
+            return;
+            }
+
+        // check if the message still is a whisper message,
+        // did the user erase the recipient
+        TBool isWhisper = ETrue;
+
+        // the pics are in different place with mirrored layout
+        if ( AknLayoutUtils::LayoutMirrored() )
+            {
+            offset = msgPtr.FindC( KSemicolon );
+            // the rest are privmsg header
+            if ( offset >= 0 )	// if found
+                {
+                //1 is space
+                msgPtr.Delete( 0, offset + 1 );
+                }
+            else
+                {
+                // user erased the recipient
+                isWhisper = EFalse;
+                }
+            }
+        else
+            {
+            if ( msgPtr[0] == CEditableText::EPictureCharacter &&
+                 msgPtr[2] == CEditableText::EPictureCharacter )
+                {
+                offset = msgPtr.FindC( KSemicolon );
+                msgPtr.Delete( 0, offset + KPictureChar );
+                }
+            else if ( msgPtr[0] == CEditableText::EPictureCharacter )
+                {
+                offset = msgPtr.FindC( KSemicolon );
+                msgPtr.Delete( 0, offset + KPictureChar );
+                }
+            else
+                {
+                // user erased the recipient
+                isWhisper = EFalse;
+                }
+            }
+
+        // send message
+        if ( msgPtr.Length() > 0 )
+            {
+
+
+            if ( ! isWhisper )
+                {
+                // no longer a whisper message, address this message to all
+                iRecipients->Reset();
+                }
+
+
+            iGroupPC->SendMessageL( msgPtr, *iRecipients );
+
+            TInt editorFlags = ( iEditor->AknEdwinFlags() | EAknEditorFlagNoEditIndicators );
+            iEditor->SetAknEditorFlags( editorFlags );
+
+            ResetAfterSendL();
+
+
+            }
+
+        CleanupStack::PopAndDestroy( msgBuf );
+        }
+    else
+        {
+        iAppUi->UISessionManager().LoginL( MCAUiLoginCmdCB::ELogin );
+        if ( iAppUi->UISessionManager().IsLoggedIn() )
+            {
+            if ( iGroupUtilsPC->IsJoined( *iGroupId ) )
+                {
+                SendMessageL();
+                }
+            else
+                {
+                iAppUi->GroupUtils()->JoinGroupL( EFalse, *iGroupId );
+                if ( iGroupUtilsPC->IsJoined( *iGroupId ) )
+                    {
+                    SendMessageL();
+                    }
+                }
+            }
+        }
+
+    // for some reason we're not redrawn, so force it
+    DrawNow();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SendImageL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::SendObjectL( TBool aNewFile,
+                                        TNewServiceFileType aFileType /*= ENewFileServiceImage */ )
+    {
+    if ( iAppUi->UISessionManager().IsLoggedIn() )
+        {
+
+
+        // get members
+        CDesCArray* members = new( ELeave )CDesCArrayFlat( 1 );
+        CleanupStack::PushL( members );
+
+
+
+        TPtrC groupid = iGroupPC->ActiveGroupId();
+        TBool isGroupFound = iGroupUtilsPC->FindGroup( groupid );
+
+        if ( isGroupFound )
+            {
+            // get joined members
+            iGroupUtilsPC->GetParticipantsL( *members, groupid );
+            }
+
+        TInt index;
+        if ( members->Find( *iAppUi->ScreenNamePtr(), index ) == KErrNone )
+            {
+            members->Delete( index );
+            members->Compress();
+            }
+
+        members->Sort( ECmpCollated );
+
+        CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC();
+
+
+        if ( aNewFile )
+            {
+            // create new
+            utils->SendNewFileL( aFileType, *iGroupPC,
+                                 iGroupPC->ScreenName(), members, IsWhisperAllowedL() );
+            }
+        else
+            {
+            // from photos
+            utils->SendImageL( *iGroupPC,
+                               iGroupPC->ScreenName(), members, IsWhisperAllowedL() );
+            }
+        //Note: code scanner warning is ignored
+        CleanupStack::PopAndDestroy( 2, members ); // utils, members
+        }
+    else
+        {
+        iAppUi->UISessionManager().LoginL( MCAUiLoginCmdCB::ELogin );
+        if ( iAppUi->UISessionManager().IsLoggedIn() )
+            {
+            if ( iGroupUtilsPC->IsJoined( *iGroupId ) )
+                {
+                SendObjectL( aNewFile, aFileType );
+                }
+            else
+                {
+                iAppUi->GroupUtils()->JoinGroupL( EFalse, *iGroupId );
+                if ( iGroupUtilsPC->IsJoined( *iGroupId ) )
+                    {
+                    SendObjectL( aNewFile, aFileType );
+                    }
+                }
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::InitPrivateMessageL()
+// Initialises privatemessage. Sets the icons to the editor
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::InitPrivateMessageL( const TDesC& aNickName,
+                                                const TBool aGroupMsg )
+    {
+    iCurrentNickInPrivMsg = aNickName;
+    iIsGroupMsgInPrivMsg = aGroupMsg;
+
+    HBufC* nickHb =
+        HBufC::NewLC( aNickName.Length() + KAknBidiExtraSpacePerLine );
+
+    TPtr nickVisPtr( nickHb->Des() );
+    nickVisPtr.Append( aNickName );
+
+    HBufC* msg = iEditor->GetTextInHBufL();
+    CleanupStack::PushL( msg );
+
+
+    if ( msg )
+        {
+        TPtr msgPtr( msg->Des() );
+        TInt scIndex( msgPtr.FindC( KSemicolon ) );
+        CHAT_DP( D_CHAT_LIT( "scIndex = %d" ), scIndex );
+        if ( scIndex >= 0 )
+            {
+            //KPictureChar is for space and icon
+            TPtrC tmpMsg( msgPtr.Mid( scIndex + KPictureChar ) );
+            CHAT_DP( D_CHAT_LIT( "tmpMsg:%S" ), &tmpMsg );
+            *msg = tmpMsg;
+            CHAT_DP( D_CHAT_LIT( "msg:%S" ), msg );
+            }
+        }
+
+    TInt textLength( iEditor->TextLength() );
+    //Read picture char from position zero to one
+    TPtrC pictureChar( iEditor->Text()->Read( 0, 1 ) );
+
+    CCAPicture* privIconPic = new ( ELeave ) CCAPicture(
+        *CCoeEnv::Static()->SystemGc().Device(),
+        iPrivIcon, -1 );
+
+    CleanupStack::PushL( privIconPic );
+
+    TPictureHeader privIconHeader;
+    privIconHeader.iPicture = TSwizzle<CPicture>( privIconPic );
+
+    if ( textLength > 0 && pictureChar[0] != CEditableText::EPictureCharacter )
+        {
+        if ( AknLayoutUtils::LayoutMirrored() )
+            {
+            CreatePrivMsgAHHeaderL( privIconHeader, aGroupMsg, nickVisPtr, msg );
+            }
+        else
+            {
+            CreatePrivMsgHeaderL( privIconHeader, aGroupMsg, nickVisPtr, msg );
+            }
+
+        }
+    else if ( ( pictureChar[0] == CEditableText::EPictureCharacter )  ||
+              ( textLength == 0 ) )
+        {
+        if ( AknLayoutUtils::LayoutMirrored() )
+            {
+            CreatePrivMsgAHHeaderL( privIconHeader, aGroupMsg,
+                                    nickVisPtr, msg );
+            }
+        else
+            {
+            CreatePrivMsgHeaderL( privIconHeader, aGroupMsg, nickVisPtr, msg );
+            }
+        }
+
+    // apply formatting for private message icon
+    TCharFormat charFormat;
+    TCharFormatMask charFormatMask;
+    charFormat.iFontPresentation.iPictureAlignment =
+        TFontPresentation::EAlignCentered;
+    charFormatMask.SetAttrib( EAttFontPictureAlignment );
+    iEditor->RichText()->ApplyCharFormatL( charFormat, charFormatMask,
+                                           0, iEditor->TextLength() );
+
+    iEditor->HandleTextChangedL();
+
+    TInt nickLengthInPixels( 0 );
+
+    TAknLayoutId layoutId;
+    CAknEnv::Static()->GetCurrentLayoutId( layoutId );
+
+    const CFont* font;
+    if ( layoutId == EAknLayoutIdAPAC )
+        {
+        font = ApacPlain12();
+        }
+    else
+        {
+        font = LatinPlain12();
+        }
+
+    if ( !aGroupMsg )
+        {
+        nickLengthInPixels =  font->TextWidthInPixels( nickVisPtr );
+        }
+
+    nickLengthInPixels += ( font->TextWidthInPixels( KSpace ) ) +
+                          font->TextWidthInPixels( KSemicolon );
+
+    iEditor->SetCursorPosL( iEditor->Text()->DocumentLength(), EFalse );
+
+    CleanupStack::Pop( privIconPic );
+    //Note: code scanner warning is ignored
+    CleanupStack::PopAndDestroy( 2, nickHb ); // msg, nickHb
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::Recipients()
+// Returns recipients array
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+CDesCArrayFlat& CCAChatViewContainer::Recipients() const
+    {
+    return *iRecipients;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SentRecipients()
+// Returns handle to sent recipients
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+CDesCArrayFlat* CCAChatViewContainer::SentRecipients() const
+    {
+    return iSentRecipients;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ResetAfterSendL()
+// Resets arrays, lines and nick length after send
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ResetAfterSendL( const TBool aActivateFromTabSwitch/*=EFalse*/ )
+    {
+    iEditor->ResetL();
+
+    if ( !aActivateFromTabSwitch )
+        {
+        iEditor->SetFocus( ETrue, EDrawNow );
+        iChatView->SetFocus( EFalse, EDrawNow );
+        }
+    else
+        {
+        iEditor->SetFocus( EFalse, EDrawNow );
+        iChatView->SetFocus( ETrue, EDrawNow );
+        }
+
+    iIsPrivateMsgActive = EFalse;
+    iCurrentNickInPrivMsg.Zero();
+    iCurrentTextLenght = 0;
+    iNickLength = 0;
+    iRecipients->Reset();
+    iEditor->EnableCcpuSupportL( ETrue );
+    iEditor->SetTextLimit( IMUtils::MaxMsgLength() );
+    iEditor->SetAknEditorCurrentCase( EAknEditorTextCase );
+    StartScrollingL( aActivateFromTabSwitch );  // Call to update CBA
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::DisplayInfoNoteL()
+// Displays info note for corresponding resource id
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::DisplayInfoNoteL( const TInt aResourceId )
+    {
+    CAknNoteDialog* infoNote = new ( ELeave ) CAknNoteDialog( CAknNoteDialog::
+                                                              EConfirmationTone, CAknNoteDialog::EShortTimeout );
+
+    infoNote->ExecuteLD( aResourceId );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ClearSelectionL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ClearSelectionL( const TInt aSelectionLength )
+    {
+    HBufC* tmpMsg = iEditor->GetTextInHBufL();
+    TPtr tmpPtr( tmpMsg->Des() );
+    CleanupStack::PushL( tmpMsg );
+    tmpPtr.Delete( 0, aSelectionLength );
+    iEditor->ResetL();
+    iEditor->SetTextL( &*tmpMsg );
+    CleanupStack::PopAndDestroy( tmpMsg );
+    iEditor->DrawNow();
+    iIsPrivateMsgActive = EFalse;
+    iNickLength = 0;
+    iRecipients->Reset();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::CreatePrivMsgHeaderL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::CreatePrivMsgHeaderL( TPictureHeader& aIconHeader,
+                                                 const TBool& aGroupMsg,
+                                                 TDesC& aNick,
+                                                 HBufC* aMsg )
+    {
+    //Richtext pointer cannot be put to local variable and that's why it is used
+    //via methods
+
+    // if already exist the prefix of private message, delete it.
+    if ( iNickLength > 0 && iEditor->Text()->DocumentLength() >= iNickLength )
+        {
+        iEditor->RichText()->DeleteL( 0, iNickLength );
+        }
+
+    // reset the prefix of private message
+    TInt originalLength = iEditor->Text()->DocumentLength();
+
+    iEditor->RichText()->InsertL( 0, KSemicolon );
+
+    if ( aGroupMsg )
+        {
+        CCAPicture* privToMany = new ( ELeave ) CCAPicture(
+            *CCoeEnv::Static()->SystemGc().Device(),
+            iPrivToMany );
+
+        CleanupStack::PushL( privToMany );
+
+        TPictureHeader groupIconHeader;
+        groupIconHeader.iPicture = TSwizzle<CPicture>( privToMany );
+
+        iEditor->RichText()->InsertL( 0, groupIconHeader );
+        CleanupStack::Pop( privToMany );
+        }
+    else
+        {
+        iEditor->RichText()->InsertL( 0, aNick );
+        }
+
+    iEditor->RichText()->InsertL( 0, KSpace );
+    iEditor->RichText()->InsertL( 0, aIconHeader );
+
+    iNickLength = iEditor->Text()->DocumentLength() - originalLength;
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::CreatePrivMsgAHHeaderL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::CreatePrivMsgAHHeaderL( TPictureHeader& aIconHeader,
+                                                   const TBool& aGroupMsg,
+                                                   TDesC& aNick,
+                                                   HBufC* aMsg )
+    {
+    //Richtext pointer cannot be put to local variable and that's why it is used
+    //via methods
+
+    // if already exist the prefix of private message, delete it.
+    if ( iNickLength > 0 && iEditor->Text()->DocumentLength() >= iNickLength )
+        {
+        iEditor->RichText()->DeleteL( 0, iNickLength );
+        }
+
+    // reset the prefix of private message
+    TInt originalLength = iEditor->Text()->DocumentLength();
+
+    iEditor->RichText()->InsertL( 0, KSemicolon );
+    iEditor->RichText()->InsertL( 0, KArabicSign );
+
+    if ( aGroupMsg )
+        {
+        CCAPicture* privToMany = new ( ELeave ) CCAPicture(
+            *CCoeEnv::Static()->SystemGc().Device(),
+            iPrivToMany );
+
+        CleanupStack::PushL( privToMany );
+
+        TPictureHeader groupIconHeader;
+        groupIconHeader.iPicture = TSwizzle<CPicture>( privToMany );
+
+        CleanupStack::Pop();
+        iEditor->RichText()->InsertL( 0, groupIconHeader );
+        }
+    else
+        {
+        iEditor->RichText()->InsertL( 0, KArabicSign );
+        iEditor->RichText()->InsertL( 0, aNick );
+        }
+
+    iEditor->RichText()->InsertL( 0, KSpace );
+    iEditor->RichText()->InsertL( 0, KArabicSign );
+    iEditor->RichText()->InsertL( 0, aIconHeader );
+    iEditor->RichText()->InsertL( 0, KArabicSign );
+
+    iNickLength = iEditor->Text()->DocumentLength() - originalLength;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::LoadBitmapsL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::LoadBitmapsL()
+    {
+    //Removed the ownership of iConnUI from this file and made it a reference
+    //APPUI owns this connection UI instance and shares the same with this component.
+    // get user-defined colors from SAP settings
+    CCAAppSettingsSAPExt* SAPExtension = CCAAppSettingsSAPExt::NewLC( iAppUi->ConnectionUI() );
+    TInt ownCol( SAPExtension->IntValueL( KIMOwnMessageColourKey ) );
+    TInt otherCol( SAPExtension->IntValueL( KIMOthersMessageColourKey ) );
+    CleanupStack::PopAndDestroy( SAPExtension );
+
+    TRgb* ownRgbCol = NULL;
+    TRgb* otherRgbCol = NULL;
+
+    TBool useCustomOtherMsgColor = EFalse;
+    if ( otherCol != KErrNotFound )
+        {
+        otherRgbCol = new ( ELeave ) TRgb( otherCol );
+        CleanupStack::PushL( otherRgbCol );
+        useCustomOtherMsgColor = ETrue;
+        }
+
+    TBool useCustomOwnMsgColor = EFalse;
+    if ( ownCol != KErrNotFound )
+        {
+        ownRgbCol = new ( ELeave ) TRgb( ownCol );
+        CleanupStack::PushL( ownRgbCol );
+        useCustomOwnMsgColor = ETrue;
+        }
+
+    // check resource colours
+    // The color settings are fetched from Resource file, and not from the Cenrep, that is the reason for using IntResourceValueFromRssL instead of IntResourceValueL
+    TBool defaultColors = IMUtils::IntResourceValueFromRssL(
+                              RSC_CHAT_DEFAULT_MESSAGE_COLORS );
+
+    if ( !useCustomOwnMsgColor && !defaultColors )
+        {
+        // user-defined color not defined and resource colour in use
+        TResourceReader reader;
+        CCoeEnv::Static()->CreateResourceReaderLC( reader,
+                                                   RSC_CHAT_MESSAGE_COLOR );
+        TUint8 red( reader.ReadUint8() );
+        TUint8 green( reader.ReadUint8() );
+        TUint8 blue( reader.ReadUint8() );
+
+        CleanupStack::PopAndDestroy(); // reader
+
+        if ( !ownRgbCol )
+            {
+            ownRgbCol = new ( ELeave ) TRgb( red, green, blue );
+            CleanupStack::PushL( ownRgbCol );
+            }
+        else
+            {
+            *ownRgbCol = TRgb( red, green, blue );
+            }
+
+        useCustomOwnMsgColor = ETrue;
+        }
+
+    if ( !useCustomOtherMsgColor && !defaultColors )
+        {
+        // user-defined color not defined and resource colour in use
+        TResourceReader reader;
+        CCoeEnv::Static()->CreateResourceReaderLC( reader,
+                                                   RSC_CHAT_OWN_MESSAGE_COLOR );
+        TUint8 red( reader.ReadUint8() );
+        TUint8 green( reader.ReadUint8() );
+        TUint8 blue( reader.ReadUint8() );
+
+        CleanupStack::PopAndDestroy(); // reader
+
+        if ( !otherRgbCol )
+            {
+            otherRgbCol = new ( ELeave ) TRgb( red, green, blue );
+            CleanupStack::PushL( otherRgbCol );
+            }
+        else
+            {
+            *otherRgbCol = TRgb( red, green, blue );
+            }
+
+        useCustomOwnMsgColor = ETrue;
+        }
+
+    CGulIcon* iconTemp;
+
+    // if custom colors are defined, use them
+    if ( useCustomOwnMsgColor )
+        {
+        iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_im_tome,
+                                          EMbmChatngQgn_prop_im_tome_mask,
+                                          iAppUi->MbmFullPath(), EFalse, ownRgbCol );
+        }
+    else
+        {
+        iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_im_tome,
+                                          EMbmChatngQgn_prop_im_tome_mask,
+                                          iAppUi->MbmFullPath() );
+        }
+
+    CleanupStack::PushL( iconTemp );
+    IMUtils::UpdateIcon( iPrivIcon, iconTemp );
+    //iconTemp is removed from CleanupStack and does not have valid value
+
+    //it can be safely reused
+    iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_im_many,
+                                      EMbmChatngQgn_prop_im_many_mask,
+                                      iAppUi->MbmFullPath() );
+    CleanupStack::PushL( iconTemp );
+    IMUtils::UpdateIcon( iPrivToMany, iconTemp );
+    //iconTemp is removed from CleanupStack and does not have valid value
+
+    //it can be safely reused
+    // if custom colors are defined, use them
+    if ( useCustomOtherMsgColor )
+        {
+        iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_im_tome,
+                                          EMbmChatngQgn_prop_im_tome_mask,
+                                          iAppUi->MbmFullPath(), EFalse, otherRgbCol );
+        }
+    else
+        {
+        iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_im_tome,
+                                          EMbmChatngQgn_prop_im_tome_mask,
+                                          iAppUi->MbmFullPath() );
+        }
+    CleanupStack::PushL( iconTemp );
+    IMUtils::UpdateIcon( iToMe, iconTemp );
+    //iconTemp is removed from CleanupStack and does not have valid value
+
+    //it can be safely reused
+    iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_image_corrupted,
+                                      EMbmChatngQgn_prop_image_corrupted_mask,
+                                      iAppUi->MbmFullPath() );
+    CleanupStack::PushL( iconTemp );
+    IMUtils::UpdateIcon( iCorrupted, iconTemp );
+    //iconTemp is removed from CleanupStack and does not have valid value
+
+    //it can be safely reused
+    iconTemp = iSkinVar->LoadBitmapL( EMbmChatngQgn_prop_unknown,
+                                      EMbmChatngQgn_prop_unknown_mask,
+                                      iAppUi->MbmFullPath() );
+    CleanupStack::PushL( iconTemp );
+    IMUtils::UpdateIcon( iUnsupported, iconTemp );
+    //iconTemp is removed from CleanupStack and does not have valid value
+
+    if ( useCustomOwnMsgColor )
+        {
+        CleanupStack::PopAndDestroy(); // ownRgbCol
+        }
+
+    if ( useCustomOtherMsgColor )
+        {
+        CleanupStack::PopAndDestroy(); // otherRgbCol
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ApplicationUserSentThis() const
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::ApplicationUserSentThis() const
+    {
+    TBool ret( EFalse );
+    MCAConversationMessage* msg = iChatView->SelectedMessage();
+    if ( msg )
+        {
+        ret = ( msg->MessagerType() == TEnumsPC::EMessageSent );
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::Received() const
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::Received() const
+    {
+    TBool ret( EFalse );
+    MCAConversationMessage* msg = iChatView->SelectedMessage();
+    if ( msg )
+        {
+        ret = ( msg->MessagerType() == TEnumsPC::EMessageReceived );
+        }
+    return ret;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SaveChatL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+
+void CCAChatViewContainer::SaveChatL()
+    {
+    TBool isMemorySelected = ETrue;
+#ifdef RD_MULTIPLE_DRIVE // show note	
+    isMemorySelected = ShowMemorySelectionDialogL();
+#endif
+
+    // if the location has not been set, don't do record
+    if ( !isMemorySelected )
+        {
+        return;
+        }
+        
+    HBufC* logFileName = HBufC::NewLC( KMaxLogFileName );
+    TPtr logFileNamePtr( logFileName->Des() );
+
+    logFileNamePtr.Copy( iGroupPC->GroupName().Left( KMaxLogFileName ) );
+
+    TInt result( IMDialogUtils::DisplayTextQueryDialogL( logFileNamePtr,
+                                                         RSC_CHATNG_LOGDIALOG_PROMPT, R_CHATCLIENT_LOG_NAME_QUERY,
+                                                         ETrue // T9
+                                                       ) );
+
+    if ( result == EAknSoftkeyOk || result == EAknSoftkeyDone )
+        {
+#ifdef RD_MULTIPLE_DRIVE // show note
+        TInt error = KErrNone;
+        TRAP( error , iGroupPC->SaveChatL( *logFileName ) );
+
+        if ( error != KErrNotSaved && error != KErrDiskFull )
+#else
+        iGroupPC->SaveChatL( *logFileName );
+#endif
+
+            {
+            IMDialogUtils::DisplayConfirmationNoteL( R_QTN_CHAT_SAVING_SAVED );
+            }
+#ifdef RD_MULTIPLE_DRIVE
+        else if ( error == KErrDiskFull )
+            {
+            TBuf< KMaxPath > defaultDrive;
+
+            CRepository* cenrep = CRepository::NewL( KWVSettingsCenRepUid );
+
+            TInt err = cenrep->Get( KIMPSCRIMDefaultMemoryDrive, defaultDrive );
+
+            CleanupStack::PushL( cenrep );
+            CleanupStack::PopAndDestroy( cenrep );
+            cenrep = NULL;
+
+            if ( err != KErrNone )
+                {
+                User::Leave( err );
+                }
+            TInt driveNo = 0;
+            err = RFs::CharToDrive( defaultDrive[0], driveNo );
+            if ( err != KErrNone )
+                {
+                User::Leave( err );
+                }
+            TDriveNumber driveNumber = TDriveNumber( driveNo );
+
+            RFs& fs = CCoeEnv::Static()->FsSession();
+
+            TDriveInfo driveInfo;
+            err = fs.Drive( driveInfo, driveNumber );
+            if ( err != KErrNone )
+                {
+                User::Leave( err );
+                }
+            if ( driveInfo.iDriveAtt & KDriveAttRemovable )
+                {
+                HBufC* prompt = iEikonEnv->AllocReadResourceLC( R_CHAT_MEMLO_MMC_NOT_ENOUGH_MEMORY );
+                IMDialogUtils::DisplayErrorNoteL( *prompt, ETrue );
+                CleanupStack::PopAndDestroy( prompt );
+                }
+            else
+                {
+                HBufC* prompt = iEikonEnv->AllocReadResourceLC( R_CHAT_MEMLO_NOT_ENOUGH_MEMORY );
+                IMDialogUtils::DisplayErrorNoteL( *prompt, ETrue );
+                CleanupStack::PopAndDestroy( prompt );
+                }
+
+            }
+
+#endif
+        }
+    CleanupStack::PopAndDestroy( logFileName );
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SetLoggingOffL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::SetLoggingOffL()
+    {
+    if ( iGroupPC->IsLoggingOn() )
+        {
+        iAppUi->ShowWaitDialogL( R_QTN_GEN_NOTE_SAVING );
+
+
+        TRAPD( err, iGroupPC->EndLoggingL() );
+
+        iAppUi->DismissWaitDialogL( err );
+        if ( err == KErrNone )
+            {
+            IMDialogUtils::DisplayNoteDialogL( R_QTN_RECORDING_ENDED );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsWhisperAllowedL() const
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsWhisperAllowedL() const
+    {
+    CHAT_DP( D_CHAT_LIT( "CCAChatViewContainer::IsWhisperAllowedL()" ) );
+
+    if ( IMUtils::IntResourceValueL( RSC_CHAT_VARIATION_GROUP_WHISPER ) )
+        {
+        return iWhisperingAllowed;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsUserAdminL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsUserAdmin() const
+    {
+    CHAT_DP( D_CHAT_LIT( "CCAChatViewContainer::IsUserAdminL()" ) );
+    return( iGroupUtilsPC->IsAdmin( *iGroupId ) || iGroupUtilsPC->IsOwnGroup( *iGroupId ) );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsGroupOpen()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsGroupOpen() const
+    {
+
+    // In error situation let the group be closed i.e. EFalse
+    CHAT_DP( D_CHAT_LIT( "CCAChatViewContainer::IsGroupOpen()" ) );
+    CHAT_DP( D_CHAT_LIT( "%d = iChatGroup->IsOpenL()" ), iIsOpen );
+    return iIsOpen;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ExtensionFits()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::ExtensionFits( TInt aLength )
+    {
+    TBool retVal( ETrue );
+    if ( iEditor->MaxLength() - iEditor->TextLength() < aLength )
+        {
+        retVal = EFalse;
+        }
+    return retVal;
+    }
+
+// logic:
+// 1. no groups/groups not supported --> hide "to group"
+// 2. no contacts --> hide "to contact"
+// 3. 1 and 2 --> hide forward menu completely
+// 4. contacts, but no online contacts, show All contacts are Offline
+// 5. skip always the current contact we're conversing with
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::FwdContactVisible
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::FwdContactVisible()
+    {
+    // contacts
+    TInt numContacts = iGroupPC->ContactCount();
+
+    TBool showFwdToContact = numContacts > 0;
+
+    CHAT_DP( D_CHAT_LIT(
+                 "CCAChatViewContainer::FwdContactVisible - contacts %d, show %d" ),
+             numContacts, showFwdToContact );
+
+    return showFwdToContact;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::FwdGroupVisible
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::FwdGroupVisible()
+    {
+    // groups
+    TBool groupsSupported = iAppUi->UISessionManager().IsSupported( CCAUISessionManager::EGroup );
+    TInt numGroups = iGroupPC->GroupCount( ETrue );
+
+    // we have to have groups supported and visible to show the forward-menu
+    // If there is only one group we have to be in it so does not need to show menuitem.
+    TBool showFwdToGroup = groupsSupported && ( numGroups > 1 );
+
+    CHAT_DP( D_CHAT_LIT( "CCAChatViewContainer::FwdGroupVisible - fwd show group: %d" ), ( TInt ) showFwdToGroup );
+
+    return showFwdToGroup;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ReplyL()
+// Reply function
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::ReplyL()
+    {
+    MCAConversationMessage* msg = iChatView->SelectedMessage();
+    if ( msg )
+        {
+        TPtrC sender( msg->Sender() );
+        iRecipients->AppendL( sender );
+        InitPrivateMessageL( sender, EFalse );
+
+        StartScrollingL();
+        iAppUi->SetFocusFlag(ETrue);
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::EditChatGroupPropertiesL()
+// Edits chat group properties. Launches setting dialog
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::EditChatGroupPropertiesL()
+    {
+
+    TBool highlight = iChatView->Highlighted();
+
+    if ( !highlight )
+        {
+        iEditor->SetFocus( EFalse );
+        }
+    
+    // Prohibit the tab group at this moment
+    //iAppUi->CAStatusPane()->ProhibitTabGroup( ETrue );
+    
+    TInt result = iAppUi->GroupUtils()->EditChatGroupPropertiesL( *iGroupId );
+
+    //iAppUi->CAStatusPane()->RestoreNaviPane();
+
+    if ( !highlight && result != EAknSoftkeyExit )
+        {
+        iEditor->SetFocus( ETrue );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::LeaveGroupL()
+// This function starts leaving procedure
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::LeaveGroupL()
+    {
+    //Save group conversation if logging is on
+    SetLoggingOffL();
+
+    iAppUi->GroupUtils()->LeaveGroupL( *iGroupId );
+
+    // Deregister group from switch back views
+    iAppUi->DeRegisterSwitchBack( KUidChatView, *iGroupId );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::DisplayChatInfoL()
+// Displays chat info
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::DisplayChatInfoL()
+    {
+    iAppUi->GroupUtils()->DisplayChatInfoL( *iGroupId );
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleEdwinSizeEventL( CEikEdwin* aEdwin,
+//			TEdwinSizeEvent aEventType, TSize aDesirableEdwinSize )
+// This method is called when editor is extended to two lines
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::HandleEdwinSizeEventL( CEikEdwin* /*aEdwin*/,
+                                                   TEdwinSizeEvent aEventType, TSize /*aDesirableEdwinSize*/ )
+    {
+    if ( aEventType == EEventSizeChanging )
+        {
+        SizeChanged();
+
+        DrawNow();
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleTapEventL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::HandleTapEventL( TTapEvent aEvent,
+                                            TUint aControlId )
+    {
+    // Handle the tap events which occur in our child controls:
+    // Message list and Message editor.
+    switch ( aControlId )
+        {
+        case EMessageList:
+            {
+            // Focused message was double tapped
+            if ( aEvent == MCATapEventObserver::EDoubleTap )
+                {
+                // Activate tapped item
+                TBool ignore;
+                TBool dummyArgument( EFalse );
+                if ( IsObjectSelected( ignore, dummyArgument ) )
+                    {
+                    iAppUi->ProcessCommandL( EChatClientOpenObject );
+                    }
+
+                }
+            // Message or item was tapped
+            else if ( aEvent == MCATapEventObserver::ESingleTap )
+                {
+                // Find objects activate with single tap
+                iRecipientObserver.ShowPopUpMenuL();
+                }
+            break;
+            }
+        case EMessageEditor:
+            {
+            // Nothing to do here ATM.
+            // Focus transition is handled in HandleControlEventL
+            break;
+            }
+        default:
+            {
+            // There is an unhandled object or the object returned wrong
+            // controlId. Check the implementation.
+            __CHAT_ASSERT_DEBUG( EFalse );
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::CheckIfPrivateMessageL()
+// Checks if written message has private icons
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::CheckIfPrivateMessageL()
+    {
+    TInt cursosPos( iEditor->CursorPos() );
+    //KPictureChar stands for for space and ':' character
+    cursosPos -= KPictureChar;
+
+    if ( cursosPos >= 0 && cursosPos <= iNickLength )
+        {
+        TPtrC text( iEditor->Text()->Read( cursosPos, 1 ) );
+
+        if ( text[0] == KColon )
+            {
+            TInt selectionLength( iEditor->SelectionLength() );
+            if ( selectionLength > 0 )
+                {
+                ClearSelectionL( selectionLength );
+                iEditor->EnableCcpuSupportL( ETrue );
+                }
+            else
+                {
+                iEditor->SetSelectionL( iEditor->CursorPos(), 0 );
+                iEditor->EnableCcpuSupportL( EFalse );
+                }
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::DoHandleGroupPropertiesChangedL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::DoHandleGroupPropertiesChangedL()
+    {
+    TBool isGroupProps( EFalse );
+    iGroupPC->GetPropertiesL( isGroupProps );
+    if ( isGroupProps )
+        {
+        TPtrC groupName = iGroupPC->GroupName();
+        if ( groupName.Length() > 0 )
+            {
+            // use name when possible
+            iViewSwitcher.CAStatusPane()->SetTitleL( groupName );
+            }
+        else if ( iGroupId )
+            {
+            // GroupId is the second option
+            iViewSwitcher.CAStatusPane()->SetTitleL(
+                CCAPCUtils::DisplayId( *iGroupId ) );
+            }
+        iWhisperingAllowed = ( TEnumsPC::EImpsPropYes == iGroupPC->IsPrivateAllowed() );
+        iIsOpen = ( TEnumsPC::EImpsPropYes == iGroupPC->IsOpen() );
+        }
+    else
+        {
+        // We don't know the states so assume the worst
+        iWhisperingAllowed = EFalse;
+        iIsOpen = EFalse;
+        }
+
+
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::DoHandleGroupLeftL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::DoHandleGroupLeftL( TInt aReason )
+    {
+    // don't redraw the list box.otherwise we might crash after background to
+    // foreground switch
+    IMNoteMapper::ShowNoteL( aReason );
+    //SwitchView and DeleteTab is called here as there can be group leave
+    //because the creater has removed the group or banned the user from the group
+
+    iAppUi->CAStatusPane()->SynchroniseAndRemoveTabGroup();
+    iViewSwitcher.SwitchViewL( KUidFriendsListView );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::LayoutChangedL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::LayoutChangedL( TInt aType )
+    {
+    LoadBitmapsL();
+    TRect mainPaneRect;
+    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
+    SetRect( mainPaneRect );
+
+    // Update skin context of editor
+    if ( iEditor )
+        {
+        iEditor->SetupSkinContextL( ETrue );
+        }
+
+    CCoeControl::HandleResourceChange( aType );
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleGroupLeft
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::HandleGroupLeft( TInt aReason )
+    {
+    CHAT_DP_TXT( "         !! CCAChatViewContainer::HandleGroupLeft !!!" );
+    TRAPD( err, DoHandleGroupLeftL( aReason ) );
+
+    if ( err )
+        {
+        CActiveScheduler::Current()->Error( err );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleGroupPropertiesChanged()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::HandleGroupPropertiesChanged()
+    {
+    TRAPD( err, DoHandleGroupPropertiesChangedL() );
+    if ( err )
+        {
+        CActiveScheduler::Current()->Error( err );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SizeChanged()
+// Called by framework when the view size is changed
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::SizeChanged()
+    {
+
+    TInt lines( iEditor->NumberOfLines() );
+
+    if ( lines > KMaxLines ) // ignore events for more than 2 lines
+        {
+        lines = 2;
+        }
+    lines--;	// convert to index
+
+    TAknLayoutRect rp;
+    if ( lines == 1 )
+        {
+        rp.LayoutRect( Rect(), AknLayoutScalable_Apps::im_reading_pane(
+                           TChatListBoxLayout::EWithEditor2Lines ) );
+        }
+    else
+        {
+        rp.LayoutRect( Rect(), AknLayoutScalable_Apps::im_reading_pane(
+                           TChatListBoxLayout::EWithEditor ) );
+        }
+
+    // Set icon sizes, do this before setting the rect for
+    // chat view to prevent icon sizes from changing after chat
+    // view rect is set.
+    ResizeIcons( TextRect() );
+
+    // set rect for chat view
+    iChatView->SetRect( rp.Rect() );
+
+
+    TAknLayoutRect wpl;
+    wpl.LayoutRect( Rect(), AknLayoutScalable_Apps::im_writing_pane( 1 - lines ) );
+
+    TAknWindowLineLayout myWPLayout( AknLayoutScalable_Apps::im_writing_pane( 1 - lines ) );
+
+    iOutLine.LayoutRect( iAppUi->LayoutInfo()->MainPaneRect(), myWPLayout );
+
+    iVertLine.LayoutRect( wpl.Rect(), AppLayout::IM_writing_field_elements_Line_1( lines ) );
+
+    iHoriline.LayoutRect( wpl.Rect(), AppLayout::IM_writing_field_elements_Line_2() );
+
+    TAknMultiLineTextLayout mlwpt = AppLayout::Multiline_IM_writing_pane_texts_Line_1( lines + 1 );
+
+    AknLayoutUtils::LayoutEdwin( iEditor , wpl.Rect(), mlwpt, EAknsCIQsnTextColorsCG25 );
+		
+	FocusChanged( EDrawNow );
+
+    DrawNow();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::CountComponentControls() const
+// ---------------------------------------------------------
+//
+TInt CCAChatViewContainer::CountComponentControls() const
+    {
+    //chatview, iEditor
+    return KControlCount;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::ComponentControl(TInt aIndex) const
+// ---------------------------------------------------------
+//
+CCoeControl* CCAChatViewContainer::ComponentControl( TInt aIndex ) const
+    {
+    switch ( aIndex )
+        {
+        case 0:
+            {
+            return iChatView;
+            }
+        case 1:
+            {
+            return iEditor;
+
+            }
+        default:
+            {
+            return NULL;
+
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::Draw(const TRect& aRect) const
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::Draw( const TRect& aRect ) const
+    {
+    CWindowGc& gc = SystemGc();
+
+    // Draw skinned background
+    iSkinVar->ClearChatListBoxBackGround(
+        gc, aRect,
+        iSkinVar->MainPaneBackgroundContext() );
+
+    TRect editorRect( iEditor->Rect() );
+    TRect outlineRect( iOutLine.Rect() );
+    TRect parent( Rect() );
+
+    TBool skinnedDraw = iSkinVar->DrawSkinnedEditor( this, gc, parent, editorRect, outlineRect );
+
+    if ( ! skinnedDraw )
+        {
+        DrawUtils::ClearBetweenRects( gc, Rect(), iEditor->Rect() );
+
+        iOutLine.DrawOutLineRect( gc );
+        iHoriline.DrawRect( gc );
+        iVertLine.DrawRect( gc );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+//												  TEventCode aType )
+// Handles keyevents
+// ---------------------------------------------------------
+//
+TKeyResponse CCAChatViewContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+                                                   TEventCode aType )
+    {
+    CHAT_DP( D_CHAT_LIT( "CCAChatViewContainer::OfferKeyEventL key %d" ), aKeyEvent.iCode );
+
+    if ( ( IsStopped() || !iEditor->IsFocused() ) )
+        {
+        if ( aKeyEvent.iScanCode >= '0' && aKeyEvent.iScanCode <= '9' )
+            {
+            // stop the automatic scrolling  and start manual
+            // if user presses any of the number keys (0-9)
+            StartScrollingL();
+            // Key event gets passed to editor after this
+            }
+        }
+
+    if ( aType == EEventKeyDown )
+        {
+        //if "#" is pressed start and timer and show the editing indicator
+        if ( ( aKeyEvent.iScanCode == KHashKey ) &&
+             ( iEditor->TextLength() == 0 ) )
+            {
+
+            if ( !iEditIndicator->IsIndicatorActive() )
+                {
+                iEditIndicator->StartTimer();
+                }
+
+            }
+        }
+
+    switch ( aKeyEvent.iCode )
+        {
+            // flowthrough
+        case EKeyEnter:
+        case EKeyOK:
+        case EKeyPhoneSend:
+            {
+            if ( iView->GetIfMenuPopup() )
+                {
+                return EKeyWasConsumed;
+                }
+            if ( iEditor->IsFocused() )
+                {
+                iEditor->SetFocus( EFalse );
+                // trapping error so that focus can be returned to editor
+                TRAPD( err, SendMessageL() );
+                if ( err )
+                    {
+                    CActiveScheduler::Current()->Error( err );
+                    }
+                iEditor->SetFocus( ETrue );
+                }
+            else if ( aKeyEvent.iCode == EKeyEnter
+                      || aKeyEvent.iCode == EKeyOK
+                      && iChatView->Highlighted() )
+                {
+                TBool ignore;
+                TBool dummyArgument( EFalse );
+
+                if ( IsObjectSelected( ignore, dummyArgument ) )
+                    {
+                    iAppUi->ProcessCommandL( EChatClientOpenObject );
+                    }
+                else
+                    {
+                    iRecipientObserver.ShowPopUpMenuL();
+                    }
+                }
+            else if ( iSendkeyInMsgList )
+                {
+                if ( aKeyEvent.iCode == EKeyPhoneSend
+                     && iChatView->Highlighted()
+                     && iChatView->SelectedItemType()
+                     == CFindItemEngine::EFindItemSearchPhoneNumberBin )
+                    {
+                    // Phone number highlighted, send key pressed -> call
+                    iAppUi->ProcessCommandL( EChatClientCall );
+                    }
+                }
+            return EKeyWasConsumed;
+            }
+
+        case EKeyBackspace:
+            {
+            // if bitmap is selected, it is deleted "normally" in
+            // iEditor's OfferKeyEvent
+            if ( iEditor->SelectionLength() > 0 )
+                {
+                break;
+                }
+
+            if ( CheckIfPrivateMessageL() )	// if there are private icons, don't go back
+                {
+                return EKeyWasConsumed;
+                }
+            else
+                {
+                TInt cursorPos( iEditor->CursorPos() );
+                if ( cursorPos > 0 ) // at least one char in editor
+                    {
+                    TPtrC ptr = iEditor->RichText()->Read( ( cursorPos - 1 ), 1 );
+                    // if a char to be "backspaced" is a picture
+                    if ( ptr[ 0 ] == CEditableText::EPictureCharacter )
+                        {
+                        iMessageExtensionsHandler.DeleteExtensionL( *iEditor,
+                                                                    EMessageExtensionSmiley, cursorPos - 1 );
+                        return EKeyWasConsumed;
+                        }
+                    }
+
+                //If cursor pos is less than 2 then it is set to 2
+                //KPictureChar for picture characters. (Two icons)
+                if ( cursorPos < KPictureChar )
+                    {
+                    cursorPos = 2;
+                    }
+
+                CHAT_DP( D_CHAT_LIT( "CursorPos(): %d" ), cursorPos );
+                }
+            break;
+            }
+
+        case EKeyLeftArrow:
+            {
+            if ( !iEditor->IsFocused() ||
+                 ( iEditor->CursorPos() <= iNickLength &&
+                   iNickLength > 0 ) )
+                {
+                TKeyResponse res = iAppUi->OfferTabEventL( aKeyEvent, aType );
+                if ( ifocusFlag )
+                    {
+                    StartScrollingL();
+                    ifocusFlag = EFalse;
+                    }
+                else
+                    {
+                    iAppUi->SetFocusFlag( EFalse );
+                    }
+                return res;
+                }
+            break;
+            }
+
+        case EKeyRightArrow:
+            {
+            if ( !iEditor->IsFocused() )
+                {
+                TKeyResponse res = iAppUi->OfferTabEventL( aKeyEvent, aType );
+                if ( ifocusFlag )
+                    {
+                    StartScrollingL();
+                    ifocusFlag = EFalse;
+                    }
+                else
+                    {
+                    iAppUi->SetFocusFlag( EFalse );
+                    }
+                return res;
+                }
+
+            TInt cursorPos( iEditor->CursorPos() );
+
+            if ( ( cursorPos >= 0 ) &&
+                 ( cursorPos < iNickLength ) &&
+                 ( iNickLength > 0 ) )
+                {
+                TPtrC text( iEditor->Text()->Read( cursorPos, 1 ) );
+
+                if ( text[0] == CEditableText::EPictureCharacter )
+                    {
+                    iEditor->SetCursorPosL( iNickLength, EFalse );
+                    return EKeyWasConsumed;
+                    }
+                }
+            else if ( cursorPos == iEditor->TextLength() )
+                {
+                iEditor->SetCursorPosL( iNickLength, EFalse );
+                return EKeyWasConsumed;
+                }
+            break;
+            }
+
+        case EKeyDownArrow: // flowthrough
+        case EKeyUpArrow:
+            {
+            if ( iEditor->IsFocused() )
+                {
+                // editor is focused, try to offer the key
+                if ( iEditor->OfferKeyEventL( aKeyEvent, aType ) == EKeyWasConsumed )
+                    {
+                    // editor took it
+                    return EKeyWasConsumed;
+                    }
+                }
+
+            // offer the key to our chat control
+            TKeyResponse res = static_cast<CCoeControl*>( iChatView )
+                               ->OfferKeyEventL( aKeyEvent, aType );
+
+            if ( iChatView->Highlighted() )
+                {
+                // change the cba
+                StopScrollingL();
+
+                iAppUi->SetFocusFlag( EFalse );
+                }
+            else
+                {
+                // change the cba
+                StartScrollingL();
+
+                iAppUi->SetFocusFlag( ETrue );
+                }
+            return res;
+            }
+        }
+
+    if ( iEditor->IsFocused() )
+        {
+        TKeyResponse resp = iEditor->OfferKeyEventL( aKeyEvent, aType );
+
+        TInt cursorPos( iEditor->CursorPos() );
+        if ( ( cursorPos >= 0 ) &&
+             ( cursorPos < iNickLength ) &&
+             ( iNickLength > 0 ) )
+            {
+            TPtrC text( iEditor->Text()->Read( cursorPos, 1 ) );
+
+            if ( text[0] == CEditableText::EPictureCharacter )
+                {
+                iEditor->SetCursorPosL( iNickLength, EFalse );
+                }
+            }
+
+        // Update CBA only when there is not a shift held down
+        if ( !( aKeyEvent.iModifiers & EModifierShift ) )
+            {
+            UpdateCbaL();
+            }
+        TInt inputLang = iAvkonEnv->SettingCache().InputLanguage();         // when the language has candidate
+        if ( ( inputLang != ELangPrcChinese ) && ( inputLang != ELangHongKongChinese )// pane then switching between tabs shouldnot
+             && ( inputLang != ELangTaiwanChinese ) && ( inputLang != ELangJapanese ) ) // happen, when editor is empty.
+            {
+            if ( resp == EKeyWasNotConsumed && iEditor->TextLength() == 0
+                 && aType == EEventKeyDown
+                 && ( aKeyEvent.iScanCode == EStdKeyLeftArrow
+                      || aKeyEvent.iScanCode == EStdKeyRightArrow ) )
+                {
+                StopScrollingL();
+                ifocusFlag = ETrue;
+                iAppUi->SetFocusFlag( ETrue );
+                }
+            }
+        return resp;
+        }
+
+    return EKeyWasNotConsumed;
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleMessageEditorEventL
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::HandleMessageEditorEventL( TEditorEvent aEvent )
+    {
+    switch ( aEvent )
+        {
+        case EEditorContentCleared: // Flowthrough
+            {
+            // Call StartScrollingL to update CBA if needed
+            StartScrollingL();
+            break;
+            }
+        case EEditorFirstContentAdded:
+            {
+            if ( !iEditor->IsFocused() )
+                {
+                StartScrollingL();
+                }
+            break;
+            }
+        default:
+            {
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::GetHelpContext
+// This function is called when Help application is launched
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::GetHelpContext( TCoeHelpContext& aContext ) const
+    {
+    aContext.iMajor = KUidChatClient;
+    aContext.iContext = KIMNG_HLP_CONVERSATIONS ;
+    }
+// ---------------------------------------------------------
+// CCAConversationsContainer::FocusChanged
+// This function is called when focus has been changed
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::FocusChanged(TDrawNow aDrawNow)
+	{
+	if ( iEditor && iAppUi->FocusFlag() )
+		{
+		iEditor->SetFocus( IsFocused() );
+		}
+	
+	CCoeControl::FocusChanged( aDrawNow );
+	}
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::RefreshEditorL
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::RefreshEditorL()
+    {
+    iEditor->RefreshEditorL();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::IsItemHighlight
+// ---------------------------------------------------------
+//
+TBool CCAChatViewContainer::IsItemHighlight() const
+    {
+    return iItemHighlight;
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::TextRect
+// ---------------------------------------------------------
+//
+const TRect CCAChatViewContainer::TextRect() const
+    {
+    TInt lines( iEditor->NumberOfLines() );
+
+    if ( lines > KMaxLines ) // ignore events for more than 2 lines
+        {
+        lines = 2;
+        }
+    lines--;	// convert to index
+
+    TAknLayoutRect rp;
+    if ( lines == 1 )
+        {
+        rp.LayoutRect( Rect(), AknLayoutScalable_Apps::im_reading_pane( 0
+                                                                        /*TChatListBoxLayout::EWithEditor2Lines*/ ) );
+        }
+    else
+        {
+        rp.LayoutRect( Rect(), AknLayoutScalable_Apps::im_reading_pane( 1
+                                                                        /*TChatListBoxLayout::EWithEditor*/ ) );
+        }
+
+    TAknLayoutText text;
+    text.LayoutText( rp.Rect(),
+                     AknLayoutScalable_Apps::im_reading_pane_t1( 1 ).LayoutLine() );
+
+    return text.TextRect();
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleControlEventL
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::HandleControlEventL( CCoeControl* aControl,
+                                                TCoeEvent aEventType )
+    {
+    if ( EEventRequestFocus == aEventType )
+        {
+        if ( aControl == ( CCoeControl* )iEditor )
+            {
+            // Focus to editor
+            StartScrollingL();
+            iAppUi->SetFocusFlag( ETrue );
+            }
+        else // aControl == iChatView
+            {
+            // Focus to messagelist
+            StopScrollingL();
+            iAppUi->SetFocusFlag( EFalse );
+            }
+        }
+
+    if ( CATouchUtils::PenEnabled() )
+        {
+        if ( EEventStateChanged == aEventType )
+            {
+            if ( aControl == ( CCoeControl* )iEditor )
+                {
+                // Update MSK - When using virtual keyboard
+                // on touch enabled devices, one is bound to receive
+                // EEventStateChanged. Hence handle the same
+                UpdateCbaL();
+                }
+            }
+        }
+
+    }
+
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::SwitchTabL
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::SwitchTabL()
+    {
+
+    if ( iGroupId )
+        {
+
+        iGroupPC->SetGroupEventObserverL( NULL, *iGroupId  );
+
+        delete 	iGroupId;
+        iGroupId = NULL;
+        }
+
+    iGroupId = iGroupPC->ActiveGroupId().AllocL();
+
+    HandleGroupPropertiesChanged();
+
+    iGroupPC->SetGroupEventObserverL( this, *iGroupId  );
+
+    delete iChatView;
+    iChatView = NULL;
+
+    MCAMsgAddedToRichTxtCtrlObserver* observer = NULL;
+
+    if ( !iAppUi->FocusFlag() )
+        {
+        observer = this;
+        }
+
+    iChatView = CCAChatViewControl::NewL( Rect(), *this,
+                                          *iGroupPC,
+                                          *iAppUi->GetProcessManager().GetSettingsInterface(),
+                                          iMessageExtensionsHandler,
+                                          iPrivIcon, iToMe,
+                                          iUnsupported,
+                                          iCorrupted,
+                                          ETrue,
+                                          observer
+                                        );
+
+    iChatView->SetObserver( this );
+
+    SizeChanged();
+
+    // Observe tap events
+    iChatView->SetTapObserver( this, EMessageList );
+
+    iAppUi->LayoutInfo()->SetLayoutID( TChatListBoxLayout::EWithEditor );
+    iAppUi->LayoutInfo()->SetEditorVisibility( ETrue );
+
+    if ( iAppUi->FocusFlag() )
+        {
+        StartScrollingL();
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAChatViewContainer::HandleMessageAddedL
+// ---------------------------------------------------------
+//
+void CCAChatViewContainer::HandleMessageAddedL( const TInt aMessageCount )
+    {
+    //called by tabswitch. hence set the foxus to the last message
+    if ( iGroupPC->MessageCount() == aMessageCount )
+        {
+        iChatView->MoveHighlightL( CCARichTextContainer::EPrevious );
+
+        iChatView->UnRegisterRichTxtCtrlObserver();
+
+        UpdateCbaL();
+        }
+
+    }
+
+#ifdef RD_MULTIPLE_DRIVE
+// -----------------------------------------------------------------------------
+// CCAChatViewContainer::ShowMemorySelectionDialogL
+// New actual filename for new history file.
+// -----------------------------------------------------------------------------
+//
+TBool CCAChatViewContainer::ShowMemorySelectionDialogL()
+    {
+    CHAT_DP_TXT( "CCALoggerManager::ShowMemorySelectionDialogL" );
+
+    ///////// read settings from cenrep ///////////////
+
+    TBuf< KMaxPath > defaultDrive;
+    TBuf< KMaxPath > pathTempWithoutDrive;
+    TBuf< KMaxPath > driveAndPath;
+
+    CRepository* cenrep = NULL;
+    TRAPD( err, cenrep = CRepository::NewL( KWVSettingsCenRepUid ) );
+
+    if ( err == KErrNone )
+        {
+        // creation of cenrep OK
+        CleanupStack::PushL( cenrep );
+        err = cenrep->Get( KIMPSCRIMDefaultMemoryDrive, defaultDrive );
+        if ( err != KErrNone )
+            {
+            CleanupStack::PopAndDestroy( cenrep );
+            cenrep = NULL;
+            User::Leave( err );
+            }
+        // end of reading from cenrep
+
+
+        TInt driveNo = 0;
+        err = RFs::CharToDrive( defaultDrive[0], driveNo );
+        TDriveNumber driveNumber = TDriveNumber( driveNo );
+
+        // Check drive's media status
+        TBool isDriveOk = iAppUi->GetDriveStatusL( driveNumber );
+        if ( !isDriveOk )
+            {
+
+            // prompt the user to save into a different drive.......
+            CAknMemorySelectionDialogMultiDrive* dlg = CAknMemorySelectionDialogMultiDrive::NewL(
+                                                           ECFDDialogTypeSave,
+                                                           EFalse );
+
+            HBufC* rootBuffer = HBufC::NewLC( KMaxPath );
+            TPtr rootBufferPtr ( rootBuffer->Des() );
+
+            HBufC* defaultFolderBuffer = HBufC::NewLC( KMaxPath );
+            TPtr defaultFolderBufferPtr ( defaultFolderBuffer->Des() );
+
+            CleanupStack::PushL( dlg );
+            TBool ret( dlg->ExecuteL( driveNumber, &rootBufferPtr, &defaultFolderBufferPtr ) );
+            CleanupStack::PopAndDestroy( dlg );
+
+            CleanupStack::PopAndDestroy( defaultFolderBuffer );
+
+            if ( ret )
+                {
+                // update the centrep sheet also..as user changed the default folder...
+                cenrep->Set( KIMPSCRIMDefaultMemoryDrive, rootBufferPtr.Left( 3 ) );
+                driveAndPath.Append( rootBufferPtr.Left( 2 ) ); // append the drive root here with user selected drive...
+                CleanupStack::PopAndDestroy( rootBuffer );
+                CleanupStack::PopAndDestroy( cenrep );
+                cenrep = NULL;
+                }
+            else
+                {
+                CleanupStack::PopAndDestroy( rootBuffer );
+                CleanupStack::PopAndDestroy( cenrep );
+                cenrep = NULL;
+                }
+    		// use selected memory
+    		return ret;
+            }
+        else
+            {
+            CleanupStack::PopAndDestroy( cenrep );
+            cenrep = NULL;
+			// use the default memory
+			return ETrue;
+            }
+        }
+    
+    // cenrep create error
+    return EFalse;
+    }
+
+
+#endif
+
+// End of File