meetingrequest/mrentry/src/cesmrconflictchecker.cpp
branchRCL_3
changeset 12 4ce476e64c59
parent 11 0396474f30f5
child 13 8592a65ad3fb
equal deleted inserted replaced
11:0396474f30f5 12:4ce476e64c59
     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: tr1sido#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 <ct/rcpointerarray.h>
       
    31 
       
    32 /// Unnamed namespace for local definitions
       
    33 namespace { // codescanner::namespace
       
    34 
       
    35 // Definition for zero
       
    36 const TInt KZero(0);
       
    37 
       
    38 /** Defines instace filter type */
       
    39 enum TInstanceFilter
       
    40     {
       
    41     EIncludeSameUID,
       
    42     ERemoveSameUID
       
    43     };
       
    44 
       
    45 #ifdef _DEBUG
       
    46 
       
    47 // Literal for panic texts
       
    48 _LIT( KESMRConflictCheckerTxt, "ESMRConflictChecker" );
       
    49 
       
    50 /** Enumeration for panic codes */
       
    51 enum TESMRConflictCheckerPanic
       
    52     {
       
    53     // Input entry is not appointment
       
    54     EESMRConflictCheckerInvalidEntryType
       
    55     };
       
    56 
       
    57 /**
       
    58  * Thows system wide panic.
       
    59  * @param aPanic Panic code.
       
    60  */
       
    61 void Panic( TESMRConflictCheckerPanic aPanic )
       
    62     {
       
    63 
       
    64     User::Panic( KESMRConflictCheckerTxt, aPanic );
       
    65     }
       
    66 
       
    67 #else
       
    68 
       
    69 /**
       
    70  * Thows system wide leave.
       
    71  * @param aError Leave code.
       
    72  */
       
    73 void Leave( TInt aError )
       
    74     {
       
    75 
       
    76     User::Leave( aError );
       
    77     }
       
    78 
       
    79 #endif
       
    80 
       
    81 /**
       
    82  * Resolves time range for possible conflicting entries. Instance view
       
    83  * is used for resolving the time range.
       
    84  *
       
    85  * @param aStart Start time
       
    86  * @param aEnd End time
       
    87  * @param aInstanceView Pointer to calendar db instance view
       
    88  * @return Time range for possible conflicting entries
       
    89  */
       
    90 CalCommon::TCalTimeRange ResolveFetchTimeRangeL(
       
    91         TTime aStart,
       
    92         TTime aEnd,
       
    93         CCalInstanceView* aInstanceView )
       
    94     {
       
    95     FUNC_LOG;
       
    96     const CalCommon::TCalViewFilter instanceFilter = 
       
    97             CalCommon::EIncludeAppts;
       
    98 
       
    99     TDateTime start = aStart.DateTime();
       
   100     TDateTime end   = aEnd.DateTime();
       
   101 
       
   102     start.SetHour( KZero );
       
   103     start.SetMinute( KZero );
       
   104     start.SetSecond( KZero );
       
   105     start.SetMicroSecond( KZero );
       
   106 
       
   107     end.SetHour( KZero );
       
   108     end.SetMinute( KZero );
       
   109     end.SetSecond( KZero );
       
   110     end.SetMicroSecond( KZero );
       
   111     TTime endTime = end;
       
   112     
       
   113     if ( TTime(start) == endTime || 
       
   114          endTime < aEnd )
       
   115         {
       
   116         
       
   117         endTime += TTimeIntervalDays(1);
       
   118         end = endTime.DateTime();
       
   119         }
       
   120 
       
   121     TCalTime rangeStart;
       
   122     rangeStart.SetTimeLocalL( start );
       
   123 
       
   124     TCalTime instanceTime = aInstanceView->PreviousInstanceL(
       
   125             instanceFilter,
       
   126             rangeStart );
       
   127 
       
   128     if (  Time::NullTTime() != instanceTime.TimeUtcL()  )
       
   129         {
       
   130         rangeStart = instanceTime;
       
   131         }
       
   132 
       
   133     TCalTime rangeEnd;
       
   134     rangeEnd.SetTimeLocalL( end );
       
   135 
       
   136     instanceTime = aInstanceView->NextInstanceL(
       
   137             instanceFilter,
       
   138             rangeEnd );
       
   139 
       
   140     if ( instanceTime.TimeLocalL() != Time::NullTTime() )
       
   141         {
       
   142         rangeEnd = instanceTime;
       
   143         }
       
   144 
       
   145     return CalCommon::TCalTimeRange( rangeStart, rangeEnd );
       
   146     }
       
   147 
       
   148 /**
       
   149  * Removes and deletes the entries, which do not confilct with
       
   150  * entry. Entry is considered to be conflicting entry if starts or
       
   151  * ends between aEntry's start and end time.
       
   152  *
       
   153  * @param aEntries Reference to entries, which may conflict
       
   154  * @param aEntry Reference to entry, which confilcts are resolved.
       
   155  */
       
   156 void RemoveAndDeleteNonConflictingInstancesL(
       
   157     RPointerArray<CCalInstance>& instanceArray,    
       
   158     // const CCalEntry& aEntry,
       
   159     TCalTime aStartTime,
       
   160     TCalTime aEndTime,
       
   161     const TDesC8& aUid,
       
   162     TInstanceFilter aFilterType )
       
   163     {
       
   164     FUNC_LOG;
       
   165     TInt index(0);
       
   166 
       
   167     TTime startTimeUtc = aStartTime.TimeUtcL();
       
   168     TTime endTimeUtc = aEndTime.TimeUtcL();
       
   169     
       
   170     while( index < instanceArray.Count() )
       
   171         {
       
   172         TBool conflictingInstance( ETrue );
       
   173         CCalInstance* instance = instanceArray[index];
       
   174         
       
   175         TTime entryStartTimeUtc = instance->StartTimeL().TimeUtcL();
       
   176         TTime entryEndTimeUtc = instance->EndTimeL().TimeUtcL();            
       
   177 
       
   178         TPtrC8 uid( instance->Entry().UidL() );
       
   179         if ( ERemoveSameUID == aFilterType && 
       
   180              0 == aUid.CompareF(uid) )
       
   181             {
       
   182             conflictingInstance = EFalse;
       
   183             }
       
   184         else if ( entryStartTimeUtc >= startTimeUtc &&
       
   185                   entryStartTimeUtc < endTimeUtc )
       
   186             {
       
   187             // Entry starts during another entry
       
   188             index++;
       
   189             }
       
   190         else if ( entryEndTimeUtc > startTimeUtc &&
       
   191                 entryEndTimeUtc <= endTimeUtc )
       
   192             {
       
   193             // Entry ends during another entry
       
   194             index++;
       
   195             }
       
   196         else if ( entryStartTimeUtc > startTimeUtc &&
       
   197                   entryEndTimeUtc < endTimeUtc )
       
   198             {
       
   199             // Antry starts and ends during another entry
       
   200             index++;
       
   201             }
       
   202         else if ( entryStartTimeUtc < startTimeUtc &&
       
   203                   entryEndTimeUtc > endTimeUtc )
       
   204             {
       
   205             // Antry starts and ends during another entry
       
   206             index++;
       
   207             }
       
   208         else
       
   209             {
       
   210             conflictingInstance = EFalse;            
       
   211             }
       
   212         
       
   213         // Remove non-conflicting instance from instance array
       
   214         if ( !conflictingInstance )
       
   215             {
       
   216             instanceArray.Remove(index);
       
   217             delete instance; 
       
   218             instance = NULL;
       
   219             }
       
   220         }
       
   221     }
       
   222 
       
   223 /**
       
   224  * Creates calendar entries from the conflicting instances
       
   225  * and stores the created entries into entry array.
       
   226  * Ownership of the created entries is transferred to caller.
       
   227  * @param aInstanceArray Reference to instance array
       
   228  * @param aConflictingEntries Reference to entry array.
       
   229  */
       
   230 void CreateEntriesFromInstancesL(
       
   231         RPointerArray<CCalInstance>& instanceArray,
       
   232         RPointerArray<CCalEntry>& aConflictingEntries )
       
   233     {
       
   234     FUNC_LOG;
       
   235     TInt instanceCount( instanceArray.Count() );    
       
   236     for ( TInt i(0); i < instanceCount; ++i )
       
   237         {        
       
   238         CCalEntry& parent( instanceArray[i]->Entry() );
       
   239         CCalEntry* entry = ESMRHelper::CopyEntryLC( parent, 
       
   240                                                     parent.MethodL(),
       
   241                                                     ESMRHelper::ECopyFull );
       
   242         
       
   243         entry->SetStartAndEndTimeL( instanceArray[i]->StartTimeL(),
       
   244                                     instanceArray[i]->EndTimeL() );
       
   245 
       
   246         User::LeaveIfError( aConflictingEntries.Append( entry ) );
       
   247         CleanupStack::Pop( entry );
       
   248         }
       
   249     }
       
   250 
       
   251 }  // namespace
       
   252 
       
   253 // ======== MEMBER FUNCTIONS ========
       
   254 
       
   255 // ---------------------------------------------------------------------------
       
   256 // CESMRConflictChecker::CESMRConflictChecker
       
   257 // ---------------------------------------------------------------------------
       
   258 //
       
   259 inline CESMRConflictChecker::CESMRConflictChecker(
       
   260         MESMRCalDbMgr& aDbMgr ) :
       
   261         iDbMgr( aDbMgr )
       
   262     {
       
   263     FUNC_LOG;
       
   264     // Not implementation yet
       
   265     }
       
   266 
       
   267 // ---------------------------------------------------------------------------
       
   268 // CESMRConflictChecker::~CESMRConflictChecker
       
   269 // ---------------------------------------------------------------------------
       
   270 //
       
   271 CESMRConflictChecker::~CESMRConflictChecker()
       
   272     {
       
   273     FUNC_LOG;
       
   274     // Not implementation yet
       
   275     }
       
   276 
       
   277 // ---------------------------------------------------------------------------
       
   278 // CESMRConflictChecker::NewL
       
   279 // ---------------------------------------------------------------------------
       
   280 //
       
   281 CESMRConflictChecker* CESMRConflictChecker::NewL(
       
   282         MESMRCalDbMgr& aDbMgr )
       
   283     {
       
   284     FUNC_LOG;
       
   285     CESMRConflictChecker* self =
       
   286             new (ELeave) CESMRConflictChecker(aDbMgr);
       
   287     return self;
       
   288     }
       
   289 
       
   290 // ---------------------------------------------------------------------------
       
   291 // CESMRConflictChecker::FindConflictsL
       
   292 // ---------------------------------------------------------------------------
       
   293 //
       
   294 void CESMRConflictChecker::FindConflictsL(
       
   295             const CCalEntry& aEntry,
       
   296             RPointerArray<CCalEntry>& aConflicts )
       
   297     {
       
   298     FUNC_LOG;
       
   299 
       
   300     // Checking input parameters
       
   301 #ifdef _DEBUG
       
   302 
       
   303     __ASSERT_DEBUG(
       
   304             CCalEntry::EAppt == aEntry.EntryTypeL(),
       
   305             Panic(EESMRConflictCheckerInvalidEntryType) );
       
   306 
       
   307 #else
       
   308 
       
   309     if ( CCalEntry::EAppt != aEntry.EntryTypeL() )
       
   310         {
       
   311         Leave( KErrArgument );
       
   312         }
       
   313 
       
   314 #endif
       
   315 
       
   316     CCalInstanceView* instanceView = iDbMgr.NormalDbInstanceView();
       
   317     
       
   318     CalCommon::TCalTimeRange timeRange =
       
   319             ResolveFetchTimeRangeL( 
       
   320                     aEntry.StartTimeL().TimeUtcL(),
       
   321                     aEntry.EndTimeL().TimeUtcL(), 
       
   322                     instanceView );
       
   323 
       
   324     RCPointerArray<CCalInstance> instanceArray;
       
   325     CleanupClosePushL( instanceArray );
       
   326 
       
   327     instanceView->FindInstanceL( instanceArray,
       
   328                                  CalCommon::EIncludeAppts,
       
   329                                  timeRange );
       
   330 
       
   331     RemoveAndDeleteNonConflictingInstancesL(
       
   332             instanceArray,
       
   333             aEntry.StartTimeL(),
       
   334             aEntry.EndTimeL(),
       
   335             aEntry.UidL(),
       
   336             ERemoveSameUID );
       
   337 
       
   338     CreateEntriesFromInstancesL( instanceArray, aConflicts );
       
   339     
       
   340     CleanupStack::PopAndDestroy(); // instanceArray
       
   341     
       
   342     }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // CESMRConflictChecker::FindInstancesForEntry
       
   346 // ---------------------------------------------------------------------------
       
   347 //
       
   348 void CESMRConflictChecker::FindInstancesForEntryL(
       
   349         TTime aStart, 
       
   350         TTime aEnd,
       
   351         const CCalEntry& aEntry,
       
   352         RPointerArray<CCalEntry>& aInstances )
       
   353     {
       
   354     FUNC_LOG;
       
   355     TDateTime startDt = aStart.DateTime();
       
   356     startDt.SetHour( KZero );
       
   357     startDt.SetMinute( KZero );
       
   358     startDt.SetSecond( KZero );
       
   359     
       
   360     TDateTime endDt = aEnd.DateTime();
       
   361     endDt.SetHour( KMaxHoursInDay );
       
   362     endDt.SetMinute( KMaxMinutesInHour );
       
   363     endDt.SetSecond( KMaxSecondsInMinute );
       
   364     
       
   365     aStart = startDt;
       
   366     aEnd = endDt;
       
   367     
       
   368     CCalInstanceView* instanceView = iDbMgr.NormalDbInstanceView();
       
   369     
       
   370     CalCommon::TCalTimeRange timeRange =
       
   371             ResolveFetchTimeRangeL( 
       
   372                     aStart,
       
   373                     aEnd, 
       
   374                     instanceView );
       
   375 
       
   376     RCPointerArray<CCalInstance> instanceArray;
       
   377     CleanupClosePushL( instanceArray );
       
   378 
       
   379     instanceView->FindInstanceL( instanceArray,
       
   380                                  CalCommon::EIncludeAppts,
       
   381                                  timeRange );
       
   382     
       
   383     TInt i(0);
       
   384     while( i < instanceArray.Count() )
       
   385         {
       
   386         CCalInstance* instance = instanceArray[i];
       
   387         CCalEntry& instanceEntry( instance->Entry() );
       
   388         
       
   389         TBool sameUid( 
       
   390                 0 == instanceEntry.UidL().CompareF( aEntry.UidL() ) );
       
   391         
       
   392         TBool thisInstance( 
       
   393                 instance->StartTimeL().TimeLocalL() == 
       
   394                 aEntry.StartTimeL().TimeLocalL() &&
       
   395                 instance->EndTimeL().TimeLocalL() == 
       
   396                 aEntry.EndTimeL().TimeLocalL() );      
       
   397         
       
   398         if ( !sameUid || thisInstance )
       
   399             {
       
   400             // This is either same entry as aEntry or then
       
   401             // this entry does not belong to this series 
       
   402             delete instance;
       
   403             instanceArray.Remove( i );            
       
   404             }
       
   405         else
       
   406             {
       
   407             ++i;
       
   408             }        
       
   409         }
       
   410     
       
   411     TCalTime start;
       
   412     start.SetTimeUtcL( aStart );
       
   413     
       
   414     TCalTime end;
       
   415     end.SetTimeUtcL( aEnd );
       
   416     
       
   417     RemoveAndDeleteNonConflictingInstancesL(
       
   418             instanceArray,
       
   419             start,
       
   420             end,
       
   421             aEntry.UidL(),
       
   422             EIncludeSameUID );
       
   423     
       
   424     CreateEntriesFromInstancesL( instanceArray, aInstances );
       
   425     
       
   426     CleanupStack::PopAndDestroy(); // instanceArray    
       
   427     }
       
   428 
       
   429 // EOF
       
   430