meetingrequest/mrviewer/src/cesmrviewerctrl.cpp
branchRCL_3
changeset 64 3533d4323edc
--- /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
+//<cmail>
+#include "emailtrace.h"
+#include "cesmrpolicy.h"
+#include "esmrdef.h"
+#include "cesmrpolicymanager.h"
+//</cmail>
+
+#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
+//<cmail>
+#include <CMRUtils.h>
+#include "esmrutilsapiext.h"
+//</cmail>
+#include <msvstd.h>
+#include <msvids.h>
+//<cmail>
+#include "FreestyleEmailUiConstants.h"
+//</cmail>
+#include <eikappui.h>
+#include <eikenv.h>
+#include <calentry.h>
+#include <CalenInterimUtils2.h>
+#include <calcommon.h>
+
+// 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<CCalEntry&>( 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<CCalEntry>& 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<CCalEntry>& 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<CMREntryProcessor*>(
+                iESMRUtils->ExtensionL(
+                        TUid::Uid(KESMRMREntryProcessorUid) ) );
+
+    iPolicyMgr =
+        static_cast<CESMRPolicyManager*>(
+                iESMRUtils->ExtensionL(
+                        TUid::Uid(KESMRPolicyMgrUid) ) );
+
+    iTaskExt =
+        static_cast<MESMRTaskExtension*>(
+                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;
+        }
+
+// <cmail>
+    if ( iCtrlSyncher &&
+            iCtrlSyncher->IsStarted() &&
+            iCtrlSyncher->CanStopNow() )
+// </cmail>
+        {
+        // 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<TESMRCommand>(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<TESMRCommand>(aCommandId);
+    TBool needToProcessOutputParams( ETrue );
+
+    MESMRCalEntry* tmpEntry = &iEntryProcessor->ESMREntryL();
+
+    ASSERT( tmpEntry->Type() == EESMREventTypeMeetingRequest );
+
+    if ( tmpEntry->Type() != EESMREventTypeMeetingRequest )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    MESMRMeetingRequestEntry& entry( *static_cast<MESMRMeetingRequestEntry*>( 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<CMREntryProcessor*>(
+                    iESMRUtils->ExtensionL(
+                            TUid::Uid( KESMRMREntryProcessorUid ) ) );
+
+    iPolicyMgr =
+        static_cast<CESMRPolicyManager*>(
+                iESMRUtils->ExtensionL(
+                        TUid::Uid( KESMRPolicyMgrUid ) ) );
+
+    iTaskExt =
+        static_cast<MESMRTaskExtension*>(
+                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<MEikCommandObserver*>( 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<MESMRMeetingRequestEntry&>( 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