diff -r 6ca72c0fe49a -r a941bc465d9f wvuing/wvuiave/AppSrc/CCAChatView.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wvuing/wvuiave/AppSrc/CCAChatView.cpp Wed Sep 01 12:31:13 2010 +0100 @@ -0,0 +1,1380 @@ +/* +* 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 chat group view +* +*/ + + +// INCLUDE FILES +#include "CCAChatView.h" +#include "CCAChatViewContainer.h" +#include "chatngclient.hrh" +#include "CCAStatusPaneHandler.h" +#include "CCAAppUi.h" +#include "CAExternalInterface.h" +#include "CCAMessageEditor.h" +#include "CCAUISessionManager.h" +#include "CAArrayUtils.h" +#include "ChatDebugPrint.h" +#include "IMDialogUtils.h" +#include "ChatDefinitions.h" +#include "CAExternalInterface.h" +#include "IMNoteMapper.h" +#include "ImpsCSPAllErrors.h" +#include "CCAMessageExtensionsHandler.h" +#include "MCAMessageExtension.h" +#include "CCAFadeControl.h" +#include "CCAUiMessageUtils.h" +#include "cautils.h" +#include "IMUtils.h" +#include "MCAConversationMessage.h" +#include "IMPrivateCRKeys.h" +#include "IMVariant.hrh" +#include "mcagrouppc.h" +#include "MCAProcessManager.h" +#include "MCAMainViewArrayPC.h" +#include "CCAPCUtils.h" +#include "CCAGroupUtils.h" +#include "MCAOpenChatsPC.h" +#include "CCAProcessManagerFactory.h" +#include "MCAGroupUtilsPC.h" + +#include +#include +#include //For the CEikGlobalTextEditor +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// 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" + + + +// ================= MEMBER FUNCTIONS ======================= + + +// --------------------------------------------------------- +// CCAChatView::CCAChatView() +// C++ default constructor can NOT contain any code, that +// might leave. +// --------------------------------------------------------- +// +CCAChatView::CCAChatView() + : iMenuPane ( NULL ) + { + } +// --------------------------------------------------------- +// CCAChatView::ConstructL( TInt aAvkonViewResourceId, TUid aViewId ) +// Symbian OS two-phased constructor +// --------------------------------------------------------- +// +void CCAChatView::ConstructL( TInt aAvkonViewResourceId, TUid aViewId, + CCAMessageExtensionsHandler& aMessageHandler ) + { + BaseConstructL( aAvkonViewResourceId, aViewId ); + + iMessageHandler = &aMessageHandler; + + // Construct array for recipient list + iRecipients = new( ELeave ) CDesCArrayFlat( KArrayGranularity ); + iJoinedMembers = new( ELeave )CDesCArrayFlat( KArrayGranularity ); + + iFindContextMenu = new( ELeave ) CEikMenuBar; + iFindContextMenu->ConstructL( this, 0, R_CHATCLIENT_MENUBAR_FINDITEMUI ); + + iAddAndReplyMenu = new( ELeave ) CEikMenuBar; + iAddAndReplyMenu->ConstructL( + this, + 0, + R_CHATCLIENT_MENUBAR_ADDANDREPLY ); + + + iGroupId = HBufC::NewL( KMaxWVIDLength ); + iRecipient = HBufC::NewL( KMaxWVIDLength ); + + + iGroupUtils = CAAppUi()->GroupUtils(); + + iGroupPC = CAAppUi()->GetProcessManager().GetGroupInterface(); + + iFindMenu = CFindItemMenu::NewL( EChatClientFindMenuPlaceHolder ); + iFindMenu->AttachItemFinderMenuL( R_CHATCLIENT_IBOX_VIEW_MENU ); + iFindMenu->AttachItemFinderMenuL( R_CHATCLIENT_MENUBAR_FINDITEMUI ); + + // automatic finder on by default + iFindMenu->HandleItemFinderCommandL( EFindItemCmdEnableAutoFind ); + iItemFinder = CItemFinder::NewL(); + } + +// --------------------------------------------------------- +// CCAChatView::~CCAChatView() +// Destructor +// --------------------------------------------------------- +// +CCAChatView::~CCAChatView() + { + //In manual login,on exit from options menu + //DoDeactivate is not getting called,so free resources here + if ( iGroupPC ) + { + iGroupPC->UnRegisterGroupObserver( ); + iGroupPC->ReleaseResources(); + } + + if ( iAsyncCallBack ) + { + if ( iAsyncCallBack->IsActive() ) + { + iAsyncCallBack->Cancel(); + } + delete iAsyncCallBack; + } + + if ( iAddAndReplyMenu ) + { + AppUi()->RemoveFromStack( iAddAndReplyMenu ); + } + + delete iAddAndReplyMenu; + + if ( iFindContextMenu ) + { + AppUi()->RemoveFromStack( iFindContextMenu ); + delete iFindContextMenu; + } + + delete iRecipients; + + if ( iContainer ) + { + AppUi()->RemoveFromStack( iContainer ); + } + delete iContainer; + delete iGroupId; + delete iRecipient; + delete iSender; + delete iJoinedMembers; + delete iFindMenu; + delete iItemFinder; + + } + +// --------------------------------------------------------- +// CCAChatView::HandleCommandL(TInt aCommand) +// Handles commands +// --------------------------------------------------------- +// +void CCAChatView::HandleCommandL( TInt aCommand ) + { + CCAAppUi* appUi = static_cast( iEikonEnv->AppUi() ); + switch ( aCommand ) + { + case EAknSoftkeyOpen: // flowthrough + case EChatClientOpenObject: + { + 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: + { + 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 + iContainer->SendObjectL( ETrue, ENewFileServiceImage ); + break; + } + case EChatClientFromPhotos: // flowthrough + case EChatClientSendImage: + { + iCba = CEikButtonGroupContainer::Current(); + + if ( iCba ) + { + iCba->MakeCommandVisible( EAknSoftkeyOptions, EFalse ); + iCba->MakeCommandVisible( EAknSoftkeyBack, EFalse ); + iCba->MakeCommandVisible( EChatClientChatViewContinue, EFalse ); + iCba->DrawNow(); + } + + iContainer->SendObjectL( EFalse ); + + if ( iCba ) + { + iCba->MakeCommandVisible( EAknSoftkeyOptions, ETrue ); + iCba->MakeCommandVisible( EAknSoftkeyBack, ETrue ); + iCba->MakeCommandVisible( EChatClientChatViewContinue, ETrue ); + iCba->DrawNow(); + } + + break; + } + + //ChatClientCmdBack and EAknSoftKeyBack have same function + case EChatClientCmdBack: + case EAknSoftkeyBack: + { + CAAppUi()->CAStatusPane()->SynchroniseAndRemoveTabGroup(); + if ( TEnumsPC::ERegister == appUi->RetForwardTo() ) + { + appUi->SetResetForwardTo( TEnumsPC::EToBeUnregistered ); + + appUi->SwitchViewL( KUidFriendsListView ); + } + else + { + if ( TEnumsPC::EAlreadyRegistered == appUi->RetForwardTo() ) + { + appUi->UnRegisterPreviousview(); + appUi->SetResetForwardTo( TEnumsPC::EUnregistered ); + } + TCADnlConvInvGroupFocus dnlConvInvGroupFocus; + dnlConvInvGroupFocus.iInvConvGroupID.Copy( iGroupId->Des().Left( KMaxWVIDLength ) ); + dnlConvInvGroupFocus.iListID.Copy( KNullDesC() ); + dnlConvInvGroupFocus.iType = EGroupItem; + TCADnlConvInvGroupFocusBuf convInvGroupFocusBuf( dnlConvInvGroupFocus ); + CAAppUi()->SwitchViewBackL( KUidFriendsListView, KConvInvGroupFocusId, convInvGroupFocusBuf ); + } + break; + } + // Flow through + case EAknSoftkeySend: // MSK command + case EChatClientIboxViewSend: + case EChatClientChatViewCmdSend: + { + iContainer->SendMessageL(); + break; + } + + case EChatClientInviteFriend: + { + // launch the invite without query + DoLaunchInviteL( EFalse ); + 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 EChatClientChatViewContinue: + { + iContainer->StartScrollingL(); + break; + } + + case EChatClientChatViewCmdWhisper: + { + ShowRecipientsListL( R_CHATVIEW_RECIPIENT_QUERY ); + break; + } + // flow through + case EChatClientIboxReply: + case EChatClientChatViewCmdReply: + { + if ( iAddAndReplyMenu->IsDisplayed() ) + { + iAddAndReplyMenu->StopDisplayingMenuBar(); + } + iContainer->ReplyL(); + break; + } + + case EChatClientIboxForwardToGroup: + { + iContainer->ForwardToGroupL(); + break; + } + case EChatClientIboxForwardToContact: + { + iContainer->ForwardToContactL(); + break; + } + + case EChatClientChatViewLogOn: + { + iContainer->SaveChatL(); + break; + } + + + + case EChatClientChatViewCmdLeave: + { + iContainer->LeaveGroupL(); + //switch view is called in handleleft also + //calling switch view twice would not create any problem + //switch view is called here because just after creating the group if + //we leave from the group view , we would not get callback in handleleft + CAAppUi()->SwitchViewL( KUidFriendsListView ); + + break; + } + case EChatClientChatViewCmdParticip: + { + iGroupUtils->DisplayJoinedMembersL( *iGroupId ); + break; + } + case EChatClientChatViewCmdGroupInfo: + { + iContainer->DisplayChatInfoL(); + break; + } + case EChatClientChatViewEdit: + { + iContainer->EditChatGroupPropertiesL(); + break; + } + case EChatClientChatViewFavor: + { + iGroupUtils->SaveAsFavouriteL( *iGroupId ); + break; + } + + // Help key support EChatClientCmdHelp is assigned EAknCmdHelp in + // chatngclient.hrh + case EChatClientCmdHelp: + { + HlpLauncher::LaunchHelpApplicationL( iEikonEnv->WsSession(), + AppUi()->AppHelpContextL() ); + break; + } + + // flow through + case EFindItemCmdEnableAutoFind: + case EFindItemCmdDisableAutoFind: + { + iContainer->SetItemHighlight( + 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: + { + CAAppUi()->CAStatusPane()->RemoveObserver( this ) ; + AppUi()->HandleCommandL( aCommand ); + break; + } + default: + { + // check if it is find menu command + if ( iFindMenu->CommandIsValidL( aCommand ) ) + { + iFindMenu->HandleItemFinderCommandL( aCommand ); + } + else + { + AppUi()->HandleCommandL( aCommand ); + } + break; + } + } + } + + +// --------------------------------------------------------- +// CCAChatView::HandleForegroundEventL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAChatView::HandleForegroundEventL( TBool aForeground ) + { + if ( iContainer ) + { + //don't read messages if we're not in foreground + iContainer->FetchMessages( aForeground ); + } + CCAView::HandleForegroundEventL( aForeground ); + } + +// --------------------------------------------------------- +// CCAChatView::DoActivateL(...) +// Handles view activation +// --------------------------------------------------------- +// +void CCAChatView::DoActivateL( + const TVwsViewId& aPrevViewId, TUid aCustomMessageId, + const TDesC8& aCustomMessage ) + { + CHAT_DP_TXT( "CCAChatView::DoActivateL" ); + TBool launchInvite( EFalse ); + + // Unregister the view that was registered from Forward option. + // didn't find any better place to put this. + if ( TEnumsPC::EToBeUnregistered == CAAppUi()->RetForwardTo() ) + { + // Deregister conversation from switch back views + CAAppUi()->UnRegisterPreviousview(); + CAAppUi()->SetResetForwardTo( TEnumsPC::EUnregistered ); + } + const MCAConversationMessage* forwardedMessage = NULL; + + TBool activateFromTabSwitch ( EFalse ); + + if ( aCustomMessageId == KUidChatViewMsgId ) + { + TCADnlChatViewBuf viewBuf; + viewBuf.Copy( aCustomMessage ); + + activateFromTabSwitch = viewBuf().iSwitchTab; + + if ( activateFromTabSwitch ) + { + iTabId = viewBuf().iTabId; + } + + HBufC* group = viewBuf().iGroupId.AllocL(); + delete iGroupId; + iGroupId = group; + if ( viewBuf().iGroupName.Length() > 0 ) + { + CAAppUi()->CAStatusPane()->SetTitleL( viewBuf().iGroupName ); + } + else + { + CAAppUi()->CAStatusPane()-> + SetTitleL( CCAPCUtils::DisplayId( *iGroupId ) ); + } + if ( viewBuf().iIsForwarded ) + { + forwardedMessage = viewBuf().iForwardedMessage; + } + + launchInvite = viewBuf().iInviteQuery; + } + + + // Register this as chat observer + + iGroupPC->RegisterGroupObserver( this ); + + // set the context menu for menubar (launched with middle softkey) +#ifndef RD_30_DISABLE_TOUCH + MenuBar()->SetContextMenuTitleResourceId( + R_CHATCLIENT_MENUBAR_FINDITEMUI ); +#endif // RD_30_DISABLE_TOUCH + + // To prevent looping between this view and search view + if ( aPrevViewId.iViewUid == KUidSearchView ) + { + // If this view is activated from search view register + // chat list view as view for back option + TCADnlChatViewBuf viewBuf; + viewBuf.Copy( aCustomMessage ); + + TCADnlConvInvGroupFocus dnlConvInvGroupFocus; + dnlConvInvGroupFocus.iInvConvGroupID.Copy( viewBuf().iGroupId ); + dnlConvInvGroupFocus.iListID.Copy( KNullDesC() ); + dnlConvInvGroupFocus.iType = EGroupItem; + TCADnlConvInvGroupFocusBuf convInvGroupFocusBuf( dnlConvInvGroupFocus ); + + static_cast( AppUi() )->RegisterSwitchBack( + KUidFriendsListView, KConvInvGroupFocusId, convInvGroupFocusBuf.AllocL(), KNullUid ); + + CAAppUi()->GetProcessManager().GetArrayInterface()->PopulateGroupsListL(); + } + + // To prevent looping between this view and refresh view + if ( aPrevViewId.iViewUid != KUidRefreshView ) + { + iPrevViewId = aPrevViewId; + } + + //can be done while construction after TCADnlChatViewBuf is refactored + iGroupPC->InitialiseResourcesL( *iGroupId ); + + MCAViewSwitcher* viewSwitcher = static_cast( CAAppUi() ); + + // When forwarding from group to group DoDeactivate is never called. + // We have to cleanup the necessary stuff ourself. + CCAChatViewContainer* oldContainer = NULL; + if ( iContainer ) + { + AppUi()->RemoveFromStack( iContainer ); + oldContainer = iContainer; + iContainer = NULL; + + if ( iAddAndReplyMenu ) + { + AppUi()->RemoveFromStack( iAddAndReplyMenu ); + } + + if ( iFindContextMenu ) + { + AppUi()->RemoveFromStack( iFindContextMenu ); + } + + CleanupStack::PushL( oldContainer ); + } + + iContainer = CCAChatViewContainer::NewL( ClientRect(), *viewSwitcher, + iGroupPC, + *this, this, *iMessageHandler, + Cba(), activateFromTabSwitch, iTabId , this ); + // Get group properties (waiting operation) + + + static_cast + ( iContainer )->HandleGroupPropertiesChanged(); + + // Restore find state + TInt findState = IMUtils::CRKeyL( KCRUidCommonUi, KCuiAutomaticHighlight ); + iContainer->SetItemHighlight( findState ); + + CCAMessageEditor& editor = iContainer->Editor(); + + // Handle forwarded message + if ( forwardedMessage ) + { + CHAT_DP( + D_CHAT_LIT( "CCAChatView::DoActivateL, forwarding message" ) ); + + + CCAUiMessageUtils* utils = CCAUiMessageUtils::NewLC(); + CDesCArray* members = new( ELeave )CDesCArrayFlat( 1 ); + CleanupStack::PushL( members ); + + + + TBool isGroupFound = iGroupUtils->FindGroup( iGroupPC->ActiveGroupId() ); + + if ( isGroupFound ) + { + iGroupUtils->GetParticipantsL( *members, iGroupPC->ActiveGroupId() ); + } + // Remove user from targets + TInt index; + if ( members->Find( iGroupPC->ScreenName(), index ) == KErrNone ) + { + members->Delete( index ); + members->Compress(); + } + members->Sort( ECmpCollated ); + + + + TBool ret = utils->ForwardContentMessageL( + *forwardedMessage, + *iGroupId, // recipient + members, + *iGroupPC, + iContainer->IsWhisperAllowedL(), // no whispering + iGroupPC->ScreenName() ); + + //Note: code scanner warning is ignored + CleanupStack::PopAndDestroy( 2 ); //utils, members + + // 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(); + + } + } + + if ( !editor.TextLength() ) + { + TInt editorFlags = ( editor.AknEdwinFlags() | EAknEditorFlagNoEditIndicators ); + editor.SetAknEditorFlags( editorFlags ); + } + + AppUi()->AddToStackL( *this, iContainer ); + AppUi()->AddToStackL( *this, iAddAndReplyMenu, ECoeStackPriorityDefault, + ECoeStackFlagRefusesFocus ); + AppUi()->AddToStackL( *this, iFindContextMenu, ECoeStackPriorityDefault, + ECoeStackFlagRefusesFocus ); + + if ( launchInvite ) + { + delete iAsyncCallBack; + iAsyncCallBack = NULL; + + iAsyncCallBack = new( ELeave )CAsyncCallBack( + TCallBack( LaunchInvite, this ), CActive::EPriorityIdle ); + + // hide CBA + iCba = CEikButtonGroupContainer::Current(); + iCba->MakeVisible( EFalse ); + iCba->DrawNow(); + + iAsyncCallBack->CallBack(); + } + + if ( !activateFromTabSwitch ) + { + //Hides navi-pane decorators. + CAAppUi()->CAStatusPane()->ClearNaviPaneL(); + + //if activation is from contact list and not from switching between + //tabs then create tabs and show them + iTabId = CAAppUi()->CAStatusPane()->ShowTabGroupL( TEnumsPC::EGroupItem, *iGroupId ); + } + CAAppUi()->CAStatusPane()->AddObserver( this ) ; + + if ( oldContainer ) + { + // Everything should be ready and we can delete the old container + CleanupStack::PopAndDestroy(); // oldContainer + } + CHAT_DP_TXT( "CCAChatView::DoActivateL done" ); + } + +// --------------------------------------------------------- +// CCAChatView::ShowRecipientsListL() +// This method launches recipient list +// (other items were commented in a header). +// --------------------------------------------------------- +// +TInt CCAChatView::ShowRecipientsListL( TInt aResourceId ) + { + CArrayFixFlat* indexArray = + new ( ELeave ) CArrayFixFlat( KArrayGranularity ); + CleanupStack::PushL( indexArray ); + + CDesCArrayFlat* items = new ( ELeave ) CDesCArrayFlat( KArrayGranularity ); + CleanupStack::PushL( items ); + + HBufC* text = HBufC::NewLC( KWVNameMaxLength + KIconTabulator().Size() ); + TPtr textPtr( text->Des() ); + + + TBool isGroupFound = iGroupUtils->FindGroup( *iGroupId ); + if ( isGroupFound ) + { + iJoinedMembers->Reset(); + iGroupUtils->GetParticipantsL( *iJoinedMembers, *iGroupId ); + } + + + iJoinedMembers->Sort( ECmpCollated ); + + TInt count( iJoinedMembers->Count() ); + for ( TInt i( 0 ); i < count; ++i ) + { + textPtr.Copy( KIconTabulator ); + textPtr.Append( ( *iJoinedMembers )[i] ); + items->AppendL( *text ); + } + CleanupStack::PopAndDestroy( text ); + + TInt result( 0 ); + CArrayFixFlat* selectedArray = + CAArrayUtils::SetSelectionsLC( *iRecipients, *iJoinedMembers ); + result = IMDialogUtils::DisplayListQueryDialogL( indexArray, + items, + aResourceId, + selectedArray ); + CleanupStack::PopAndDestroy( 2, items ); //selectedArray, items + + if ( result ) + { + // use indexArray here + TInt selectionCount( indexArray->Count() ); + iRecipients->Reset(); + iContainer->Recipients().Reset(); + HBufC* userIdBuf = HBufC::NewLC( KMaxWVIDLength ); + TPtr userIdPtr( userIdBuf->Des() ); + TBool groupMsg( EFalse ); + if ( selectionCount > 0 ) + { + for ( TInt i( 0 ); i < selectionCount; i++ ) + { + //Cache user id to descriptor + userIdPtr.Copy( ( *iJoinedMembers )[ indexArray->At( i ) ] ); + iContainer->Recipients().AppendL( *userIdBuf ); + iRecipients->AppendL( *userIdBuf ); + } + if ( selectionCount > 1 ) + { + groupMsg = ETrue; + } + iContainer->InitPrivateMessageL( + iContainer->Recipients().MdcaPoint( 0 ), groupMsg ); + } + else + { + result = 0; + } + CleanupStack::PopAndDestroy( userIdBuf ); + } + + CleanupStack::PopAndDestroy( indexArray ); + + return result; + } + +// --------------------------------------------------------- +// CCAChatView::ShowPopUpMenuL() +// This method shows popup menu +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAChatView::ShowPopUpMenuL( ) + { + if ( iContainer->SelectedItemType() != KErrNotFound ) + { +#ifndef RD_30_DISABLE_TOUCH + // S60 COMMON + MenuBar()->StopDisplayingMenuBar(); + MenuBar()->TryDisplayContextMenuBarL(); +#else + // S60 3.0 + iFindContextMenu->StopDisplayingMenuBar(); + iFindContextMenu->TryDisplayMenuBarL(); +#endif //RD_30_DISABLE_TOUCH + } + } + +// --------------------------------------------------------- +// CCAChatView::DoDeactivate() +// Handles view deactivation +// --------------------------------------------------------- +// +void CCAChatView::DoDeactivate() + { + CHAT_DP_TXT( "DoDeactivate" ); + if ( !CAAppUi()->IsUnderDestruction() ) + { + + CCAStatusPaneHandler* statuspaneHandler = CAAppUi()->CAStatusPane(); + if ( statuspaneHandler ) + { + statuspaneHandler->RemoveObserver( this ) ; + } + } + if ( iGroupPC ) + { + iGroupPC->UnRegisterGroupObserver( ); + iGroupPC->ReleaseResources(); + } + + + + if ( iContainer ) + { + AppUi()->RemoveFromStack( iContainer ); + } + + if ( iAddAndReplyMenu ) + { + AppUi()->RemoveFromStack( iAddAndReplyMenu ); + } + + if ( iFindContextMenu ) + { + AppUi()->RemoveFromStack( iFindContextMenu ); + } + + delete iContainer; + iContainer = NULL; + } + +// --------------------------------------------------------- +// CCAChatView::DynInitMenuPaneL +// Called when menupane is about to be shown. +// --------------------------------------------------------- +// +void CCAChatView::DynInitMenuPaneL( TInt aResourceId, CEikMenuPane* aMenuPane ) + { + CHAT_DP_FUNC_ENTER( "DynInitMenuPaneL" ); + + TBool showFwdToContact = iContainer->FwdContactVisible(); + TBool showFwdToGroup = iContainer->FwdGroupVisible(); + TBool showForwardMenu = showFwdToGroup || showFwdToContact; + + iMenuPane = aMenuPane; + switch ( aResourceId ) + { + case R_CHATCLIENT_GENERAL_MENU: + { + if ( !FeatureManager::FeatureSupported( KFeatureIdHelp ) ) + { + // dims the help menu item + aMenuPane->SetItemDimmed( EChatClientCmdHelp, ETrue ); + } + break; + } + + case R_CHATCLIENT_ADDANDREPLY_MENU: + { + aMenuPane->SetItemDimmed( EChatClientSearchAddFriends, ETrue ); + if ( iContainer->Editor().IsFocused() + || !iContainer->IsWhisperAllowedL() + || iContainer->ApplicationUserSentThis() + || !iContainer->Received() ) + { + // editor is focused, whispering is not allowed, + // this is our own message or this is not received from server + aMenuPane->SetItemDimmed( EChatClientIboxReply, ETrue ); + } + break; + } + + case R_CHATCLIENT_CHAT_VIEW_MENU: + { + TBool text( iContainer->Editor().TextLength() != 0 ); + TBool openable = EFalse; + TBool savable = EFalse; + TBool object = iContainer->IsObjectSelected( openable, savable ); + + TBool isInviteAllowed( iContainer->IsInvitationAllowed() ); + TBool isUserAdmin( iContainer->IsUserAdmin() ); + TBool isGroupOpen( iContainer->IsGroupOpen() ); + + // "send" + aMenuPane->SetItemDimmed( EChatClientChatViewCmdSend, !text ); + + // "insert smiley" + if ( iContainer->Editor().IsFocused() ) + { + aMenuPane->SetItemDimmed( EChatClientChatViewInsertSmiley, + !iContainer->ExtensionFits( KChatSmileyLength ) ); + } + else + { + aMenuPane->SetItemDimmed( EChatClientChatViewInsertSmiley, + ETrue ); + } + + // "open" + aMenuPane->SetItemDimmed( EChatClientOpenObject, !openable ); + + // "save" + aMenuPane->SetItemDimmed( EChatClientSaveObject, !savable ); + + + // item finder menu + aMenuPane->SetItemDimmed( EChatClientFindMenuPlaceHolder, ETrue ); + + if ( iContainer->IsStopped() ) + { + UpdateItemTypeL(); + + iFindMenu->AddItemFindMenuL( iItemFinder, aMenuPane, + EChatClientFindMenuPlaceHolder, + KNullDesC ); // We can ignore 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( + "CCAChatView::DynInitMenuPaneL Hide the whole forward menu" ); + aMenuPane->SetItemDimmed( + EChatClientChatViewCmdForward, ETrue ); + } + else + { + CHAT_DP_TXT( + "CCAChatView::DynInitMenuPaneL Hide the whole forward menu" ); + aMenuPane->SetItemDimmed( EChatClientChatViewCmdForward, + !iContainer->IsStopped() ); + } + + TBool inviteSupported( UISessionManager().IsSupported( + CCAUISessionManager::EInvite ) ); + + if ( !inviteSupported ) + { + aMenuPane->SetItemDimmed( EChatClientInviteFriend, + ETrue ); + } + else if ( isInviteAllowed ) + { + if ( !isUserAdmin ) + { + aMenuPane->SetItemDimmed( EChatClientInviteFriend, + ( !isGroupOpen ) ); + } + } + else + { + aMenuPane->SetItemDimmed( EChatClientInviteFriend, + ETrue ); + } + + aMenuPane->SetItemDimmed( EChatClientChatViewCmdWhisper, + ( iContainer->IsStopped() || !iContainer->IsWhisperAllowedL() ) ); + + if ( iContainer->Editor().IsFocused() + || !iContainer->IsWhisperAllowedL() + || iContainer->ApplicationUserSentThis() + || !iContainer->Received() ) + { + // editor is focused, whispering is not allowed, + // this is our own message or this is not received from server + aMenuPane->SetItemDimmed( EChatClientChatViewCmdReply, ETrue ); + } + + + + break; + } + + case R_CHATCLIENT_CHATVIEW_SUB_MENU: + { + + + aMenuPane->SetItemDimmed( EChatClientChatViewFavor, + iGroupUtils->IsFavouriteChatGroup( *iGroupId ) ); + aMenuPane->SetItemDimmed( EChatClientChatViewRmv, + ETrue ); + + // branding things: edit group properties + if ( ! IMUtils::IntResourceValueL( + RSC_CHAT_VARIATION_ALLOW_EDIT_GROUP_PROPERTIES ) ) + { + // branded as inactive + aMenuPane->SetItemDimmed( EChatClientChatViewEdit, ETrue ); + } + else + { + // not branded + aMenuPane->SetItemDimmed( EChatClientChatViewEdit, + !iContainer->IsUserAdmin() ); + } + break; + } + + case R_CHATCLIENT_IBOX_FORWARD_SUBMENU: + { + // forward-menu funkiness + 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; + } + } + } + +// --------------------------------------------------------- +// CCAChatView::UpdateItemTypeL +// --------------------------------------------------------- +// +void CCAChatView::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( KHttpLength ); + if ( pref.CompareF( KIMHTTPPREFIX().Left( KHttpLength ) ) != 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( KHttpLength ); + if ( pref.CompareF( KIMHTTPPREFIX().Left( KHttpLength ) ) == 0 + || pref.CompareF( KIMRTSP ) == 0 ) + { + item.iItemType = CItemFinder::EUrlAddress; + } + } + } + + +// --------------------------------------------------------- +// CCAChatView::LaunchInvite +// --------------------------------------------------------- +// +TInt CCAChatView::LaunchInvite( TAny *aInstance ) + { + // launch the invite with query + TRAPD( + err, static_cast( aInstance )->DoLaunchInviteL( ETrue ) ); + + if ( err != KErrNone ) + { + CActiveScheduler::Current()->Error( err ); + } + + return EFalse; + } + +// --------------------------------------------------------- +// CCAChatView::DoLaunchInviteL +// --------------------------------------------------------- +// +void CCAChatView::DoLaunchInviteL( TBool aShowQuery ) + { + if ( iCba ) + { + iCba->MakeVisible( ETrue ); + iCba->DrawNow(); + } + + if ( aShowQuery ) + { + TInt retVal( IMDialogUtils::DisplayYesNoConfirmationDialogL( + R_QTN_CHAT_INVITE_FRIENDS_NOW ) ); + if ( retVal != EAknSoftkeyOk && retVal != EAknSoftkeyYes ) + { + // user declined the query + return; + } + } + + if ( UISessionManager().IsSupported( CCAUISessionManager::EInvite ) ) + { + iContainer->InviteFriendsToGroupL(); + } + else + { + // We don't need the returned keycode. + IMDialogUtils::DisplayNoteDialogL( R_CHAT_ERROR_NOT_SUP_FUNCTIONS ); + } + } + + +// --------------------------------------------------------- +// CCAChatView::HandleChatEvent +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAChatView::HandleChatEvent( const TDesC& aWvid , + const TDesC& aContactId ) + { + + TRAPD( err, DoHandleChatEventL( aWvid, aContactId ) ); + if ( err != KErrNone ) + { + CActiveScheduler::Current()->Error( err ); + } + + } + + +// --------------------------------------------------------- +// CCAChatView::DoHandleChatEventL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAChatView::DoHandleChatEventL( const TDesC& aWvid , + const TDesC& aContactId ) + { + HBufC* tempSender = aWvid.AllocL(); + delete iSender; + iSender = tempSender; + + // nickname or wv-less contact id + + + iCleanSender.Set( aContactId ); + + } + +// --------------------------------------------------------- +// CCAChatView::SwitchTabL +// (other items were commented in a header). +// --------------------------------------------------------- +// +void CCAChatView::SwitchTabL( const TDesC& aWvId, const TInt aTabIndex ) + { + //change the contact id based on tteh currenttab + HBufC* group = aWvId.AllocL(); + delete iGroupId; + iGroupId = group; + + iTabId = aTabIndex; + + CAAppUi()->CAStatusPane()->SetTitleL( CAAppUi()->CAStatusPane()->GetTabItemIdentification( iTabId ) ); + + + iGroupPC->SetActiveGroupChatL( aWvId ); + + //remove the controls from view stack + if ( iContainer ) + { + CAAppUi()->RemoveFromViewStack( *this, iContainer ); + } + + if ( iAddAndReplyMenu ) + { + CAAppUi()->RemoveFromViewStack( *this, iAddAndReplyMenu ); + } + + if ( iFindContextMenu ) + { + CAAppUi()->RemoveFromViewStack( *this, iFindContextMenu ); + } + + + iContainer->SwitchTabL(); + + //again add those controls to view stack + if ( iContainer ) + { + CAAppUi()->AddToViewStackL( *this, iContainer ); + } + + if ( iAddAndReplyMenu ) + { + CAAppUi()->AddToViewStackL( *this, iAddAndReplyMenu, ECoeStackPriorityDefault, + ECoeStackFlagRefusesFocus ); + } + + if ( iFindContextMenu ) + { + CAAppUi()->AddToStackL( *this, iFindContextMenu, ECoeStackPriorityDefault, + ECoeStackFlagRefusesFocus ); + } + + } + + +// --------------------------------------------------------- +// CCAChatView::HandleMessageError +// --------------------------------------------------------- +// +void CCAChatView::HandleMessageError( TInt aError, + const TDesC& aNick ) + { + TRAPD( err, DoHandleMessageErrorL( aError, aNick ) ); + if ( err != KErrNone ) + { + CActiveScheduler::Current()->Error( err ); + } + } + +// --------------------------------------------------------- +// CCAChatView::DoHandleMessageErrorL +// --------------------------------------------------------- +// +void CCAChatView::DoHandleMessageErrorL( TInt aError, + const TDesC& aNick ) + { + if ( aError == KErrNoMemory ) // handled in AppUi::HandleMessageError + { + return; + } + else if ( aError == TEnumsPC::EContentPicture ) + { + TInt res( aError == KErrOverflow ? + R_QTN_CHAT_SCALING_IMAGE_TOO_BIG : + R_QTN_CHAT_SCALING_ERROR ); + + // sending of image failed + IMDialogUtils::DisplayInformationNoteL( res ); + return; + } + + CHAT_DP( + D_CHAT_LIT( "CCAChatViewContainer::DoHandleMessageErrorL %d %S" ), + aError, + &aNick ); + + IMNoteMapper::ShowNoteL( aError, aNick ); + + + } + +// --------------------------------------------------------- +// CCAChatView::GetIfMenuPopup() +// --------------------------------------------------------- +// +TBool CCAChatView::GetIfMenuPopup() + { + TBool reValue = EFalse; + if ( !iMenuPane ) + { + reValue = EFalse; + } + else + { + reValue = iMenuPane->IsFocused(); + } + return reValue; + } +// End of File