--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wvuing/wvuiave/AppSrc/CCAChatView.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -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 <eikbtgpc.h>
+#include <stringloader.h>
+#include <eikgted.h> //For the CEikGlobalTextEditor
+#include <eikmenup.h>
+#include <eikmenub.h>
+#include <aknpopup.h>
+#include <aknnotewrappers.h>
+#include <aknenv.h>
+#include <flogger.h>
+#include <utf.h>
+#include <aknquerydialog.h>
+#include <ChatNG.rsg>
+#include <bldvariant.hrh>
+#include <FeatMgr.h>
+#include <hlplch.h>
+#include <finditem.hrh>
+#include <finditemmenu.h>
+#include <commonuiinternalcrkeys.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"
+
+
+
+// ================= 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<CCAAppUi*>( 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<CCAAppUi*>( 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<MCAViewSwitcher*>( 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<MCAGroupEventObserverPC*>
+ ( 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<TInt>* indexArray =
+ new ( ELeave ) CArrayFixFlat<TInt>( 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<TInt>* 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<CCAChatView*>( 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