diff -r 000000000000 -r 094583676ce7 wvuing/wvuiave/AppSrc/CCAConversationsView.cpp --- /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 +#include //For the CEikGlobalTextEditor +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // TNewServiceFileType + +#include +#include +#include + +#include +#include + +#include + +#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 ( 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 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( 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( iAppUI->Application() ) + ->VariantFactory()->SkinVariantL(); + + // show selection dialog + + MCAViewSwitcher& aViewSwitcher( *static_cast( 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