--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/meetingrequest/mrentry/src/cesmrconflictchecker.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,430 @@
+/*
+* 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 conflict checker implementation
+* Version : %version: tr1sido#7 %
+*
+*/
+
+#include "emailtrace.h"
+#include "cesmrconflictchecker.h"
+#include "cesmrcaldbmgr.h"
+#include "esmrhelper.h"
+#include "esmrentryhelper.h"
+#include "esmrinternaluid.h"
+
+#include <calcommon.h>
+#include <calinstance.h>
+#include <calentryview.h>
+#include <calinstanceview.h>
+#include <ct/rcpointerarray.h>
+
+/// Unnamed namespace for local definitions
+namespace { // codescanner::namespace
+
+// Definition for zero
+const TInt KZero(0);
+
+/** Defines instace filter type */
+enum TInstanceFilter
+ {
+ EIncludeSameUID,
+ ERemoveSameUID
+ };
+
+#ifdef _DEBUG
+
+// Literal for panic texts
+_LIT( KESMRConflictCheckerTxt, "ESMRConflictChecker" );
+
+/** Enumeration for panic codes */
+enum TESMRConflictCheckerPanic
+ {
+ // Input entry is not appointment
+ EESMRConflictCheckerInvalidEntryType
+ };
+
+/**
+ * Thows system wide panic.
+ * @param aPanic Panic code.
+ */
+void Panic( TESMRConflictCheckerPanic aPanic )
+ {
+
+ User::Panic( KESMRConflictCheckerTxt, aPanic );
+ }
+
+#else
+
+/**
+ * Thows system wide leave.
+ * @param aError Leave code.
+ */
+void Leave( TInt aError )
+ {
+
+ User::Leave( aError );
+ }
+
+#endif
+
+/**
+ * Resolves time range for possible conflicting entries. Instance view
+ * is used for resolving the time range.
+ *
+ * @param aStart Start time
+ * @param aEnd End time
+ * @param aInstanceView Pointer to calendar db instance view
+ * @return Time range for possible conflicting entries
+ */
+CalCommon::TCalTimeRange ResolveFetchTimeRangeL(
+ TTime aStart,
+ TTime aEnd,
+ CCalInstanceView* aInstanceView )
+ {
+ FUNC_LOG;
+ const CalCommon::TCalViewFilter instanceFilter =
+ CalCommon::EIncludeAppts;
+
+ TDateTime start = aStart.DateTime();
+ TDateTime end = aEnd.DateTime();
+
+ start.SetHour( KZero );
+ start.SetMinute( KZero );
+ start.SetSecond( KZero );
+ start.SetMicroSecond( KZero );
+
+ end.SetHour( KZero );
+ end.SetMinute( KZero );
+ end.SetSecond( KZero );
+ end.SetMicroSecond( KZero );
+ TTime endTime = end;
+
+ if ( TTime(start) == endTime ||
+ endTime < aEnd )
+ {
+
+ endTime += TTimeIntervalDays(1);
+ end = endTime.DateTime();
+ }
+
+ TCalTime rangeStart;
+ rangeStart.SetTimeLocalL( start );
+
+ TCalTime instanceTime = aInstanceView->PreviousInstanceL(
+ instanceFilter,
+ rangeStart );
+
+ if ( Time::NullTTime() != instanceTime.TimeUtcL() )
+ {
+ rangeStart = instanceTime;
+ }
+
+ TCalTime rangeEnd;
+ rangeEnd.SetTimeLocalL( end );
+
+ instanceTime = aInstanceView->NextInstanceL(
+ instanceFilter,
+ rangeEnd );
+
+ if ( instanceTime.TimeLocalL() != Time::NullTTime() )
+ {
+ rangeEnd = instanceTime;
+ }
+
+ return CalCommon::TCalTimeRange( rangeStart, rangeEnd );
+ }
+
+/**
+ * Removes and deletes the entries, which do not confilct with
+ * entry. Entry is considered to be conflicting entry if starts or
+ * ends between aEntry's start and end time.
+ *
+ * @param aEntries Reference to entries, which may conflict
+ * @param aEntry Reference to entry, which confilcts are resolved.
+ */
+void RemoveAndDeleteNonConflictingInstancesL(
+ RPointerArray<CCalInstance>& instanceArray,
+ // const CCalEntry& aEntry,
+ TCalTime aStartTime,
+ TCalTime aEndTime,
+ const TDesC8& aUid,
+ TInstanceFilter aFilterType )
+ {
+ FUNC_LOG;
+ TInt index(0);
+
+ TTime startTimeUtc = aStartTime.TimeUtcL();
+ TTime endTimeUtc = aEndTime.TimeUtcL();
+
+ while( index < instanceArray.Count() )
+ {
+ TBool conflictingInstance( ETrue );
+ CCalInstance* instance = instanceArray[index];
+
+ TTime entryStartTimeUtc = instance->StartTimeL().TimeUtcL();
+ TTime entryEndTimeUtc = instance->EndTimeL().TimeUtcL();
+
+ TPtrC8 uid( instance->Entry().UidL() );
+ if ( ERemoveSameUID == aFilterType &&
+ 0 == aUid.CompareF(uid) )
+ {
+ conflictingInstance = EFalse;
+ }
+ else if ( entryStartTimeUtc >= startTimeUtc &&
+ entryStartTimeUtc < endTimeUtc )
+ {
+ // Entry starts during another entry
+ index++;
+ }
+ else if ( entryEndTimeUtc > startTimeUtc &&
+ entryEndTimeUtc <= endTimeUtc )
+ {
+ // Entry ends during another entry
+ index++;
+ }
+ else if ( entryStartTimeUtc > startTimeUtc &&
+ entryEndTimeUtc < endTimeUtc )
+ {
+ // Antry starts and ends during another entry
+ index++;
+ }
+ else if ( entryStartTimeUtc < startTimeUtc &&
+ entryEndTimeUtc > endTimeUtc )
+ {
+ // Antry starts and ends during another entry
+ index++;
+ }
+ else
+ {
+ conflictingInstance = EFalse;
+ }
+
+ // Remove non-conflicting instance from instance array
+ if ( !conflictingInstance )
+ {
+ instanceArray.Remove(index);
+ delete instance;
+ instance = NULL;
+ }
+ }
+ }
+
+/**
+ * Creates calendar entries from the conflicting instances
+ * and stores the created entries into entry array.
+ * Ownership of the created entries is transferred to caller.
+ * @param aInstanceArray Reference to instance array
+ * @param aConflictingEntries Reference to entry array.
+ */
+void CreateEntriesFromInstancesL(
+ RPointerArray<CCalInstance>& instanceArray,
+ RPointerArray<CCalEntry>& aConflictingEntries )
+ {
+ FUNC_LOG;
+ TInt instanceCount( instanceArray.Count() );
+ for ( TInt i(0); i < instanceCount; ++i )
+ {
+ CCalEntry& parent( instanceArray[i]->Entry() );
+ CCalEntry* entry = ESMRHelper::CopyEntryLC( parent,
+ parent.MethodL(),
+ ESMRHelper::ECopyFull );
+
+ entry->SetStartAndEndTimeL( instanceArray[i]->StartTimeL(),
+ instanceArray[i]->EndTimeL() );
+
+ User::LeaveIfError( aConflictingEntries.Append( entry ) );
+ CleanupStack::Pop( entry );
+ }
+ }
+
+} // namespace
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::CESMRConflictChecker
+// ---------------------------------------------------------------------------
+//
+inline CESMRConflictChecker::CESMRConflictChecker(
+ MESMRCalDbMgr& aDbMgr ) :
+ iDbMgr( aDbMgr )
+ {
+ FUNC_LOG;
+ // Not implementation yet
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::~CESMRConflictChecker
+// ---------------------------------------------------------------------------
+//
+CESMRConflictChecker::~CESMRConflictChecker()
+ {
+ FUNC_LOG;
+ // Not implementation yet
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::NewL
+// ---------------------------------------------------------------------------
+//
+CESMRConflictChecker* CESMRConflictChecker::NewL(
+ MESMRCalDbMgr& aDbMgr )
+ {
+ FUNC_LOG;
+ CESMRConflictChecker* self =
+ new (ELeave) CESMRConflictChecker(aDbMgr);
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::FindConflictsL
+// ---------------------------------------------------------------------------
+//
+void CESMRConflictChecker::FindConflictsL(
+ const CCalEntry& aEntry,
+ RPointerArray<CCalEntry>& aConflicts )
+ {
+ FUNC_LOG;
+
+ // Checking input parameters
+#ifdef _DEBUG
+
+ __ASSERT_DEBUG(
+ CCalEntry::EAppt == aEntry.EntryTypeL(),
+ Panic(EESMRConflictCheckerInvalidEntryType) );
+
+#else
+
+ if ( CCalEntry::EAppt != aEntry.EntryTypeL() )
+ {
+ Leave( KErrArgument );
+ }
+
+#endif
+
+ CCalInstanceView* instanceView = iDbMgr.NormalDbInstanceView();
+
+ CalCommon::TCalTimeRange timeRange =
+ ResolveFetchTimeRangeL(
+ aEntry.StartTimeL().TimeUtcL(),
+ aEntry.EndTimeL().TimeUtcL(),
+ instanceView );
+
+ RCPointerArray<CCalInstance> instanceArray;
+ CleanupClosePushL( instanceArray );
+
+ instanceView->FindInstanceL( instanceArray,
+ CalCommon::EIncludeAppts,
+ timeRange );
+
+ RemoveAndDeleteNonConflictingInstancesL(
+ instanceArray,
+ aEntry.StartTimeL(),
+ aEntry.EndTimeL(),
+ aEntry.UidL(),
+ ERemoveSameUID );
+
+ CreateEntriesFromInstancesL( instanceArray, aConflicts );
+
+ CleanupStack::PopAndDestroy(); // instanceArray
+
+ }
+
+// ---------------------------------------------------------------------------
+// CESMRConflictChecker::FindInstancesForEntry
+// ---------------------------------------------------------------------------
+//
+void CESMRConflictChecker::FindInstancesForEntryL(
+ TTime aStart,
+ TTime aEnd,
+ const CCalEntry& aEntry,
+ RPointerArray<CCalEntry>& aInstances )
+ {
+ FUNC_LOG;
+ TDateTime startDt = aStart.DateTime();
+ startDt.SetHour( KZero );
+ startDt.SetMinute( KZero );
+ startDt.SetSecond( KZero );
+
+ TDateTime endDt = aEnd.DateTime();
+ endDt.SetHour( KMaxHoursInDay );
+ endDt.SetMinute( KMaxMinutesInHour );
+ endDt.SetSecond( KMaxSecondsInMinute );
+
+ aStart = startDt;
+ aEnd = endDt;
+
+ CCalInstanceView* instanceView = iDbMgr.NormalDbInstanceView();
+
+ CalCommon::TCalTimeRange timeRange =
+ ResolveFetchTimeRangeL(
+ aStart,
+ aEnd,
+ instanceView );
+
+ RCPointerArray<CCalInstance> instanceArray;
+ CleanupClosePushL( instanceArray );
+
+ instanceView->FindInstanceL( instanceArray,
+ CalCommon::EIncludeAppts,
+ timeRange );
+
+ TInt i(0);
+ while( i < instanceArray.Count() )
+ {
+ CCalInstance* instance = instanceArray[i];
+ CCalEntry& instanceEntry( instance->Entry() );
+
+ TBool sameUid(
+ 0 == instanceEntry.UidL().CompareF( aEntry.UidL() ) );
+
+ TBool thisInstance(
+ instance->StartTimeL().TimeLocalL() ==
+ aEntry.StartTimeL().TimeLocalL() &&
+ instance->EndTimeL().TimeLocalL() ==
+ aEntry.EndTimeL().TimeLocalL() );
+
+ if ( !sameUid || thisInstance )
+ {
+ // This is either same entry as aEntry or then
+ // this entry does not belong to this series
+ delete instance;
+ instanceArray.Remove( i );
+ }
+ else
+ {
+ ++i;
+ }
+ }
+
+ TCalTime start;
+ start.SetTimeUtcL( aStart );
+
+ TCalTime end;
+ end.SetTimeUtcL( aEnd );
+
+ RemoveAndDeleteNonConflictingInstancesL(
+ instanceArray,
+ start,
+ end,
+ aEntry.UidL(),
+ EIncludeSameUID );
+
+ CreateEntriesFromInstancesL( instanceArray, aInstances );
+
+ CleanupStack::PopAndDestroy(); // instanceArray
+ }
+
+// EOF
+