wvuing/wvuiave/AppSrc/CCAConversationsView.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuiave/AppSrc/CCAConversationsView.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,1749 @@
+/*
+* 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:  view class for conversation view
+*
+*/
+
+
+// INCLUDE FILES
+#include	"chatngclient.hrh"
+#include	"CCAConversationsView.h"
+#include	"CCAConversationsContainer.h"
+#include    "CCAUISessionManager.h"
+#include	"CCAStatusPaneHandler.h"
+#include	"CCAAppUi.h"
+#include	"CAExternalInterface.h"
+#include	"CCAMessageEditor.h"
+#include	"ChatDebugPrint.h"
+#include    "ChatDefinitions.h"
+#include    "CAExternalInterface.h"
+#include    "IMNoteMapper.h"
+#include    "IMDialogUtils.h"
+#include	"ImpsCSPAllErrors.h"
+#include    "CCAMessageExtensionsHandler.h"
+#include    "CCAFadeControl.h"
+#include    "MCAIndicatorTerminator.h"
+#include    "MCAMessageExtension.h"
+#include    "IMUtils.h"
+#include    "CCAUiMessageUtils.h"
+#include    "CAUtils.h"
+#include    "CCAPCUtils.h"
+#include	"CCAApp.h"
+#include    "CCAContactSelectionDialog.h"
+#include	"CCAVariantFactory.h"
+
+#include    "MCAConversationMessage.h"
+#include    "MCAMessageCreator.h"
+#include    "MCASettingsPC.h"
+#include    "mcamessagecontainerinfo.h"
+#include    "IMPRivateCRKeys.h"
+#include    "IMVariant.hrh"
+
+#include	<eikbtgpc.h>
+#include	<eikgted.h> //For the CEikGlobalTextEditor
+#include	<eikmenup.h>
+#include	<eikmenub.h>
+#include	<aknpopup.h>
+#include	<aknnotewrappers.h>
+#include    <stringloader.h>
+#include    <aknenv.h>
+#include 	<aknlists.h>
+#include	<flogger.h>
+#include	<utf.h>
+#include 	<txtrich.h>
+#include	<aknquerydialog.h>
+#include	<chatNG.rsg>
+#include	<CAVariationNG.rsg>
+#include    <NewFileService.hrh> // TNewServiceFileType
+
+#include	<bldvariant.hrh>
+#include    <hlplch.h>
+#include    <FeatMgr.h>
+
+#include    <finditem.hrh>
+#include    <finditemmenu.h>
+
+#include    <commonuiinternalcrkeys.h>
+
+#include 	"MCAConversationPC.h"
+#include	"MCAProcessManager.h"
+#include	"MCAServerContactsArrayPC.h"
+#include    "CCAGroupUtils.h"
+#include    "MCALoginPC.h"
+#include    "CCaSyncChecker.h"
+#include 	"MCAMainViewArrayPC.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"
+const TInt KMaxTitleLength = 32;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCAConversationsView::CCAConversationsView()
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CCAConversationsView::CCAConversationsView()
+        : iCleanSender( NULL, 0 ),
+        iLastUnreadIndex( KErrNotFound ),
+        iForeground( ETrue )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCAConversationsView::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CCAConversationsView::ConstructL( TInt aAvkonViewResourceId, TUid aViewId,
+                                       CCAMessageExtensionsHandler& aMessageHandler )
+    {
+    BaseConstructL( aAvkonViewResourceId, aViewId );
+
+    iMessageHandler = &aMessageHandler;
+
+    iFindContextMenu = new( ELeave ) CEikMenuBar;
+    iFindContextMenu->ConstructL( this, 0, R_CHATCLIENT_MENUBAR_FINDITEMUI );
+
+    iAddAndReplyMenu = new( ELeave ) CEikMenuBar;
+    iAddAndReplyMenu->ConstructL(
+        this,
+        0,
+        R_CHATCLIENT_MENUBAR_ADDANDREPLY );
+
+    iContactId = HBufC::NewL( KMaxChatGroupLenght );
+    iListId = HBufC::NewL( KMaxChatGroupLenght );
+    iFindMenu = CFindItemMenu::NewL( EChatClientFindMenuPlaceHolder );
+    iFindMenu->AttachItemFinderMenuL( R_CHATCLIENT_IBOX_VIEW_MENU );
+    // automatic finder on by default
+    iFindMenu->HandleItemFinderCommandL( EFindItemCmdEnableAutoFind );
+    iItemFinder = CItemFinder::NewL();
+
+    iAppUI = static_cast <CCAAppUi*> ( CCoeEnv::Static()->AppUi() );
+
+    iConversationPC = iAppUI->GetProcessManager().GetConversationInterface();
+
+    iTitlePane = iAppUI->CAStatusPane();
+    }
+
+// Destructor
+CCAConversationsView::~CCAConversationsView()
+    {
+
+
+
+    if ( iContainer && iAppUI )
+        {
+        iAppUI->RemoveFromViewStack( *this, iContainer );
+        }
+
+    delete iContainer;
+
+    if ( iAddAndReplyMenu && iAppUI )
+        {
+        iAppUI->RemoveFromViewStack( *this, iAddAndReplyMenu );
+        }
+
+    if ( iFindContextMenu && iAppUI )
+        {
+        iAppUI->RemoveFromStack( iFindContextMenu );
+        }
+
+    delete iFindContextMenu;
+    delete iAddAndReplyMenu;
+    delete iContactId;
+    if ( iListId )
+        {
+        delete iListId;
+        }
+    delete iTitle;
+    delete iSender;
+    delete iFindMenu;
+    delete iItemFinder;
+    delete iEditorContent;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CCAConversationsView::HandleCbaChangeL()
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CCAConversationsView::HandleCbaChangeL( TInt aResourceId )
+    {
+    Cba()->SetCommandSetL( aResourceId );
+    Cba()->DrawNow();
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::SetLastUnreadIndex()
+// Sets last unread message index
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::SetLastUnreadIndex(
+    const TInt aLastUnreadIndex /* = -1  */ )
+    {
+    iLastUnreadIndex = aLastUnreadIndex;
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::CloseConversationL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::CloseConversationL()
+    {
+
+    MCAMainViewArrayPC* mainViewArrayPC = iAppUI->GetProcessManager().GetArrayInterface();
+
+    if ( iTitlePane )
+        {
+        HBufC* identification = iTitlePane->GetTabItemIdentification( iTabId ).AllocLC();
+
+
+        HBufC* prompt = StringLoader::LoadLC( R_CLOSE_CONVERSATION_PROMPT,
+                                              *identification );
+
+
+        CAknQueryDialog* dlg = new ( ELeave ) CAknQueryDialog(
+            CAknQueryDialog::ENoTone );
+
+        CleanupStack::PushL( dlg );
+
+        dlg->SetPromptL( *prompt );
+
+        CleanupStack::Pop( dlg );
+
+        TInt ret( dlg->ExecuteLD( R_CLOSE_COVERSATION_QUERY ) );
+
+        CleanupStack::PopAndDestroy( 2, identification ); // prompt, identification
+
+
+        if ( ( ret == EAknSoftkeyOk ) || ( ret == EAknSoftkeyYes ) )
+            {
+            // hide button group to prevent back button using during close
+            iCba = CEikButtonGroupContainer::Current();
+            iCba->MakeVisible( EFalse );
+            iCba->DrawNow();
+
+            iConversationPC->DeleteChatL( KNullDesC,
+                                          KNullDesC,
+                                          *iContactId );
+
+            //To remove the item from open chats array when conv is closed
+            mainViewArrayPC->RemoveConversationItem( *iContactId );
+
+            // Deregister conversation from switch back views
+            iAppUI->DeRegisterSwitchBack( KUidConversationsView,
+                                          *iContactId );
+            if ( iTitlePane )
+                {
+                //iTitlePane->DeleteTab(iTabId);
+                iTitlePane->SynchroniseAndRemoveTabGroup();
+                }
+
+            iAppUI->SwitchViewBackL( KUidFriendsListView );
+            //iAppUI->SwitchViewL( KUidFriendsListView );
+
+            // XXX before or after SwitchView
+            iCba->MakeVisible( ETrue );
+            iCba->DrawNow();
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::DynInitMenuPaneL
+// Called when menupane is about to be shown.
+// ---------------------------------------------------------
+//
+void CCAConversationsView::DynInitMenuPaneL(
+    TInt aResourceId, CEikMenuPane* aMenuPane )
+    {
+    TInt Temp = aMenuPane->NumberOfItemsInPane();
+    TBool showFwdToContact = iContainer->FwdContactVisible();
+    TBool showFwdToGroup   = iContainer->FwdGroupVisible();
+
+    if ( ! iAppUI->UISessionManager().IsSupported( CCAUISessionManager::EGroup ) )
+        {
+        // groups are not supported, hide forward to group
+        showFwdToGroup = EFalse;
+        }
+
+    TBool showForwardMenu = showFwdToGroup || showFwdToContact;
+
+    // if we're displaying general menu and help feature is not supported..
+    switch ( aResourceId )
+        {
+
+            //added for edit text, writing language options
+            /*  case R_CHATCLIENT_TEXTEDIT_MENU:
+              	{
+
+              	TBool editorFocus = iContainer->Editor().IsFocused();
+
+              	aMenuPane->SetItemDimmed( EChatClientEditText, !editorFocus );
+              	aMenuPane->SetItemDimmed( EAknCmdInputLanguage, !editorFocus );
+              	break;
+
+              	}*/
+
+        case R_CHATCLIENT_GENERAL_MENU:
+            {
+            aMenuPane->SetItemDimmed( EChatClientCmdHelp,
+                                      !FeatureManager::FeatureSupported( KFeatureIdHelp ) );
+            break;
+            }
+        case R_CHATCLIENT_ADDANDREPLY_MENU:
+            {
+            aMenuPane->SetItemDimmed( EChatClientIboxReply, ETrue );
+            if ( iConversationPC->FindAnyContact( *iContactId ) )
+                {
+                aMenuPane->SetItemDimmed( EChatClientSearchAddFriends, ETrue );
+                }
+            break;
+            }
+        case R_CHATCLIENT_IBOX_VIEW_MENU:
+            {
+            TBool text( iContainer->Editor().TextLength() != 0 );
+            TBool openable = EFalse;
+            TBool savePossible( EFalse );
+            TBool object = iContainer->IsObjectSelected( openable, savePossible );
+
+            //	IM client UI customization, phase 2
+            //  Based on Variation flag, Show Templates
+            TBool showTemplates = IMUtils::IntResourceValueL( RSC_CHAT_VARIATION_SHOW_TEMPLATES );
+            // Convention does not allow comparison to NULL, using ugly if/else
+            TBool contactInList;
+
+            if ( iConversationPC->FindAnyContact( *iContactId ) )
+                {
+                contactInList = ETrue;
+                }
+            else
+                {
+                contactInList = EFalse;
+                }
+
+            // "send"
+            aMenuPane->SetItemDimmed( EChatClientIboxViewSend, !text );
+
+            // "insert smiley"
+            if ( !iContainer->Editor().IsFocused() )
+                {
+                aMenuPane->SetItemDimmed(
+                    EChatClientChatViewInsertSmiley, ETrue );
+                }
+            else
+                {
+                aMenuPane->SetItemDimmed( EChatClientChatViewInsertSmiley,
+                                          !iContainer->ExtensionFits( KChatSmileyLength ) );
+                }
+
+            // "Templates"
+            aMenuPane->SetItemDimmed( EChatClientIboxInsertTemplate, !showTemplates );
+
+            // "open"
+            aMenuPane->SetItemDimmed( EChatClientOpenObject, !openable );
+
+            // "save"
+            aMenuPane->SetItemDimmed( EChatClientSaveObject, !savePossible );
+
+            // item finder menu
+            aMenuPane->SetItemDimmed( EChatClientFindMenuPlaceHolder, ETrue );
+            if ( iContainer->IsStopped() )
+                {
+                UpdateItemTypeL();
+                iFindMenu->AddItemFindMenuL( iItemFinder, aMenuPane,
+                                             EChatClientFindMenuPlaceHolder,
+                                             KNullDesC ); // we can ignore the sender here
+                }
+
+            // "send image"
+            if ( IMUtils::IntResourceValueL( RSC_CHAT_VARIATION_SEND_IMAGE ) == 0 )
+                {
+                aMenuPane->SetItemDimmed( EChatClientSendImage, ETrue );
+                aMenuPane->SetItemDimmed( EChatClientSendImageCascade, ETrue );
+                }
+            else
+                {
+                TBool cam( FeatureManager::FeatureSupported(
+                               KFeatureIdCamera ) );
+                CHAT_DP( D_CHAT_LIT( " Camera %d" ), cam );
+
+                // if camera is supported, show cascade menu
+                // otherwise hide cascade menu
+                aMenuPane->SetItemDimmed( EChatClientSendImage, cam );
+                aMenuPane->SetItemDimmed( EChatClientSendImageCascade, !cam );
+                }
+
+            // "forward" hiding logic case 3
+            // Hide also when focus on object that is not openable
+            if ( !showForwardMenu || ( object && !openable ) )
+                {
+                CHAT_DP_TXT( "CCAConversationsView::DynInitMenuPaneL \
+			              Hide the whole forward menu" );
+                aMenuPane->SetItemDimmed( EChatClientIboxForward, ETrue );
+                }
+            else
+                {
+                CHAT_DP_TXT( "CCAConversationsView::DynInitMenuPaneL \
+			              Show the forward menu" );
+                aMenuPane->SetItemDimmed(
+                    EChatClientIboxForward, !iContainer->IsStopped() );
+                }
+
+            // "add to contacts"
+            aMenuPane->SetItemDimmed( EChatClientSearchAddFriends,
+                                      contactInList );
+
+            // "save to conversations always show"
+            aMenuPane->SetItemDimmed( EChatClientIboxRecord, EFalse );
+
+            // "block", check if user block/unblock is supported
+            if ( !iAppUI->UISessionManager().IsSupported( CCAUISessionManager::EBlock ) )
+                {
+                aMenuPane->SetItemDimmed( EChatClientIboxBlockOpt, ETrue );
+                }
+            //As per new UI spec change own status is not avilable in conversation
+            //view menu
+            aMenuPane->SetItemDimmed( EChatClientMainViewCmdChangeStatus, ETrue );
+
+            break;
+            }
+        case R_CHATCLIENT_IBOX_BLOCK_SUBMENU:
+            {
+            TBool blocked( iContainer->IsBlocked() );
+            if ( blocked )
+                {
+                aMenuPane->SetItemDimmed( EChatClientIboxBlock, ETrue );
+                // show/hide "show blocked list" option
+                if ( !IMUtils::IntResourceValueL(
+                         RSC_CHAT_VARIATION_SHOW_BLOCKED_LIST ) )
+                    {
+                    aMenuPane->SetItemDimmed( EChatClientIboxBlockShow, ETrue );
+                    }
+                }
+            break;
+            }
+        case R_CHATCLIENT_IBOX_FORWARD_SUBMENU:
+            {
+            aMenuPane->SetItemDimmed( EChatClientIboxForwardToGroup,
+                                      ! showFwdToGroup );
+            aMenuPane->SetItemDimmed( EChatClientIboxForwardToContact,
+                                      ! showFwdToContact );
+            break;
+            }
+
+        case R_CHATCLIENT_FINDITEMUI_MENU:
+            {
+            if ( iContainer->IsStopped() )
+                {
+                UpdateItemTypeL();
+                iFindMenu->AddItemFindMenuL( iItemFinder, aMenuPane,
+                                             EFindItemContextMenuPlaceHolder,
+                                             KNullDesC, // we can ignore the sender here
+                                             EFalse, ETrue ); // context menu
+                }
+            break;
+            }
+
+        default:
+            {
+            // update find menu
+            iFindMenu->UpdateItemFinderMenuL( aResourceId, aMenuPane );
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::UpdateItemTypeL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::UpdateItemTypeL()
+    {
+    CItemFinder::CFindItemExt& item = iItemFinder->CurrentItemExt();
+    switch ( iContainer->SelectedItemType() )
+        {
+        case CFindItemEngine::EFindItemSearchPhoneNumberBin:
+            {
+            item.iItemType = CItemFinder::EPhoneNumber;
+            break;
+            }
+        case CFindItemEngine::EFindItemSearchMailAddressBin:
+            {
+            item.iItemType = CItemFinder::EEmailAddress;
+            break;
+            }
+        case CFindItemEngine::EFindItemSearchURLBin:
+            {
+            item.iItemType = CItemFinder::EUrlAddress;
+            break;
+            }
+        case CFindItemEngine::EFindItemSearchScheme:
+            {
+            item.iItemType = CItemFinder::EUriScheme;
+            break;
+            }
+        case KErrNotFound:  // flowthrough
+        default:
+            {
+            item.iItemType = CItemFinder::ENoneSelected;
+            break;
+            }
+        }
+    delete item.iItemDescriptor;
+    item.iItemDescriptor = NULL;
+    item.iItemDescriptor = iContainer->SelectedItemL();  // takes the ownership
+
+    // this logic comes from CItemFinder::ResolveAndSetItemTypeL.
+    // should be in ItemFinder engine, but for some reason it isn't,
+    // so, next few lines are copypasted from AknItemFinder.cpp..
+    if ( item.iItemType == CItemFinder::EUrlAddress )
+        {
+        // old url types need prefix in order to work w/ schemehandler
+        const TDesC& pref = item.iItemDescriptor->Des().Left( 4 );
+
+        //To avoid adding :http://" to rtsp links, we check it before it is done
+        //and return.
+        if ( pref.CompareF ( KIMRTSP().Left ( 4 ) ) == 0 )
+            {
+            return;
+            }
+
+        if ( pref.CompareF( KIMHTTPPREFIX().Left( 4 ) ) != 0 )
+            {
+            HBufC* tmp = item.iItemDescriptor->ReAlloc(
+                             item.iItemDescriptor->Length() + KIMHTTPPREFIX().Length() );
+            if ( tmp )
+                {
+                // realloc succeeded
+                item.iItemDescriptor = tmp;
+                item.iItemDescriptor->Des().Insert( 0, KIMHTTPPREFIX );
+                }
+            }
+        }
+    if ( item.iItemType == CItemFinder::EUriScheme )
+        {
+        // some schemes (ie. "old ones") have special handling
+        const TDesC& pref = item.iItemDescriptor->Des().Left( 4 );
+        if ( pref.CompareF( KIMHTTPPREFIX().Left( 4 ) ) == 0
+             || pref.CompareF( KIMRTSP ) == 0 )
+            {
+            item.iItemType = CItemFinder::EUrlAddress;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::UpdateTitleL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::UpdateTitleL()
+    {
+    if ( iTitlePane )
+        {
+
+        HBufC* tempTitle = iTitlePane->GetTabItemIdentification( iTabId ).AllocL();
+
+        delete iTitle;
+        iTitle = tempTitle;
+
+        iTitlePane->SetTitleL( *iTitle );
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::StoreContent
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::StoreContent( const HBufC* aContent )
+    {
+    // Delete previous stored content
+    delete iEditorContent;
+    iEditorContent = NULL;
+    iEditorContent = aContent;
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::CheckBlockedL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::CheckBlockedL()
+    {
+    iContainer->CheckBlockedL();
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::HandleCommandL(TInt aCommand)
+// Handles commands
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::HandleCommandL( TInt aCommand )
+    {
+    // This case is used to display the login query in offline mode.
+    switch ( aCommand )
+        {
+        case EChatClientNewImage:
+        case EChatClientFromPhotos:
+        case EChatClientSendImage:
+        case EChatClientIboxBlockEnter:
+        case EChatClientIboxBlockShow:
+        case EChatClientIboxBlock:
+        case EChatClientIboxUnblock:
+        case EChatClientIboxForwardToGroup:
+        case EChatClientIboxForwardToContact:
+        case EChatClientSearchAddFriends:
+            {
+            if ( !UISessionManager().LoginL( MCAUiLoginCmdCB::EQueryLogin ) )
+                {
+                return;
+                }
+            break;
+            }
+        default:
+            {
+            break;
+            }
+
+        }
+
+#ifdef IMPS_CONTACT_FETCH_BACKGROUND
+    switch ( aCommand )
+        {
+
+        case EChatClientIboxBlockEnter:
+        case EChatClientIboxBlockShow:
+        case EChatClientIboxBlock:
+        case EChatClientIboxUnblock:
+        case EChatClientIboxForwardToGroup:
+        case EChatClientIboxForwardToContact:
+        case EChatClientSearchAddFriends:
+            {
+            if ( !CCASyncChecker::CheckSyncStateL() )
+                {
+                return;
+                }
+            break;
+            }
+        default:
+            {
+            break;
+            }
+
+        }
+#endif
+
+    switch ( aCommand )
+        {
+        case EAknSoftkeyOpen:   // Flowthrough, MSK command
+        case EChatClientOpenObject:
+            {
+            // Fix TELYG-7H2A6N
+            if ( iObjectOpenedSaved )
+                {
+                return;
+                }
+
+            MCAConversationMessage* msg = iContainer->SelectedMessage();
+            if ( msg )
+                {
+                CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC();
+                // Set the indicator to true
+                iObjectOpenedSaved = ETrue;
+                TRAPD( err, utils->OpenObjectL( *msg ) );
+                // Set it back
+                iObjectOpenedSaved = EFalse;
+
+                CleanupStack::PopAndDestroy( utils );
+                User::LeaveIfError( err );
+                }
+            break;
+            }
+        case EChatClientSaveObject:
+            {
+            // Fix TELYG-7H2A6N
+            if ( iObjectOpenedSaved )
+                {
+                return;
+                }
+
+            MCAConversationMessage* msg = iContainer->SelectedMessage();
+            if ( msg )
+                {
+                CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC();
+
+                // Set the indicator to true
+                iObjectOpenedSaved = ETrue;
+                TRAPD( err, utils->SaveObjectL( *msg ) );
+                // Set it back
+                iObjectOpenedSaved = EFalse;
+
+                CleanupStack::PopAndDestroy( utils );
+                User::LeaveIfError( err );
+                }
+            break;
+            }
+        case EChatClientNewImage:
+            {
+            // new file
+            if ( iAppUI->UISessionManager().IsLoggedIn() )
+                {
+                iContainer->CheckReplyL();
+
+                CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC( this );
+                utils->SendNewFileL( ENewFileServiceImage,
+                                     *iConversationPC );
+                CleanupStack::PopAndDestroy( utils );
+
+                }
+            break;
+            }
+        case EChatClientFromPhotos: // flowthrough
+        case EChatClientSendImage:
+            {
+            if ( iAppUI->UISessionManager().IsLoggedIn() )
+                {
+                iContainer->CheckReplyL();
+                CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC( this );
+
+                iCba = CEikButtonGroupContainer::Current();
+
+                if ( iCba )
+                    {
+                    iCba->MakeCommandVisible( EAknSoftkeyOptions, EFalse );
+                    iCba->MakeCommandVisible( EAknSoftkeyBack, EFalse );
+                	iCba->MakeCommandVisible( EChatClientChatViewContinue, EFalse );
+                    iCba->DrawNow();
+                    }
+
+                utils->SendImageL( *iConversationPC );
+                iCba = CEikButtonGroupContainer::Current();
+
+                if ( iCba )
+                    {
+                    iCba->MakeCommandVisible( EAknSoftkeyOptions, ETrue );
+                    iCba->MakeCommandVisible( EAknSoftkeyBack, ETrue );
+                	iCba->MakeCommandVisible( EChatClientChatViewContinue, ETrue );
+                    iCba->DrawNow();
+                    }
+
+                CleanupStack::PopAndDestroy( utils );
+                }
+            break;
+            }
+
+        // flow through
+        case EChatClientCmdBack:
+        case EAknSoftkeyBack:
+            {
+            if ( iTitlePane )
+                {
+                iTitlePane->SynchroniseAndRemoveTabGroup();
+                }
+            if ( TEnumsPC::ERegister == iAppUI->RetForwardTo() )
+                {
+                iAppUI->SetResetForwardTo( TEnumsPC::EToBeUnregistered );
+
+                iAppUI->SwitchViewL( KUidFriendsListView );
+                }
+            else
+                {
+                if ( TEnumsPC::EAlreadyRegistered == iAppUI->RetForwardTo() )
+                    {
+                    // Deregister conversation from switch back views
+                    iAppUI->UnRegisterPreviousview();
+                    iAppUI->SetResetForwardTo( TEnumsPC::EUnregistered );
+                    }
+                TCADnlConvInvGroupFocus dnlConvInvGroupFocus;
+                dnlConvInvGroupFocus.iInvConvGroupID.Copy( iContactId->Des().Left( KMaxWVIDLength ) );
+                dnlConvInvGroupFocus.iListID.Copy( iListId->Des().Left( KMaxWVIDLength ) );
+                dnlConvInvGroupFocus.iType = EConversationItem;
+                TCADnlConvInvGroupFocusBuf convInvGroupFocusBuf( dnlConvInvGroupFocus );
+                iAppUI->SwitchViewBackL( KUidFriendsListView, KConvInvGroupFocusId, convInvGroupFocusBuf );
+                }
+            break;
+            }
+        // flow through
+        case EAknSoftkeySend:   // MSK command
+        case EChatClientIboxViewSend:
+        case EChatClientChatViewCmdSend:
+            {
+            iContainer->SendMessageL();
+            break;
+            }
+
+        case EChatClientChatViewContinue:
+            {
+            iContainer->StartScrollingL();
+            iAppUI->SetFocusFlag( ETrue );
+            break;
+            }
+        case EChatClientSearchAddFriends:
+            {
+            iContainer->AddToFriendsL();
+            break;
+            }
+
+        case EChatClientChatViewInsertSmiley:
+            {
+            TBool dialogCancelled = EFalse;
+            iMessageHandler->InsertExtensionL( iContainer->Editor(),
+                                               EMessageExtensionSmiley,
+                                               dialogCancelled );
+
+            // Resize icons, use reading pane text line element as parent
+            iContainer->ResizeIcons( iContainer->TextRect() );
+
+            if ( !dialogCancelled )
+                {
+                iContainer->RefreshEditorL();
+                }
+            break;
+            }
+        case EChatClientIboxInsertTemplate:
+            {
+            ShowTemplatesL();
+            break;
+            }
+        case EChatClientIboxForwardToGroup:
+            {
+            ForwardToGroupL();
+            break;
+            }
+        case EChatClientIboxForwardToContact:
+            {
+            ForwardToContactL();
+            break;
+            }
+        case EChatClientIboxRecord:
+            {
+            iContainer->RecordChatL();
+            break;
+            }
+        case EChatClientIboxBlockEnter:
+            {
+            if ( iAppUI->UISessionManager().IsLoggedIn() )
+                {
+                iContainer->BlockUserWVIdL();
+                }
+            break;
+            }
+        case EChatClientIboxBlockShow:
+            {
+            if ( iAppUI->UISessionManager().IsLoggedIn() )
+                {
+                iContainer->DisplayBlockedListL();
+                }
+            break;
+            }
+        case EChatClientIboxBlock:
+            {
+            if ( iAppUI->UISessionManager().IsLoggedIn() )
+                {
+                iContainer->BlockUserL();
+                }
+            break;
+            }
+        case EChatClientIboxUnblock:
+            {
+            if ( iAppUI->UISessionManager().IsLoggedIn() )
+                {
+                iContainer->UnBlockL();
+                }
+            break;
+            }
+        case EChatClientIboxClose:
+            {
+            CloseConversationL();
+            break;
+            }
+
+        // Help key support EChatClientCmdHelp is assigned EAknCmdHelp in
+        // chatngclient.hrh
+        case EChatClientCmdHelp:
+            {
+            HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(),
+                                                 iAppUI->AppHelpContextL() );
+            break;
+            }
+
+        // flow through
+        case EFindItemCmdEnableAutoFind:
+        case EFindItemCmdDisableAutoFind:
+            {
+            iContainer->SetItemHighlightL(
+                aCommand == EFindItemCmdEnableAutoFind );
+            iFindMenu->HandleItemFinderCommandL( aCommand );
+            if ( MenuBar()->IsDisplayed() )
+                {
+                MenuBar()->StopDisplayingMenuBar();
+                }
+            if ( iFindContextMenu->IsDisplayed() )
+                {
+                iFindContextMenu->StopDisplayingMenuBar();
+                }
+            break;
+            }
+        case EChatClientCall:
+            {
+            UpdateItemTypeL();
+            iFindMenu->HandleCallL( *iItemFinder->CurrentItemExt().iItemDescriptor );
+            break;
+            }
+        case EAknCmdExit:           // fall-through, handled similarily
+        case EEikCmdExit:           // fall-through, handled similarily
+        case EAknSoftkeyExit:       // fall-through, handled similarily
+        case EChatClientCmdExit:
+            {
+
+            if ( iFindMenu->CommandIsValidL( aCommand ) )
+                {
+                iFindMenu->HandleItemFinderCommandL( aCommand );
+                }
+
+            iAppUI->HandleCommandL( aCommand );
+            break;
+            }
+        default:
+            {
+            // check if it is find menu command
+            if ( iFindMenu->CommandIsValidL( aCommand ) )
+                {
+                iFindMenu->HandleItemFinderCommandL( aCommand );
+                }
+            else
+                {
+                //As per new UI spec change own status is not avilable in conversation
+                //view menu
+                iAppUI->HandleCommandL( aCommand );
+                }
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::ShowTemplatesL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::ShowTemplatesL()
+    {
+    CDesCArray* aResultArray = NULL;
+    CEikonEnv* env = CEikonEnv::Static();
+    aResultArray = env->ReadDesC16ArrayResourceL( R_CHATVIEW_TEMPLATES_LIST );
+
+    // Create CEikTextListBox instance, list
+    CEikTextListBox* nTemplateList = new( ELeave ) CAknSinglePopupMenuStyleListBox;
+
+    // Push nProfileList pointer to CleanupStack.
+    CleanupStack::PushL( nTemplateList );
+
+    // Create CAknPopupList instance, popupList
+    CAknPopupList* popupList = CAknPopupList::NewL( nTemplateList,
+                                                    R_AVKON_SOFTKEYS_SELECT_CANCEL,
+                                                    AknPopupLayouts::EMenuWindow );
+    // Push popupList'pointer to CleanupStack.
+    CleanupStack::PushL( popupList );
+
+
+    // Initialize listbox.
+    nTemplateList->ConstructL( popupList, CEikListBox::ELeftDownInViewRect );
+    nTemplateList->CreateScrollBarFrameL( ETrue );
+    nTemplateList->ScrollBarFrame()->SetScrollBarVisibilityL(
+        CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto );
+
+    // Set title
+    // Allocate TBuf with constant length.
+    TBuf<KMaxTitleLength> title;
+
+    // Reads a resource into a descriptor.
+    env->ReadResourceL( title, R_QTN_CHAT_TEMPLATE_LIST_TITLE );
+
+    popupList->SetTitleL( title );
+    //popupList->SetTitleL( _L("Select Templates:") );
+
+    // Set listitems.
+    CTextListBoxModel* model = nTemplateList->Model();
+    model->SetOwnershipType( ELbmOwnsItemArray );
+    model->SetItemTextArray( aResultArray );
+
+    // Show popup nProfileList and then show return value.
+    TBool popupOk = popupList->ExecuteLD();
+    CleanupStack::Pop();
+
+    // Pop the popupList's pointer from CleanupStack
+
+    if ( popupOk )
+        {
+        TInt index = nTemplateList->CurrentItemIndex();
+        CCAMessageEditor& editor = iContainer->Editor();
+        TInt cursorPos( editor.CursorPos() );
+        editor.RichText()->InsertL( cursorPos, ( *aResultArray )[index] );
+        //editor.SetTextL( &((*aResultArray)[index]) );
+        editor.SetCursorPosL( editor.TextLength() + 1, EFalse );
+        iContainer->StartScrollingL();
+        }
+
+    // Pop and Destroy the nProfileList pointer from CleanupStack
+    CleanupStack::PopAndDestroy( nTemplateList );
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::HandleForegroundEventL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::HandleForegroundEventL( TBool aForeground )
+    {
+    iForeground = aForeground;
+
+    if ( iContainer )
+        {
+        //don't read messages if we're not in foreground
+        iContainer->FetchMessages( aForeground );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::HandleContactChange(...)
+// ---------------------------------------------------------
+//
+void CCAConversationsView::HandleContactChange( const TDesC& /*aContact*/ )
+    {
+    // this contact was added/edited to contact store, update title
+    TRAPD( err, UpdateTitleL() );
+    if ( err != KErrNone )
+        {
+        CActiveScheduler::Current()->Error( err );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::DoActivateL(...)
+// Handles view activation
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::DoActivateL(
+    const TVwsViewId& aPrevViewId, TUid aCustomMessageId,
+    const TDesC8& aCustomMessage )
+    {
+    // Unregister the view that was registered from Forward option.
+    // didn't find any better place to put this.
+    if ( TEnumsPC::EToBeUnregistered == iAppUI->RetForwardTo() )
+        {
+        // Deregister conversation from switch back views
+        iAppUI->UnRegisterPreviousview();
+        iAppUI->SetResetForwardTo( TEnumsPC::EUnregistered );
+        }
+
+    const MCAConversationMessage* forwardedMessage = NULL;
+    TBool storedEditorContent = EFalse;
+    TPtr groupId( iContactId->Des() );
+    TPtr listId( iListId->Des() );
+    TBool activateFromTabSwitch = EFalse;
+    if ( aCustomMessageId == KUidConvViewMsgId ||
+         aCustomMessageId == KUidExtViewActivationId )
+        {
+        TCADnlConvViewBuf viewBuf;
+        viewBuf.Copy( aCustomMessage );
+
+        groupId.Copy( viewBuf().iWVID.Left( groupId.MaxLength() ) );
+        listId.Copy( viewBuf().iListID.Left( listId.MaxLength() ) );
+        activateFromTabSwitch = viewBuf().iSwitchTab;
+
+        if ( activateFromTabSwitch )
+            {
+            iTabId = viewBuf().iTabId;
+            }
+
+        if ( viewBuf().iIsForwarded )
+            {
+            CHAT_DP( D_CHAT_LIT( "--forwarding message %S" ), &viewBuf().iForwardedMessage->Text() );
+            forwardedMessage = viewBuf().iForwardedMessage;
+            }
+
+        storedEditorContent = viewBuf().iSAPChanged;
+        }
+
+    // When forwarding from contact to contact DoDeactivate is never called.
+    // We have to cleanup the necessary stuff ourself.
+    CCAConversationsContainer* oldContainer = NULL;
+    if ( iContainer && iAppUI )
+        {
+        // if we were in a middle of sending message, don't delete the container
+        if ( !iContainer->Sending() )
+            {
+            // Container
+            iAppUI->RemoveFromStack( iContainer );
+            oldContainer = iContainer;
+            CleanupStack::PushL( oldContainer );
+            iContainer = NULL;
+
+            if ( iAddAndReplyMenu )
+                {
+                iAppUI->RemoveFromViewStack( *this, iAddAndReplyMenu );
+                }
+
+            if ( iFindContextMenu )
+                {
+                iAppUI->RemoveFromViewStack( *this, iFindContextMenu );
+                }
+            }
+        }
+
+
+    iConversationPC->InitialiseResourcesL( *iContactId );
+
+    // Register this as chat observer
+    iConversationPC->AddObserver( this );
+
+    // Register switch back if conversation view is opened from
+    // search view
+    if ( iAppUI && aPrevViewId.iViewUid == KUidSearchView )
+        {
+
+        TCADnlConvViewBuf viewBuf;
+        viewBuf.Copy( aCustomMessage );
+
+        TCADnlConvInvGroupFocus dnlConvInvGroupFocus;
+        dnlConvInvGroupFocus.iInvConvGroupID.Copy( iContactId->Des().Left( KMaxWVIDLength ) );
+        dnlConvInvGroupFocus.iListID.Copy( iListId->Des().Left( KMaxWVIDLength ) );
+        dnlConvInvGroupFocus.iType = EConversationItem;
+        TCADnlConvInvGroupFocusBuf convInvGroupFocusBuf( dnlConvInvGroupFocus );
+
+        iAppUI->RegisterSwitchBack(
+            KUidFriendsListView,
+            KConvInvGroupFocusId,
+            convInvGroupFocusBuf.AllocL(),
+            KNullUid );
+        }
+
+
+    // To prevent looping between this view and refresh view
+    if ( aPrevViewId.iViewUid != KUidRefreshView )
+        {
+        iPrevViewId = aPrevViewId;
+        }
+
+
+    if ( iContainer )
+        {
+        // container already exists, reset sending flag
+        iContainer->ResetSending();
+        }
+    else
+        {
+        iContainer = CCAConversationsContainer::NewL( ClientRect(),
+                                                      *static_cast<MCAViewSwitcher*>( iAppUI ),
+                                                      iConversationPC,
+                                                      *this, this, *iMessageHandler, *this, *this, Cba(),
+                                                      activateFromTabSwitch, iTabId );
+        }
+
+
+    // Restore find state
+    TInt findState = IMUtils::CRKeyL( KCRUidCommonUi, KCuiAutomaticHighlight );
+    CCAMessageEditor& editor = iContainer->Editor();
+
+    iContainer->SetItemHighlightL( findState );
+
+    // Handle forwarded message
+    if ( forwardedMessage )
+        {
+        CHAT_DP(
+            D_CHAT_LIT( "CCAConversationsView::DoActivateL, forwarding message" ) );
+
+        MCASettingsPC* settingsPC = iAppUI->GetProcessManager().GetSettingsInterface();
+
+        HBufC* ownId = settingsPC->GetSapSettingValuePCL(
+                           TEnumsPC::EOwnWVUserID );
+        CleanupStack::PushL( ownId );
+
+        CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC();
+        TBool ret = utils->ForwardContentMessageL(
+                        *forwardedMessage,
+                        groupId, // recipient
+                        NULL,
+                        *iConversationPC,
+                        EFalse, // no whispering
+                        ownId->Des() );
+
+        CleanupStack::PopAndDestroy( 2, ownId ); //utils, ownId
+
+        // Message was not handled so we put it into the editor.
+        if ( !ret )
+            {
+            // Wether to put part or whole message
+            if ( forwardedMessage->ForwardPart() )
+                {
+                editor.SetTextL( forwardedMessage->ForwardPart() );
+                }
+            else
+                {
+                editor.SetTextL( &forwardedMessage->Text() );
+                }
+            editor.SetCursorPosL( editor.TextLength(), EFalse );
+
+            iContainer->StartScrollingL();
+
+            }
+        }
+
+    // Handle stored editor content
+    if ( storedEditorContent )
+        {
+        editor.SetTextL( iEditorContent );
+        editor.SetCursorPosL( editor.TextLength(), EFalse );
+        iContainer->SendMessageL();
+        }
+
+    if ( !editor.TextLength() )
+        {
+        TInt editorFlags = ( editor.AknEdwinFlags() | EAknEditorFlagNoEditIndicators );
+        editor.SetAknEditorFlags( editorFlags );
+        }
+
+    iAppUI->AddToViewStackL( *this, iContainer );
+    iAppUI->AddToViewStackL( *this, iAddAndReplyMenu, 0,
+                             ECoeStackFlagRefusesFocus );
+    iAppUI->AddToStackL( *this, iFindContextMenu, ECoeStackPriorityDefault,
+                         ECoeStackFlagRefusesFocus );
+    if ( iTitlePane )
+        {
+
+        if ( !activateFromTabSwitch )
+            {
+
+            //hide navi pane decorators
+            iTitlePane->ClearNaviPaneL();
+
+            //if activation is from contact list and not from switching between
+            //tabs then create tabs and show them
+            iTabId = iTitlePane->ShowTabGroupL( TEnumsPC::EConversationItem, iContactId->Des() );
+            }
+
+        iTitlePane->AddObserver( this ) ;
+
+        // Get temp id handler handle
+        // Get identification through temp identification handler
+        // code merge 14 nov, 2006
+        MCAMainViewArrayPC* mainViewArrayPC = iAppUI->GetProcessManager().GetArrayInterface();
+
+        delete iTitle;
+        iTitle = NULL;
+        TRAPD( err, iTitle = iTitlePane->GetTabItemIdentification( iTabId ).AllocL() );
+        if ( err )
+            {
+            // Contact list was not synchronized yet, just strip the "wv:" etc.
+            iTitle = CCAPCUtils::DisplayId( *iContactId ).AllocL();
+            }
+
+
+        iTitlePane->SetTitleL( *iTitle );
+
+
+        }
+#ifndef RD_30_DISABLE_TOUCH
+    // set the context menu for menubar (launched with middle softkey)
+    MenuBar()->SetContextMenuTitleResourceId( R_CHATCLIENT_MENUBAR_FINDITEMUI );
+#endif
+
+
+
+    if ( oldContainer )
+        {
+        // Everything should be ready and we can delete the old container
+        CleanupStack::PopAndDestroy(); // oldContainer
+        }
+
+
+
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::HandleCommandL()
+// Handles view deactivation
+// ---------------------------------------------------------
+//
+void CCAConversationsView::DoDeactivate()
+    {
+    CHAT_DP_TXT( "DoDeactivate" );
+
+    iConversationPC->RemoveObserver();
+    iConversationPC->ReleaseResources();
+
+    if ( iTitlePane )
+        {
+        iTitlePane->RemoveObserver( this );
+        }
+    if ( iContainer )
+        {
+        iAppUI->RemoveFromViewStack( *this, iContainer );
+
+        if ( !iContainer->Sending() )
+            {
+            // not in a middle of sending message
+            delete iContainer;
+            iContainer = NULL;
+            }
+        }
+
+    if ( iAddAndReplyMenu )
+        {
+        iAppUI->RemoveFromViewStack( *this, iAddAndReplyMenu );
+        }
+
+    if ( iFindContextMenu )
+        {
+        iAppUI->RemoveFromViewStack( *this, iFindContextMenu );
+        }
+
+    iLastUnreadIndex = KErrNotFound;
+
+    delete iTitle;
+    iTitle = NULL;
+    delete iSender;
+    iSender = NULL;
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::ShowRecipientsListL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+TInt CCAConversationsView::ShowRecipientsListL( TInt /*aResourceId*/ )
+    {
+    return KErrNotFound;
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::ShowPopUpMenuL()
+// This method shows popup menu
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::ShowPopUpMenuL( )
+    {
+    if ( iContainer->SelectedItemType() != KErrNotFound )
+        {
+#ifndef RD_30_DISABLE_TOUCH
+        MenuBar()->StopDisplayingMenuBar();
+        MenuBar()->TryDisplayContextMenuBarL();
+#else
+        iFindContextMenu->StopDisplayingMenuBar();
+        iFindContextMenu->TryDisplayMenuBarL();
+#endif
+        }
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::HandleChatEvent
+// (other items were commented in a header).
+// ---------------------------------------------------------
+void CCAConversationsView::HandleChatEvent( const TDesC& aWvid,
+                                            const TDesC& aContactId )
+    {
+
+    TRAPD( err, DoHandleChatEventL( aWvid, aContactId ) );
+    if ( err != KErrNone )
+        {
+        CActiveScheduler::Current()->Error( err );
+        }
+
+    }
+
+// ---------------------------------------------------------
+// CCAConversationsView::DoHandleChatEventL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::DoHandleChatEventL( const TDesC& aWvid,
+                                               const TDesC& aContactId )
+    {
+    HBufC* tempSender = aWvid.AllocL();
+    delete iSender;
+    iSender = tempSender;
+
+    // nickname or wv-less contact id
+    iCleanSender.Set( aContactId );
+
+    }
+
+//added for multitab support
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::SwitchTabL
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::SwitchTabL( const TDesC& aWvId, const TInt aTabIndex )
+    {
+    //change the contact id based on tteh currenttab
+    TPtr groupId( iContactId->Des() );
+    TPtr listId( iListId->Des() );
+    if ( iListId )
+        {
+        listId = KNullDesC();
+        }
+    groupId.Copy( aWvId.Left( groupId.MaxLength() ) );
+
+    iTabId = aTabIndex;
+
+    UpdateTitleL();
+
+    iConversationPC->SetActiveConversationL( aWvId );
+
+    //remove the controls from view stack
+    if ( iContainer )
+        {
+        iAppUI->RemoveFromViewStack( *this, iContainer );
+        }
+
+    if ( iAddAndReplyMenu )
+        {
+        iAppUI->RemoveFromViewStack( *this, iAddAndReplyMenu );
+        }
+
+    if ( iFindContextMenu )
+        {
+        iAppUI->RemoveFromViewStack( *this, iFindContextMenu );
+        }
+
+
+    iContainer->SwitchViewL();
+
+    //again add those controls to view stack
+    if ( iContainer )
+        {
+        iAppUI->AddToViewStackL( *this, iContainer );
+        }
+
+    if ( iAddAndReplyMenu )
+        {
+        iAppUI->AddToViewStackL( *this, iAddAndReplyMenu, 0,
+                                 ECoeStackFlagRefusesFocus );
+        }
+
+    if ( iFindContextMenu )
+        {
+        iAppUI->AddToStackL( *this, iFindContextMenu, ECoeStackPriorityDefault,
+                             ECoeStackFlagRefusesFocus );
+        }
+
+    }
+
+
+// ---------------------------------------------------------
+
+// ---------------------------------------------------------
+// CCAConversationsView::HandleMessageError
+// ---------------------------------------------------------
+//
+void CCAConversationsView::HandleMessageError( TInt aError,
+                                               const TDesC& aInfo,
+                                               TEnumsPC::TContentType aMsgContentType )
+    {
+    TRAPD( err, DoHandleMessageErrorL( aError, aInfo, aMsgContentType ) );
+    if ( err != KErrNone )
+        {
+        CActiveScheduler::Current()->Error( err );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::DoHandleMessageErrorL
+// ---------------------------------------------------------
+//
+void CCAConversationsView::DoHandleMessageErrorL( TInt aError,
+                                                  const TDesC& aInfo,
+                                                  TEnumsPC::TContentType aMsgContentType )
+    {
+    if ( aError == KErrNoMemory ) // handled in AppUi::HandleMessageError
+        {
+        return;
+        }
+    if ( TEnumsPC::EContentPicture == aMsgContentType )
+        {
+        TInt res( aError == KErrOverflow ?
+                  R_QTN_CHAT_SCALING_IMAGE_TOO_BIG :
+                  R_QTN_CHAT_SCALING_ERROR );
+
+        // sending of image failed
+        IMDialogUtils::DisplayInformationNoteL( res );
+        return;
+        }
+    if ( aError == ECSPUnknownUserId )
+        {
+        // This way error can be recognized in note mapper
+        aError += Imps_ERROR_BASE;
+        }
+
+    IMNoteMapper::ShowNoteL( aError, aInfo );
+    }
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::ForwardToContactL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::ForwardToContactL()
+    {
+    MCAConversationMessage* message = iContainer->SelectedMessage();
+    if ( !message )
+        {
+        // nothing selected
+        return;
+        }
+
+    //Set the focus flag as true 
+    iAppUI->SetFocusFlag(ETrue);
+
+    CDesCArray* selectedContacts = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( selectedContacts );
+
+    CDesCArray* selectedIdentifications = new ( ELeave ) CDesCArrayFlat( KArrayGranularity );
+    CleanupStack::PushL( selectedIdentifications );
+
+    MCASkinVariant* skinVar = static_cast<CCAApp*>( iAppUI->Application() )
+                              ->VariantFactory()->SkinVariantL();
+
+    // show selection dialog
+
+    MCAViewSwitcher& aViewSwitcher( *static_cast<MCAViewSwitcher*>( iAppUI ) );
+
+    if ( !CCAContactSelectionDialog::ShowDialogL(
+             *selectedContacts,
+             *iAppUI->GetProcessManager().GetArrayInterface(),
+             *skinVar,
+             *iAppUI->GetProcessManager().GetSettingsInterface(),
+             iAppUI->MbmFullPath(),
+             TEnumsPC::ESingleSelect,
+             R_CONTACT_SELECTION_DIALOG,
+             *aViewSwitcher.CAStatusPane(),
+             selectedIdentifications  ) )
+        {
+        // no contacts
+        CleanupStack::PopAndDestroy( 2, selectedContacts ); // selectedContacts,selectedIdentifications
+        return;
+        }
+
+    // allow tabs - suppose user would have received new messages
+    iTitlePane->RestoreNaviPane();
+
+    // handle selected contact (if any)
+    if ( selectedContacts->MdcaCount() == 1 )
+        {
+
+        TPtrC wvid( selectedContacts->MdcaPoint( 0 ) );
+
+        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 = iContainer->SelectedItemL();
+        CleanupStack::PushL( item );
+
+        if ( item->Length() > 0 )
+            {
+            // Set forwarded message
+            message->SetForwardPartL( item );
+            }
+        else
+            {
+            // Clear previous forward part
+            message->SetForwardPartL( NULL );
+            }
+
+        CleanupStack::PopAndDestroy( item );
+
+        iAppUI->SetForwardMessageL( message );
+
+        const MCAConversationMessage* fwdMessage = iAppUI->ForwardMessage();
+
+        if ( !fwdMessage )
+            {
+            CleanupStack::PopAndDestroy(); // selectedContacts.Close()
+            return;
+            }
+
+        if ( TEnumsPC::EUnregistered == iAppUI->RetForwardTo()  )
+            {
+            iAppUI->SetResetForwardTo( TEnumsPC::ERegister );
+            iAppUI->GroupUtils()->PrepareToSwitchBackL( iContactId->Des(),
+                                                        KUidConversationsView,
+                                                        KUidConversationsView );
+            }
+        else if ( TEnumsPC::ERegister == iAppUI->RetForwardTo() )
+            {
+            iAppUI->SetResetForwardTo( TEnumsPC::EAlreadyRegistered );
+            }
+
+        if ( !iConversationPC->IsActiveConversation( wvid ) && iTitlePane )
+            {
+
+            iTabId = iTitlePane->ShowTabGroupL( TEnumsPC::EConversationItem, wvid );
+
+            SwitchTabL( wvid, iTabId );
+
+            }
+        //Check whether we have fwded the message to any other contact
+        //if so add a tab and switch the tab to focus on the forwarded contact
+        MCASettingsPC* settingsPC = iAppUI->GetProcessManager().GetSettingsInterface();
+
+        HBufC* ownId = settingsPC->GetSapSettingValuePCL(
+                           TEnumsPC::EOwnWVUserID );
+        CleanupStack::PushL( ownId );
+
+        CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC();
+        TBool ret = utils->ForwardContentMessageL(
+                        *fwdMessage,
+                        wvid, // recipient
+                        NULL,
+                        *iConversationPC,
+                        EFalse, // no whispering
+                        ownId->Des() );
+
+        CleanupStack::PopAndDestroy( 2, ownId ); //utils, ownId
+
+        CCAMessageEditor& editor = iContainer->Editor();
+
+        // Message was not handled so we put it into the editor.
+        if ( !ret )
+            {
+            // Wether to put part or whole message
+            if ( fwdMessage->ForwardPart() )
+                {
+                editor.SetTextL( fwdMessage->ForwardPart() );
+                }
+            else
+                {
+                editor.SetTextL( &fwdMessage->Text() );
+                }
+            editor.SetCursorPosL( editor.TextLength(), EFalse );
+
+            iContainer->StartScrollingL();
+
+            }
+
+        }
+
+    CleanupStack::PopAndDestroy( 2, selectedContacts ); // selectedContacts,selectedIdentifications
+    }
+
+
+
+// ---------------------------------------------------------
+// CCAConversationsView::ForwardToGroupL()
+// (other items were commented in a header).
+// ---------------------------------------------------------
+//
+void CCAConversationsView::ForwardToGroupL()
+    {
+    MCAConversationMessage* message = iContainer->SelectedMessage();
+    if ( !message )
+        {
+        // nothing selected
+        return;
+        }
+
+    MCAServerContactsArrayPC* pairsArray ( iConversationPC->PopulateGroupDetailsLC() );
+
+    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 ) );
+
+    CleanupStack::PopAndDestroy( 2, emptyText ); // title, emptyText
+
+    if ( retVal == EAknSoftkeyOk || retVal == EAknSoftkeyDone
+         || retVal == EAknSoftkeySelect )
+        {
+        // Check if there is highlighted item
+        HBufC* item = iContainer->SelectedItemL();
+        CleanupStack::PushL( item );
+
+        if ( TEnumsPC::EUnregistered == iAppUI->RetForwardTo()  )
+            {
+            iAppUI->SetResetForwardTo( TEnumsPC::ERegister );
+            iAppUI->GroupUtils()->PrepareToSwitchBackL( iContactId->Des(),
+                                                        KUidConversationsView,
+                                                        KUidChatView );
+            }
+        else if ( TEnumsPC::ERegister == iAppUI->RetForwardTo() )
+            {
+            iAppUI->SetResetForwardTo( TEnumsPC::EAlreadyRegistered );
+            }
+        if ( item->Length() > 0 )
+            {
+            // Set forwarded message
+            message->SetForwardPartL( item );
+            }
+        else
+            {
+            // Clear previous forward part
+            message->SetForwardPartL( NULL );
+            }
+
+        CleanupStack::PopAndDestroy( item );
+
+
+        TInt err( iAppUI->GroupUtils()->JoinGroupL( ETrue,
+                                                    pairsArray->WVIdL( selectedIndex )->iWVID,
+                                                    KNullDesC, message ) );
+
+        if ( err )
+            {
+            CActiveScheduler::Current()->Error( err );
+            }
+        }
+    //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();
+    }
+
+
+//  End of File