meetingrequest/mrentry/src/cesmrconflictchecker.cpp
changeset 0 8466d47a6819
--- /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
+