meetingrequest/mrservices/src/cesmrconflictchecker.cpp
branchRCL_3
changeset 33 da5135c61bad
child 29 6b8f3b30d0ec
equal deleted inserted replaced
32:a3a1ae9acec6 33:da5135c61bad
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 *  Description : ESMR conflict checker implementation
       
    15 *  Version     : %version: e002sa33#7 %
       
    16 *
       
    17 */
       
    18 
       
    19 #include "emailtrace.h"
       
    20 #include "cesmrconflictchecker.h"
       
    21 #include "cesmrcaldbmgr.h"
       
    22 #include "esmrhelper.h"
       
    23 #include "esmrentryhelper.h"
       
    24 #include "esmrinternaluid.h"
       
    25 
       
    26 #include <calcommon.h>
       
    27 #include <calinstance.h>
       
    28 #include <calentryview.h>
       
    29 #include <calinstanceview.h>
       
    30 #include <calinstanceiterator.h>
       
    31 #include <ct/rcpointerarray.h>
       
    32 
       
    33 /// Unnamed namespace for local definitions
       
    34 namespace { // codescanner::namespace
       
    35 
       
    36 // Definition for zero
       
    37 const TInt KZero(0);
       
    38 
       
    39 /** Defines instace filter type */
       
    40 enum TInstanceFilter
       
    41     {
       
    42     EIncludeSameUID,
       
    43     ERemoveSameUID
       
    44     };
       
    45 
       
    46 #ifdef _DEBUG
       
    47 
       
    48 // Literal for panic texts
       
    49 _LIT( KESMRConflictCheckerTxt, "ESMRConflictChecker" );
       
    50 
       
    51 /** Enumeration for panic codes */
       
    52 enum TESMRConflictCheckerPanic
       
    53     {
       
    54     // Input entry is not appointment
       
    55     EESMRConflictCheckerInvalidEntryType
       
    56     };
       
    57 
       
    58 /**
       
    59  * Thows system wide panic.
       
    60  * @param aPanic Panic code.
       
    61  */
       
    62 void Panic( TESMRConflictCheckerPanic aPanic )
       
    63     {
       
    64 
       
    65     User::Panic( KESMRConflictCheckerTxt, aPanic );
       
    66     }
       
    67 
       
    68 #else
       
    69 
       
    70 /**
       
    71  * Thows system wide leave.
       
    72  * @param aError Leave code.
       
    73  */
       
    74 void Leave( TInt aError )
       
    75     {
       
    76 
       
    77     User::Leave( aError );
       
    78     }
       
    79 
       
    80 #endif
       
    81 
       
    82 /**
       
    83  * Resolves time range for possible conflicting entries. Instance view
       
    84  * is used for resolving the time range.
       
    85  *
       
    86  * @param aStart Start time
       
    87  * @param aEnd End time
       
    88  * @param aInstanceView Pointer to calendar db instance view
       
    89  * @return Time range for possible conflicting entries
       
    90  */
       
    91 CalCommon::TCalTimeRange ResolveFetchTimeRangeL(
       
    92         TTime aStart,
       
    93         TTime aEnd,
       
    94         CCalInstanceView* aInstanceView )
       
    95     {
       
    96     FUNC_LOG;
       
    97     const CalCommon::TCalViewFilter instanceFilter = 
       
    98             CalCommon::EIncludeAppts;
       
    99 
       
   100     TDateTime start = aStart.DateTime();
       
   101     TDateTime end   = aEnd.DateTime();
       
   102 
       
   103     start.SetHour( KZero );
       
   104     start.SetMinute( KZero );
       
   105     start.SetSecond( KZero );
       
   106     start.SetMicroSecond( KZero );
       
   107 
       
   108     end.SetHour( KZero );
       
   109     end.SetMinute( KZero );
       
   110     end.SetSecond( KZero );
       
   111     end.SetMicroSecond( KZero );
       
   112     TTime endTime = end;
       
   113     
       
   114     if ( TTime(start) == endTime || 
       
   115          endTime < aEnd )
       
   116         {
       
   117         
       
   118         endTime += TTimeIntervalDays(1);
       
   119         end = endTime.DateTime();
       
   120         }
       
   121 
       
   122     TCalTime rangeStart;
       
   123     rangeStart.SetTimeLocalL( start );
       
   124 
       
   125     TCalTime instanceTime = aInstanceView->PreviousInstanceL(
       
   126             instanceFilter,
       
   127             rangeStart );
       
   128 
       
   129     if (  Time::NullTTime() != instanceTime.TimeUtcL()  )
       
   130         {
       
   131         rangeStart = instanceTime;
       
   132         }
       
   133 
       
   134     TCalTime rangeEnd;
       
   135     rangeEnd.SetTimeLocalL( end );
       
   136 
       
   137     instanceTime = aInstanceView->NextInstanceL(
       
   138             instanceFilter,
       
   139             rangeEnd );
       
   140 
       
   141     if ( instanceTime.TimeLocalL() != Time::NullTTime() )
       
   142         {
       
   143         rangeEnd = instanceTime;
       
   144         }
       
   145 
       
   146     return CalCommon::TCalTimeRange( rangeStart, rangeEnd );
       
   147     }
       
   148 
       
   149 /**
       
   150  * Removes and deletes the entries, which do not conflict with
       
   151  * entry. Entry is considered to be conflicting entry if starts or
       
   152  * ends between aEntry's start and end time.
       
   153  *
       
   154  * @param aEntries Reference to entries, which may conflict
       
   155  * @param aEntry Reference to entry, which confilcts are resolved.
       
   156  */
       
   157 void RemoveAndDeleteNonConflictingInstancesL(
       
   158     RPointerArray<CCalInstance>& instanceArray,
       
   159     TCalTime aStartTime,
       
   160     TCalTime aEndTime,
       
   161     const TDesC8& aUid,
       
   162     TInstanceFilter aFilterType )
       
   163     {
       
   164     FUNC_LOG;
       
   165     TInt index(0);
       
   166 
       
   167     TTime startTimeLocal = aStartTime.TimeLocalL();
       
   168     TTime endTimeLocal = aEndTime.TimeLocalL();
       
   169     
       
   170     while( index < instanceArray.Count() )
       
   171         {
       
   172         TBool conflictingInstance( ETrue );
       
   173         CCalInstance* instance = instanceArray[index];
       
   174         
       
   175         TTime entryStartTimeLocal = instance->StartTimeL().TimeLocalL();
       
   176         TTime entryEndTimeLocal = instance->EndTimeL().TimeLocalL();            
       
   177 
       
   178         TPtrC8 uid( instance->Entry().UidL() );
       
   179         if ( ERemoveSameUID == aFilterType && 
       
   180              0 == aUid.CompareF(uid) )
       
   181             {
       
   182             conflictingInstance = EFalse;
       
   183             }
       
   184         else if ( entryStartTimeLocal >= startTimeLocal &&
       
   185                   entryStartTimeLocal < endTimeLocal )
       
   186             {
       
   187             // Entry starts during another entry
       
   188             index++;
       
   189             }
       
   190         else if ( entryEndTimeLocal > startTimeLocal &&
       
   191                 entryEndTimeLocal <= endTimeLocal )
       
   192             {
       
   193             // Entry ends during another entry
       
   194             index++;
       
   195             }
       
   196         else if ( entryStartTimeLocal < startTimeLocal &&
       
   197                   entryEndTimeLocal > endTimeLocal )
       
   198             {
       
   199             // Antry starts and ends during another entry
       
   200             index++;
       
   201             }
       
   202         else
       
   203             {
       
   204             conflictingInstance = EFalse;            
       
   205             }
       
   206         
       
   207         // Remove non-conflicting instance from instance array
       
   208         if ( !conflictingInstance )
       
   209             {
       
   210             instanceArray.Remove(index);
       
   211             delete instance; 
       
   212             instance = NULL;
       
   213             }
       
   214         }
       
   215     }
       
   216 
       
   217 /**
       
   218  * Creates calendar entries from the conflicting instances
       
   219  * and stores the created entries into entry array.
       
   220  * Ownership of the created entries is transferred to caller.
       
   221  * @param aInstanceArray Reference to instance array
       
   222  * @param aConflictingEntries Reference to entry array.
       
   223  */
       
   224 void CreateEntriesFromInstancesL(
       
   225         RPointerArray<CCalInstance>& instanceArray,
       
   226         RPointerArray<CCalEntry>& aConflictingEntries )
       
   227     {
       
   228     FUNC_LOG;
       
   229     TInt instanceCount( instanceArray.Count() );    
       
   230     for ( TInt i(0); i < instanceCount; ++i )
       
   231         {        
       
   232         CCalEntry& parent( instanceArray[i]->Entry() );
       
   233         CCalEntry* entry = ESMRHelper::CopyEntryLC( parent, 
       
   234                                                     parent.MethodL(),
       
   235                                                     ESMRHelper::ECopyFull );
       
   236         
       
   237         entry->SetStartAndEndTimeL( instanceArray[i]->StartTimeL(),
       
   238                                     instanceArray[i]->EndTimeL() );
       
   239 
       
   240         User::LeaveIfError( aConflictingEntries.Append( entry ) );
       
   241         CleanupStack::Pop( entry );
       
   242         }
       
   243     }
       
   244 
       
   245 }  // namespace
       
   246 
       
   247 // ======== MEMBER FUNCTIONS ========
       
   248 
       
   249 // ---------------------------------------------------------------------------
       
   250 // CESMRConflictChecker::CESMRConflictChecker
       
   251 // ---------------------------------------------------------------------------
       
   252 //
       
   253 inline CESMRConflictChecker::CESMRConflictChecker(
       
   254         MESMRCalDbMgr& aDbMgr ) :
       
   255         iDbMgr( aDbMgr )
       
   256     {
       
   257     FUNC_LOG;
       
   258     // Not implementation yet
       
   259     }
       
   260 
       
   261 // ---------------------------------------------------------------------------
       
   262 // CESMRConflictChecker::~CESMRConflictChecker
       
   263 // ---------------------------------------------------------------------------
       
   264 //
       
   265 EXPORT_C CESMRConflictChecker::~CESMRConflictChecker()
       
   266     {
       
   267     FUNC_LOG;
       
   268     // Not implementation yet
       
   269     }
       
   270 
       
   271 // ---------------------------------------------------------------------------
       
   272 // CESMRConflictChecker::NewL
       
   273 // ---------------------------------------------------------------------------
       
   274 //
       
   275 EXPORT_C CESMRConflictChecker* CESMRConflictChecker::NewL(
       
   276         MESMRCalDbMgr& aDbMgr )
       
   277     {
       
   278     FUNC_LOG;
       
   279     CESMRConflictChecker* self =
       
   280             new (ELeave) CESMRConflictChecker(aDbMgr);
       
   281     return self;
       
   282     }
       
   283 
       
   284 // ---------------------------------------------------------------------------
       
   285 // CESMRConflictChecker::FindConflictsL
       
   286 // ---------------------------------------------------------------------------
       
   287 //
       
   288 EXPORT_C void CESMRConflictChecker::FindConflictsL(
       
   289             const CCalEntry& aEntry,
       
   290             RPointerArray<CCalEntry>& aConflicts )
       
   291     {
       
   292     FUNC_LOG;
       
   293 
       
   294     // Checking input parameters
       
   295 #ifdef _DEBUG
       
   296 
       
   297     __ASSERT_DEBUG(
       
   298             CCalEntry::EAppt == aEntry.EntryTypeL(),
       
   299             Panic(EESMRConflictCheckerInvalidEntryType) );
       
   300 
       
   301 #else
       
   302 
       
   303     if ( CCalEntry::EAppt != aEntry.EntryTypeL() )
       
   304         {
       
   305         Leave( KErrArgument );
       
   306         }
       
   307 
       
   308 #endif
       
   309 
       
   310     // Get instance views of all calendar
       
   311     RPointerArray<CCalInstanceView> allCalenInstanceView = 
       
   312                                     iDbMgr.NormalDbAllCalenInstanceView();
       
   313     
       
   314     RCPointerArray<CCalInstance> instanceArray;
       
   315     CleanupClosePushL( instanceArray );
       
   316     
       
   317     // Check if there is any conflict in each calendar
       
   318     for( TInt i = 0; i < allCalenInstanceView.Count(); i++ )
       
   319         {
       
   320         CalCommon::TCalTimeRange timeRange =
       
   321                     ResolveFetchTimeRangeL( 
       
   322                                     aEntry.StartTimeL().TimeUtcL(),
       
   323                                     aEntry.EndTimeL().TimeUtcL(), 
       
   324                                     allCalenInstanceView[i] );
       
   325         
       
   326         allCalenInstanceView[i]->FindInstanceL( instanceArray,
       
   327                                                 CalCommon::EIncludeAppts,
       
   328                                                 timeRange );
       
   329 
       
   330 
       
   331         }
       
   332     
       
   333     RemoveAndDeleteNonConflictingInstancesL(
       
   334                                     instanceArray,
       
   335                                     aEntry.StartTimeL(),
       
   336                                     aEntry.EndTimeL(),
       
   337                                     aEntry.UidL(),
       
   338                                     ERemoveSameUID );
       
   339     
       
   340     CreateEntriesFromInstancesL( instanceArray, aConflicts );
       
   341     CleanupStack::PopAndDestroy(); // instanceArray
       
   342     }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // CESMRConflictChecker::FindInstancesForEntry
       
   346 // ---------------------------------------------------------------------------
       
   347 //
       
   348 EXPORT_C void CESMRConflictChecker::FindInstancesForEntryL(
       
   349         TTime aStart, 
       
   350         TTime aEnd,
       
   351         const CCalEntry& aEntry,
       
   352         TCalCollectionId aColId, 
       
   353         RPointerArray<CCalEntry>& aInstances )
       
   354     {
       
   355     FUNC_LOG;
       
   356     CCalInstanceView* instanceView = iDbMgr.InstanceViewL( aEntry );
       
   357 
       
   358     RCPointerArray<CCalInstance> instanceArray;
       
   359     CleanupClosePushL( instanceArray );
       
   360 
       
   361     // First we need the parent entry of the series ...
       
   362     CCalInstance* entryInstance = instanceView->FindInstanceL( 
       
   363     		aEntry.LocalUidL(), 
       
   364     		aEntry.StartTimeL() ); //Ownership gained
       
   365     CleanupStack::PushL( entryInstance );
       
   366 
       
   367     CCalInstance* parentEntryInstance = instanceView->FindInstanceL( 
       
   368     		aEntry.LocalUidL(), 
       
   369     		entryInstance->Entry().StartTimeL() );
       
   370     CleanupStack::PopAndDestroy( entryInstance );
       
   371     CleanupStack::PushL( parentEntryInstance );
       
   372     
       
   373     // ... And the parent entry instances start time
       
   374     TCalTime firstIntanceStartTime( parentEntryInstance->StartTimeL() );
       
   375 
       
   376     CleanupStack::Pop( parentEntryInstance ); // ownership given to instanceArray
       
   377     instanceArray.Append( parentEntryInstance );
       
   378 
       
   379     // Let's get all instances which have same uid and collection id
       
   380     // as the aEntry to an iterator.
       
   381     CCalInstanceIterator* instanceIterator = instanceView->FindInstanceByUidL( 
       
   382     		aColId, 
       
   383     		aEntry.UidL(), 
       
   384     		firstIntanceStartTime );
       
   385     CleanupStack::PushL( instanceIterator );
       
   386     
       
   387     TInt count( instanceIterator->Count() );
       
   388     
       
   389     for( TInt i = 0; i < count; ++i )
       
   390     	{
       
   391 		CCalInstance* instance = NULL;
       
   392 		TRAPD( err, instance = instanceIterator->NextL() ); //Ownership gained
       
   393 		if( !err && instance )
       
   394 			{
       
   395 			instanceArray.Append( instance );	
       
   396 			}
       
   397     	}
       
   398 
       
   399     CleanupStack::PopAndDestroy( instanceIterator );
       
   400 
       
   401     // Now the instanceArray has all instances of the aEntry, 
       
   402     // let's remove this instance == instance of aEntry, from the array
       
   403 	TInt i( 0 );
       
   404     while( i < instanceArray.Count() )
       
   405     	{
       
   406 		CCalInstance* instance = instanceArray[i];
       
   407 		
       
   408         TBool thisInstance( 
       
   409                 instance->StartTimeL().TimeLocalL() == 
       
   410                 aEntry.StartTimeL().TimeLocalL() &&
       
   411                 instance->EndTimeL().TimeLocalL() == 
       
   412                 aEntry.EndTimeL().TimeLocalL() );
       
   413         
       
   414         if( thisInstance )
       
   415         	{
       
   416 			delete instance;
       
   417 			instanceArray.Remove( i );  
       
   418         	}
       
   419         else
       
   420         	{
       
   421 			++i;
       
   422         	}
       
   423     	}
       
   424   
       
   425     TCalTime start;
       
   426     start.SetTimeLocalL( aStart );
       
   427     
       
   428     TCalTime end;
       
   429     end.SetTimeLocalL( aEnd );
       
   430 
       
   431     RemoveAndDeleteNonConflictingInstancesL(
       
   432             instanceArray,
       
   433             start,
       
   434             end,
       
   435             aEntry.UidL(),
       
   436             EIncludeSameUID );
       
   437     
       
   438     CreateEntriesFromInstancesL( instanceArray, aInstances );
       
   439     
       
   440     CleanupStack::PopAndDestroy(); // instanceArray    
       
   441     }
       
   442 
       
   443 // EOF
       
   444