diff -r d189ee25cf9d -r 3533d4323edc meetingrequest/mrviewer/src/cesmrviewerctrl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mrviewer/src/cesmrviewerctrl.cpp Wed Sep 01 12:28:57 2010 +0100 @@ -0,0 +1,1266 @@ +/* +* Copyright (c) 2007-2009 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: ESMR esmviewer controller implementation +* +*/ + +// INCLUDE FILES +// +#include "emailtrace.h" +#include "cesmrpolicy.h" +#include "esmrdef.h" +#include "cesmrpolicymanager.h" +// + +#include "cesmrviewerctrl.h" +#include "cmrentryprocessor.h" +#include "mesmrmeetingrequestentry.h" +#include "mesmrtaskextension.h" +#include "esmrentryhelper.h" +#include "esmrhelper.h" +#include "cesmruifactory.h" + +#include "mesmruibase.h" +#include "tesmrinputparams.h" +#include "tmroutputparams.h" +#include "esmrconfig.hrh" +#include "cesmrconfirmationquery.h" +#include "cesmrutils.h" +#include "cesmrcaluserutil.h" +#include "cesmrlistquery.h" +#include "cesmrcaldbmgr.h" + +#include "cesmrtaskfactory.h" +#include "cesmrtaskextensionimpl.h" + +// Logging utilities + +// From System +// +#include +#include "esmrutilsapiext.h" +// +#include +#include +// +#include "FreestyleEmailUiConstants.h" +// +#include +#include +#include +#include +#include + +// CONSTANTS +/// Unnamed namespace for local definitions +namespace { // codescanner::namespace + +#if defined(_DEBUG) + +// Definition for MR VIEWER ctrl panic text +_LIT(KMRViewerCtrlPanicTxt, "ESMRViewerCtrl" ); + +// MR VIEWER ctrl panic codes +enum TMRViewerCtrlPanicCode + { + EESMRViewerCtrlSyncher = 0, // Syncher is not created, + EESMRViewerCtrlProcessor, + EESMRViewerCtrlTaskExt, + EESMRViewerCtrlPolicyMgr, + EESMRViewerCtrlInvalidModifyingRule, + EESMRViewerCtrlInvalidEntryType + }; + +void Panic(TMRViewerCtrlPanicCode aPanicCode) + { + User::Panic( KMRViewerCtrlPanicTxt, aPanicCode ); + } + +#endif + +/** + * Maps calendar entry type to MR entry type + * @param aEntryType to be mapped to MR entry type + * @return MR event type + */ +TESMRCalendarEventType MapType( const CCalEntry& aEntry ) + { + TESMRCalendarEventType type( EESMREventTypeNone ); + + switch ( aEntry.EntryTypeL() ) + { + case CCalEntry::EAppt: + { + if( CCalenInterimUtils2::IsMeetingRequestL( + ( const_cast( aEntry ) ) ) ) + { + type = EESMREventTypeMeetingRequest; + } + else + { + type = EESMREventTypeAppt; + } + break; + } + case CCalEntry::ETodo: + { + type = EESMREventTypeETodo; + break; + } + case CCalEntry::EEvent: + { + type = EESMREventTypeEEvent; + break; + } + case CCalEntry::EReminder: + { + type = EESMREventTypeEReminder; + break; + } + case CCalEntry::EAnniv: + { + type = EESMREventTypeEAnniv; + break; + } + default: + { + __ASSERT_DEBUG( EFalse, Panic( EESMRViewerCtrlInvalidEntryType ) ); + } + } + + return type; + } + +/** + * Creates calendar entry + * @param required parameters for creating an entry + * @return CCalEntry Created entry. + */ +CCalEntry* CreateEntryL( + CCalEntry::TType aType, + const TDesC8& aUid, + CCalEntry::TMethod aMethod, + CalCommon::TRecurrenceRange aRange ) + { + HBufC8* guid = aUid.AllocLC(); + CCalEntry* entry = CCalEntry::NewL( aType, guid, aMethod, aRange ); + CleanupStack::Pop( guid ); + + return entry; + } + +/** + * Converts to-do specific priority to normal priority + * @param Calendar entry, which priority is converted + * @return The converted priority + */ +TInt ConvertTodoPriorityToNormalL( const CCalEntry& entry ) + { + FUNC_LOG; + TInt priority( 0 ); + if( entry.PriorityL() == EFSCalenTodoPriorityHigh ) + { + priority = EFSCalenMRPriorityHigh; + } + + else if( entry.PriorityL() == EFSCalenTodoPriorityNormal ) + { + priority = EFSCalenMRPriorityNormal; + } + + else if( entry.PriorityL() == EFSCalenTodoPriorityLow ) + { + priority = EFSCalenMRPriorityLow; + } + + else + { + // Priority unknown, let's set it to normal then + priority = EFSCalenMRPriorityNormal; + } + + return priority; + } + +/** + * Converts normal priority to to-do specific priority + * @param Calendar entry, which priority is converted + * @return The converted priority + */ +TInt ConvertNormalPriorityToTodoL( const CCalEntry& entry ) + { + FUNC_LOG; + TInt priority( 0 ); + if( entry.PriorityL() == EFSCalenMRPriorityHigh ) + { + priority = EFSCalenTodoPriorityHigh; + } + + else if( entry.PriorityL() == EFSCalenMRPriorityNormal ) + { + priority = EFSCalenTodoPriorityNormal; + } + + else if( entry.PriorityL() == EFSCalenMRPriorityLow ) + { + priority = EFSCalenTodoPriorityLow; + } + + else + { + // Priority unknown, let's set it to normal then + priority = EFSCalenMRPriorityNormal; + } + + return priority; + } + +} // namespace + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CESMRViewerController::CESMRViewerController +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CESMRViewerController::CESMRViewerController( + RPointerArray& aEntries, + const MAgnEntryUi::TAgnEntryUiInParams& aParams, + MAgnEntryUi::TAgnEntryUiOutParams& aOutParams, + MAgnEntryUiCallback& aCallback ) + : iInParams( aParams ), + iOutParams( aOutParams ), + iCallback( aCallback ), + iEntries( aEntries ) + { + FUNC_LOG; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::~CESMRViewerController +// ----------------------------------------------------------------------------- +// +EXPORT_C CESMRViewerController::~CESMRViewerController() + { + FUNC_LOG; + delete iCtrlSyncher; + delete iGuiFactory; + delete iCalEntry; + delete iESMRUtils; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::NewL +// ----------------------------------------------------------------------------- +// +EXPORT_C CESMRViewerController* CESMRViewerController::NewL( + const TDesC8& aMtmuid, + RPointerArray& aEntries, + const MAgnEntryUi::TAgnEntryUiInParams& aParams, + MAgnEntryUi::TAgnEntryUiOutParams& aOutParams, + MAgnEntryUiCallback& aCallback ) + { + FUNC_LOG; + + CESMRViewerController* self = + new( ELeave ) CESMRViewerController( aEntries, + aParams, + aOutParams, + aCallback ); + + CleanupStack::PushL( self ); + self->ConstructL(aMtmuid); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ConstructL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::ConstructL(const TDesC8& /*aMtmUid */) + { + FUNC_LOG; + // This will create ESMR UTILS. Initialization is asynchronous. + // Competion is signaled via CESMRViewerController::HandleCalEngStatus. + iESMRUtils = CESMRUtils::NewL( *this ); + iESMRUtils->SessionSetupL( + iInParams.iCalSession, + iInParams.iMsgSession ); + + iESMRUtils->CreateExtensionsL( + ESMREntryHelper::EventTypeL( *(iEntries[0]) ) ); + + iGuiFactory = CESMRUiFactory::NewL(); + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ExecuteL +// ----------------------------------------------------------------------------- +// +EXPORT_C void CESMRViewerController::ExecuteL() + { + FUNC_LOG; + + iExecutionError = KErrNone; + + // Initialization waiter is needed because MR VIEWER user expects + // MR VIEWER operation to be synchronous. + iCtrlSyncher = new (ELeave) CActiveSchedulerWait; + + // MR UTILS calls CESMRViewerController::HandleCalEngStatus after init is + // complete. CESMRViewerController::HandleCalEngStatus also sets + // iExectionError if there occurs error during MR UTILS init. + iCtrlSyncher->Start(); + + User::LeaveIfError( iExecutionError ); + + iEntryProcessor = + static_cast( + iESMRUtils->ExtensionL( + TUid::Uid(KESMRMREntryProcessorUid) ) ); + + iPolicyMgr = + static_cast( + iESMRUtils->ExtensionL( + TUid::Uid(KESMRPolicyMgrUid) ) ); + + iTaskExt = + static_cast( + iESMRUtils->ExtensionL( + TUid::Uid(KESMRTaskExtensionUid) ) ); + + // Check that all extensions are found + if ( !iEntryProcessor || !iPolicyMgr || !iTaskExt ) + { + // All extensions are not found --> Leave + User::Leave( KErrNotSupported ); + } + + iEntryProcessor->ProcessL( + &iInParams, + &iEntries ); + + LaunchCorrectOperationModeL(); + + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::IsCommandAvailable +// ----------------------------------------------------------------------------- +// +TBool CESMRViewerController::IsCommandAvailable( TInt aCommandId ) + { + FUNC_LOG; + + + TBool retValue( EFalse ); + + if ( KFSEmailUiUid == iInParams.iCallingApp ) + { + retValue = iCallback.IsCommandAvailable( aCommandId ); + } + + + return retValue; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ProcessCommandWithResultL +// ----------------------------------------------------------------------------- +// +TInt CESMRViewerController::ProcessCommandWithResultL( TInt aCommandId ) + { + FUNC_LOG; + + TInt result = ProcessCommandWithResultInternalL(aCommandId); + + + return result; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::ProcessCommandL( TInt aCommandId ) + { + FUNC_LOG; + + ProcessCommandWithResultL( aCommandId ); + + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::HandleCalEngStatus +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::HandleCalEngStatus( TMRUtilsCalEngStatus aStatus ) + { + FUNC_LOG; + + + __ASSERT_DEBUG( iCtrlSyncher, Panic(EESMRViewerCtrlSyncher) ); + + if ( ENotReady == aStatus ) + { + // cal db is not ready + iExecutionError = KErrNotReady; + } + else if (ENotAvailable == aStatus ) + { + // cal db cannot be found + iExecutionError = KErrNotFound; + } + +// + if ( iCtrlSyncher && + iCtrlSyncher->IsStarted() && + iCtrlSyncher->CanStopNow() ) +// + { + // Exection continues in CESMRViewerController::ExecuteL + iCtrlSyncher->AsyncStop(); + } + + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::HandleOperation +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::HandleOperation( + TInt /*aType*/, + TInt /*aPercentageCompleted*/, + TInt /*aStatus*/ ) + { + FUNC_LOG; + + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::PolicyProvider +// ----------------------------------------------------------------------------- +// +MMRPolicyProvider& CESMRViewerController::PolicyProvider() const + { + return *iPolicyMgr; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::EntryL +// ----------------------------------------------------------------------------- +// +MESMRCalEntry* CESMRViewerController::EntryL() + { + return &iEntryProcessor->ESMREntryL(); + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ProcessCommandWithResultInternalL +// ----------------------------------------------------------------------------- +// +TInt CESMRViewerController::ProcessCommandWithResultInternalL( + TInt aCommandId ) + { + FUNC_LOG; + + TInt ret = ProcessDefaultCommandL( aCommandId ); + + if ( ret == KErrNotSupported ) + { + ret = ProcessMeetingRequestCommandL( aCommandId ); + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ProcessDefaultCommandL +// ----------------------------------------------------------------------------- +// +TInt CESMRViewerController::ProcessDefaultCommandL( TInt aCommandId ) + { + FUNC_LOG; + + TESMRCommand command = static_cast(aCommandId); + TBool needToProcessOutputParams( ETrue ); + + MESMRCalEntry& entry = iEntryProcessor->ESMREntryL(); + TInt ret = KErrNone; + + MESMRCalDbMgr& dbMgr = entry.GetDBMgr(); + switch( aCommandId ) + { + case EESMRCmdSaveMR: // Saves Entry + case EESMRCmdCalEntryUISave: + { + // If we are editing an existing entry. + if ( entry.IsStoredL() ) + { + // If entry is type changed. + if ( entry.IsEntryTypeChangedL() ) + { + // If entry is type changed, delete the old entry first + // from db ... + + CCalEntry* lastStoredEntry = + dbMgr.FetchEntryL( + entry.Entry().UidL(), + entry.Entry().RecurrenceIdL() ); + ASSERT( lastStoredEntry ); + CleanupStack::PushL( lastStoredEntry ); + + if( CCalenInterimUtils2::IsMeetingRequestL( + *lastStoredEntry ) ) + { + // Last stored entry was MR. If MR is sent, it needs to be + // also cancelled before deleting + CancelAndDeleteMRInEntryTypeChangeL( + *lastStoredEntry,dbMgr ); + } + else + { + // Use right taskExtension + CESMRTaskFactory* taskFactory = CESMRTaskFactory::NewL( + MapType( *lastStoredEntry ), + dbMgr ); + CleanupStack::PushL( taskFactory ); + + MESMRTaskExtension* taskExtension = + CESMRTaskExtenstionImpl::NewL( *taskFactory ); + CleanupDeletePushL( taskExtension ); + + taskExtension->DeleteEntryFromLocalDBL( + EESMRCmdCalEntryUIDelete, + entry ); + + CleanupStack::PopAndDestroy( taskExtension ); + CleanupStack::PopAndDestroy( taskFactory ); + } + + // ... and then store the new (edited) entry to db. + iTaskExt->StoreEntryToLocalDBL( + command, + entry ); + + CleanupStack::PopAndDestroy( lastStoredEntry ); + } + + // If we are saving entry that previously existed in + // different db. + else if ( dbMgr.EntryViewL( entry.Entry() ) != NULL + && dbMgr.EntryViewL( entry.Entry() ) != dbMgr.EntryView() ) + { + iTaskExt->MoveEntryToCurrentDBL( command, entry ); + } + + // And if none of the above conditions apply, we are just editing + // an entry and want to save it. + else + { + iTaskExt->StoreEntryToLocalDBL( + command, + entry ); + } + } + + // Store new entry to db. + else + { + iTaskExt->StoreEntryToLocalDBL( + command, + entry ); + } + } + break; + + case EESMRCmdCalEntryUIDelete: // Deletes Entry + { + iTaskExt->DeleteEntryFromLocalDBL( + command, + entry ); + + } + break; + + case EESMRCmdEdit: // Edit MR + case EESMRCmdEditLocal: // Locally edit meeting request + case EESMRCmdCalEntryUIEdit: // Edit calendar entries + { + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeEdit ); + iPolicyMgr->PushPolicyL(); + LaunchUIL(); + + // No need to process parameters because the view is closed + // and editing view has processed to parameters + needToProcessOutputParams = EFalse; + iPolicyMgr->PopPolicy(); + + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeView ); + } + break; + + case EESMRCmdCalEntryUISend: // Send calendar entry item + case EESMRCmdCalEntryUIAddParticipants: // Add participants to meeting item + { + ASSERT( EFalse ); + } + break; + + case EESMRCmdEditorInitializationComplete: + { + if ( iCallback.IsCommandAvailable( EESMRCmdEditorInitializationComplete ) ) + { + iCallback.ProcessCommandL( EESMRCmdEditorInitializationComplete ); + } + break; + } + + case EMRCommandSwitchToMR: + case EMRCommandSwitchToMeeting: + case EMRCommandSwitchToMemo: + case EMRCommandSwitchToAnniversary: + case EMRCommandSwitchToTodo: + { + ChangeEntryTypeL( aCommandId ); + needToProcessOutputParams = EFalse; + } + break; + + /* + case EMRLaunchAttachmentsView: + case EMRViewAttachmentInCorrespondingApp: + { + iCallback.ProcessCommandL( command ); + } + break; +*/ + case EESMRCmdTodoMarkAsDone: + { + iTaskExt->MarkTodoAsDoneL( command, + iEntryProcessor->ESMREntryL() ); + } + break; + + case EESMRCmdTodoMarkAsNotDone: + { + iTaskExt->MarkTodoAsNotDoneL( command, + iEntryProcessor->ESMREntryL() ); + } + break; + + default: + ret = KErrNotSupported; + needToProcessOutputParams = EFalse; + break; + } + + if ( needToProcessOutputParams ) + { + iEntryProcessor->ProcessOutputParametersL( + iOutParams, + command ); + } + + + return ret; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ProcessMeetingRequestCommandL +// ----------------------------------------------------------------------------- +// +TInt CESMRViewerController::ProcessMeetingRequestCommandL( TInt aCommandId ) + { + FUNC_LOG; + + TESMRCommand command = static_cast(aCommandId); + TBool needToProcessOutputParams( ETrue ); + + MESMRCalEntry* tmpEntry = &iEntryProcessor->ESMREntryL(); + + ASSERT( tmpEntry->Type() == EESMREventTypeMeetingRequest ); + + if ( tmpEntry->Type() != EESMREventTypeMeetingRequest ) + { + User::Leave( KErrNotSupported ); + } + + MESMRMeetingRequestEntry& entry( *static_cast( tmpEntry ) ); + MESMRCalDbMgr& dbMgr = entry.GetDBMgr(); + + switch( aCommandId ) + { + case EESMRCmdSendMR: // Send Meeting request + case EESMRCmdSendMRUpdate: // Send MR update + { + entry.ConfirmEntryL(); + + if( entry.IsStoredL() ) + { + if( entry.IsEntryTypeChangedL() || + ( ( dbMgr.EntryViewL( entry.Entry() ) != NULL ) && + ( dbMgr.EntryViewL( entry.Entry() ) != dbMgr.EntryView() ) ) ) + { + if(!entry.IsEntryTypeChangedL()) + { + entry.SetSendCanellationAvailable( EFalse ); + } + iTaskExt->DeleteEntryFromLocalDBL( + EESMRCmdDeleteMR, + entry ); + } + } + iTaskExt->SendAndStoreMRL( + command, + entry ); + } + break; + + case EESMRCmdAcceptMR: // Accept received MR + case EESMRCmdTentativeMR: // Tentatively accept MR + case EESMRCmdDeclineMR: // Decline MR + { + entry.ConfirmEntryL(); + iTaskExt->SendAndStoreResponseL( + command, + entry ); + } + break; + + case EESMRAcceptWithoutAttachmentCheck: + case EESMRTentativeWithoutAttachmentCheck: + case EESMRDeclineWithoutAttachmentCheck: + { + entry.ConfirmEntryL(); + iTaskExt->SendAndStoreResponseL( + command, + entry ); + } + break; + + case EESMRCmdDeleteMR: // Deletes MR + case EESMRCmdRemoveFromCalendar: // Removes MR from calendar + case EESMRCmdMailDelete: // Mail specific delete command + { + if ( EESMRCmdDeleteMR == command || + EESMRCmdMailDelete == command ) + { + entry.MarkMeetingCancelledL(); + } + + iTaskExt->DeleteAndSendMRL( + command, + entry ); + + if ( entry.IsOpenedFromMail() ) + { + // Triggering mail delete command also + needToProcessOutputParams = EFalse; + iCallback.ProcessCommandL( aCommandId ); + } + } + break; + + case EESMRCmdViewTrack: + { + TESMRViewMode viewMode = iEntryProcessor->ScenarioData().iViewMode; + // iEntryProcessor->SwitchToTrackL(); + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeTrack ); + iPolicyMgr->PushPolicyL(); + LaunchUIL(); + + //go back to original view depending on where we came from + if (viewMode == EESMREditMR) + { + //iEntryProcessor->SwitchToEditL(); + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeEdit ); + } + else + { + // iEntryProcessor->SwitchToViewL(); + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeView ); + } + + LaunchUIL(); + iPolicyMgr->PopPolicy(); + } + break; + case EESMRCmdForwardAsMeeting: // Forward MR as meeting + { + // iEntryProcessor->SwitchToForwardL(); + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeForward ); + iPolicyMgr->PushPolicyL(); + LaunchUIL(); + iPolicyMgr->PopPolicy(); + // iEntryProcessor->SwitchToViewL(); + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeView ); + } + break; + + case EESMRCmdForwardAsMail: // Forward MR as mail + { + if ( entry.IsOpenedFromMail() ) + { + needToProcessOutputParams = EFalse; + iCallback.ProcessCommandL( + EESMRCmdMailForwardAsMessage ); + } + else + { + iTaskExt->ForwardMRAsEmailL( + command, + entry ); + } + } + break; + + case EESMRCmdReply: // Forward MR as mail + case EESMRCmdReplyAll: //Flow through + { + if ( entry.IsOpenedFromMail() ) + { + TInt emailCommand( EESMRCmdMailReply ); + if ( EESMRCmdReplyAll == aCommandId ) + { + emailCommand = EESMRCmdMailReplyAll; + } + needToProcessOutputParams = EFalse; + iCallback.ProcessCommandL( + emailCommand ); + } + else + { + iTaskExt->ReplyAsEmailL( + command, + entry ); + } + } + break; + + // Email commands + case EESMRCmdMailMarkUnread: + case EESMRCmdMailMarkRead: + case EESMRCmdMailForwardAsMessage: + case EESMRCmdMailMoveMessage: + case EESMRCmdMailCopyMessage: + case EESMRCmdMailFlagMessage: + case EESMRCmdMailComposeMessage: + case EESMRCmdMailMessageDetails: + case EESMRCmdMailPreviousMessage: + case EESMRCmdMailNextMessage: + case EESMRCmdMailMoveMessageToDrafts: + case EESMRCmdOpenAttachment: + case EESMRCmdOpenAttachmentView: + case EESMRCmdDownloadAttachment: + case EESMRCmdDownloadAllAttachments: + case EESMRCmdSaveAttachment: + case EESMRCmdSaveAllAttachments: + case EESMRCmdDownloadManager: + { + needToProcessOutputParams = EFalse; + iCallback.ProcessCommandL( aCommandId ); + } + break; + + default: + User::Leave( KErrNotSupported ); + } + + if ( needToProcessOutputParams ) + { + iEntryProcessor->ProcessOutputParametersL( + iOutParams, + command ); + } + + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::ChangeEntryTypeL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::ChangeEntryTypeL( TInt aCommandId ) + { + TESMRCalendarEventType type = EESMREventTypeNone; + + switch ( aCommandId ) + { + case EMRCommandSwitchToMR: + { + type = EESMREventTypeMeetingRequest; + break; + } + + case EMRCommandSwitchToMeeting: + { + type = EESMREventTypeAppt; + break; + } + + case EMRCommandSwitchToMemo: + { + type = EESMREventTypeEEvent; + break; + } + + case EMRCommandSwitchToAnniversary: + { + type = EESMREventTypeEAnniv; + break; + } + + case EMRCommandSwitchToTodo: + { + type = EESMREventTypeETodo; + break; + } + + default: + { + break; + } + } + + // Original entry is needed for creating new comparative entry + CCalEntry* originalEntry = + ESMRHelper::CopyEntryL( + iEntryProcessor->ESMREntryL().OriginalEntry(), + iEntryProcessor->ESMREntryL().OriginalEntry().MethodL(), + ESMRHelper::ECopyFull ); + + CleanupStack::PushL( originalEntry ); + + // Create a new entry by cloning the existing entry. + // This also does the type conversion and judges what + // entry information will be copied from the old entry + // to the new entry + CCalEntry* newEntry = + iEntryProcessor->ESMREntryL().CloneEntryLC( + MESMRCalEntry::TESMRCalEntryType( type ) ); + + iESMRUtils->CreateExtensionsL( type ); + + iEntryProcessor = + static_cast( + iESMRUtils->ExtensionL( + TUid::Uid( KESMRMREntryProcessorUid ) ) ); + + iPolicyMgr = + static_cast( + iESMRUtils->ExtensionL( + TUid::Uid( KESMRPolicyMgrUid ) ) ); + + iTaskExt = + static_cast( + iESMRUtils->ExtensionL( + TUid::Uid( KESMRTaskExtensionUid ) ) ); + + // Process entry + iEntryProcessor->ResetL(); + iEntryProcessor->ProcessL( &iInParams, *newEntry, EFalse, ETrue ); + + if ( iInParams.iEditorMode == MAgnEntryUi::EViewEntry ) + { + // If user has been viewing original entry, switch processor to editor. + iEntryProcessor->SwitchProcessorToModeL( EMRProcessorModeEdit ); + } + + // Resolve new policy + iPolicyMgr->ResolvePolicyL( iEntryProcessor->ScenarioData(), + iEntryProcessor->ESMREntryL(), + NULL ); + + if ( iCalEntry ) + { + delete iCalEntry; + } + + iCalEntry = newEntry; + CleanupStack::Pop( newEntry ); + newEntry = NULL; + + // Comparative entry needs to be updated also, otherwise + // type changed entry's saving won't function correctly + UpdateComparativeEntryInTypeChangeL( *originalEntry ); + + iEntryProcessor->ESMREntryL().SetTypeChanged( ETrue ); + + CleanupStack::PopAndDestroy( originalEntry ); + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::LaunchUIL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::LaunchUIL() + { + FUNC_LOG; + iPolicyMgr->ResolvePolicyL( + iEntryProcessor->ScenarioData(), + iEntryProcessor->ESMREntryL(), + NULL ); // Passing NULL --> Default policy resolver is used + + MESMRUiBase* uibase = + iGuiFactory->CreateUIL( + *this, + *this ); + + TInt retValue = uibase->ExecuteViewLD(); + + if ( retValue == EAknCmdExit ) + { + MESMRCalEntry* calEntry = &iEntryProcessor->ESMREntryL(); + + if( CCalenInterimUtils2::IsMeetingRequestL( calEntry->Entry() ) ) + { + // Cast safe, after we have identified the entry as mr + MESMRMeetingRequestEntry& mrEntry( + *static_cast< MESMRMeetingRequestEntry* >( calEntry ) ); + + if( mrEntry.IsOpenedFromMail() ) + { + CEikAppUi* appUi = + CEikonEnv::Static()->EikAppUi(); // codescanner::eikonenvstatic + // Exit application + static_cast( appUi )->ProcessCommandL( + EAknCmdExit ); + } + else + { + // Let's inform via output parameters that + // exit is desired. + TMROutputParams* outputParams = + reinterpret_cast< TMROutputParams* >( iOutParams.iSpare ); + outputParams->iCommand = EMRDialogOptionsMenuExit; + } + } + else + { + // Let's inform via output parameters that + // exit is desired. + TMROutputParams* outputParams = + reinterpret_cast< TMROutputParams* >( iOutParams.iSpare ); + outputParams->iCommand = EMRDialogOptionsMenuExit; + } + } + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::LaunchCorrectOperationModeL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::LaunchCorrectOperationModeL() + { + FUNC_LOG; + TESMRInputParams* esmrInputParams = (TESMRInputParams*)(iInParams.iSpare); + + if ( esmrInputParams && + EESMRCmdUndefined != esmrInputParams->iCommand ) + { + ProcessCommandWithResultL( esmrInputParams->iCommand ); + } + else + { + LaunchUIL(); + } + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::UpdateComparativeEntryInTypeChangeL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::UpdateComparativeEntryInTypeChangeL( + const CCalEntry& aOriginalEntry ) + { + /* + * This is needed because if user creates an entry and only type changes + * the entry, but does not input any data, we cannot save the entry. + */ + + CCalEntry& esmrEntry = iEntryProcessor->ESMREntryL().Entry(); + + TESMRCalendarEventType type = MapType( aOriginalEntry ); + + // Let's create new comparative entry based on the current + // type changed entry + CCalEntry* newComparativeEntry = CreateEntryL( + iCalEntry->EntryTypeL(), + iCalEntry->UidL(), + CCalEntry::EMethodNone, + CalCommon::EThisOnly ); + + CleanupStack::PushL( newComparativeEntry ); + + newComparativeEntry->CopyFromL( *iCalEntry ); + + // New comparative entry needs still data from original entry. + // Use case: + // - User opens entry to editor + // - User changes values + // - User changes entry type + // -> We need to determine if entry values have changed from the original + newComparativeEntry->SetSummaryL( + aOriginalEntry.SummaryL() ); + newComparativeEntry->SetLocationL( + aOriginalEntry.LocationL() ); + newComparativeEntry->SetDescriptionL( + aOriginalEntry.DescriptionL() ); + newComparativeEntry->SetReplicationStatusL( + aOriginalEntry.ReplicationStatusL() ); + + // If original and new entries are both appointments, + // then also start and end times can be copied from original entry + // to comparative entry + if( aOriginalEntry.EntryTypeL() == CCalEntry::EAppt && + esmrEntry.EntryTypeL() == CCalEntry::EAppt ) + { + newComparativeEntry->SetStartAndEndTimeL( + aOriginalEntry.StartTimeL(), + aOriginalEntry.EndTimeL() ); + } + + // Time stamp must be the same as in esmrEntry + newComparativeEntry->SetDTStampL( esmrEntry.DTStampL() ); + + // If neither the original entry, nor the new entry + // are To-do's, we can also copy the priority from + // the original entry, since priority value is then compatible + // between the old and the new entry types + if( aOriginalEntry.EntryTypeL() != CCalEntry::ETodo && + iCalEntry->EntryTypeL() != CCalEntry::ETodo ) + { + newComparativeEntry->SetPriorityL( + aOriginalEntry.PriorityL() ); + } + // One of the entries, original or new, are to-do's, + // so the priority value is not compatible between them. + // we need to convert that + else + { + if( aOriginalEntry.EntryTypeL() == CCalEntry::ETodo ) + { + newComparativeEntry->SetPriorityL( + ConvertTodoPriorityToNormalL( aOriginalEntry ) ); + } + else if( iCalEntry->EntryTypeL() == CCalEntry::ETodo ) + { + newComparativeEntry->SetPriorityL( + ConvertNormalPriorityToTodoL( aOriginalEntry ) ); + } + } + + // If new entry is meeting request, let's also + // copy the same phone owner to the comparative entry + if( iCalEntry->MethodL() == CCalEntry::EMethodRequest ) + { + CCalUser* temp = esmrEntry.OrganizerL(); // Ownership not transfered + CCalUser* organizer = ESMRHelper::CopyUserL( *temp ); + + newComparativeEntry->SetOrganizerL( organizer ); + newComparativeEntry->SetPhoneOwnerL( + newComparativeEntry->OrganizerL() ); + } + + // Attachment information is also needed from original entry + if( aOriginalEntry.AttachmentCountL() == 0 ) + { + // Original entry did not have attachments, so let's + // remove possible attachments from comparative entry also + TInt count = newComparativeEntry->AttachmentCountL(); + + // Attachments need to be deleted in reversed order + for( TInt i = ( count - 1 ); i == 0; --i ) + { + newComparativeEntry->DeleteAttachmentL( + *( newComparativeEntry->AttachmentL( i ) ) ); + } + + // If original entry does have attachments, we do nothing -> + // If original entry has attachments, it has been already saved + // and now type changed, which means that it needs to be saved + // anyway. + } + + iEntryProcessor->ESMREntryL().UpdateComparativeEntry( + newComparativeEntry ); // Takes ownership + + CleanupStack::Pop( newComparativeEntry ); + } + +// ----------------------------------------------------------------------------- +// CESMRViewerController::CancelAndDeleteMRInEntryTypeChangeL +// ----------------------------------------------------------------------------- +// +void CESMRViewerController::CancelAndDeleteMRInEntryTypeChangeL( + CCalEntry& aEntry, MESMRCalDbMgr& aDbMgr ) + { + FUNC_LOG; + // We need new task factor, processor and task extension + // for this temporary MR action. + CESMRTaskFactory* taskFactory = CESMRTaskFactory::NewL( + EESMREventTypeMeetingRequest, + aDbMgr ); + CleanupStack::PushL( taskFactory ); + + CMREntryProcessor* entryProcessor = CMREntryProcessor::NewL( + EESMREventTypeMeetingRequest, + aDbMgr ); + CleanupStack::PushL( entryProcessor ); + + MESMRTaskExtension* taskExtension = + CESMRTaskExtenstionImpl::NewL( *taskFactory ); + CleanupDeletePushL( taskExtension ); + + entryProcessor->ProcessL( &iInParams, aEntry, EFalse, ETrue ); + MESMRCalEntry& entry = entryProcessor->ESMREntryL(); + + // Cast safe, because entry is always MR + MESMRMeetingRequestEntry& mrEntry( + static_cast( entry ) ); + + if ( EESMRRoleOrganizer == mrEntry.RoleL() ) + { + CCalEntry::TStatus status( mrEntry.Entry().StatusL() ); + if ( CCalEntry::ENullStatus != status ) + { + // We are changing entry type from MR to some other type + // And we have sent the MR invitation to attendees. + // We provide possibility for user to send + // cancellation message to attendees. + mrEntry.MarkMeetingCancelledL(); + + taskExtension->DeleteAndSendMRL( + EESMRCmdDeleteMR, + mrEntry ); + } + else + { + taskExtension->DeleteEntryFromLocalDBL( + EESMRCmdDeleteMR, + mrEntry ); + } + } + + CleanupStack::PopAndDestroy( taskExtension ); + CleanupStack::PopAndDestroy( entryProcessor ); + CleanupStack::PopAndDestroy( taskFactory ); + } + +// End of File