meetingrequest/mrservices/src/cesmrconflictchecker.cpp
branchRCL_3
changeset 64 3533d4323edc
child 80 726fba06891a
equal deleted inserted replaced
63:d189ee25cf9d 64:3533d4323edc
       
     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#9 %
       
    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 #include <calrrule.h>
       
    33 
       
    34 /// Unnamed namespace for local definitions
       
    35 namespace { // codescanner::namespace
       
    36 
       
    37 // Definition for zero
       
    38 const TInt KZero(0);
       
    39 
       
    40 /** Defines instace filter type */
       
    41 enum TInstanceFilter
       
    42     {
       
    43     EIncludeSameUID,
       
    44     ERemoveSameUID
       
    45     };
       
    46 
       
    47 #ifdef _DEBUG
       
    48 
       
    49 // Literal for panic texts
       
    50 _LIT( KESMRConflictCheckerTxt, "ESMRConflictChecker" );
       
    51 
       
    52 /** Enumeration for panic codes */
       
    53 enum TESMRConflictCheckerPanic
       
    54     {
       
    55     // Input entry is not appointment
       
    56     EESMRConflictCheckerInvalidEntryType
       
    57     };
       
    58 
       
    59 /**
       
    60  * Thows system wide panic.
       
    61  * @param aPanic Panic code.
       
    62  */
       
    63 void Panic( TESMRConflictCheckerPanic aPanic )
       
    64     {
       
    65 
       
    66     User::Panic( KESMRConflictCheckerTxt, aPanic );
       
    67     }
       
    68 
       
    69 #else
       
    70 
       
    71 /**
       
    72  * Thows system wide leave.
       
    73  * @param aError Leave code.
       
    74  */
       
    75 void Leave( TInt aError )
       
    76     {
       
    77 
       
    78     User::Leave( aError );
       
    79     }
       
    80 
       
    81 #endif
       
    82 
       
    83 /**
       
    84  * Resolves time range for possible conflicting entries. Instance view
       
    85  * is used for resolving the time range.
       
    86  *
       
    87  * @param aStart Start time
       
    88  * @param aEnd End time
       
    89  * @param aInstanceView Pointer to calendar db instance view
       
    90  * @return Time range for possible conflicting entries
       
    91  */
       
    92 CalCommon::TCalTimeRange ResolveFetchTimeRangeL(
       
    93         TTime aStart,
       
    94         TTime aEnd,
       
    95         CCalInstanceView* aInstanceView )
       
    96     {
       
    97     FUNC_LOG;
       
    98     const CalCommon::TCalViewFilter instanceFilter =
       
    99             CalCommon::EIncludeAppts;
       
   100 
       
   101     TDateTime start = aStart.DateTime();
       
   102     TDateTime end   = aEnd.DateTime();
       
   103 
       
   104     start.SetHour( KZero );
       
   105     start.SetMinute( KZero );
       
   106     start.SetSecond( KZero );
       
   107     start.SetMicroSecond( KZero );
       
   108 
       
   109     end.SetHour( KZero );
       
   110     end.SetMinute( KZero );
       
   111     end.SetSecond( KZero );
       
   112     end.SetMicroSecond( KZero );
       
   113     TTime endTime = end;
       
   114 
       
   115     if ( TTime(start) == endTime ||
       
   116          endTime < aEnd )
       
   117         {
       
   118 
       
   119         endTime += TTimeIntervalDays(1);
       
   120         end = endTime.DateTime();
       
   121         }
       
   122 
       
   123     TCalTime rangeStart;
       
   124     rangeStart.SetTimeLocalL( start );
       
   125 
       
   126     TCalTime instanceTime = aInstanceView->PreviousInstanceL(
       
   127             instanceFilter,
       
   128             rangeStart );
       
   129 
       
   130     if (  Time::NullTTime() != instanceTime.TimeUtcL()  )
       
   131         {
       
   132         rangeStart = instanceTime;
       
   133         }
       
   134 
       
   135     TCalTime rangeEnd;
       
   136     rangeEnd.SetTimeLocalL( end );
       
   137 
       
   138     instanceTime = aInstanceView->NextInstanceL(
       
   139             instanceFilter,
       
   140             rangeEnd );
       
   141 
       
   142     if ( instanceTime.TimeLocalL() != Time::NullTTime() )
       
   143         {
       
   144         rangeEnd = instanceTime;
       
   145         }
       
   146 
       
   147     return CalCommon::TCalTimeRange( rangeStart, rangeEnd );
       
   148     }
       
   149 
       
   150 /**
       
   151  * Removes and deletes the entries, which do not conflict with
       
   152  * entry. Entry is considered to be conflicting entry if starts or
       
   153  * ends between aEntry's start and end time.
       
   154  *
       
   155  * @param aEntries Reference to entries, which may conflict
       
   156  * @param aEntry Reference to entry, which confilcts are resolved.
       
   157  */
       
   158 void RemoveAndDeleteNonConflictingInstancesL(
       
   159     RPointerArray<CCalInstance>& instanceArray,
       
   160     TCalTime aStartTime,
       
   161     TCalTime aEndTime,
       
   162     const TDesC8& aUid,
       
   163     TInstanceFilter aFilterType )
       
   164     {
       
   165     FUNC_LOG;
       
   166     TInt index(0);
       
   167 
       
   168     TTime startTimeLocal = aStartTime.TimeLocalL();
       
   169     TTime endTimeLocal = aEndTime.TimeLocalL();
       
   170 
       
   171     while( index < instanceArray.Count() )
       
   172         {
       
   173         TBool conflictingInstance( ETrue );
       
   174         CCalInstance* instance = instanceArray[index];
       
   175 
       
   176         TTime entryStartTimeLocal = instance->StartTimeL().TimeLocalL();
       
   177         TTime entryEndTimeLocal = instance->EndTimeL().TimeLocalL();
       
   178 
       
   179         TPtrC8 uid( instance->Entry().UidL() );
       
   180         if ( ERemoveSameUID == aFilterType &&
       
   181              0 == aUid.CompareF(uid) )
       
   182             {
       
   183             conflictingInstance = EFalse;
       
   184             }
       
   185         else if ( entryStartTimeLocal >= startTimeLocal &&
       
   186                   entryStartTimeLocal < endTimeLocal )
       
   187             {
       
   188             // Entry starts during another entry
       
   189             index++;
       
   190             }
       
   191         else if ( entryEndTimeLocal > startTimeLocal &&
       
   192                 entryEndTimeLocal <= endTimeLocal )
       
   193             {
       
   194             // Entry ends during another entry
       
   195             index++;
       
   196             }
       
   197         else if ( entryStartTimeLocal < startTimeLocal &&
       
   198                   entryEndTimeLocal > endTimeLocal )
       
   199             {
       
   200             // Antry starts and ends during another entry
       
   201             index++;
       
   202             }
       
   203         else
       
   204             {
       
   205             conflictingInstance = EFalse;
       
   206             }
       
   207 
       
   208         // Remove non-conflicting instance from instance array
       
   209         if ( !conflictingInstance )
       
   210             {
       
   211             instanceArray.Remove(index);
       
   212             delete instance;
       
   213             instance = NULL;
       
   214             }
       
   215         }
       
   216     }
       
   217 
       
   218 /**
       
   219  * Creates calendar entries from the conflicting instances
       
   220  * and stores the created entries into entry array.
       
   221  * Ownership of the created entries is transferred to caller.
       
   222  * @param aInstanceArray Reference to instance array
       
   223  * @param aConflictingEntries Reference to entry array.
       
   224  */
       
   225 void CreateEntriesFromInstancesL(
       
   226         RPointerArray<CCalInstance>& instanceArray,
       
   227         RPointerArray<CCalEntry>& aConflictingEntries )
       
   228     {
       
   229     FUNC_LOG;
       
   230     TInt instanceCount( instanceArray.Count() );
       
   231     for ( TInt i(0); i < instanceCount; ++i )
       
   232         {
       
   233         CCalEntry& parent( instanceArray[i]->Entry() );
       
   234         CCalEntry* entry = ESMRHelper::CopyEntryLC( parent,
       
   235                                                     parent.MethodL(),
       
   236                                                     ESMRHelper::ECopyFull );
       
   237 
       
   238         entry->SetStartAndEndTimeL( instanceArray[i]->StartTimeL(),
       
   239                                     instanceArray[i]->EndTimeL() );
       
   240 
       
   241         aConflictingEntries.AppendL( entry );
       
   242         CleanupStack::Pop( entry );
       
   243         }
       
   244     }
       
   245 
       
   246 /**
       
   247  * Checks if entry is repeating.
       
   248  * @return ETrue if entry is repeating
       
   249  */
       
   250 TBool IsRepeatingMeetingL( const CCalEntry& aEntry,
       
   251                            MESMRCalDbMgr& aDb )
       
   252     {
       
   253     FUNC_LOG;
       
   254 
       
   255     TBool recurrent( EFalse );
       
   256 
       
   257     CCalInstance* instance = aDb.FindInstanceL( aEntry );
       
   258 
       
   259     if ( instance )
       
   260         {
       
   261         CleanupStack::PushL( instance );
       
   262         recurrent = ESMREntryHelper::IsRepeatingMeetingL( instance->Entry() );
       
   263         CleanupStack::PopAndDestroy( instance );
       
   264         }
       
   265     else
       
   266         {
       
   267         recurrent = ESMREntryHelper::IsRepeatingMeetingL( aEntry );
       
   268         }
       
   269 
       
   270     return recurrent;
       
   271     }
       
   272 
       
   273 /**
       
   274  * Finds conflicts for entry
       
   275  */
       
   276 void FindConflictsForEntryL(
       
   277         const CCalEntry& aEntry,
       
   278         RPointerArray< CCalInstance >& aInstances,
       
   279         MESMRCalDbMgr& aDb )
       
   280     {
       
   281     FUNC_LOG;
       
   282 
       
   283     // Get instance views of all calendar
       
   284     RPointerArray<CCalInstanceView> allCalenInstanceView =
       
   285             aDb.NormalDbAllCalenInstanceView();
       
   286 
       
   287     // Check if there is any conflict in each calendar
       
   288     for( TInt i = 0; i < allCalenInstanceView.Count(); i++ )
       
   289         {
       
   290         CalCommon::TCalTimeRange timeRange =
       
   291                     ResolveFetchTimeRangeL(
       
   292                                     aEntry.StartTimeL().TimeUtcL(),
       
   293                                     aEntry.EndTimeL().TimeUtcL(),
       
   294                                     allCalenInstanceView[i] );
       
   295 
       
   296         allCalenInstanceView[i]->FindInstanceL(
       
   297                 aInstances,
       
   298                 CalCommon::EIncludeAppts,
       
   299                 timeRange );
       
   300         }
       
   301 
       
   302     RemoveAndDeleteNonConflictingInstancesL(
       
   303             aInstances,
       
   304             aEntry.StartTimeL(),
       
   305             aEntry.EndTimeL(),
       
   306             aEntry.UidL(),
       
   307             ERemoveSameUID );
       
   308     }
       
   309 
       
   310 /**
       
   311  * Moves instances from an array to another.
       
   312  */
       
   313 void MoveInstancesL(
       
   314         RPointerArray< CCalInstance >& aFrom,
       
   315         RPointerArray< CCalInstance >& aTo )
       
   316     {
       
   317     FUNC_LOG;
       
   318 
       
   319     aTo.ReserveL( aTo.Count() + aFrom.Count() );
       
   320     while ( aFrom.Count() )
       
   321         {
       
   322         aTo.AppendL( aFrom[ 0 ] );
       
   323         aFrom.Remove( 0 );
       
   324         }
       
   325     }
       
   326 
       
   327 /**
       
   328  * Finds conflicts based on Daily recurrence.
       
   329  *
       
   330  */
       
   331 void FindConflictsForDailyRRuleL(
       
   332         CCalEntry& aEntry,
       
   333         RPointerArray< CCalInstance >& aInstances,
       
   334         MESMRCalDbMgr& aDb,
       
   335         TBool aFindAllConflicts )
       
   336     {
       
   337     FUNC_LOG;
       
   338 
       
   339     TCalRRule rRule;
       
   340     aEntry.GetRRuleL( rRule );
       
   341     RCPointerArray< CCalInstance > tmpInstanceArray;
       
   342     CleanupClosePushL( tmpInstanceArray );
       
   343 
       
   344     // Entry start and end time
       
   345     TTime start( aEntry.StartTimeL().TimeUtcL() );
       
   346     TTime end( aEntry.EndTimeL().TimeUtcL() );
       
   347 
       
   348     if ( rRule.Count() )
       
   349         {
       
   350         for ( TInt i = 0; i < rRule.Count(); ++i )
       
   351             {
       
   352             // Set each occurence start and end time on entry
       
   353             TTimeIntervalDays interval( i * rRule.Interval() );
       
   354             TCalTime startTime;
       
   355             startTime.SetTimeUtcL( start + interval );
       
   356             TCalTime endTime;
       
   357             endTime.SetTimeUtcL( end + interval );
       
   358             aEntry.SetStartAndEndTimeL(
       
   359                     startTime,
       
   360                     endTime );
       
   361 
       
   362             // Find conflicts for this occurence
       
   363             FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
       
   364 
       
   365             if ( tmpInstanceArray.Count() )
       
   366                 {
       
   367                 MoveInstancesL( tmpInstanceArray, aInstances );
       
   368                 if ( !aFindAllConflicts )
       
   369                     {
       
   370                     break;
       
   371                     }
       
   372                 }
       
   373             }
       
   374         }
       
   375     else if ( rRule.Until().TimeUtcL() != Time::NullTTime() )
       
   376         {
       
   377         TTime until( rRule.Until().TimeUtcL() );
       
   378         TTime start( aEntry.StartTimeL().TimeUtcL() );
       
   379         TTime end( aEntry.EndTimeL().TimeUtcL() );
       
   380         TTimeIntervalDays interval( rRule.Interval() );
       
   381 
       
   382         // Loop while start time is before until time
       
   383         while ( start <= until )
       
   384             {
       
   385             // Set start and end time for occurence
       
   386             TCalTime startTime;
       
   387             startTime.SetTimeUtcL( start );
       
   388             TCalTime endTime;
       
   389             endTime.SetTimeUtcL( end );
       
   390             aEntry.SetStartAndEndTimeL(
       
   391                     startTime,
       
   392                     endTime );
       
   393 
       
   394             // Find conflicts
       
   395             FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
       
   396 
       
   397             if ( tmpInstanceArray.Count() )
       
   398                 {
       
   399                 MoveInstancesL( tmpInstanceArray, aInstances );
       
   400                 if ( !aFindAllConflicts )
       
   401                     {
       
   402                     break;
       
   403                     }
       
   404                 }
       
   405 
       
   406             // Move to next occurence
       
   407             start += interval;
       
   408             end += interval;
       
   409             }
       
   410         }
       
   411 
       
   412     CleanupStack::PopAndDestroy( &tmpInstanceArray );
       
   413     }
       
   414 
       
   415 /**
       
   416  * Finds conflicts based on Weekly recurrence.
       
   417  */
       
   418 void FindConflictsForWeeklyRRuleL(
       
   419         CCalEntry& aEntry,
       
   420         RPointerArray< CCalInstance >& aInstances,
       
   421         MESMRCalDbMgr& aDb,
       
   422         TBool aFindAllConflicts )
       
   423     {
       
   424     FUNC_LOG;
       
   425 
       
   426     TCalRRule rRule;
       
   427     aEntry.GetRRuleL( rRule );
       
   428 
       
   429     // Tmp array for conflic instances
       
   430     RCPointerArray< CCalInstance > tmpInstanceArray;
       
   431     CleanupClosePushL( tmpInstanceArray );
       
   432 
       
   433     // Array of recurrence days
       
   434     RArray< TDay > days;
       
   435     CleanupClosePushL( days );
       
   436     rRule.GetByDayL( days );
       
   437 
       
   438     // Recurrence start time
       
   439     TTime start( aEntry.StartTimeL().TimeUtcL() );
       
   440     // Recurrence end time
       
   441     TTime end( aEntry.EndTimeL().TimeUtcL() );
       
   442     const TTimeIntervalDays KWeek( 7 );
       
   443     TDay startDayOfWeek( start.DayNoInWeek() );
       
   444 
       
   445     // Instance duration
       
   446     TTimeIntervalMinutes duration;
       
   447     end.MinutesFrom( start, duration );
       
   448 
       
   449     if ( rRule.Count() )
       
   450         {
       
   451         for ( TInt i = 0; i < rRule.Count(); ++i )
       
   452             {
       
   453             // Calculate weekly start time
       
   454             TTimeIntervalDays interval( i* KWeek.Int() );
       
   455             TDateTime date( TTime( start + interval ).DateTime() );
       
   456             date.SetDay( date.Day() - startDayOfWeek );
       
   457             TTime weekStartTime( date );
       
   458 
       
   459             for ( TInt j = 0; j < days.Count(); ++j )
       
   460                 {
       
   461                 // Iterate through days of week
       
   462                 TTime entryStartTime( weekStartTime + TTimeIntervalDays( days[ j ] ) );
       
   463 
       
   464                 if ( start <= entryStartTime )
       
   465                     {
       
   466                     // Start time is in recurrence range
       
   467                     // Calcualte end time
       
   468                     TCalTime startCalTime;
       
   469                     startCalTime.SetTimeUtcL( entryStartTime );
       
   470                     TCalTime endCalTime;
       
   471                     endCalTime.SetTimeUtcL( entryStartTime + duration );
       
   472                     aEntry.SetStartAndEndTimeL( startCalTime, endCalTime );
       
   473 
       
   474                     // Find conflicts of for entry and move them to result array
       
   475                     FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
       
   476 
       
   477                     if ( tmpInstanceArray.Count() )
       
   478                         {
       
   479                         MoveInstancesL( tmpInstanceArray, aInstances );
       
   480                         if ( !aFindAllConflicts )
       
   481                             {
       
   482                             break;
       
   483                             }
       
   484                         }
       
   485                     }
       
   486                 }
       
   487 
       
   488             if ( !aFindAllConflicts && aInstances.Count() )
       
   489                 {
       
   490                 break;
       
   491                 }
       
   492             }
       
   493         }
       
   494     else if ( rRule.Until().TimeUtcL() != Time::NullTTime() )
       
   495         {
       
   496         TDateTime date( start.DateTime() );
       
   497         date.SetDay( date.Day() - startDayOfWeek );
       
   498         TTime weekStartTime( date );
       
   499         TTime until( rRule.Until().TimeUtcL() );
       
   500 
       
   501         while ( weekStartTime < until )
       
   502             {
       
   503             for ( TInt j = 0; j < days.Count(); ++j )
       
   504                 {
       
   505                 // Iterate through days of week
       
   506                 TTime entryStartTime( weekStartTime + TTimeIntervalDays( days[ j ] ) );
       
   507 
       
   508                 if ( start <= entryStartTime )
       
   509                     {
       
   510                     // Start time is in recurrence range
       
   511                     // Calculate end time
       
   512                     TCalTime startCalTime;
       
   513                     startCalTime.SetTimeUtcL( entryStartTime );
       
   514                     TCalTime endCalTime;
       
   515                     endCalTime.SetTimeUtcL( entryStartTime + duration );
       
   516                     aEntry.SetStartAndEndTimeL( startCalTime, endCalTime );
       
   517 
       
   518                     // Find conflicts of for entry and move them to result array
       
   519                     FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
       
   520 
       
   521                     if ( tmpInstanceArray.Count() )
       
   522                         {
       
   523                         MoveInstancesL( tmpInstanceArray, aInstances );
       
   524                         if ( !aFindAllConflicts )
       
   525                             {
       
   526                             break;
       
   527                             }
       
   528                         }
       
   529                     }
       
   530                 }
       
   531 
       
   532             if ( !aFindAllConflicts && aInstances.Count() )
       
   533                 {
       
   534                 break;
       
   535                 }
       
   536             else
       
   537                 {
       
   538                 weekStartTime += KWeek;
       
   539                 }
       
   540             }
       
   541         }
       
   542 
       
   543     CleanupStack::PopAndDestroy( &days );
       
   544     CleanupStack::PopAndDestroy( &tmpInstanceArray );
       
   545     }
       
   546 
       
   547 /**
       
   548  * Finds conflict for recurrent entry
       
   549  */
       
   550 void FindConflictsForRepeatingMeetingL(
       
   551         const CCalEntry& aEntry,
       
   552         RPointerArray< CCalInstance >& aInstances,
       
   553         MESMRCalDbMgr& aDb,
       
   554         TBool aFindAllConflicts )
       
   555     {
       
   556     FUNC_LOG;
       
   557 
       
   558     CCalInstance* instance = aDb.FindInstanceL( aEntry );
       
   559 
       
   560     if ( instance ) // Instance is stored
       
   561         {
       
   562         CleanupStack::PushL( instance );
       
   563         RCPointerArray< CCalInstance > tmpInstanceArray;
       
   564         CleanupClosePushL( tmpInstanceArray );
       
   565 
       
   566         CCalEntry& parent = instance->Entry();
       
   567         CCalInstanceView* instanceView = aDb.InstanceViewL( parent );
       
   568         CCalInstanceIterator* iterator = instanceView->FindInstanceByUidL(
       
   569                         parent.UidL(),
       
   570                         parent.StartTimeL() );
       
   571         CleanupStack::PushL( iterator );
       
   572         CCalEntry* entry = ESMRHelper::CopyEntryLC(
       
   573                             parent,
       
   574                             parent.MethodL(),
       
   575                             ESMRHelper::ECopyFull );
       
   576 
       
   577         while ( iterator->HasMore() )
       
   578             {
       
   579             CCalInstance* next = iterator->NextL();
       
   580             CleanupStack::PushL( next );
       
   581             entry->SetStartAndEndTimeL( next->StartTimeL(), next->EndTimeL() );
       
   582             CleanupStack::PopAndDestroy( next );
       
   583             FindConflictsForEntryL( *entry,
       
   584                                     tmpInstanceArray,
       
   585                                     aDb );
       
   586 
       
   587             if ( tmpInstanceArray.Count() )
       
   588                 {
       
   589                 MoveInstancesL( tmpInstanceArray, aInstances );
       
   590 
       
   591                 if ( !aFindAllConflicts )
       
   592                     {
       
   593                     break;
       
   594                     }
       
   595                 }
       
   596             }
       
   597 
       
   598         CleanupStack::PopAndDestroy( entry );
       
   599 
       
   600         CleanupStack::PopAndDestroy( iterator );
       
   601 
       
   602         if ( aFindAllConflicts
       
   603              || !aInstances.Count() )
       
   604             {
       
   605             // Find conflicts also for parent entry
       
   606             FindConflictsForEntryL( parent, tmpInstanceArray, aDb );
       
   607             MoveInstancesL( tmpInstanceArray, aInstances );
       
   608             }
       
   609 
       
   610         CleanupStack::PopAndDestroy( &tmpInstanceArray );
       
   611         CleanupStack::PopAndDestroy( instance );
       
   612         }
       
   613     else // Entry is not stored yet
       
   614         {
       
   615         CCalEntry* entry = ESMRHelper::CopyEntryLC(
       
   616                 aEntry,
       
   617                 aEntry.MethodL(),
       
   618                 ESMRHelper::ECopyFull );
       
   619 
       
   620         TCalRRule rRule;
       
   621         if ( aEntry.GetRRuleL( rRule ) )
       
   622             {
       
   623             switch ( rRule.Type() )
       
   624                 {
       
   625                 case TCalRRule::EDaily:
       
   626                     {
       
   627                     FindConflictsForDailyRRuleL(
       
   628                             *entry,
       
   629                             aInstances,
       
   630                             aDb,
       
   631                             aFindAllConflicts );
       
   632                     break;
       
   633                     }
       
   634                 case TCalRRule::EWeekly:
       
   635                     {
       
   636                     FindConflictsForWeeklyRRuleL(
       
   637                             *entry,
       
   638                             aInstances,
       
   639                             aDb,
       
   640                             aFindAllConflicts );
       
   641                     break;
       
   642                     }
       
   643                 default:
       
   644                     break;
       
   645                 }
       
   646             }
       
   647         else
       
   648             {
       
   649             // Entry has RDates set
       
   650             RCPointerArray< CCalInstance > tmpInstanceArray;
       
   651             CleanupClosePushL( tmpInstanceArray );
       
   652 
       
   653             RArray< TCalTime > rDates;
       
   654             CleanupClosePushL( rDates );
       
   655             aEntry.GetRDatesL( rDates );
       
   656 
       
   657             // Get entry start time, end time and duration
       
   658             TTime start( aEntry.StartTimeL().TimeUtcL() );
       
   659             TTime end( aEntry.EndTimeL().TimeUtcL() );
       
   660             TTimeIntervalMinutes duration(0);
       
   661             end.MinutesFrom(
       
   662                     start,
       
   663                     duration );
       
   664 
       
   665             for ( TInt i = 0; i < rDates.Count(); ++i )
       
   666                 {
       
   667                 // Set start and end times for entry
       
   668                 TCalTime startTime( rDates[ i ] );
       
   669                 TCalTime endTime;
       
   670                 endTime.SetTimeUtcL( startTime.TimeUtcL() + duration );
       
   671                 entry->SetStartAndEndTimeL( startTime, endTime );
       
   672 
       
   673                 // Find conflicts
       
   674                 FindConflictsForEntryL( *entry, tmpInstanceArray, aDb );
       
   675 
       
   676                 if ( tmpInstanceArray.Count() )
       
   677                     {
       
   678                     MoveInstancesL( tmpInstanceArray, aInstances );
       
   679                     if ( !aFindAllConflicts )
       
   680                         {
       
   681                         break;
       
   682                         }
       
   683                     }
       
   684                 }
       
   685 
       
   686             CleanupStack::PopAndDestroy( &rDates );
       
   687 
       
   688             if ( aFindAllConflicts
       
   689                  || aInstances.Count() == 0 )
       
   690                 {
       
   691                 // Find conflicts for parent entry
       
   692                 FindConflictsForEntryL( aEntry, tmpInstanceArray, aDb );
       
   693                 MoveInstancesL( tmpInstanceArray, aInstances );
       
   694                 }
       
   695 
       
   696             CleanupStack::PopAndDestroy( &tmpInstanceArray );
       
   697             }
       
   698 
       
   699         CleanupStack::PopAndDestroy( entry );
       
   700         }
       
   701     }
       
   702 
       
   703 }  // namespace
       
   704 
       
   705 // ======== MEMBER FUNCTIONS ========
       
   706 
       
   707 // ---------------------------------------------------------------------------
       
   708 // CESMRConflictChecker::CESMRConflictChecker
       
   709 // ---------------------------------------------------------------------------
       
   710 //
       
   711 inline CESMRConflictChecker::CESMRConflictChecker(
       
   712         MESMRCalDbMgr& aDbMgr ) :
       
   713         iDbMgr( aDbMgr )
       
   714     {
       
   715     FUNC_LOG;
       
   716     // Not implementation yet
       
   717     }
       
   718 
       
   719 // ---------------------------------------------------------------------------
       
   720 // CESMRConflictChecker::~CESMRConflictChecker
       
   721 // ---------------------------------------------------------------------------
       
   722 //
       
   723 EXPORT_C CESMRConflictChecker::~CESMRConflictChecker()
       
   724     {
       
   725     FUNC_LOG;
       
   726     // Not implementation yet
       
   727     }
       
   728 
       
   729 // ---------------------------------------------------------------------------
       
   730 // CESMRConflictChecker::NewL
       
   731 // ---------------------------------------------------------------------------
       
   732 //
       
   733 EXPORT_C CESMRConflictChecker* CESMRConflictChecker::NewL(
       
   734         MESMRCalDbMgr& aDbMgr )
       
   735     {
       
   736     FUNC_LOG;
       
   737     CESMRConflictChecker* self =
       
   738             new (ELeave) CESMRConflictChecker(aDbMgr);
       
   739     return self;
       
   740     }
       
   741 
       
   742 // ---------------------------------------------------------------------------
       
   743 // CESMRConflictChecker::FindConflictsL
       
   744 // ---------------------------------------------------------------------------
       
   745 //
       
   746 EXPORT_C void CESMRConflictChecker::FindConflictsL(
       
   747             const CCalEntry& aEntry,
       
   748             RPointerArray<CCalEntry>& aConflicts )
       
   749     {
       
   750     FUNC_LOG;
       
   751 
       
   752     // Checking input parameters
       
   753 #ifdef _DEBUG
       
   754 
       
   755     __ASSERT_DEBUG(
       
   756             CCalEntry::EAppt == aEntry.EntryTypeL(),
       
   757             Panic(EESMRConflictCheckerInvalidEntryType) );
       
   758 
       
   759 #else
       
   760 
       
   761     if ( CCalEntry::EAppt != aEntry.EntryTypeL() )
       
   762         {
       
   763         Leave( KErrArgument );
       
   764         }
       
   765 
       
   766 #endif
       
   767 
       
   768     RCPointerArray<CCalInstance> instanceArray;
       
   769     CleanupClosePushL( instanceArray );
       
   770 
       
   771     if ( IsRepeatingMeetingL( aEntry, iDbMgr ) )
       
   772         {
       
   773         FindConflictsForRepeatingMeetingL(
       
   774                 aEntry,
       
   775                 instanceArray,
       
   776                 iDbMgr,
       
   777                 EFalse );
       
   778         }
       
   779     else
       
   780         {
       
   781         FindConflictsForEntryL(
       
   782                 aEntry,
       
   783                 instanceArray,
       
   784                 iDbMgr );
       
   785         }
       
   786 
       
   787     CreateEntriesFromInstancesL( instanceArray, aConflicts );
       
   788     CleanupStack::PopAndDestroy( &instanceArray);
       
   789     }
       
   790 
       
   791 // ---------------------------------------------------------------------------
       
   792 // CESMRConflictChecker::FindInstancesForEntry
       
   793 // ---------------------------------------------------------------------------
       
   794 //
       
   795 EXPORT_C void CESMRConflictChecker::FindInstancesForEntryL(
       
   796         TTime aStart,
       
   797         TTime aEnd,
       
   798         const CCalEntry& aEntry,
       
   799         TCalCollectionId aColId,
       
   800         RPointerArray<CCalEntry>& aInstances )
       
   801     {
       
   802     FUNC_LOG;
       
   803     CCalInstanceView* instanceView = iDbMgr.InstanceViewL( aEntry );
       
   804 
       
   805     RCPointerArray<CCalInstance> instanceArray;
       
   806     CleanupClosePushL( instanceArray );
       
   807 
       
   808     // First we need the parent entry of the series ...
       
   809     CCalInstance* entryInstance = instanceView->FindInstanceL(
       
   810     		aEntry.LocalUidL(),
       
   811     		aEntry.StartTimeL() ); //Ownership gained
       
   812     CleanupStack::PushL( entryInstance );
       
   813 
       
   814     CCalInstance* parentEntryInstance = instanceView->FindInstanceL(
       
   815     		aEntry.LocalUidL(),
       
   816     		entryInstance->Entry().StartTimeL() );
       
   817     CleanupStack::PopAndDestroy( entryInstance );
       
   818     CleanupStack::PushL( parentEntryInstance );
       
   819 
       
   820     // ... And the parent entry instances start time
       
   821     TCalTime firstIntanceStartTime( parentEntryInstance->StartTimeL() );
       
   822 
       
   823     CleanupStack::Pop( parentEntryInstance ); // ownership given to instanceArray
       
   824     instanceArray.Append( parentEntryInstance );
       
   825 
       
   826     // Let's get all instances which have same uid and collection id
       
   827     // as the aEntry to an iterator.
       
   828     CCalInstanceIterator* instanceIterator = instanceView->FindInstanceByUidL(
       
   829     		aColId,
       
   830     		aEntry.UidL(),
       
   831     		firstIntanceStartTime );
       
   832     CleanupStack::PushL( instanceIterator );
       
   833 
       
   834     TInt count( instanceIterator->Count() );
       
   835 
       
   836     for( TInt i = 0; i < count; ++i )
       
   837     	{
       
   838 		CCalInstance* instance = NULL;
       
   839 		TRAPD( err, instance = instanceIterator->NextL() ); //Ownership gained
       
   840 		if( !err && instance )
       
   841 			{
       
   842 			instanceArray.Append( instance );
       
   843 			}
       
   844     	}
       
   845 
       
   846     CleanupStack::PopAndDestroy( instanceIterator );
       
   847 
       
   848     // Now the instanceArray has all instances of the aEntry,
       
   849     // let's remove this instance == instance of aEntry, from the array
       
   850 	TInt i( 0 );
       
   851     while( i < instanceArray.Count() )
       
   852     	{
       
   853 		CCalInstance* instance = instanceArray[i];
       
   854 
       
   855         TBool thisInstance(
       
   856                 instance->StartTimeL().TimeLocalL() ==
       
   857                 aEntry.StartTimeL().TimeLocalL() &&
       
   858                 instance->EndTimeL().TimeLocalL() ==
       
   859                 aEntry.EndTimeL().TimeLocalL() );
       
   860 
       
   861         if( thisInstance )
       
   862         	{
       
   863 			delete instance;
       
   864 			instanceArray.Remove( i );
       
   865         	}
       
   866         else
       
   867         	{
       
   868 			++i;
       
   869         	}
       
   870     	}
       
   871 
       
   872     TCalTime start;
       
   873     start.SetTimeLocalL( aStart );
       
   874 
       
   875     TCalTime end;
       
   876     end.SetTimeLocalL( aEnd );
       
   877 
       
   878     RemoveAndDeleteNonConflictingInstancesL(
       
   879             instanceArray,
       
   880             start,
       
   881             end,
       
   882             aEntry.UidL(),
       
   883             EIncludeSameUID );
       
   884 
       
   885     CreateEntriesFromInstancesL( instanceArray, aInstances );
       
   886 
       
   887     CleanupStack::PopAndDestroy(); // instanceArray
       
   888     }
       
   889 
       
   890 // EOF
       
   891