meetingrequest/mrservices/src/cesmrrecurrenceinfohandler.cpp
branchRCL_3
changeset 12 4ce476e64c59
parent 0 8466d47a6819
equal deleted inserted replaced
11:0396474f30f5 12:4ce476e64c59
    13 *
    13 *
    14 * Description: This file implements CESMRRecurrenceInfoHandler.
    14 * Description: This file implements CESMRRecurrenceInfoHandler.
    15 *
    15 *
    16 */
    16 */
    17 
    17 
    18 
       
    19 //<cmail>
       
    20 #include "emailtrace.h"
       
    21 #include "cesmrrecurrenceinfohandler.h"
    18 #include "cesmrrecurrenceinfohandler.h"
       
    19 #include "cesmrcaluserutil.h"
    22 #include "esmrdef.h"
    20 #include "esmrdef.h"
    23 //</cmail>
       
    24 
       
    25 #include "mesmrmeetingrequestentry.h"
    21 #include "mesmrmeetingrequestentry.h"
       
    22 #include "cesmrcaldbmgr.h"
    26 
    23 
    27 #include <calentry.h>
    24 #include <calentry.h>
    28 #include <calrrule.h>
    25 #include <calrrule.h>
    29 #include <calcommon.h>
    26 #include <ct/rcpointerarray.h>
       
    27 #include <calinstanceview.h>
       
    28 #include <calinstanceiterator.h>
       
    29 
       
    30 #include <calinstance.h>
       
    31 
       
    32 #include "emailtrace.h"
    30 
    33 
    31 /// Unnamed namespace for local definitions
    34 /// Unnamed namespace for local definitions
    32 namespace {
    35 namespace {
    33 
    36 
    34 // Definition for 0
    37 // Definition for 0
   181                 break;
   184                 break;
   182             }
   185             }
   183         }
   186         }
   184     }
   187     }
   185 
   188 
       
   189 /**
       
   190  * Checks if entry's recurrence end time is being adjusted
       
   191  * @param aEntry Reference to entry 
       
   192  */
       
   193 TBool RecurrenceEndtimeAdjustedL( 
       
   194         const CCalEntry& aEntry,
       
   195         MESMRCalDbMgr& aCalDb )
       
   196     {
       
   197     TBool retValue( EFalse );
       
   198     
       
   199     TCalRRule rRule;
       
   200     if ( aEntry.GetRRuleL( rRule) )
       
   201         {
       
   202         TCalTime recurrenceId;
       
   203         recurrenceId.SetTimeUtcL( Time::NullTTime() );
       
   204         CCalEntry* entry = aCalDb.FetchEntryL( aEntry.UidL(), recurrenceId  );
       
   205         CleanupStack::PushL( entry );
       
   206         
       
   207         if ( entry )
       
   208             {
       
   209             TCalRRule entryRRule;
       
   210             if ( entry->GetRRuleL( entryRRule ) )
       
   211                 {
       
   212                 TTime until1 = entryRRule.Until().TimeLocalL();
       
   213                 TTime until2 = rRule.Until().TimeLocalL();
       
   214                 
       
   215                 if ( until1 != until2 )
       
   216                     {
       
   217                     retValue = ETrue;
       
   218                     }
       
   219                 }
       
   220             }
       
   221                 
       
   222         CleanupStack::PopAndDestroy( entry );        
       
   223         }
       
   224     
       
   225     return retValue;
       
   226     }
       
   227 
       
   228 /**
       
   229  * Get the beginning of current param time
       
   230  * @param aStartTime Reference to time 
       
   231  */
       
   232 TTime BeginningOfDay( const TTime& aStartTime )
       
   233     {
       
   234     TTime zero(TInt64(0));
       
   235     return zero + aStartTime.DaysFrom( zero );
       
   236     }
       
   237 
       
   238 /**
       
   239  * Get the Time, hour, minute, sec, micsec of current param time
       
   240  * @param aStartTime Reference to time 
       
   241  */
       
   242 TTimeIntervalMinutes TimeOfDay( const TTime& aDateTime )
       
   243     {
       
   244     TTime midnight = BeginningOfDay( aDateTime );
       
   245     TTimeIntervalMinutes result;
       
   246     aDateTime.MinutesFrom( midnight, result );
       
   247 
       
   248     return result;
       
   249     }
       
   250 
       
   251 template<typename T> class CleanupResetAndDestroyClose
       
   252     {
       
   253     public:
       
   254         inline static void PushL( T& aRef );
       
   255     private:
       
   256         static void Close( TAny *aPtr );
       
   257     };
       
   258 
       
   259 template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef );
       
   260 
       
   261 template<typename T> inline void CleanupResetAndDestroyClose<T>::PushL( T& aRef )
       
   262     {
       
   263     CleanupStack::PushL( TCleanupItem( &Close, &aRef ) );
       
   264     }
       
   265 
       
   266 template<typename T> void CleanupResetAndDestroyClose<T>::Close( TAny *aPtr )
       
   267     {
       
   268     static_cast<T*>(aPtr)->ResetAndDestroy();
       
   269     static_cast<T*>(aPtr)->Close();
       
   270     }
       
   271 
       
   272 template<typename T> inline void CleanupResetAndDestroyClosePushL( T& aRef )
       
   273     {
       
   274     CleanupResetAndDestroyClose<T>::PushL( aRef );
       
   275     }
       
   276 
   186 }  // namespace
   277 }  // namespace
   187 
   278 
   188 // ======== MEMBER FUNCTIONS ========
   279 // ======== MEMBER FUNCTIONS ========
   189 
   280 
   190 // ---------------------------------------------------------------------------
   281 // ---------------------------------------------------------------------------
   191 // CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler
   282 // CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler
   192 // ---------------------------------------------------------------------------
   283 // ---------------------------------------------------------------------------
   193 //
   284 //
   194 inline CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler(
   285 inline CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler(
   195         CCalEntry& aEntry ) :
   286         CCalEntry& aEntry,
   196         iEntry( aEntry )
   287         MESMRCalDbMgr* aCalDb ) :
       
   288         iEntry( aEntry ),
       
   289         iCalDb( aCalDb )
   197     {
   290     {
   198     FUNC_LOG;
   291     FUNC_LOG;
   199     // Not implementation yet
   292     // Not implementation yet
   200     }
   293     }
   201 
   294 
   216 EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewL(
   309 EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewL(
   217         CCalEntry& aEntry )
   310         CCalEntry& aEntry )
   218     {
   311     {
   219     FUNC_LOG;
   312     FUNC_LOG;
   220 
   313 
   221     CESMRRecurrenceInfoHandler* self = NewLC( aEntry );
   314     CESMRRecurrenceInfoHandler* self = NewLC( aEntry, NULL );
       
   315     CleanupStack::Pop( self );
       
   316 
       
   317 
       
   318     return self;
       
   319     }
       
   320 
       
   321 // ---------------------------------------------------------------------------
       
   322 // CESMRRecurrenceInfoHandler::NewL
       
   323 // ---------------------------------------------------------------------------
       
   324 //
       
   325 EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewL(
       
   326         CCalEntry& aEntry,
       
   327         MESMRCalDbMgr* aCalDb )
       
   328     {
       
   329     FUNC_LOG;
       
   330 
       
   331     CESMRRecurrenceInfoHandler* self = NewLC( aEntry, aCalDb );
   222     CleanupStack::Pop( self );
   332     CleanupStack::Pop( self );
   223 
   333 
   224 
   334 
   225     return self;
   335     return self;
   226     }
   336     }
   233         CCalEntry& aEntry )
   343         CCalEntry& aEntry )
   234     {
   344     {
   235     FUNC_LOG;
   345     FUNC_LOG;
   236 
   346 
   237     CESMRRecurrenceInfoHandler* self =
   347     CESMRRecurrenceInfoHandler* self =
   238             new (ELeave) CESMRRecurrenceInfoHandler(aEntry);
   348             new (ELeave) CESMRRecurrenceInfoHandler( aEntry, NULL );
       
   349     CleanupStack::PushL( self );
       
   350     self->ConstructL();
       
   351 
       
   352 
       
   353     return self;
       
   354     }
       
   355 
       
   356 // ---------------------------------------------------------------------------
       
   357 // CESMRRecurrenceInfoHandler::NewLC
       
   358 // ---------------------------------------------------------------------------
       
   359 //
       
   360 EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewLC(
       
   361         CCalEntry& aEntry,
       
   362         MESMRCalDbMgr* aCalDb )
       
   363     {
       
   364     FUNC_LOG;
       
   365 
       
   366     CESMRRecurrenceInfoHandler* self =
       
   367             new (ELeave) CESMRRecurrenceInfoHandler( aEntry, aCalDb );
   239     CleanupStack::PushL( self );
   368     CleanupStack::PushL( self );
   240     self->ConstructL();
   369     self->ConstructL();
   241 
   370 
   242 
   371 
   243     return self;
   372     return self;
   497             }
   626             }
   498         }
   627         }
   499 
   628 
   500     CleanupStack::PopAndDestroy( &rdates );
   629     CleanupStack::PopAndDestroy( &rdates );
   501     aRecurrence = recurrenceValue;
   630     aRecurrence = recurrenceValue;
   502 
       
   503     }
   631     }
   504 
   632 
   505 
   633 
   506 EXPORT_C void CESMRRecurrenceInfoHandler::RemoveInstanceL(
   634 EXPORT_C void CESMRRecurrenceInfoHandler::RemoveInstanceL(
   507         TCalTime aInstanceTime )
   635         TCalTime aInstanceTime )
   709         aEnd = iEntry.EndTimeL();
   837         aEnd = iEntry.EndTimeL();
   710         }
   838         }
   711 
   839 
   712     }
   840     }
   713 
   841 
       
   842 // -----------------------------------------------------------------------------
       
   843 // CCalenEditorDataHandler::GetPreviousInstanceTimeL
       
   844 // 
       
   845 // -----------------------------------------------------------------------------
       
   846 //
       
   847 EXPORT_C void CESMRRecurrenceInfoHandler::GetPreviousInstanceTimeL( TCalTime& aPreviousStartTime,
       
   848                                                                     TCalTime& aPreviousEndTime,
       
   849                                                                     TTime aInstanceDateTime )
       
   850     {
       
   851     FUNC_LOG;
       
   852     
       
   853     aPreviousStartTime.SetTimeLocalL( Time::NullTTime() );
       
   854     aPreviousEndTime.SetTimeLocalL( Time::NullTTime() );
       
   855 
       
   856     RPointerArray<CCalEntry> entries;
       
   857     CleanupResetAndDestroyClosePushL( entries );
       
   858 
       
   859     iCalDb->EntryViewL( iEntry )->FetchL( iEntry.UidL(), entries );
       
   860 
       
   861     TCalTime currentInstanceDate = iEntry.RecurrenceIdL();
       
   862     if( currentInstanceDate.TimeUtcL() == Time::NullTTime() )
       
   863         {
       
   864         // We must be creating a new exception. Calculate the recurrence id.
       
   865         TTimeIntervalMinutes timeOfDay = TimeOfDay( entries[0]->StartTimeL().TimeLocalL() );
       
   866         TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
       
   867         currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
       
   868         }
       
   869 
       
   870     TCalRRule rrule;
       
   871     if( entries[0]->GetRRuleL(rrule) )
       
   872         {
       
   873         TESMRRecurrenceValue repeatIndex = RepeatIndexL( *entries[0] );
       
   874         
       
   875         TBool keepLooking = ETrue;
       
   876         RArray<TCalTime> exdates;
       
   877         CleanupClosePushL( exdates );
       
   878         entries[0]->GetExceptionDatesL(exdates);
       
   879         
       
   880         // Needed for case ERepeatOther
       
   881         TCalRRule::TType type( rrule.Type() );
       
   882         TInt repeatInterval( rrule.Interval() );
       
   883         TCalTime start, end;
       
   884         TTime previousInstanceTime = Time::NullTTime(); 
       
   885         
       
   886         while( keepLooking )
       
   887             {
       
   888             // Subtract the repeat interval of the parent.
       
   889             switch( repeatIndex )
       
   890                 {
       
   891                 case ERecurrenceDaily:
       
   892                     {
       
   893                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(1) );
       
   894                     break;
       
   895                     }
       
   896 
       
   897                 case ERecurrenceWeekly:
       
   898                     {
       
   899                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7) );
       
   900                     break;
       
   901                     }
       
   902 
       
   903                 case ERecurrenceEverySecondWeek:
       
   904                     {
       
   905                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(14) );
       
   906                     break;
       
   907                     }
       
   908 
       
   909                 case ERecurrenceMonthly:
       
   910                     {
       
   911                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalMonths(1) );
       
   912                     break;
       
   913                     }
       
   914 
       
   915                 case ERecurrenceYearly:
       
   916                     {
       
   917                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalYears(1) );
       
   918                     break;
       
   919                     }
       
   920 
       
   921                 case ERecurrenceUnknown:
       
   922                     {
       
   923                     // Check if the current entry being edited is child entry
       
   924                     // If yes, then put back the child entry time to currentInstanceDate  
       
   925                     if( iEntry.RecurrenceIdL().TimeUtcL() != Time::NullTTime() )
       
   926                         {
       
   927                         TTimeIntervalMinutes timeOfDay = TimeOfDay( iEntry.StartTimeL().TimeLocalL() );
       
   928                         TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
       
   929                         currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
       
   930                         }
       
   931 
       
   932                     switch( type )
       
   933                         {
       
   934                         case TCalRRule::EDaily:
       
   935                             {
       
   936                             start.SetTimeLocalL( currentInstanceDate.TimeLocalL() - 
       
   937                                     TTimeIntervalDays( 1 * repeatInterval ) );
       
   938                             break;
       
   939                             }
       
   940 
       
   941                         case TCalRRule::EWeekly:
       
   942                             {
       
   943                             start.SetTimeLocalL( currentInstanceDate.TimeLocalL() - 
       
   944                                     TTimeIntervalDays(7 * repeatInterval) );
       
   945                             break;
       
   946                             }
       
   947 
       
   948                         case TCalRRule::EMonthly: 
       
   949                             {
       
   950                             // Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
       
   951                             // can go beuong 30 days. Ex: Every third wednesday of every month 
       
   952                             start.SetTimeLocalL( currentInstanceDate.TimeLocalL() -
       
   953                                     TTimeIntervalMonths(repeatInterval)-TTimeIntervalDays(7 * repeatInterval) );
       
   954                             break;
       
   955                             }
       
   956 
       
   957                         case TCalRRule::EYearly:  
       
   958                             {
       
   959                             // Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
       
   960                             // can go beuong 365 days. Ex: Every third wednesday of September of every year
       
   961                             start.SetTimeLocalL( currentInstanceDate.TimeLocalL() -
       
   962                                     TTimeIntervalYears(repeatInterval)-TTimeIntervalDays(7 * repeatInterval) );
       
   963                             break;
       
   964                             }
       
   965                         }
       
   966 
       
   967                     end.SetTimeLocalL( BeginningOfDay( currentInstanceDate.TimeLocalL() ) );
       
   968                     previousInstanceTime = GetPreviousInstanceForRepeatOtherL( *entries[0], 
       
   969                             CalCommon::TCalTimeRange(start, end) );
       
   970                     currentInstanceDate.SetTimeLocalL( previousInstanceTime );
       
   971                     break;
       
   972                     }
       
   973                     
       
   974                 case ERecurrenceNot:
       
   975                 default:
       
   976                     {
       
   977                     keepLooking = EFalse;
       
   978                     break;
       
   979                     }
       
   980                 }
       
   981 
       
   982             // Is currentInstanceDate before parent dt start?
       
   983             if( currentInstanceDate.TimeLocalL() < entries[0]->StartTimeL().TimeLocalL() )
       
   984                 {
       
   985                 // There are no instances before the exception
       
   986                 keepLooking = EFalse;
       
   987                 }
       
   988             else
       
   989                 {
       
   990                 // Is there an exdate on currentInstanceDate?
       
   991                 TBool isExdateOnDay = EFalse;
       
   992                 for(TInt i=0; i<exdates.Count(); ++i)
       
   993                     {
       
   994                     if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() )
       
   995                         {
       
   996                         isExdateOnDay = ETrue;
       
   997                         // There is an exdate - is there a child associated with the exdate?
       
   998                         for(TInt j=1; j<entries.Count(); ++j)
       
   999                             {
       
  1000                             if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() )
       
  1001                                 {
       
  1002                                 // This child is the previous instance.
       
  1003                                 aPreviousStartTime = entries[j]->StartTimeL();
       
  1004                                 aPreviousEndTime = entries[j]->EndTimeL();
       
  1005                                 keepLooking = EFalse;
       
  1006                                 }
       
  1007                             }
       
  1008                         break;
       
  1009                         }
       
  1010                     }
       
  1011 
       
  1012                 if( !isExdateOnDay )
       
  1013                     {
       
  1014                     // The instance exists and hasn't been deleted or made into an exception.
       
  1015                     // Use information from the parent to set the start/end times.
       
  1016                     aPreviousStartTime = currentInstanceDate;
       
  1017 
       
  1018                     TTimeIntervalMinutes duration;
       
  1019                     TTime start = entries[0]->StartTimeL().TimeLocalL();
       
  1020                     TTime end = entries[0]->EndTimeL().TimeLocalL(); 
       
  1021                     end.MinutesFrom( start, duration );
       
  1022                     aPreviousEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration );
       
  1023                     keepLooking = EFalse;
       
  1024                     }
       
  1025                 }
       
  1026             }
       
  1027         CleanupStack::PopAndDestroy( &exdates );
       
  1028         }
       
  1029 
       
  1030     CleanupStack::PopAndDestroy(&entries);
       
  1031     }
       
  1032 
       
  1033 // -----------------------------------------------------------------------------
       
  1034 // CESMRRecurrenceInfoHandler::GetNextInstanceTimeL
       
  1035 // 
       
  1036 // -----------------------------------------------------------------------------
       
  1037 //
       
  1038 EXPORT_C void CESMRRecurrenceInfoHandler::GetNextInstanceTimeL( TCalTime& aNextStartTime,
       
  1039                                                                 TCalTime& aNextEndTime,
       
  1040                                                                 TTime aInstanceDateTime )
       
  1041     {
       
  1042     FUNC_LOG;
       
  1043     aNextStartTime.SetTimeLocalL( Time::NullTTime() );
       
  1044     aNextEndTime.SetTimeLocalL( Time::NullTTime() );
       
  1045 
       
  1046     RPointerArray<CCalEntry> entries;
       
  1047     CleanupResetAndDestroyClosePushL(entries);
       
  1048 
       
  1049     iCalDb->EntryViewL(iEntry)->FetchL( iEntry.UidL(), entries );
       
  1050     TCalTime currentInstanceDate = iEntry.RecurrenceIdL();
       
  1051     
       
  1052     if( currentInstanceDate.TimeUtcL() == Time::NullTTime() )
       
  1053         {
       
  1054         // We must be creating a new exception. Calculate the recurrence id.
       
  1055         TTimeIntervalMinutes timeOfDay = TimeOfDay( entries[0]->StartTimeL().TimeLocalL() );
       
  1056         TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
       
  1057         currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
       
  1058         }
       
  1059 
       
  1060     TCalRRule rrule;
       
  1061     if( entries[0]->GetRRuleL(rrule) )
       
  1062         {
       
  1063         TESMRRecurrenceValue repeatIndex = RepeatIndexL( *entries[0] );
       
  1064         
       
  1065         TBool keepLooking = ETrue;
       
  1066         RArray<TCalTime> exdates;
       
  1067         CleanupClosePushL( exdates );
       
  1068         entries[0]->GetExceptionDatesL( exdates );
       
  1069         
       
  1070         // Needed for case ERepeatOther
       
  1071         TCalRRule::TType type( rrule.Type() );
       
  1072         TInt repeatInterval( rrule.Interval() );
       
  1073         TCalTime start, end;
       
  1074         TTime nextInstanceTime = Time::NullTTime(); 
       
  1075         
       
  1076         while( keepLooking )
       
  1077             {
       
  1078             // Subtract the repeat interval of the parent.
       
  1079             switch( repeatIndex )
       
  1080                 {
       
  1081                 case ERecurrenceDaily:
       
  1082                     {
       
  1083                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1) );
       
  1084                     break;
       
  1085                     }
       
  1086 
       
  1087                 case ERecurrenceWeekly:
       
  1088                     {
       
  1089                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7) );
       
  1090                     break;
       
  1091                     }
       
  1092 
       
  1093                 case ERecurrenceEverySecondWeek:
       
  1094                     {
       
  1095                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(14) );
       
  1096                     break;
       
  1097                     }
       
  1098 
       
  1099                 case ERecurrenceMonthly:
       
  1100                     {
       
  1101                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalMonths(1) );
       
  1102                     break;
       
  1103                     }
       
  1104 
       
  1105                 case ERecurrenceYearly:
       
  1106                     {
       
  1107                     currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalYears(1) );
       
  1108                     break;
       
  1109                     }
       
  1110 
       
  1111                 case ERecurrenceUnknown:
       
  1112                     {
       
  1113                     // Check if the current entry being edited is child entry
       
  1114                     // If yes, then put back the child entry time to currentInstanceDate
       
  1115                     if(iEntry.RecurrenceIdL().TimeUtcL() != Time::NullTTime())
       
  1116                         {
       
  1117                         TTimeIntervalMinutes timeOfDay = TimeOfDay( iEntry.StartTimeL().TimeLocalL() );
       
  1118                         TTime beginningOfDay = BeginningOfDay( aInstanceDateTime );
       
  1119                         currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay );
       
  1120                         }
       
  1121                     
       
  1122                     switch( type )
       
  1123                         {
       
  1124                         case TCalRRule::EDaily:
       
  1125                             {
       
  1126                             end.SetTimeLocalL( currentInstanceDate.TimeLocalL() + 
       
  1127                                     TTimeIntervalDays(1*repeatInterval) );
       
  1128                             break;
       
  1129                             }
       
  1130 
       
  1131                         case TCalRRule::EWeekly:
       
  1132                             {
       
  1133                             end.SetTimeLocalL( currentInstanceDate.TimeLocalL() + 
       
  1134                                     TTimeIntervalDays(7 *repeatInterval) );
       
  1135                             break;
       
  1136                             }
       
  1137 
       
  1138                         case TCalRRule::EMonthly:
       
  1139                             {
       
  1140                             // Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
       
  1141                             // can go beuong 30 days. Ex: Every third wednesday of every month
       
  1142                             end.SetTimeLocalL( currentInstanceDate.TimeLocalL() + 
       
  1143                                     TTimeIntervalMonths(repeatInterval) + TTimeIntervalDays(7 * repeatInterval) );
       
  1144                             break;
       
  1145                             }
       
  1146                             
       
  1147                         case TCalRRule::EYearly:
       
  1148                             {
       
  1149                             // Add 7 days of buffer to cover the cases were gap b/w two instances of the event 
       
  1150                             // can go beuong 365 days. Ex: Every third wednesday of September of every year
       
  1151                             end.SetTimeLocalL( currentInstanceDate.TimeLocalL() + 
       
  1152                                     TTimeIntervalYears(repeatInterval) + TTimeIntervalDays(7 * repeatInterval) );
       
  1153                             break;
       
  1154                             }
       
  1155                         }
       
  1156 
       
  1157                     start.SetTimeLocalL(BeginningOfDay(currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1)));
       
  1158                     nextInstanceTime = GetNextInstanceForRepeatOtherL(*entries[0], CalCommon::TCalTimeRange( start, end));
       
  1159                     currentInstanceDate.SetTimeLocalL( nextInstanceTime);
       
  1160                     break;
       
  1161                     }
       
  1162                 case ERecurrenceNot:
       
  1163                     {
       
  1164                     keepLooking = EFalse;
       
  1165                     break;
       
  1166                     }
       
  1167 
       
  1168                 default:
       
  1169                     {
       
  1170                     break;
       
  1171                     } 
       
  1172                 }
       
  1173 
       
  1174             // Is currentInstanceDate after parent dt end?
       
  1175             if( currentInstanceDate.TimeLocalL() > rrule.Until().TimeLocalL() )
       
  1176                 {
       
  1177                 // There are no instances before the exception
       
  1178                 keepLooking = EFalse;
       
  1179                 }
       
  1180             else
       
  1181                 {
       
  1182                 // Is there an exdate on currentInstanceDate?
       
  1183                 TBool isExdateOnDay = EFalse;
       
  1184                 for(TInt i=0; i<exdates.Count(); ++i)
       
  1185                     {
       
  1186                     if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() )
       
  1187                         {
       
  1188                         isExdateOnDay = ETrue;
       
  1189                         // There is an exdate - is there a child associated with the exdate?
       
  1190                         for(TInt j=1; j<entries.Count(); ++j)
       
  1191                             {
       
  1192                             if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() )
       
  1193                                 {
       
  1194                                 // This child is the previous instance.
       
  1195                                 aNextStartTime = entries[j]->StartTimeL();
       
  1196                                 aNextEndTime = entries[j]->EndTimeL();
       
  1197                                 keepLooking = EFalse;
       
  1198                                 }
       
  1199                             }
       
  1200                         break;
       
  1201                         }
       
  1202                     }
       
  1203                 
       
  1204                 if( !isExdateOnDay )
       
  1205                     {
       
  1206                     // The instance exists and hasn't been deleted or made into an exception.
       
  1207                     // Use information from the parent to set the start/end times.
       
  1208                     aNextStartTime = currentInstanceDate;
       
  1209 
       
  1210                     TTimeIntervalMinutes duration;
       
  1211                     TTime start = entries[0]->StartTimeL().TimeLocalL();
       
  1212                     TTime end = entries[0]->EndTimeL().TimeLocalL();
       
  1213                     end.MinutesFrom( start, duration );
       
  1214                     aNextEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration );
       
  1215                     keepLooking = EFalse;
       
  1216                     }
       
  1217                 }
       
  1218             }
       
  1219         CleanupStack::PopAndDestroy( &exdates );
       
  1220         }
       
  1221 
       
  1222     CleanupStack::PopAndDestroy(&entries);
       
  1223     }
       
  1224 
       
  1225 
       
  1226 // -----------------------------------------------------------------------------
       
  1227 // CESMRRecurrenceInfoHandler::GetPreviousInstanceForRepeatOtherL()
       
  1228 // 
       
  1229 // -----------------------------------------------------------------------------
       
  1230 //
       
  1231 TTime CESMRRecurrenceInfoHandler::GetPreviousInstanceForRepeatOtherL(
       
  1232             CCalEntry& aEntry, const CalCommon::TCalTimeRange& timeRange)
       
  1233     {
       
  1234     RPointerArray<CCalInstance> allInstances;
       
  1235     CleanupResetAndDestroyClosePushL( allInstances );
       
  1236     
       
  1237     TInt filter;
       
  1238     // Get the entry type to be filtered
       
  1239     switch(aEntry.EntryTypeL())
       
  1240         {
       
  1241         case CCalEntry::EAppt:
       
  1242             {
       
  1243             filter = CalCommon::EIncludeAppts;
       
  1244             break;
       
  1245             }
       
  1246 
       
  1247         case CCalEntry::ETodo:
       
  1248             {
       
  1249             filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos;
       
  1250             break;
       
  1251             }
       
  1252 
       
  1253         case CCalEntry::EEvent:
       
  1254             {
       
  1255             filter = CalCommon::EIncludeEvents;
       
  1256             break;
       
  1257             }
       
  1258 
       
  1259         case CCalEntry::EReminder:
       
  1260             {
       
  1261             filter = CalCommon::EIncludeReminder;
       
  1262             break;
       
  1263             }
       
  1264 
       
  1265         case CCalEntry::EAnniv:
       
  1266             {
       
  1267             filter = CalCommon::EIncludeAnnivs;
       
  1268             break;
       
  1269             }
       
  1270 
       
  1271         default:
       
  1272             {
       
  1273             filter = CalCommon::EIncludeAll;
       
  1274             break;
       
  1275             }
       
  1276 
       
  1277         };
       
  1278 
       
  1279     iCalDb->InstanceViewL(iEntry)->FindInstanceL( allInstances, 
       
  1280                                      (CalCommon::TCalViewFilterFlags)filter,
       
  1281                                      timeRange);
       
  1282 
       
  1283     TTime previousTime = Time::NullTTime();
       
  1284     
       
  1285     for( TInt i = allInstances.Count() - 1; i >= 0; i-- )
       
  1286         {
       
  1287         if( allInstances[i]->Entry().UidL() == aEntry.UidL() )
       
  1288             {
       
  1289             previousTime = allInstances[i]->Time().TimeLocalL();
       
  1290             break;
       
  1291             }
       
  1292         }
       
  1293 
       
  1294     CleanupStack::PopAndDestroy( &allInstances );  
       
  1295     return previousTime;
       
  1296     }
       
  1297 
       
  1298 // -----------------------------------------------------------------------------
       
  1299 // CESMRRecurrenceInfoHandler::GetNextInstanceForRepeatOtherL()
       
  1300 // 
       
  1301 // -----------------------------------------------------------------------------
       
  1302 //
       
  1303 TTime CESMRRecurrenceInfoHandler::GetNextInstanceForRepeatOtherL( 
       
  1304            CCalEntry& aEntry, const CalCommon::TCalTimeRange& timeRange )
       
  1305     {
       
  1306     RPointerArray<CCalInstance> allInstances;
       
  1307     CleanupResetAndDestroyClosePushL( allInstances );
       
  1308     
       
  1309     TInt filter;
       
  1310     // Get the entry type to be filtered
       
  1311     switch( aEntry.EntryTypeL() )
       
  1312         {
       
  1313         case CCalEntry::EAppt:
       
  1314             {
       
  1315             filter = CalCommon::EIncludeAppts;
       
  1316             break;
       
  1317             }  
       
  1318         case CCalEntry::ETodo:
       
  1319             {
       
  1320             filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos;
       
  1321             break;
       
  1322             }
       
  1323         case CCalEntry::EEvent:
       
  1324             {
       
  1325             filter = CalCommon::EIncludeEvents;
       
  1326             break;
       
  1327             }
       
  1328         case CCalEntry::EReminder:
       
  1329             {
       
  1330             filter = CalCommon::EIncludeReminder;
       
  1331             break;
       
  1332             }
       
  1333         case CCalEntry::EAnniv:
       
  1334             {
       
  1335             filter = CalCommon::EIncludeAnnivs;
       
  1336             break;
       
  1337             }
       
  1338         default:
       
  1339             {
       
  1340             filter = CalCommon::EIncludeAll;
       
  1341             break;
       
  1342             }
       
  1343         };
       
  1344     
       
  1345     iCalDb->InstanceViewL(iEntry)->FindInstanceL( allInstances, 
       
  1346                                      ( CalCommon::TCalViewFilterFlags )filter,
       
  1347                                      timeRange);
       
  1348                                      
       
  1349     TTime nextTime = Time::NullTTime();
       
  1350     
       
  1351     TInt i( 0 );
       
  1352     for( ; i < allInstances.Count(); i++ )
       
  1353         {
       
  1354         if( allInstances[i]->Entry().UidL() == aEntry.UidL() )
       
  1355             {
       
  1356             nextTime = allInstances[i]->Time().TimeLocalL();
       
  1357             break;
       
  1358             }
       
  1359         }
       
  1360   
       
  1361     CleanupStack::PopAndDestroy( &allInstances );  
       
  1362     return nextTime;
       
  1363     }
       
  1364 
       
  1365 // ---------------------------------------------------------------------------
       
  1366 // CESMRRecurrenceInfoHandler::RepeatIndexL
       
  1367 //
       
  1368 // ---------------------------------------------------------------------------
       
  1369 //
       
  1370 TESMRRecurrenceValue CESMRRecurrenceInfoHandler::RepeatIndexL( const CCalEntry& aEntry )
       
  1371     {
       
  1372     FUNC_LOG;
       
  1373 
       
  1374     TESMRRecurrenceValue repeatIndex( ERecurrenceNot );
       
  1375 
       
  1376     TCalRRule rrule;
       
  1377 
       
  1378     if( aEntry.GetRRuleL( rrule) )
       
  1379         {
       
  1380         TCalRRule::TType type( rrule.Type() );
       
  1381         TInt repeatInterval( rrule.Interval() );
       
  1382 
       
  1383         // If repeat type of current note is not supported in Calendar,
       
  1384         // default repeat value is "Other".
       
  1385         repeatIndex = ERecurrenceUnknown;
       
  1386 
       
  1387         switch( type )
       
  1388             {
       
  1389             case TCalRRule::EDaily:
       
  1390                 {
       
  1391                 switch (repeatInterval)
       
  1392                     {
       
  1393                     case 1:
       
  1394                         {
       
  1395                         repeatIndex = ERecurrenceDaily;
       
  1396                         break;
       
  1397                         }
       
  1398                     case 7:
       
  1399                         {
       
  1400                         repeatIndex = ERecurrenceWeekly;
       
  1401                         break;
       
  1402                         }
       
  1403                     case 14:
       
  1404                         {
       
  1405                         repeatIndex = ERecurrenceEverySecondWeek;
       
  1406                         break;
       
  1407                         }
       
  1408                     default:
       
  1409                         {
       
  1410                         break;
       
  1411                         }
       
  1412                     }
       
  1413                 break;
       
  1414                 }
       
  1415 
       
  1416             case TCalRRule::EWeekly:
       
  1417                 {
       
  1418                 switch( repeatInterval )
       
  1419                     {
       
  1420                     case 1:
       
  1421                         {
       
  1422                         repeatIndex = ERecurrenceWeekly;
       
  1423                         break;
       
  1424                         }
       
  1425                     case 2:
       
  1426                         {
       
  1427                         repeatIndex = ERecurrenceEverySecondWeek;
       
  1428                         break;
       
  1429                         }
       
  1430                     default:
       
  1431                         {
       
  1432                         break;
       
  1433                         }
       
  1434                     }
       
  1435                 break;
       
  1436                 }
       
  1437 
       
  1438             case TCalRRule::EMonthly:
       
  1439                 {
       
  1440                 RArray<TInt> monthDays(31);
       
  1441                 rrule.GetByMonthDayL ( monthDays );
       
  1442 
       
  1443                 if( monthDays.Count() == 1) 
       
  1444                     {
       
  1445                     switch( repeatInterval )
       
  1446                         {
       
  1447                         case 1:
       
  1448                             {
       
  1449                             repeatIndex = ERecurrenceMonthly;
       
  1450                             break;
       
  1451                             }
       
  1452                         // If interval of repeat is 12 months, 
       
  1453                         // every year is shown in Note Editor, 
       
  1454                         // because it means yearly repeat.
       
  1455                         case 12:
       
  1456                             {
       
  1457                             repeatIndex = ERecurrenceYearly;
       
  1458                             break;
       
  1459                             }
       
  1460                         default:
       
  1461                             {
       
  1462                             break;
       
  1463                             }
       
  1464                         }
       
  1465                     }
       
  1466 
       
  1467                 monthDays.Close();
       
  1468                 break;
       
  1469                 }
       
  1470                 
       
  1471             case TCalRRule::EYearly:
       
  1472                 {
       
  1473                 if( repeatInterval == 1 )
       
  1474                     {
       
  1475                     repeatIndex = ERecurrenceYearly;
       
  1476                     }
       
  1477                 break;
       
  1478                 }
       
  1479 
       
  1480             default:
       
  1481                 {
       
  1482                 // If repeat type of current note is not supported in Calendar,
       
  1483                 // default repeat value is "Other".
       
  1484                 repeatIndex = ERecurrenceUnknown;
       
  1485                 break;
       
  1486                 }
       
  1487             }
       
  1488         }
       
  1489 
       
  1490     return repeatIndex;
       
  1491     }
       
  1492 
   714 // ---------------------------------------------------------------------------
  1493 // ---------------------------------------------------------------------------
   715 // CESMRRecurrenceInfoHandler::CalculateRecurrenceUntilDateL
  1494 // CESMRRecurrenceInfoHandler::CalculateRecurrenceUntilDateL
   716 //
  1495 //
   717 // ---------------------------------------------------------------------------
  1496 // ---------------------------------------------------------------------------
   718 //
  1497 //
   721             TTime& aUntil,
  1500             TTime& aUntil,
   722             TCalRRule& aRule,
  1501             TCalRRule& aRule,
   723             const CCalEntry& aEntry  ) const
  1502             const CCalEntry& aEntry  ) const
   724     {
  1503     {
   725     FUNC_LOG;
  1504     FUNC_LOG;
       
  1505     
   726     TCalRRule::TType rType = aRule.Type();
  1506     TCalRRule::TType rType = aRule.Type();
   727     TInt count             = aRule.Count();
  1507     TInt count             = aRule.Count();
   728     TCalTime until         = aRule.Until();
  1508     TCalTime until         = aRule.Until();
   729 
  1509     
   730     if ( count == KZero &&
  1510     if ( count == KZero &&
   731          until.TimeUtcL() == Time::NullTTime() )
  1511          until.TimeUtcL() == Time::NullTTime() )
   732         {
  1512         {
   733         User::Leave( KErrNotFound );
  1513         User::Leave( KErrNotFound );
   734         }
  1514         }
   744             {
  1524             {
   745             case ERecurrenceDaily:
  1525             case ERecurrenceDaily:
   746                 {
  1526                 {
   747                 --count;
  1527                 --count;
   748                 aUntil += TTimeIntervalDays(count);
  1528                 aUntil += TTimeIntervalDays(count);
       
  1529                 
       
  1530                 CESMRCalUserUtil* entryUtil = 
       
  1531                         CESMRCalUserUtil::NewLC( const_cast<CCalEntry&>(aEntry) );
       
  1532                 
       
  1533                 if ( iCalDb && entryUtil->IsAlldayEventL() &&
       
  1534                         RecurrenceEndtimeAdjustedL( aEntry, *iCalDb ) )
       
  1535                     {
       
  1536                     // If until is adjusted for allday entries
       
  1537                     // we wound return until day one day too long 
       
  1538                     aUntil -= TTimeIntervalDays( KOne );
       
  1539                     }                
       
  1540                 CleanupStack::PopAndDestroy( entryUtil );                
   749                 break;
  1541                 break;
   750                 }
  1542                 }
   751             case ERecurrenceWeekly:
  1543             case ERecurrenceWeekly:
   752                 {
  1544                 {
   753                 --count;
  1545                 --count;