diff -r d189ee25cf9d -r 3533d4323edc meetingrequest/mrentry/src/cesmrmeetingrequestentry.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/meetingrequest/mrentry/src/cesmrmeetingrequestentry.cpp Wed Sep 01 12:28:57 2010 +0100 @@ -0,0 +1,2372 @@ +/* +* 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 MR Entry implementation +* +*/ + + +// INCLUDE FILES +#include "cesmrmeetingrequestentry.h" +#include "cesmrfsmailboxutils.h" +#include "cesmrcaldbmgr.h" +#include "esmrhelper.h" +#include "esmrentryhelper.h" +#include "cesmrconflictchecker.h" +#include "cesmrcaluserutil.h" +#include "cesmralarminfohandler.h" +#include "cesmrrecurrenceinfohandler.h" +#include "mmrinfoobject.h" +#include "mmrattendee.h" + +#include "cfsmailmessage.h" + +#include "esmrconfig.hrh" +#include "cesmrfeaturesettings.h" + +#include "emailtrace.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/// Unnamed namespace for local definitions +namespace { + +// Alarm resource file location +_LIT( KAlarmInfoResource, "esmralarminfo.rsc" ); + +// Definition for default alarm time for meeting +const TInt KDefaultMeetingAlarmMinutes( 15 ); + +_LIT( KReplaceLineFeedChar, "\n" ); +_LIT( KLineFeed, "\x2029"); + +/** + * Sets phone owner to entry. + * @param aMbUtils Reference to mailbox utils. + * @param aEntry Reference to calendar entry. + */ +void SetPhoneOwnerL( + CMRMailboxUtils& aMbUtils, + CCalEntry& aEntry ) + { + CESMRFsMailboxUtils* fsMbUtils = + CESMRFsMailboxUtils::NewL( aMbUtils ); + CleanupStack::PushL( fsMbUtils ); + + fsMbUtils->SetPhoneOwnerL( aEntry ); + CleanupStack::PopAndDestroy( fsMbUtils ); + fsMbUtils = NULL; + } + +/** + * Makes copy of the entry and sets phone owner accordingly + * @param aMbUtils Reference to mailbox utils. + * @param aEntry Reference to calendar entry. + */ +CCalEntry* CopyEntryL( + CMRMailboxUtils& aMbUtils, + const CCalEntry& aEntry ) + { + CCalEntry* entry = ESMRHelper::CopyEntryL( + aEntry, + aEntry.MethodL(), + ESMRHelper::ECopyFull, + EESMREventTypeMeetingRequest ); + + SetPhoneOwnerL( aMbUtils, *entry ); + + return entry; + } + +#ifdef _DEBUG + +// Definition for panic text +_LIT( KESMREntryPanicTxt, "ESMRMeetingRequestEntry" ); + +/** + * ES MR Entry panic codes + */ +enum TESMRMeetingRequestEntry + { + EESMREntryNotExist = 1, // Entry does not exist + EESMRInvalidRole, // Phone owner has invalid role + EESMRNoInfoObjectAttendeeFound, + EESMRPhoneOwnerNotSet, + EESMRRecurrenceError, + EESMRInvalidReplyType, + EESMRInvalidInvalidAttendeeStatus, + EESMRParentNotFound + }; + +/** + * Raises panic. + * @param aPanic Panic code + */ +void Panic(TESMRMeetingRequestEntry aPanic) + { + User::Panic( KESMREntryPanicTxt, aPanic); + } + +#endif // _DEBUG + +} // namespace + +// ======== MEMBER FUNCTIONS ======== + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::CESMRMeetingRequestEntry +// --------------------------------------------------------------------------- +// +inline CESMRMeetingRequestEntry::CESMRMeetingRequestEntry( + CMRMailboxUtils& aMRMailboxUtils, + MESMRCalDbMgr& aCalDb, + TBool aConflictsExists, + TESMRInputParams* aESMRInputParams ) +: iMRMailboxUtils( aMRMailboxUtils ), + iConflictsExists( aConflictsExists), + iCalDb( aCalDb ), + iESMRInputParams( aESMRInputParams ), + iSendCanellation( ETrue ) + { + FUNC_LOG; + // Not yet implementation + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::~CESMRMeetingRequestEntry +// --------------------------------------------------------------------------- +// +EXPORT_C CESMRMeetingRequestEntry::~CESMRMeetingRequestEntry() + { + FUNC_LOG; + delete iEntry; + delete iForwardEntry; + delete iOrginalEntry; + delete iParameterEntry; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::NewL +// --------------------------------------------------------------------------- +// +EXPORT_C CESMRMeetingRequestEntry* CESMRMeetingRequestEntry::NewL( + const CCalEntry& aEntry, + CMRMailboxUtils& aMRMailboxUtils, + MESMRCalDbMgr& aCalDb, + TBool aConflictsExists, + TESMRInputParams* aESMRInputParams ) + { + FUNC_LOG; + + CESMRMeetingRequestEntry* self = + new (ELeave) CESMRMeetingRequestEntry( + aMRMailboxUtils, + aCalDb, + aConflictsExists, + aESMRInputParams ); + + CleanupStack::PushL( self ); + self->ConstructL( aEntry ); + CleanupStack::Pop( self ); + + return self; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::ConstructL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::ConstructL( + const CCalEntry& aEntry ) + { + FUNC_LOG; + + iParameterEntry = CopyEntryL( iMRMailboxUtils, aEntry ); + iEntry = CopyEntryL( iMRMailboxUtils, aEntry ); + + iOrginalEntry = CopyEntryL( iMRMailboxUtils, aEntry ); + + if ( EESMRRoleOrganizer == RoleL() && IsStoredL() ) + { + // Increase sequence number + TInt seqNo( iEntry->SequenceNumberL() + 1); + iEntry->SetSequenceNumberL( seqNo ); + iOrginalEntry->SetSequenceNumberL( seqNo ); + } + + + CCalEntry::TMethod method( iEntry->MethodL() ); + + if ( CCalEntry::EMethodNone == method ) + { + iEntry->SetMethodL( CCalEntry::EMethodRequest ); + iOrginalEntry->SetMethodL( CCalEntry::EMethodRequest ); + } + + HBufC* newDescription = ReplaceCharactersFromBufferLC( + iEntry->DescriptionL(), + KReplaceLineFeedChar(), + KLineFeed() ); + iEntry->SetDescriptionL( *newDescription ); + iOrginalEntry->SetDescriptionL( *newDescription ); + + CleanupStack::PopAndDestroy( newDescription ); + + __ASSERT_DEBUG( iEntry->PhoneOwnerL(), Panic( EESMRPhoneOwnerNotSet) ); + + CESMRFeatureSettings* settings = CESMRFeatureSettings::NewL(); + if ( settings->FeatureSupported( + CESMRFeatureSettings::EMRUIMeetingRequestViewerCmailOnly ) ) + { + // Meeting request viewer available only from email. + // Remove attachments from entry. + iRemoveAttachments = ETrue; + } + delete settings; + + if ( CurrentPluginL() == EESMRActiveSync ) + { + // Set correct calendar database + SetDefaultDatabaseL(); + } + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::ReplaceCharactersFromBufferL +// --------------------------------------------------------------------------- +// +HBufC* CESMRMeetingRequestEntry::ReplaceCharactersFromBufferLC( const TDesC& aTarget, + const TDesC& aFindString, + const TDesC& aReplacement ) + { + FUNC_LOG; + HBufC* newBuffer = aTarget.AllocLC(); + TPtr16 ptr = newBuffer->Des(); + + // find next occurance: + TInt offset = ptr.Find(aFindString); + while ( offset != KErrNotFound ) + { + // replace the data: + ptr.Replace( offset, aFindString.Length(), aReplacement); + + // find next occurance: + offset = ptr.Find(aFindString); + } + + return newBuffer; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::Type +// --------------------------------------------------------------------------- +// +MESMRCalEntry::TESMRCalEntryType CESMRMeetingRequestEntry::Type() const + { + FUNC_LOG; + // This is meeting request + return MESMRCalEntry::EESMRCalEntryMeetingRequest; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::MESMRCalEntryRef +// --------------------------------------------------------------------------- +// +MESMRCalEntry& CESMRMeetingRequestEntry::MESMRCalEntryRef() + { + FUNC_LOG; + return *this; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::MESMRCalEntryRef +// --------------------------------------------------------------------------- +// +const MESMRCalEntry& CESMRMeetingRequestEntry::MESMRCalEntryRef() const + { + FUNC_LOG; + return *this; + } +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::Entry +// --------------------------------------------------------------------------- +// +CCalEntry& CESMRMeetingRequestEntry::Entry() + { + FUNC_LOG; + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + if ( iForwardEntry ) + { + return *iForwardEntry; + } + + return *iEntry; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::Entry +// --------------------------------------------------------------------------- +// +const CCalEntry& CESMRMeetingRequestEntry::Entry() const + { + FUNC_LOG; + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + if ( iForwardEntry ) + { + return *iForwardEntry; + } + return *iEntry; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::InstanceL +// --------------------------------------------------------------------------- +// +CCalInstance* CESMRMeetingRequestEntry::InstanceL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + __ASSERT_DEBUG( iOrginalEntry, Panic(EESMREntryNotExist ) ); + + CCalInstance* instance = NULL; + + instance = iCalDb.FindInstanceL( *iEntry ); + if ( !instance ) + { + // Instance not found by using the edited entry + // Trying with orginal. + instance = iCalDb.FindInstanceL( *iOrginalEntry ); + } + + if ( !instance ) + { + // Instance not found by using edited or orginal entry. + // --> Leave + User::Leave( KErrNotFound ); + } + + return instance; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::CanSetRecurrenceL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::CanSetRecurrenceL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TBool canSetRecurrence( ETrue ); + + if ( iEntry->EntryTypeL() == CCalEntry::EAppt && + ESMREntryHelper::IsRepeatingMeetingL(*iEntry) && + (!ESMREntryHelper::IsModifyingEntryL(*iEntry) && + MESMRCalEntry::EESMRThisOnly == iRecurrenceModRule )) + { + canSetRecurrence = EFalse; + } + + + return canSetRecurrence; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsRecurrentEventL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsRecurrentEventL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + 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 ( ESMREntryHelper::IsRepeatingMeetingL( instanceParentEntry ) ) + { + recurrenceEvent = ETrue; + } + CleanupStack::PopAndDestroy( instance ); + } + else if ( ESMREntryHelper::IsRepeatingMeetingL( *iEntry ) ) + { + recurrenceEvent = ETrue; + } + } + else + { + // Entry is not stored in calendar db + if ( ESMREntryHelper::IsRepeatingMeetingL( *iEntry ) ) + { + // This is repeating meeting + recurrenceEvent = ETrue; + } + } + + + return recurrenceEvent; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetRecurrenceL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetRecurrenceL( + TESMRRecurrenceValue aRecurrence, + TTime aUntil ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + // Check if this entry's recurrence can be edited + if ( !CanSetRecurrenceL() ) + { + User::Leave( KErrNotSupported ); + } + + if ( aRecurrence != ERecurrenceNot && + MESMRCalEntry::EESMRAllInSeries != iRecurrenceModRule ) + { + // Make sure that mod rule is correct + SetModifyingRuleL( + MESMRCalEntry::EESMRAllInSeries ); + } + + CESMRRecurrenceInfoHandler* recurrenceHandler = + CESMRRecurrenceInfoHandler::NewLC( *iEntry ); + + recurrenceHandler->SetRecurrenceL( aRecurrence, aUntil ); + + CleanupStack::PopAndDestroy( recurrenceHandler ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetRecurrenceL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::GetRecurrenceL( + TESMRRecurrenceValue& aRecurrence, + TTime& aUntil) const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRRecurrenceInfoHandler* recurrenceHandler = + CESMRRecurrenceInfoHandler::NewLC( *iEntry, &iCalDb ); + + recurrenceHandler->GetRecurrenceL( aRecurrence, aUntil ); + CleanupStack::PopAndDestroy( recurrenceHandler ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::RecurrenceModRule +// --------------------------------------------------------------------------- +// +MESMRCalEntry::TESMRRecurrenceModifyingRule + CESMRMeetingRequestEntry::RecurrenceModRule() const + { + return iRecurrenceModRule; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetModifyingRuleL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetModifyingRuleL( + TESMRRecurrenceModifyingRule aRule, const TBool aTypeChanging ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRRecurrenceInfoHandler* recHandler = + CESMRRecurrenceInfoHandler::NewL( *iOrginalEntry ); + CleanupStack::PushL( recHandler ); + + TESMRRecurrenceValue orginalRecurrence; + TTime orginalUntil; + + recHandler->GetRecurrenceL( + orginalRecurrence, + orginalUntil); + CleanupStack::PopAndDestroy( recHandler ); + recHandler = NULL; + + TBool modifyingEntry( ESMREntryHelper::IsModifyingEntryL( *iEntry ) ); + + if ( MESMRCalEntry::EESMRAllInSeries == aRule && + IsStoredL() && !IsForwardedL() && !IsOpenedFromMail() && !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 iForwardEntry; + iForwardEntry = NULL; + + delete iOrginalEntry; + iOrginalEntry = NULL; + + RCPointerArray 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; + } + } + + __ASSERT_DEBUG( KErrNotFound != parentIndex, Panic(EESMRParentNotFound) ); + + CCalEntry& parent = *entries[parentIndex]; + + TPtrC description( parent.DescriptionL() ); + + iEntry = CopyEntryL( iMRMailboxUtils, 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 ); + + iOrginalEntry = CopyEntryL( iMRMailboxUtils, *iEntry ); + + if ( iEntry->MethodL() != entryMethod ) + { + iEntry->SetMethodL( entryMethod ); + iOrginalEntry->SetMethodL( entryMethod ); + } + + iEntry->SetDescriptionL( description ); + iOrginalEntry->SetDescriptionL( description ); + + CleanupStack::PopAndDestroy(); // entries + CleanupStack::PopAndDestroy( instance ); + + if ( EESMRRoleOrganizer == RoleL() && IsStoredL() ) + { + // Increase sequence number + TInt seqNo( iEntry->SequenceNumberL() + 1); + iEntry->SetSequenceNumberL( seqNo ); + iOrginalEntry->SetSequenceNumberL( seqNo ); + } + } + } + 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; + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetAllDayEventL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetAllDayEventL( + TTime aStartDate, + TTime aEndDate ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + 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. + TTime endDate = aEndDate + TTimeIntervalDays( 1 ); + end.Set( endDate.DateTime().Year(), + endDate.DateTime().Month(), + endDate.DateTime().Day(), + 0, + 0, + 0, + 0 ); + + startTime.SetTimeLocalL( start ); + stopTime.SetTimeLocalL( end ); + + iEntry->SetStartAndEndTimeL( startTime, stopTime ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsAllDayEventL +// +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsAllDayEventL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRCalUserUtil* entryUtil = CESMRCalUserUtil::NewLC( *iEntry ); + + TBool allDayEvent( entryUtil->IsAlldayEventL() ); + + CleanupStack::PopAndDestroy( entryUtil ); + + return allDayEvent; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsStoredL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsStoredL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + 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; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsSentL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsSentL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iOrginalEntry, Panic(EESMREntryNotExist ) ); + + TBool retVal( EFalse ); + + if ( EESMRRoleOrganizer == RoleL() ) + { + CCalEntry::TStatus status( iOrginalEntry->StatusL() ); + if ( CCalEntry::ENullStatus != status ) + { // When we send a request for the first time we set + // it's status to some other value than ENullStatus + retVal = ETrue; + } + } + else + { + // In attendee mode, we have sent the entry, if it is stored to + // calendar db and status is known and not declined. + // Declined entries are not stored to calendar db. + TESMRAttendeeStatus currentStatus( AttendeeStatusL() ); + if ( IsStoredL() + && EESMRAttendeeStatusUnknown != currentStatus + && EESMRAttendeeStatusDecline != currentStatus ) + { + retVal = ETrue; + } + } + + + return retVal; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsEntryEditedL +// +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsEntryEditedL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + __ASSERT_DEBUG( iOrginalEntry, Panic(EESMREntryNotExist ) ); + + TBool edited( EFalse ); + + if ( iOrginalEntry ) + { // edited if differs from the db entry + edited = !( iEntry->CompareL( *iOrginalEntry ) ); + + TESMRRole role( RoleL() ); + if ( !edited && EESMRRoleOrganizer != role ) + { + // CCalEntry::CompareL does not compare attedee statuses + CCalAttendee* dbAttendee = + iMRMailboxUtils.ThisAttendeeL( *iOrginalEntry ); + + CCalAttendee* me = + iMRMailboxUtils.ThisAttendeeL( *iEntry ); + + if ( dbAttendee && me ) + { + edited = dbAttendee->StatusL() != me->StatusL(); + } + } + if ( !edited && EESMRRoleOrganizer == role && + iEntry->MethodL() != iOrginalEntry->MethodL() ) + { + // For organizer CCalEntry::Compare does not compare entry's + // method at all --> Need to compare ourselves. + edited = ETrue; + } + + // CCalEntry's CompareL doesn't check the priority value: + if ( iOrginalEntry->PriorityL() != iEntry->PriorityL() ) + { + edited = ETrue; + } + + TPtrC description( iEntry->DescriptionL() ); + if ( description.CompareF( iOrginalEntry->DescriptionL() ) ) + { + edited = ETrue; + } + + TPtrC location( iEntry->LocationL() ); + if ( location.CompareF( iOrginalEntry->LocationL() ) ) + { + edited = ETrue; + } + + if( IsStoredL() ) + { + if ( iCalDb.EntryViewL( *iEntry ) != iCalDb.EntryView() ) + { + edited = ETrue; + } + } + } + + + + return edited; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsEntryTypeChangedL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsEntryTypeChangedL() const + { + FUNC_LOG; + + return iTypeChanged; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetAlarmL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::GetAlarmL( + MESMRCalEntry::TESMRAlarmType& aAlarmType, + TTime &aAlarmTime ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + aAlarmType = MESMRCalEntry::EESMRAlarmNotFound; + aAlarmTime = Time::NullTTime(); + + TFileName alarmInfoResource; + ESMRHelper::LocateResourceFile( + KAlarmInfoResource, + KDC_RESOURCE_FILES_DIR, + alarmInfoResource); + + + CESMRAlarmInfoHandler* alarmInfoHandler = + CESMRAlarmInfoHandler::NewLC(); + + alarmInfoHandler->ReadFromResourceL( + alarmInfoResource, + ESRM_ALARM_INFO_TABLE ); + + TRAPD( err, + alarmInfoHandler->GetAbsoluteAlarmTimeL(*iEntry, aAlarmTime) ); + + if ( KErrNone == err ) + { + aAlarmType = MESMRCalEntry::EESMRAlarmAbsolute; + + // only meeting request that is not allday event can have + // relative alarm: + if ( !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 ); + + } + + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::OriginalEntry +// --------------------------------------------------------------------------- +// +const CCalEntry& CESMRMeetingRequestEntry::OriginalEntry() + { + FUNC_LOG; + return *iOrginalEntry; + } + + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::UpdateEntryAfterStoringL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::UpdateEntryAfterStoringL() + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CCalEntry* storedEntry = NULL; + + + if ( IsRecurrentEventL() && + EESMRThisOnly == iRecurrenceModRule && + !IsForwardedL() && IsStoredL() && + !ESMREntryHelper::IsModifyingEntryL(*iEntry) ) + { + // We have stored one instance of series. + storedEntry = iCalDb.FetchEntryL( + iEntry->UidL(), + iOrginalEntry->StartTimeL() ); + } + else + { + // We are dealing with single instance or with the series + storedEntry = iCalDb.FetchEntryL( + iEntry->UidL(), + iEntry->RecurrenceIdL() ); + } + + + __ASSERT_DEBUG( storedEntry, Panic( EESMREntryNotExist ) ); + CleanupStack::PushL( storedEntry ); + + // Description needs to be fecthed explicitly into memory + TPtrC description( storedEntry->DescriptionL() ); + + + delete iEntry; + iEntry = NULL; + iEntry = CopyEntryL( iMRMailboxUtils, *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 = CopyEntryL( iMRMailboxUtils, *iEntry ); + + delete iOrginalEntry; + iOrginalEntry = temp; + + CleanupStack::PopAndDestroy( storedEntry ); + } + +// ---------------------------------------------------------------------------- +// CMRCalEntry::UpdateComparativeEntry +// ---------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::UpdateComparativeEntry( + CCalEntry* aNewComparativeEntry ) + { + FUNC_LOG; + + if( iOrginalEntry ) // Update comparative entry + { + delete iOrginalEntry; + iOrginalEntry = NULL; + + iOrginalEntry = aNewComparativeEntry; + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetDefaultValuesToEntryL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetDefaultValuesToEntryL() + { + FUNC_LOG; + + if ( !IsStoredL() ) + { + SetPriorityL( EFSCalenMRPriorityNormal ); + + // Get default alarm time from central repository + TInt defaultAlarmTime=0; + CRepository* repository = CRepository::NewLC( KCRUidCalendar ); + + TInt err = KErrNotFound; + + if ( repository ) + { + err = repository->Get( + KCalendarDefaultAlarmTime, + defaultAlarmTime ); + CleanupStack::PopAndDestroy( repository ); + } + + if ( err != KErrNone ) + { + // By default 15 minutes if not found from central repository + 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 ); + } + + // Set the default end time if not set by client + if ( iEntry->StartTimeL().TimeUtcL() == iEntry->EndTimeL().TimeUtcL() ) + { + // This value might also be read from cenrep + TTimeIntervalHours KDefaultMeetingDuration(1); + + TCalTime newEndTime; + newEndTime.SetTimeUtcL( + iEntry->StartTimeL().TimeUtcL() + KDefaultMeetingDuration ); + iEntry->SetStartAndEndTimeL(iEntry->StartTimeL(), newEndTime); + } + + iEntry->SetReplicationStatusL( CCalEntry::EOpen ); + + //Original entry must be stored after the default values are set. + //Otherwise it looks like settings are changed even though they haven't + CCalEntry* temp = CopyEntryL( iMRMailboxUtils, *iEntry ); + + delete iOrginalEntry; + iOrginalEntry = temp; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::CloneEntryLC +// --------------------------------------------------------------------------- +// +CCalEntry* CESMRMeetingRequestEntry::CloneEntryLC( + TESMRCalEntryType aType ) const + { + CCalEntry* entry = + ESMRHelper::CopyEntryLC( *iEntry, + iEntry->MethodL(), + ESMRHelper::ECopyFull, + TESMRCalendarEventType( aType ) ); + + return entry; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::RoleL +// --------------------------------------------------------------------------- +// +TESMRRole CESMRMeetingRequestEntry::RoleL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRCalUserUtil* caluserUtil = CESMRCalUserUtil::NewLC( *iEntry ); + TESMRRole role = caluserUtil->PhoneOwnerRoleL(); + CleanupStack::PopAndDestroy( caluserUtil ); + + + return role; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::Conflicts +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::Conflicts() const + { + FUNC_LOG; + return iConflictsExists; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::MarkMeetingCancelledL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::MarkMeetingCancelledL() + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TESMRRole role = RoleL(); + + if ( EESMRRoleOrganizer == role ) + { + iEntry->SetMethodL( CCalEntry::EMethodCancel ); + iEntry->SetStatusL( CCalEntry::ECancelled ); + } + else if ( EESMRRoleRequiredAttendee == role || + EESMRRoleOptionalAttendee == role || + EESMRRoleNonParticipant == role ) + { + ConstructReplyL( EESMRAttendeeStatusDecline ); + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::ConstructReplyL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::ConstructReplyL( + TESMRAttendeeStatus aStatus ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CCalAttendee* attendee = + iMRMailboxUtils.ThisAttendeeL( *iEntry ); + + if ( !attendee ) + { + + User::Leave( KErrNotFound ); + } + + CCalAttendee::TCalStatus status( + CCalAttendee::EDeclined ); + + CCalEntry::TStatus entryStatus = CCalEntry::ENullStatus; + switch ( aStatus ) + { + case EESMRAttendeeStatusAccept: + status = CCalAttendee::EAccepted; + entryStatus = CCalEntry::EConfirmed; + break; + + case EESMRAttendeeStatusTentative: + status = CCalAttendee::ETentative; + entryStatus = CCalEntry::ETentative; + break; + case EESMRAttendeeStatusDecline: + status = CCalAttendee::EDeclined; + entryStatus = CCalEntry::ECancelled; + break; + default: + // This should not occur + __ASSERT_DEBUG( + EFalse, + Panic( EESMRInvalidReplyType ) ); + + User::Leave( KErrArgument ); + break; + } + + attendee->SetStatusL(status); + iEntry->SetStatusL(entryStatus); + + iEntry->SetMethodL( CCalEntry::EMethodReply ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsEntryOutOfDateL +// +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsEntryOutOfDateL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TBool outOfDate( EFalse ); + + CCalEntry::TMethod method( iEntry->MethodL() ); + if ( IsOpenedFromMail() && + CCalEntry::EMethodCancel != method ) + { + CCalEntry* dbEntry = NULL; + + TRAP_IGNORE( dbEntry = iCalDb.FetchEntryL( iEntry->UidL(), + iEntry->RecurrenceIdL() ) ); + + CleanupStack::PushL( dbEntry ); + if ( dbEntry ) + { + TInt currentSeqNo( iEntry->SequenceNumberL() ); + TInt dbEntrySeqNo( dbEntry->SequenceNumberL() ); + + if ( currentSeqNo < dbEntrySeqNo ) + { + outOfDate = ETrue; + } + } + CleanupStack::PopAndDestroy( dbEntry ); + } + + + return outOfDate; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsMeetingCancelledL +// +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsMeetingCancelledL() const + { + FUNC_LOG; + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TBool retValue( EFalse ); + + CCalEntry::TMethod method( iEntry->MethodL() ); + + if ( CCalEntry::ECancelled == iEntry->StatusL() || + CCalEntry::EMethodCancel == method ) + { + retValue = ETrue; + } + + return retValue; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::AttendeeStatusL +// +// --------------------------------------------------------------------------- +// +TESMRAttendeeStatus CESMRMeetingRequestEntry::AttendeeStatusL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TESMRAttendeeStatus status( + EESMRAttendeeStatusDecline ); + + if ( iMRMailboxUtils.IsOrganizerL( *iEntry ) ) + { + + User::Leave( KErrNotFound ); + } + + CCalAttendee* attendee = iMRMailboxUtils.ThisAttendeeL( *iEntry ); + if (!attendee ) + { + User::Leave( KErrNotFound ); + } + + CCalAttendee::TCalStatus attendeeStatus( attendee->StatusL() ); + switch ( attendeeStatus ) + { + case CCalAttendee::ENeedsAction: + status = EESMRAttendeeStatusUnknown; + break; + + case CCalAttendee::EAccepted: + status = EESMRAttendeeStatusAccept; + break; + + case CCalAttendee::ETentative: + status = EESMRAttendeeStatusTentative; + break; + + case CCalAttendee::EDeclined: + status = EESMRAttendeeStatusDecline; + break; + + default: + status = EESMRAttendeeStatusDecline; + break; + } + + + return status; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsForwardedL +// +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsForwardedL() const + { + FUNC_LOG; + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TBool retValue( EFalse ); + if ( iForwardEntry ) + { + retValue = ETrue; + } + return retValue; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SwitchToForwardL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SwitchToForwardL() + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CCalEntry* temp = CopyEntryL( iMRMailboxUtils, *iEntry ); + + delete iForwardEntry; + iForwardEntry = temp; + + RPointerArray& attendeeList = + iForwardEntry->AttendeesL(); + + while ( attendeeList.Count() ) + { + //remove attendees from entry that is to be forwarded + iForwardEntry->DeleteAttendeeL( 0 ); + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SwitchToOrginalL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SwitchToOrginalL() + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + // We just delete the forwarded entry + delete iForwardEntry; + iForwardEntry = NULL; + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SwitchToOrginalL +// +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::ConfirmEntryL() + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + if ( iForwardEntry && + iForwardEntry->StatusL() == CCalEntry::ENullStatus ) + { + iForwardEntry->SetStatusL( CCalEntry::EConfirmed ); + } + else if ( RoleL() == EESMRRoleOrganizer || + iEntry->StatusL() == CCalEntry::ENullStatus ) + { + iEntry->SetStatusL( CCalEntry::EConfirmed ); + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::OccursInPastL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::OccursInPastL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TTime currentTimeUtc; + currentTimeUtc.UniversalTime(); + + TTime startTimeUtc = iEntry->StartTimeL().TimeUtcL(); + + if( IsRecurrentEventL() && + IsOpenedFromMail() && + EESMRAllInSeries == iRecurrenceModRule ) + { + // Get recurrence + TESMRRecurrenceValue recValue( ERecurrenceNot ); + GetRecurrenceL( recValue, startTimeUtc ); + } + + return (startTimeUtc < currentTimeUtc); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::EntryAttendeeInfoL +// --------------------------------------------------------------------------- +// +MESMRMeetingRequestEntry::TESMREntryInfo + CESMRMeetingRequestEntry::EntryAttendeeInfoL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + +#ifdef _DEBUG + + __ASSERT_DEBUG( EESMRRoleOrganizer != RoleL(), Panic(EESMRInvalidRole) ); + +#else + + if ( EESMRRoleOrganizer == RoleL() ) + { + // Info cannot be resolved in organzier role + User::Leave( KErrNotSupported ); + } +#endif + + TESMRAttendeeStatus attendeeStatus( + AttendeeStatusL() ); + + MESMRMeetingRequestEntry::TESMREntryInfo info = + EESMREntryInfoNormal; + + if ( IsEntryOutOfDateL() ) + { + info = EESMREntryInfoOutOfDate; + } + else if( IsMeetingCancelledL() ) + { + info = EESMREntryInfoCancelled; + } + else if ( IsSentL() ) + { + info = EESMREntryInfoAccepted; + if ( EESMRAttendeeStatusTentative == attendeeStatus ) + { + info = EESMREntryInfoTentativelyAccepted; + } + } + else if ( OccursInPastL() ) + { + info = EESMREntryInfoOccursInPast; + } + + + return info; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetPriorityL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetPriorityL( + TUint aPriority ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + iEntry->SetPriorityL( aPriority ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetPriorityL +// --------------------------------------------------------------------------- +// +TUint CESMRMeetingRequestEntry::GetPriorityL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TUint entryPriority = iEntry->PriorityL(); + + if ( entryPriority != EFSCalenMRPriorityLow && + entryPriority != EFSCalenMRPriorityNormal && + entryPriority != EFSCalenMRPriorityHigh ) + { + entryPriority = EFSCalenMRPriorityNormal; + } + + + return entryPriority; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetAttendeesL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::GetAttendeesL( + RArray& aAttendeeArray, + TUint aFilterFlags ) const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRCalUserUtil* caluserUtil = CESMRCalUserUtil::NewLC( *iEntry ); + caluserUtil->GetAttendeesL( aAttendeeArray, aFilterFlags ); + CleanupStack::PopAndDestroy( caluserUtil ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::ValidateEntryL +// --------------------------------------------------------------------------- +// +CCalEntry* CESMRMeetingRequestEntry::ValidateEntryL() + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + __ASSERT_DEBUG( iOrginalEntry, Panic(EESMREntryNotExist ) ); + + CCalEntry* entry = NULL; + + if ( iForwardEntry ) + { + entry = CopyEntryL( iMRMailboxUtils, *iForwardEntry ); + } + + if ( !entry && IsRecurrentEventL() && + EESMRThisOnly == iRecurrenceModRule && + !IsForwardedL() && 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(), + iOrginalEntry->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, + iOrginalEntry->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(); + iMRMailboxUtils.SetPhoneOwnerL( *entry ); + + CleanupStack::Pop( entry ); + } + } + + if ( !entry ) + { + entry = CopyEntryL( iMRMailboxUtils, *iEntry ); + } + + if ( iRemoveAttachments ) + { + // Remove attachments from the entry + TInt count( entry->AttachmentCountL() ); + + for ( TInt i = 0; i < count; ++i ) + { + CCalAttachment* attachment = entry->AttachmentL( i ); + entry->DeleteAttachmentL( *attachment ); + } + } + + return entry; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::FetchConflictingEntriesL +// --------------------------------------------------------------------------- +// +TInt CESMRMeetingRequestEntry::FetchConflictingEntriesL( + RPointerArray& aEntryArray) + { + FUNC_LOG; + + TInt ret( KErrNone ); + + CESMRConflictChecker* conflictChecker = + CESMRConflictChecker::NewL(iCalDb); + CleanupStack::PushL( conflictChecker ); + + + conflictChecker->FindConflictsL( *iEntry, aEntryArray ); + + CleanupStack::PopAndDestroy( conflictChecker ); + + if ( aEntryArray.Count() == 0 ) + { + ret = KErrNotFound; + } + + + return ret; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsSyncObjectPresent +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsSyncObjectPresent() const + { + FUNC_LOG; + TBool retValue(EFalse); + + if ( iESMRInputParams && iESMRInputParams->iMRInfoObject) + { + retValue = ETrue; + } + + return retValue; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SyncObjectL +// --------------------------------------------------------------------------- +// +MMRInfoObject& CESMRMeetingRequestEntry::SyncObjectL() + { + FUNC_LOG; + if ( !IsSyncObjectPresent() ) + { + User::Leave(KErrNotSupported); + } + + return *iESMRInputParams->iMRInfoObject; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::ValidateSyncObjectL +// --------------------------------------------------------------------------- +// +MMRInfoObject& CESMRMeetingRequestEntry::ValidateSyncObjectL() + { + FUNC_LOG; + if ( EESMRRoleOrganizer == RoleL() ) + { + User::Leave( KErrNotSupported ); + } + + MMRInfoObject& syncObject = SyncObjectL(); + + CCalAttendee* thisAttendee = + iMRMailboxUtils.ThisAttendeeL( *iEntry ); + + RPointerArray attendeeArray = + syncObject.AttendeesL(); + + TBool found( EFalse ); + TInt attendeeCount( attendeeArray.Count() ); + for (TInt i (0); i < attendeeCount && !found; ++i ) + { + MMRAttendee* attendee = attendeeArray[i]; + + TPtrC calEntryAddress( thisAttendee->Address() ); + TPtrC infoAddress( attendee->Address() ); + if ( 0 == infoAddress.Compare(calEntryAddress ) ) + { + found = ETrue; + + MMRInfoObject::TResponse entryResp( + MMRInfoObject::EMrCmdResponseAccept ); + + CCalAttendee::TCalStatus calEntryAttStatus( + thisAttendee->StatusL() ); + + MMRAttendee::TAttendeeStatus infoAttStatus( + MMRAttendee::EMRAttendeeActionAccepted ); + + if ( CCalAttendee::ETentative == calEntryAttStatus) + { + infoAttStatus = MMRAttendee::EMRAttendeeActionTentative; + entryResp = MMRInfoObject::EMrCmdResponseTentative; + } + else if ( CCalAttendee::EDeclined == calEntryAttStatus || + CCalEntry::EMethodCancel == iEntry->MethodL() ) + { + infoAttStatus = MMRAttendee::EMRAttendeeActionDeclined; + entryResp = MMRInfoObject::EMrCmdResponseDecline; + } + + attendee->SetAttendeeStatusL(infoAttStatus); + syncObject.SetMRResponseL( entryResp ); + } + } + + __ASSERT_DEBUG( found, Panic(EESMRNoInfoObjectAttendeeFound) ); + + return syncObject; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::StartupParameters +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::StartupParameters( + TESMRInputParams& aStartupParams) const + { + FUNC_LOG; + TBool retValue( EFalse ); + + if ( iESMRInputParams ) + { + retValue = ETrue; + + aStartupParams.iCalEntry = iESMRInputParams->iCalEntry; + aStartupParams.iMRInfoObject = iESMRInputParams->iMRInfoObject; + aStartupParams.iMailMessage = iESMRInputParams->iMailMessage; + aStartupParams.iMailClient = iESMRInputParams->iMailClient; + aStartupParams.iSpare = iESMRInputParams->iSpare; + } + return retValue; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::AttendeeCountL +// --------------------------------------------------------------------------- +// +TInt CESMRMeetingRequestEntry::AttendeeCountL( + TUint aFilterFlags ) const + { + FUNC_LOG; + + TInt attendeeCount(0); + + RArray attendeeArray; + CleanupClosePushL( attendeeArray ); + + GetAttendeesL( + attendeeArray, + aFilterFlags ); + + attendeeCount = attendeeArray.Count(); + + CleanupStack::PopAndDestroy( &attendeeArray ); + + + return attendeeCount; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::RemoveInstanceFromSeriesL +// --------------------------------------------------------------------------- +// +CCalEntry* CESMRMeetingRequestEntry::RemoveInstanceFromSeriesL() + { + FUNC_LOG; + + CCalEntry* retEntry = NULL; + + if ( IsRecurrentEventL() && + EESMRThisOnly == iRecurrenceModRule && + !IsForwardedL() ) + { + 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( + iOrginalEntry->StartTimeL().TimeUtcL() ); + + recurrenceHandler->RemoveInstanceL( orginalInstanceTime ); + + CleanupStack::PopAndDestroy( recurrenceHandler ); + CleanupStack::Pop( retEntry ); + } + } + else + { + User::Leave( KErrNotSupported ); + } + + + return retEntry; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::IsOpenedFromMail +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::IsOpenedFromMail() const + { + FUNC_LOG; + TBool openedFromMail( EFalse ); + + if ( iESMRInputParams ) + { + openedFromMail = ETrue; + } + + return openedFromMail; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetAddedAttendeesL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::GetAddedAttendeesL( + RArray& aAttendeeArray, + TUint aFilterFlags ) const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRCalUserUtil* caluserUtil = CESMRCalUserUtil::NewLC( *iEntry ); + caluserUtil->GetAttendeesL( aAttendeeArray, aFilterFlags ); + CleanupStack::PopAndDestroy( caluserUtil ); + caluserUtil = NULL; + + RArray orgAttendees; + CleanupClosePushL( orgAttendees ); + + caluserUtil = CESMRCalUserUtil::NewLC( *iParameterEntry ); + caluserUtil->GetAttendeesL( orgAttendees, aFilterFlags ); + + CleanupStack::PopAndDestroy( caluserUtil ); + caluserUtil = NULL; + + TInt index( 0 ); + while( index < aAttendeeArray.Count() ) + { + TPtrC attendeeEmail( aAttendeeArray[index]->Address() ); + + TBool found( EFalse ); + TInt orgAttendeeCount( orgAttendees.Count() ); + for( TInt i(0); (i < orgAttendeeCount) && !found; ++i ) + { + TPtrC orgAttendeeEmail( orgAttendees[i]->Address() ); + if ( 0 == attendeeEmail.CompareF(orgAttendeeEmail) ) + { + found = ETrue; + } + } + + if ( found ) + { + // Attendee was not found from orginal list + // --> it is added + aAttendeeArray.Remove( index ); + } + else + { + ++index; + } + } + + CleanupStack::PopAndDestroy( &orgAttendees ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetRemovedAttendeesL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::GetRemovedAttendeesL( + RArray& aAttendeeArray, + TUint aFilterFlags ) const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + CESMRCalUserUtil* caluserUtil = CESMRCalUserUtil::NewLC( *iParameterEntry ); + caluserUtil->GetAttendeesL( aAttendeeArray, aFilterFlags ); + CleanupStack::PopAndDestroy( caluserUtil ); + caluserUtil = NULL; + + RArray currentAttendees; + CleanupClosePushL( currentAttendees ); + + caluserUtil = CESMRCalUserUtil::NewLC( *iEntry ); + caluserUtil->GetAttendeesL( currentAttendees, aFilterFlags ); + + CleanupStack::PopAndDestroy( caluserUtil ); + caluserUtil = NULL; + + TInt index( 0 ); + while( index < aAttendeeArray.Count() ) + { + TPtrC attendeeEmail( aAttendeeArray[index]->Address() ); + + TBool found( EFalse ); + TInt orgAttendeeCount( currentAttendees.Count() ); + for( TInt i(0); (i < orgAttendeeCount) && !found; ++i ) + { + TPtrC curAttendeeEmail( currentAttendees[i]->Address() ); + if ( 0 == attendeeEmail.CompareF(curAttendeeEmail) ) + { + found = ETrue; + } + } + + if ( found ) + { + // Attendee was found from orginal list + // --> It has not been removed from MR + aAttendeeArray.Remove( index ); + } + else + { + ++index; + } + } + + CleanupStack::PopAndDestroy( ¤tAttendees ); + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::UpdateChildEntriesSeqNumbersL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::UpdateChildEntriesSeqNumbersL() + { + FUNC_LOG; + + if ( MESMRCalEntry::EESMRAllInSeries == iRecurrenceModRule && + IsStoredL() ) + { + RCPointerArray childEntries; + CleanupClosePushL( childEntries ); + + // Fetch all entries (this and child entries + iCalDb.EntryView()->FetchL( + iEntry->UidL(), + childEntries ); + + // Next: Remove parent entry from the array + TBool removed( EFalse ); + TInt entryCount( childEntries.Count() ); + for ( TInt i(0); (i < entryCount) && !removed; ++i ) + { + CCalEntry* entry = childEntries[i]; + + if ( !ESMREntryHelper::IsModifyingEntryL( *entry) ) + { + removed = ETrue; + childEntries.Remove( i ); + delete entry; + } + entry = NULL; + } + + TInt childCount( childEntries.Count() ); + if ( childCount ) + { + for (TInt i(0); i < childCount; ++i ) + { + CCalEntry* child = childEntries[i]; + TInt childSeqNo( child->SequenceNumberL() ); + child->SetSequenceNumberL( childSeqNo + 1); + } + + TInt updatedChilds; + iCalDb.EntryView()->StoreL(childEntries, updatedChilds); + } + + CleanupStack::PopAndDestroy(); // childEntries + } + + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::CurrentPluginL +// --------------------------------------------------------------------------- +// +TESMRMailPlugin CESMRMeetingRequestEntry::CurrentPluginL() + { + FUNC_LOG; + + if ( EESMRUnknownPlugin == iCurrentFSEmailPlugin) + { + CESMRFsMailboxUtils* fsMbUtils = + CESMRFsMailboxUtils::NewL( iMRMailboxUtils ); + CleanupStack::PushL( fsMbUtils ); + + iCurrentFSEmailPlugin = fsMbUtils->FSEmailPluginForEntryL( *iEntry ); + CleanupStack::PopAndDestroy( fsMbUtils ); + fsMbUtils = NULL; + } + + return iCurrentFSEmailPlugin; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::UpdateTimeStampL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::UpdateTimeStampL() + { + FUNC_LOG; + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + TTime currentUTCTime; + currentUTCTime.UniversalTime(); + + TCalTime currentTime; + currentTime.SetTimeUtcL( currentUTCTime ); + + iEntry->SetDTStampL( currentTime ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::AnyInstancesBetweenTimePeriodL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::AnyInstancesBetweenTimePeriodL( + TTime& aStart, + TTime& aEnd ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + __ASSERT_DEBUG( iOrginalEntry, Panic(EESMREntryNotExist ) ); + + TBool retValue( EFalse ); + + RCPointerArray 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; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetFirstInstanceStartAndEndTimeL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::GetFirstInstanceStartAndEndTimeL( + TTime& aStart, + TTime& aEnd ) + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic(EESMREntryNotExist ) ); + + // 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 ); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::CalendarOwnerAddressL +// --------------------------------------------------------------------------- +// +const TDesC& CESMRMeetingRequestEntry::CalendarOwnerAddressL() const + { + FUNC_LOG; + + __ASSERT_DEBUG( iEntry, Panic( EESMREntryNotExist ) ); + + CCalUser* po = iEntry->PhoneOwnerL(); + + __ASSERT_DEBUG( po, Panic( EESMRPhoneOwnerNotSet ) ); + + return po->Address(); + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::MailboxUtils +// --------------------------------------------------------------------------- +// +CMRMailboxUtils& CESMRMeetingRequestEntry::MailboxUtils() const + { + return iMRMailboxUtils; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::GetDBMgr +// --------------------------------------------------------------------------- +// +MESMRCalDbMgr& CESMRMeetingRequestEntry::GetDBMgr() + { + return iCalDb; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SupportsCapabilityL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::SupportsCapabilityL( + MESMRCalEntry::TMREntryCapability aCapability ) const + { + TBool retValue( EFalse ); + + switch( aCapability ) + { + case MESMRCalEntry::EMRCapabilityAttachments: + { + CESMRFsMailboxUtils* fsMbUtils = + CESMRFsMailboxUtils::NewL( iMRMailboxUtils ); + CleanupStack::PushL( fsMbUtils ); + + retValue = fsMbUtils->DefaultMailboxSupportCapabilityL( + CESMRFsMailboxUtils::EMRCapabilityAttachment ); + CleanupStack::PopAndDestroy( fsMbUtils ); + } + break; + } + + return retValue; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::ContainsRemoteAttachmentsL +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::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; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SendCanellationAvailable +// --------------------------------------------------------------------------- +// +TBool CESMRMeetingRequestEntry::SendCanellationAvailable () + { + return iSendCanellation; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetSendCanellationAvailable +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetSendCanellationAvailable ( + TBool aSendCanellation ) + { + iSendCanellation = aSendCanellation; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetTypeChanged +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetTypeChanged( TBool aTypeChanged ) + { + FUNC_LOG; + + iTypeChanged = aTypeChanged; + } + +// --------------------------------------------------------------------------- +// CESMRMeetingRequestEntry::SetDefaultDatabaseL +// --------------------------------------------------------------------------- +// +void CESMRMeetingRequestEntry::SetDefaultDatabaseL() + { + FUNC_LOG; + + if ( !IsStoredL() ) + { + // If entry has not been stored, set database manager to use correct + // database supported by plugin sync solution. + CESMRFsMailboxUtils* fsMbUtils = + CESMRFsMailboxUtils::NewL( iMRMailboxUtils ); + CleanupStack::PushL( fsMbUtils ); + TCalFileId aDbId( KNullFileId ); + fsMbUtils->GetCalendarDatabaseIdL( CurrentPluginL(), aDbId ); + CleanupStack::PopAndDestroy( fsMbUtils ); + + if ( aDbId != KNullFileId ) + { + iCalDb.SetCurCalendarByDbIdL( aDbId ); + } + else if ( CurrentPluginL() == EESMRActiveSync ) + { + _LIT( KMfeDb, "Mail for Exchange" ); + iCalDb.SetCurCalendarByNameL( KMfeDb ); + } + } + } + +// EOF