meetingrequest/mrprocessor/mrcaleventplugin/src/cmrcalentry.cpp
branchRCL_3
changeset 12 4ce476e64c59
child 16 b5fbb9b25d57
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrprocessor/mrcaleventplugin/src/cmrcalentry.cpp	Wed Mar 31 21:08:33 2010 +0300
@@ -0,0 +1,1534 @@
+/*
+* Copyright (c) 2007-2008 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:  Calendar Entry wrapper implementation
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "cmrcalentry.h"
+#include "esmrhelper.h"
+
+#include "cesmrrecurrenceinfohandler.h"
+#include "cesmralarminfohandler.h"
+#include "tesmralarminfo.h"
+#include "cesmrcaluserutil.h"
+#include "cesmrcaldbmgr.h"
+#include "esmrentryhelper.h"
+#include "cesmrconflictchecker.h"
+
+#include <mrcaleventdata.rsg>
+#include <coemain.h>
+#include <e32std.h>
+#include <aknutils.h>
+#include <data_caging_path_literals.hrh>
+#include <centralrepository.h>
+#include <calentry.h>
+#include <calattachment.h>
+#include <calalarm.h>
+#include <calrrule.h>
+#include <calinstance.h>
+#include <calinstanceview.h>
+#include <caleninterimutils2.h>
+
+#include <calendarinternalcrkeys.h>
+#include <ct/rcpointerarray.h>
+
+#include <calenservices.h>
+
+#include "emailtrace.h"
+
+namespace { // codescanner::namespace
+
+const TInt KHoursInDay( 24 );
+const TInt KDefaultTodoAlarmHours( 12 );
+const TInt KDefaultAnniversaryAlarmHours( 12 );
+
+// Definition for max hours, minutes, seconds in day for To-Do
+const TInt KMaxHoursForTodo( 23 );
+const TInt KMaxMinutesForTodo( 59 );
+const TInt KMaxSecondsForTodo( 00 );
+
+// Definition for max hours, minutes, seconds in day for Memo
+const TInt KMaxHoursForMemo( 23 );
+const TInt KMaxMinutesForMemo( 59 );
+const TInt KMaxSecondsForMemo( 59 );
+
+// Definition for default alarm time for meeting
+const TInt KDefaultMeetingAlarmMinutes( 15 );
+
+// Definitions for alarm information resource file
+_LIT( KAlarmInfoResource, "mrcaleventdata.rsc" );
+
+#ifdef _DEBUG
+
+// Definition for panic text
+_LIT( KBCCalEntryPanicTxt, "MRCalEntry" );
+
+enum TBCCalEntryPanic
+    {
+    EBCCalEntryNotExist = 1, // Entry does not exist
+    };
+
+// ---------------------------------------------------------------------------
+// Raises panic.
+// ---------------------------------------------------------------------------
+//
+void Panic(TBCCalEntryPanic aPanic)
+    {
+    User::Panic( KBCCalEntryPanicTxt, aPanic);
+    }
+
+#endif // _DEBUG
+
+}  // namespace
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::CMRCalEntry
+// ---------------------------------------------------------------------------
+//
+CMRCalEntry::CMRCalEntry(
+        MESMRCalDbMgr& aCalDb  )
+:   iCalDb( aCalDb )
+    {
+    FUNC_LOG;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::~CMRCalEntry
+// ---------------------------------------------------------------------------
+//
+CMRCalEntry::~CMRCalEntry()
+    {
+    FUNC_LOG;
+    delete iEntry;
+    delete iOriginalEntry;
+    delete iComparativeEntry;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::NewL
+// ---------------------------------------------------------------------------
+//
+CMRCalEntry* CMRCalEntry::NewL(
+        CCalEntry& aEntry,
+        MESMRCalDbMgr& aCalDb )
+    {
+    FUNC_LOG;
+    
+    CMRCalEntry* self = new (ELeave) CMRCalEntry( aCalDb );
+    CleanupStack::PushL( self );
+    self->ConstructL( aEntry );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::ConstructL(
+        CCalEntry& aEntry )
+    {
+    FUNC_LOG;
+    iOriginalEntry = CreateCopyL( aEntry );
+    
+    // Create the entry for editing:
+    iEntry = CreateCopyL( *iOriginalEntry );   
+    
+    // Create copy of initialized entry for 
+    // comparing purposes e.g. IsEntryEdited.
+    iComparativeEntry = CreateCopyL( *iEntry );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::CreateCopyL
+//
+CCalEntry* CMRCalEntry::CreateCopyL( CCalEntry& aSourceEntry )
+    {
+    FUNC_LOG;
+    CCalEntry* entry = 
+        ESMRHelper::CopyEntryL(
+                aSourceEntry,
+                aSourceEntry.MethodL(),
+                ESMRHelper::ECopyFull );
+
+    return entry;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::Type
+// ---------------------------------------------------------------------------
+//
+MESMRCalEntry::TESMRCalEntryType CMRCalEntry::Type() const
+    {
+    FUNC_LOG;
+    
+    MESMRCalEntry::TESMRCalEntryType type( EESMRCalEntryNotSupported );
+
+    CCalEntry::TType entryType( CCalEntry::EAppt );
+
+    TRAP_IGNORE( {
+                 entryType = DoGetEntry()->EntryTypeL();
+                 } );
+
+    switch ( entryType )
+        {
+        case CCalEntry::EAppt:
+            {
+            type = EESMRCalEntryMeeting;
+            break;
+            }
+        case CCalEntry::ETodo:
+            {
+            type = EESMRCalEntryTodo;
+            break;
+            }
+        case CCalEntry::EEvent:
+            {
+            type = EESMRCalEntryMemo;
+            break;
+            }
+        case CCalEntry::EReminder:
+            {
+            type = EESMRCalEntryReminder;
+            break;
+            }
+        case CCalEntry::EAnniv:
+            {
+            type = EESMRCalEntryAnniversary;
+            break;
+            }
+        default:
+            break;
+        }
+
+    return type;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::MESMRCalEntryRef
+// ---------------------------------------------------------------------------
+//
+MESMRCalEntry& CMRCalEntry::MESMRCalEntryRef()
+    {
+    FUNC_LOG;
+    return *this;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::MESMRCalEntryRef
+// ---------------------------------------------------------------------------
+//
+const MESMRCalEntry& CMRCalEntry::MESMRCalEntryRef() const
+    {
+    FUNC_LOG;
+    return *this;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::Entry
+// ---------------------------------------------------------------------------
+//
+const CCalEntry& CMRCalEntry::Entry() const
+    {
+    FUNC_LOG;
+    return *DoGetEntry();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::Entry
+// ---------------------------------------------------------------------------
+//
+CCalEntry& CMRCalEntry::Entry()
+    {
+    FUNC_LOG;
+    return *DoGetEntry();
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::InstanceL
+// ---------------------------------------------------------------------------
+//
+CCalInstance* CMRCalEntry::InstanceL() const
+    {
+    FUNC_LOG;
+
+    CCalInstance* instance = NULL;
+
+    instance = iCalDb.FindInstanceL( *DoGetEntry() );
+    if ( !instance )
+        {
+        // Instance not found by using the edited entry
+        // Trying with orginal.
+        instance = iCalDb.FindInstanceL( *iComparativeEntry );
+        }
+
+    if ( !instance )
+        {
+        // Instance not found by using edited or orginal entry.
+        // --> Leave
+        User::Leave( KErrNotFound );
+        }
+
+    return instance;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::CanSetRecurrenceL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::CanSetRecurrenceL() const
+    {
+    FUNC_LOG;
+    
+    TBool canSetRecurrence( ETrue );
+    
+    if ( DoGetEntry()->EntryTypeL() == CCalEntry::EAppt &&
+         IsRepeatingMeetingL(*iEntry) &&
+        (!ESMREntryHelper::IsModifyingEntryL(*iEntry) &&
+          MESMRCalEntry::EESMRThisOnly == iRecurrenceModRule ))
+        {
+        canSetRecurrence = EFalse;
+        }
+    
+    return canSetRecurrence;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::GetRecurrenceL(
+        TESMRRecurrenceValue& aRecurrence,
+        TTime& aUntil ) const
+    {
+    FUNC_LOG;
+    
+    CESMRRecurrenceInfoHandler* recurrenceHandler =
+    		CESMRRecurrenceInfoHandler::NewLC( *DoGetEntry() );
+    
+    recurrenceHandler->GetRecurrenceL( aRecurrence, aUntil );
+    CleanupStack::PopAndDestroy( recurrenceHandler );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsAllDayEventL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsAllDayEventL() const
+    {
+    FUNC_LOG;
+    
+    TBool allDayEvent(EFalse);
+
+    CCalEntry::TType entryType = DoGetEntry()->EntryTypeL();
+    
+    if ( (CCalEntry::EAppt == entryType) || 
+         (CCalEntry::EEvent == entryType) )        
+    	{    
+	    TCalTime startTime = iEntry->StartTimeL();
+	    TCalTime stopTime  = iEntry->EndTimeL();
+	
+	    TTimeIntervalHours hoursBetweenStartAndEnd;
+	    stopTime.TimeLocalL().HoursFrom(
+	            startTime.TimeLocalL(),
+	            hoursBetweenStartAndEnd );
+	
+	    TCalTime::TTimeMode mode = startTime.TimeMode();
+	
+	    TInt hoursBetweenStartAndEndAsInt( hoursBetweenStartAndEnd.Int() );
+	    TInt alldayDivident( hoursBetweenStartAndEndAsInt % KHoursInDay );
+	
+	    if ( hoursBetweenStartAndEndAsInt && 0 == alldayDivident )
+	        {
+	        TDateTime startTimeLocal = startTime.TimeLocalL().DateTime();
+	        TDateTime stopTimeLocal =  stopTime.TimeLocalL().DateTime();
+	
+            if ( startTimeLocal.Hour() == 0 &&
+	             startTimeLocal.Minute() == 0 && 
+	             startTimeLocal.Minute() == stopTimeLocal.Minute() && 
+	        	 startTimeLocal.Second() == 0 && 
+	        	 startTimeLocal.Second() == stopTimeLocal.Second() )
+	            {
+	            allDayEvent = ETrue;
+	            }
+	        }
+    	}
+
+    return allDayEvent;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetRecurrenceL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetRecurrenceL(
+        TESMRRecurrenceValue aRecurrence,
+        TTime aUntil )
+    {
+    FUNC_LOG;
+    // Check if this entry's recurrence can be edited
+    
+    if ( !CanSetRecurrenceL() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+
+    CESMRRecurrenceInfoHandler* recurrenceHandler =
+            CESMRRecurrenceInfoHandler::NewLC( *DoGetEntry() );
+
+    recurrenceHandler->SetRecurrenceL( aRecurrence, aUntil );
+    CleanupStack::PopAndDestroy( recurrenceHandler );
+
+    iRecurrenceModRule = MESMRCalEntry::EESMRAllInSeries;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetAllDayEventL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetAllDayEventL( TTime aStartDate, TTime aEndDate)
+    {
+    FUNC_LOG;
+    TCalTime startTime;
+    TCalTime stopTime;
+
+    TDateTime start;
+    TDateTime end;
+
+    // set the start time to 0:00
+    start.Set( aStartDate.DateTime().Year(),
+               aStartDate.DateTime().Month(),
+               aStartDate.DateTime().Day(),
+               0,
+               0,
+               0,
+               0);
+
+    // set the end date to next day from given end date since
+    // all day event should last 24 hours.
+    aEndDate += TTimeIntervalDays( 1 );
+
+    end.Set( aEndDate.DateTime().Year(),
+             aEndDate.DateTime().Month(),
+             aEndDate.DateTime().Day(),
+             0,
+             0,
+             0,
+             0);
+
+    startTime.SetTimeLocalL( start );
+    stopTime.SetTimeLocalL( end );
+
+    DoGetEntry()->SetStartAndEndTimeL( startTime, stopTime );
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsStoredL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsStoredL() const
+    {
+    FUNC_LOG;
+
+    __ASSERT_DEBUG( iEntry, Panic(EBCCalEntryNotExist ) );
+
+    TBool ret(EFalse);
+    CCalEntry* dbEntry = NULL;
+    
+    TRAPD( err, dbEntry = iCalDb.FetchEntryL(
+                                iEntry->UidL(),
+                                iEntry->RecurrenceIdL() ) );
+    
+    if ( KErrNotFound == err )
+        {
+        // Error has occured while retrieving an entry        
+        ret = EFalse;
+        }    
+    else if ( dbEntry)
+        {
+        // Entry was found from the calendar db --> it is stored for sure.
+        ret = ETrue;
+        }
+
+    delete dbEntry;
+
+    return ret;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsEntryEditedL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsEntryEditedL() const
+    {
+    FUNC_LOG;
+    
+    TBool isSame(ETrue);    
+    
+    // The compare entry has not been created yet; so 
+    // entry has not changed. 
+    if ( iComparativeEntry )
+        {
+        isSame = iComparativeEntry->CompareL( *DoGetEntry() );
+
+        // CCalEntry's CompareL doesn't check the priority value:
+        if ( isSame && iEntry->PriorityL() != iComparativeEntry->PriorityL() )
+            {
+            isSame = EFalse;
+            }
+        else if ( iEntry->DescriptionL() != iComparativeEntry->DescriptionL() )
+            {
+            isSame = EFalse;
+            }
+        else if ( iEntry->LocationL() != iComparativeEntry->LocationL() )
+            {
+            isSame = EFalse;
+            }
+        else if ( iEntry->ReplicationStatusL() != iComparativeEntry->ReplicationStatusL() )
+            {
+            isSame = EFalse;
+            }
+        
+        if ( IsStoredL() )
+            if ( iCalDb.EntryViewL( *iEntry ) != iCalDb.EntryView() )
+                {
+                isSame = EFalse;
+                }
+        }
+
+    
+    
+    return !isSame;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsRecurrentEventL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsRecurrentEventL() const
+    {
+    FUNC_LOG;
+    if ( DoGetEntry()->EntryTypeL() != CCalEntry::EAppt )
+        {
+        return EFalse;
+        }
+
+    TBool recurrenceEvent( EFalse );
+    if ( IsStoredL() )
+        {
+        // Entry is stored in calendar db
+        // Lets look recurrence using instance
+
+        // Ownership is transferred
+        CCalInstance* instance = NULL;
+        TRAPD(err, instance = InstanceL() );
+        if ( KErrNotFound != err )
+            {
+            User::LeaveIfError( err );
+            }
+
+        if ( instance )
+            {
+            CleanupStack::PushL( instance );
+
+            CCalEntry& instanceParentEntry = instance->Entry();
+
+            if ( IsRepeatingMeetingL( instanceParentEntry ) )
+                {
+                recurrenceEvent = ETrue;
+                }
+            CleanupStack::PopAndDestroy( instance );
+            }
+        else
+            {
+            if ( IsRepeatingMeetingL( *iEntry ) )
+                {
+                recurrenceEvent = ETrue;
+                }
+            }
+        }
+    else
+        {
+        // Entry is not stored in calendar db
+        if ( IsRepeatingMeetingL( *iEntry ) )
+            {
+            // This is repeating meeting
+            recurrenceEvent = ETrue;
+            }
+        }
+    
+    return recurrenceEvent;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::IsEntryTypeChangedL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsEntryTypeChangedL() const
+    {
+    FUNC_LOG;
+    
+    return iTypeChanged;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetModifyingRuleL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetModifyingRuleL( TESMRRecurrenceModifyingRule aRule, 
+		const TBool aTypeChanging )
+    {
+    FUNC_LOG;
+    
+    CESMRRecurrenceInfoHandler* recHandler =
+            CESMRRecurrenceInfoHandler::NewL( *iComparativeEntry );
+    CleanupStack::PushL( recHandler );
+
+    TESMRRecurrenceValue orginalRecurrence;
+    TTime orginalUntil;
+
+    recHandler->GetRecurrenceL(
+            orginalRecurrence,
+            orginalUntil);
+    CleanupStack::PopAndDestroy( recHandler );
+    recHandler = NULL;    
+
+    TBool modifyingEntry( ESMREntryHelper::IsModifyingEntryL( *DoGetEntry() ) );
+    
+    if ( MESMRCalEntry::EESMRAllInSeries == aRule && IsStoredL() && !aTypeChanging)
+        {
+        // When we want to modify series of recurrence entries -->
+        // Parent entry is modified
+        if ( ERecurrenceNot == orginalRecurrence && !modifyingEntry )
+            {
+            // Orginal entry was not recurrent event
+            // No need to fect instance at all
+            // For modifying entries we need to fetch the original parent entry
+            iRecurrenceModRule = aRule;
+            return;
+            }
+
+        CCalInstance* instance = NULL;
+        TRAPD(err, instance = InstanceL() );
+        if( KErrNotFound != err )
+            {
+            User::LeaveIfError( err );
+            }
+
+        if ( instance )
+            {
+            CleanupStack::PushL( instance );
+
+            CCalEntry::TMethod entryMethod( iEntry->MethodL() );
+           
+            delete iEntry; 
+            iEntry = NULL;
+            
+            delete iComparativeEntry; 
+            iComparativeEntry = NULL;
+
+            RCPointerArray<CCalEntry> entries;
+            CleanupClosePushL( entries );
+
+            iCalDb.EntryViewL( instance->Entry() )->FetchL(
+                    instance->Entry().UidL(), entries );
+
+            TInt parentIndex( KErrNotFound );
+            TInt entryCount( entries.Count() );            
+            for ( TInt i(0); i < entryCount && KErrNotFound == parentIndex; ++i )
+                {
+                TBool modifyingEntry( ESMREntryHelper::IsModifyingEntryL( *entries[i]) );
+                if ( !modifyingEntry )
+                    {
+                    parentIndex = i;
+                    }
+                }
+            
+            CCalEntry& parent = *entries[parentIndex];
+
+            TPtrC description( parent.DescriptionL() );
+            
+            iEntry = CreateCopyL( parent );
+            
+            // Adjust parent entry's start and end time to entry
+            TCalTime start;
+            TCalTime end;
+
+            CESMRRecurrenceInfoHandler* recurrenceHandler =
+                    CESMRRecurrenceInfoHandler::NewLC( parent );
+
+            recurrenceHandler->GetFirstInstanceTimeL( start, end );
+            CleanupStack::PopAndDestroy( recurrenceHandler );
+            recurrenceHandler = NULL;
+
+            iEntry->SetStartAndEndTimeL( start, end );
+
+            iComparativeEntry = CreateCopyL( *iEntry );
+
+            iEntry->SetDescriptionL( description );
+            iComparativeEntry->SetDescriptionL( description );
+            
+            CleanupStack::PopAndDestroy(); // entries
+            CleanupStack::PopAndDestroy( instance );
+            }
+        }
+    else if ( ERecurrenceNot != orginalRecurrence && 
+    		aTypeChanging && !modifyingEntry )
+    	{
+		// if entry( in the memory) is a recurrent event 
+		// ,and if entry type is changing, and not in modifying status then EESMRAllInSeries
+		iRecurrenceModRule = EESMRAllInSeries ;
+		return;
+    	}
+    
+
+    iRecurrenceModRule = aRule;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::RecurrenceModRule
+// ---------------------------------------------------------------------------
+//
+MESMRCalEntry::TESMRRecurrenceModifyingRule 
+        CMRCalEntry::RecurrenceModRule() const
+    {
+    FUNC_LOG;
+    return iRecurrenceModRule;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetAlarmL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::GetAlarmL(TESMRAlarmType& aAlarmType, TTime &aAlarmTime )
+    {
+    FUNC_LOG;
+    
+    aAlarmType = MESMRCalEntry::EESMRAlarmNotFound;
+    aAlarmTime = Time::NullTTime();
+
+    TFileName alarmInfoResource;
+    ESMRHelper::LocateResourceFile(
+            KAlarmInfoResource,
+            KDC_RESOURCE_FILES_DIR,
+            alarmInfoResource);
+
+    CESMRAlarmInfoHandler* alarmInfoHandler =
+    		CESMRAlarmInfoHandler::NewLC();
+
+    alarmInfoHandler->ReadFromResourceL(
+            alarmInfoResource,
+            MRCALEVENT_ALARM_INFO_TABLE );
+
+    TRAPD( err,
+            alarmInfoHandler->GetAbsoluteAlarmTimeL(*DoGetEntry(), aAlarmTime) );
+
+    if ( KErrNone == err )
+        {
+        aAlarmType = MESMRCalEntry::EESMRAlarmAbsolute;
+
+        // only meeting that is not allday event can have relative alarm:
+        if ( Type() == EESMRCalEntryMeeting && !IsAllDayEventL() )
+            {
+            TESMRAlarmInfo alarmInfo;
+            TRAP( err,
+                  alarmInfoHandler->GetAlarmInfoObjectL(*iEntry, alarmInfo) );
+
+            if ( KErrNone == err )
+                {
+                aAlarmType = MESMRCalEntry::EESMRAlarmRelative;
+                if( alarmInfo.iRelativeAlarmInSeconds < 0 )
+                    {
+                    aAlarmType = MESMRCalEntry::EESMRAlarmNotFound;
+                    }
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy( alarmInfoHandler );
+    alarmInfoHandler = NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::OriginalEntry
+// ---------------------------------------------------------------------------
+//
+const CCalEntry& CMRCalEntry::OriginalEntry()
+    {
+    FUNC_LOG;
+    return *iComparativeEntry;
+    }
+
+
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::IsRepeatingMeetingL
+// ----------------------------------------------------------------------------
+//
+TBool CMRCalEntry::IsRepeatingMeetingL(const CCalEntry& aEntry) const
+    {
+    FUNC_LOG;
+    TBool retVal( EFalse );
+
+    if ( ESMREntryHelper::IsModifyingEntryL(aEntry) )
+        {
+        retVal = ETrue;
+        }
+    else
+        {
+        TCalRRule dummyRule;
+        if ( aEntry.GetRRuleL( dummyRule ) )
+            {
+            retVal = ETrue;
+            }
+        else
+            {
+            RArray<TCalTime> dummyRDateList;
+            CleanupClosePushL( dummyRDateList );
+            aEntry.GetRDatesL( dummyRDateList );
+            if ( dummyRDateList.Count() > 0 )
+                {
+                retVal = ETrue;
+                }
+            CleanupStack::PopAndDestroy(); // dummyRDateList
+            }
+        }
+
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetPriorityL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetPriorityL ( TUint aPriority )
+    {
+    FUNC_LOG;
+    DoGetEntry()->SetPriorityL( aPriority );
+    }
+
+// ---------------------------------------------------------------------------
+// CESMRMeetingRequestEntry::GetPriorityL
+// ---------------------------------------------------------------------------
+//
+TUint CMRCalEntry::GetPriorityL() const
+    {
+    FUNC_LOG;
+    TUint entryPriority = DoGetEntry()->PriorityL();
+
+    if ( iEntry->EntryTypeL() == CCalEntry::ETodo )
+        {
+        if ( entryPriority != EFSCalenTodoPriorityLow &&
+             entryPriority != EFSCalenTodoPriorityNormal &&
+             entryPriority != EFSCalenTodoPriorityHigh )
+             {
+             entryPriority = EFSCalenTodoPriorityNormal;
+             }
+        }
+    else
+        { 
+        if ( entryPriority != EFSCalenMRPriorityLow &&
+             entryPriority != EFSCalenMRPriorityNormal &&
+             entryPriority != EFSCalenMRPriorityHigh )
+             {
+             entryPriority = EFSCalenMRPriorityNormal;
+             }
+        }
+        
+    return entryPriority;
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::UpdateEntryAfterStoringL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::UpdateEntryAfterStoringL()
+    {
+    FUNC_LOG;
+
+    __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+    CCalEntry* storedEntry = NULL;
+        
+    if ( IsRecurrentEventL() &&
+         EESMRThisOnly == iRecurrenceModRule &&
+         IsStoredL() && !ESMREntryHelper::IsModifyingEntryL(*iEntry) )
+        {
+        // We have stored one instance of series. 
+        storedEntry = iCalDb.FetchEntryL( 
+                    iEntry->UidL(), 
+                    iComparativeEntry->StartTimeL() );        
+        }
+    else
+        {
+        // We are dealing with single instance or with the series
+        storedEntry = iCalDb.FetchEntryL( 
+                    iEntry->UidL(), 
+                    iEntry->RecurrenceIdL() );
+        }
+    
+    __ASSERT_DEBUG( storedEntry, Panic( EBCCalEntryNotExist ) );
+    CleanupStack::PushL( storedEntry );
+    
+    // Description needs to be fecthed explicitly into memory
+    TPtrC description( storedEntry->DescriptionL() );                
+    
+    delete iEntry;
+    iEntry = NULL;
+    iEntry = CreateCopyL(*storedEntry);
+        
+    if ( MESMRCalEntry::EESMRAllInSeries == iRecurrenceModRule && 
+         IsRecurrentEventL() )
+        {
+        // Adjust parent entry's start and end time to entry
+        TCalTime start;
+        TCalTime end;
+
+        CESMRRecurrenceInfoHandler* recurrenceHandler =
+                CESMRRecurrenceInfoHandler::NewLC( *iEntry );
+
+        recurrenceHandler->GetFirstInstanceTimeL( start, end );
+        CleanupStack::PopAndDestroy( recurrenceHandler );
+        recurrenceHandler = NULL;
+
+        iEntry->SetStartAndEndTimeL( start, end );
+        iEntry->SetDescriptionL( description );
+        }
+    
+    CCalEntry* temp  = CreateCopyL( *iEntry );
+     
+    delete iComparativeEntry;
+    iComparativeEntry = temp;
+    
+    CleanupStack::PopAndDestroy( storedEntry );
+    }
+    
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesToEntryL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesToEntryL()
+    {
+    FUNC_LOG;
+    
+    if ( !IsStoredL() )
+        {
+        // by default when creating a meeting the priority
+        // value is normal
+        switch ( DoGetEntry()->EntryTypeL() )
+            {
+            case CCalEntry::ETodo:
+                {
+                SetDefaultValuesForTodoL();
+                }
+                break;
+            case CCalEntry::EEvent: // Memo
+                {
+                SetDefaultValuesForMemoL();
+                }
+                break;
+            case CCalEntry::EAppt:
+                {
+                SetDefaultValuesForMeetingL();
+                }
+                break;
+            case CCalEntry::EAnniv:
+            default:
+                {
+                SetDefaultValuesForAnniversaryL();
+                }
+                break;
+            }
+        iEntry->SetReplicationStatusL( CCalEntry::EOpen );
+
+        // Entry has now been set up with default values; 
+        // Let's update comparative entry
+        delete iComparativeEntry;
+        iComparativeEntry = NULL;
+        
+        iComparativeEntry = CreateCopyL( *iEntry ); 
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::UpdateTimeStampL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::UpdateTimeStampL()
+    {
+    FUNC_LOG;
+    
+    ASSERT( iEntry );
+    
+    TTime currentUTCTime;
+    currentUTCTime.UniversalTime();
+
+    TCalTime currentTime;
+    currentTime.SetTimeUtcL( currentUTCTime );
+
+    iEntry->SetDTStampL( currentTime );    
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::CloneEntryLC
+// ----------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::CloneEntryLC( TESMRCalEntryType aType ) const
+    {
+    CCalEntry* entry = ESMRHelper::CopyEntryLC(
+            *DoGetEntry(),
+            iEntry->MethodL(),
+            ESMRHelper::ECopyFull,
+            TESMRCalendarEventType( aType ) );
+        
+    return entry;
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::UpdateComparativeEntry
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::UpdateComparativeEntry( CCalEntry* aNewComparativeEntry )
+    {
+    FUNC_LOG;
+    if( iComparativeEntry )
+        {
+        delete iComparativeEntry;
+        iComparativeEntry = NULL;
+        
+        iComparativeEntry = aNewComparativeEntry;
+        }
+    
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForTodoL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForTodoL()
+    {
+    FUNC_LOG;
+    
+    SetPriorityL( EFSCalenTodoPriorityNormal );
+    
+    // Update event time
+    TDateTime start = iEntry->StartTimeL().TimeLocalL().DateTime();
+    start.SetHour( KMaxHoursForTodo );
+    start.SetMinute( KMaxMinutesForTodo );
+    start.SetSecond( KMaxSecondsForTodo );
+    
+    TCalTime dueTime;
+    dueTime.SetTimeLocalL( start );
+    iEntry->SetStartAndEndTimeL( dueTime, dueTime );
+    
+    // Create default alarm
+    TTime eventTime = iEntry->EndTimeL().TimeLocalL();
+    
+    // Calculate alarm time (due date at 12:00am)
+    TTime alarmTime = eventTime;
+    TDateTime alarmDateTime = alarmTime.DateTime();
+    alarmDateTime.SetHour( KDefaultTodoAlarmHours );
+    alarmDateTime.SetMinute( 0 );
+    alarmDateTime.SetSecond( 0 );
+    alarmDateTime.SetMicroSecond( 0 );
+    alarmTime = alarmDateTime;
+    
+    TTime currentTime;
+    currentTime.HomeTime();
+    
+    if ( alarmTime > currentTime )
+        {
+        CCalAlarm* alarm = CCalAlarm::NewL();
+        CleanupStack::PushL( alarm );
+        TTimeIntervalMinutes alarmOffset( 0 );
+        eventTime.MinutesFrom( alarmTime, alarmOffset );
+        alarm->SetTimeOffset( alarmOffset );
+        iEntry->SetAlarmL( alarm );
+        CleanupStack::PopAndDestroy( alarm );
+        }    
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForMemoL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForMemoL()
+    {
+    FUNC_LOG;
+
+    SetPriorityL( EFSCalenMRPriorityNormal );
+    
+    // Update event time
+    TDateTime start = iEntry->StartTimeL().TimeLocalL().DateTime();
+    start.SetHour( 0 );
+    start.SetMinute( 0 );
+    start.SetSecond( 0 );
+        
+    TDateTime end = iEntry->EndTimeL().TimeLocalL().DateTime();
+    end.SetHour( KMaxHoursForMemo );
+    end.SetMinute( KMaxMinutesForMemo );
+    end.SetSecond( KMaxSecondsForMemo );
+    
+    TCalTime startTime;
+    startTime.SetTimeLocalL( start );
+    TCalTime endTime;
+    endTime.SetTimeLocalL( end );
+
+    iEntry->SetStartAndEndTimeL( startTime, endTime );    
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForMeetingL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForMeetingL()
+    {
+    FUNC_LOG;
+    
+    SetPriorityL( EFSCalenMRPriorityNormal );
+    
+    // Get default alarm time from central repository
+    TInt defaultAlarmTime;
+    CRepository* repository = CRepository::NewLC( TUid::Uid(0x101F874B) /*KCRUidCalendar*/ );
+    TInt err = repository->Get( KCalendarDefaultAlarmTime, defaultAlarmTime );
+    CleanupStack::PopAndDestroy( repository );
+    
+    if ( err != KErrNone )
+        {
+        defaultAlarmTime = KDefaultMeetingAlarmMinutes;
+        }
+    
+    // Getting current time
+    TTime currentTime;
+    currentTime.HomeTime();
+    
+    // Getting meeting start time
+    TTime start = iEntry->StartTimeL().TimeLocalL();
+   
+    // Create default alarm
+    CCalAlarm* alarm = CCalAlarm::NewL();
+    CleanupStack::PushL( alarm );
+    
+    TTimeIntervalMinutes alarmOffset( defaultAlarmTime );
+    
+    // If alarm time is in past
+    if ( ( start - alarmOffset ) < currentTime )
+        {
+        // Setting alarm off
+        iEntry->SetAlarmL( NULL );
+        }
+    else
+        {
+        // Set default alarm time
+        alarm->SetTimeOffset( alarmOffset );
+        iEntry->SetAlarmL( alarm );
+        }
+    CleanupStack::PopAndDestroy( alarm );   
+    
+    if ( iEntry->StartTimeL().TimeUtcL() == iEntry->EndTimeL().TimeUtcL() )
+        {
+        // Should this value be read from cenrep?
+        TTimeIntervalHours KDefaultMeetingDuration(1);
+
+        TCalTime newEndTime;
+        newEndTime.SetTimeUtcL(
+                iEntry->StartTimeL().TimeUtcL() + KDefaultMeetingDuration );
+        iEntry->SetStartAndEndTimeL(iEntry->StartTimeL(), newEndTime);        
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::SetDefaultValuesForAnniversaryL
+// ----------------------------------------------------------------------------
+//
+void CMRCalEntry::SetDefaultValuesForAnniversaryL()
+    {
+    FUNC_LOG;
+
+    SetPriorityL( EFSCalenMRPriorityNormal );
+
+    // Getting event time
+    TTime eventTime = iEntry->StartTimeL().TimeLocalL();
+    
+    // Setting default alarm parameters to previous day at noon
+    TTime alarmTime = eventTime - TTimeIntervalDays( 1 );
+    TDateTime alarmDateTime = alarmTime.DateTime(); 
+    alarmDateTime.SetHour( KDefaultAnniversaryAlarmHours );
+    alarmDateTime.SetMinute( 0 );
+    alarmDateTime.SetSecond( 0 );
+    alarmDateTime.SetMicroSecond( 0 );
+    alarmTime = alarmDateTime;
+    
+    // Calculating alarm offset
+    TTimeIntervalMinutes alarmOffset( 0 );
+    eventTime.MinutesFrom( alarmTime, alarmOffset );
+    
+    // Creating alarm
+    CCalAlarm* alarm = CCalAlarm::NewL();
+    CleanupStack::PushL( alarm );
+    alarm->SetTimeOffset( alarmOffset );
+
+    // Setting alarm
+    iEntry->SetAlarmL( alarm );
+    CleanupStack::PopAndDestroy( alarm );
+    alarm = NULL;    
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::DoGetEntry
+// ----------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::DoGetEntry() const
+    {
+    __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+    
+    return iEntry;
+    }
+
+// ----------------------------------------------------------------------------
+// CMRCalEntry::ValidateEntryL
+// ----------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::ValidateEntryL()
+    {
+    FUNC_LOG;
+    
+    CCalEntry* entry = NULL;
+
+    MESMRCalEntry::TESMRCalEntryType entryType = Type();
+    switch ( entryType )
+       {
+       case EESMRCalEntryMeeting:
+           {
+           entry = ValidateMeetingL();
+           }
+           break;
+       
+       case EESMRCalEntryAnniversary:
+           {
+           entry = CreateCopyL( *iEntry );
+           CleanupStack::PushL( entry );
+
+           // Special check for anniversary: Occurancy must be set to yearly
+           // for new entries
+           if ( ( entry->EntryTypeL() == CCalEntry::EAnniv ) && 
+                   !IsStoredL() &&
+                       !IsRecurrentEventL() )
+               {
+               TCalRRule rrule( TCalRRule::EYearly );
+               rrule.SetDtStart( Entry().StartTimeL() );
+               rrule.SetInterval( 1 );
+               rrule.SetCount( 0 );
+               entry->SetRRuleL( rrule );
+               }
+          
+           CleanupStack::Pop( entry ); //Ownership given to caller
+           }
+           break;
+           
+       case EESMRCalEntryTodo: // flow through 
+       case EESMRCalEntryMemo: // flow through 
+       case EESMRCalEntryReminder:
+           {
+           entry = CreateCopyL( *iEntry );
+           }
+           break;
+       default:
+           // This should not occur
+           User::Leave( KErrArgument );
+           break;
+       }
+    
+    return entry;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::RemoveInstanceFromSeriesL
+// ---------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::RemoveInstanceFromSeriesL()
+    {
+    FUNC_LOG;
+
+    CCalEntry* retEntry = NULL;
+
+    if ( IsRecurrentEventL() &&
+            EESMRThisOnly == iRecurrenceModRule )
+       {
+       CCalInstance* instance = NULL;
+       TRAPD( err, instance = InstanceL() );
+       if( KErrNotFound != err )
+           {
+           User::LeaveIfError( err );
+           }
+
+       if ( instance )
+           {
+           CleanupStack::PushL( instance );
+
+           CCalEntry& parentEntry = instance->Entry();
+           retEntry = ESMRHelper::CopyEntryL(
+                    parentEntry,
+                    parentEntry.MethodL(),
+                    ESMRHelper::ECopyFull );
+
+           CleanupStack::PopAndDestroy( instance );
+           instance = NULL;
+
+           CleanupStack::PushL( retEntry );
+
+           CESMRRecurrenceInfoHandler* recurrenceHandler =
+                    CESMRRecurrenceInfoHandler::NewLC( *retEntry );
+
+           TCalTime orginalInstanceTime;
+           orginalInstanceTime.SetTimeUtcL(
+                    iEntry->StartTimeL().TimeUtcL() );
+
+           recurrenceHandler->RemoveInstanceL( orginalInstanceTime );
+
+           CleanupStack::PopAndDestroy( recurrenceHandler );
+           CleanupStack::Pop( retEntry );
+           }
+       }
+    else
+       {
+       User::Leave( KErrNotSupported );
+       }
+
+    return retEntry;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetDBMgr
+// ---------------------------------------------------------------------------
+//
+MESMRCalDbMgr& CMRCalEntry::GetDBMgr()
+    {
+    return iCalDb;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SupportsCapabilityL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::SupportsCapabilityL( 
+        MESMRCalEntry::TMREntryCapability aCapability ) const
+    {
+    FUNC_LOG;
+    
+    TBool retValue( EFalse );
+    
+    if ( aCapability == MESMRCalEntry::EMRCapabilityAttachments )
+        {
+        retValue = ETrue;
+        }
+    
+    return retValue;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::ContainsRemoteAttachmentsL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::ContainsRemoteAttachmentsL()
+    {
+    FUNC_LOG;
+    
+    TBool retValue( EFalse );
+    
+    TInt attachmentCount( iEntry->AttachmentCountL() );
+    
+    for ( TInt i(0); i < attachmentCount && !retValue; ++i )
+        {
+        CCalAttachment* attachment = iEntry->AttachmentL(i);        
+        CCalAttachment::TType type( attachment->Type() );
+        
+        if ( CCalAttachment::EFile != type )
+            {
+            retValue = ETrue;
+            }        
+        }
+    
+    return retValue;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::ValidateMeetingL
+// ---------------------------------------------------------------------------
+//
+CCalEntry* CMRCalEntry::ValidateMeetingL()
+    {
+    FUNC_LOG;
+    
+    CCalEntry* entry = NULL;
+    
+    if ( IsRecurrentEventL() &&
+         EESMRThisOnly == iRecurrenceModRule &&
+         IsStoredL() && 
+         !ESMREntryHelper::IsModifyingEntryL( *iEntry ) )
+        {
+        CCalInstance* instance = NULL;
+        TRAPD( err, instance = InstanceL() );
+        if( KErrNotFound != err )
+            {
+            User::LeaveIfError( err );
+            }
+
+        if ( instance )
+            {
+
+            CleanupStack::PushL( instance );
+            CCalEntry& parent = instance->Entry();
+
+            entry = iCalDb.FetchEntryL(
+                            parent.UidL(),
+                            iComparativeEntry->StartTimeL() );
+
+            if ( !entry )
+                {
+
+                // copy global UID from the original entry
+                HBufC8* guid = parent.UidL().AllocLC();
+
+                // create new (child) entry
+                entry = CCalEntry::NewL(
+                                parent.EntryTypeL(),
+                                guid,
+                                parent.MethodL(),
+                                0,
+                                iComparativeEntry->StartTimeL(),
+                                CalCommon::EThisOnly );
+
+                CleanupStack::Pop( guid ); 
+                guid = NULL; // ownership transferred
+                }
+
+            CleanupStack::PopAndDestroy( instance );  
+            instance = NULL; // instance
+            CleanupStack::PushL( entry );
+
+
+            CCalEntry::TMethod method( iEntry->MethodL() );
+
+            entry->CopyFromL( *iEntry, CCalEntry::EDontCopyId );
+            entry->SetSequenceNumberL( 0 );
+            entry->SetMethodL( method );
+            entry->SetSummaryL( iEntry->SummaryL() );
+            entry->SetLocalUidL( TCalLocalUid( 0 ) );
+            entry->ClearRepeatingPropertiesL();
+
+            CleanupStack::Pop( entry );
+            }
+        }
+
+    if ( !entry )
+        {
+        entry = CreateCopyL( *iEntry );
+        }
+    
+    return entry;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::SetTypeChanged
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::SetTypeChanged( TBool aTypeChanged )
+    {
+    FUNC_LOG;
+    
+    iTypeChanged = aTypeChanged;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::AnyInstancesBetweenTimePeriodL
+// ---------------------------------------------------------------------------
+//
+TBool CMRCalEntry::AnyInstancesBetweenTimePeriodL(
+            TTime& aStart,
+            TTime& aEnd )
+    {
+    FUNC_LOG;
+
+    __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+    TBool retValue( EFalse );
+
+    RCPointerArray<CCalEntry> entries;
+    CleanupClosePushL( entries );
+
+    CESMRConflictChecker* conflictCheckker =
+        CESMRConflictChecker::NewL( iCalDb );
+    CleanupStack::PushL( conflictCheckker );
+
+    CCalInstance* instance = InstanceL();
+    CleanupStack::PushL( instance );
+    
+    TCalCollectionId colId = instance->InstanceIdL().iCollectionId;
+    CleanupStack::PopAndDestroy( instance );
+    
+    conflictCheckker->FindInstancesForEntryL( aStart,
+                                              aEnd,
+                                              *iEntry,
+                                              colId, 
+                                              entries );
+
+    if ( entries.Count() )
+        {
+        retValue = ETrue;
+        }
+
+    CleanupStack::PopAndDestroy( conflictCheckker );
+    CleanupStack::PopAndDestroy(); // entries
+
+    return retValue;
+    }
+
+// ---------------------------------------------------------------------------
+// CMRCalEntry::GetFirstInstanceStartAndEndTimeL
+// ---------------------------------------------------------------------------
+//
+void CMRCalEntry::GetFirstInstanceStartAndEndTimeL(
+            TTime& aStart,
+            TTime& aEnd )
+    {
+    FUNC_LOG;
+
+    __ASSERT_DEBUG( iEntry, Panic( EBCCalEntryNotExist ) );
+
+    // This fetches the parent entry
+    TCalTime recurrenceId;
+    recurrenceId.SetTimeLocalL( Time::NullTTime() );
+    CCalEntry* parent = iCalDb.FetchEntryL(
+                iEntry->UidL(),
+                recurrenceId );
+
+    CleanupStack::PushL( parent );
+
+    aStart = parent->StartTimeL().TimeLocalL();
+    aEnd = parent->EndTimeL().TimeLocalL();
+
+    CleanupStack::PopAndDestroy( parent );
+    }
+
+// EOF