meetingrequest/mrservices/src/cesmrrecurrenceinfohandler.cpp
branchRCL_3
changeset 64 3533d4323edc
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: This file implements CESMRRecurrenceInfoHandler.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "cesmrrecurrenceinfohandler.h"
       
    19 #include "cesmrcaluserutil.h"
       
    20 #include "esmrdef.h"
       
    21 #include "mesmrmeetingrequestentry.h"
       
    22 #include "cesmrcaldbmgr.h"
       
    23 
       
    24 #include <calentry.h>
       
    25 #include <calrrule.h>
       
    26 #include <ct/rcpointerarray.h>
       
    27 #include <calinstanceview.h>
       
    28 #include <calinstanceiterator.h>
       
    29 
       
    30 #include <calinstance.h>
       
    31 
       
    32 #include "emailtrace.h"
       
    33 
       
    34 /// Unnamed namespace for local definitions
       
    35 namespace {
       
    36 
       
    37 // Definition for 0
       
    38 const TInt KZero = 0;
       
    39 
       
    40 // Definition for 1
       
    41 const TInt KOne = 1;
       
    42 
       
    43 // Definition for 2
       
    44 const TInt KTwo = 2;
       
    45 
       
    46 // Definition for days in week
       
    47 const TInt KDaysInWeek = 7;
       
    48 
       
    49 // Definition for days in two weeks
       
    50 const TInt KDaysInTwoWeeks = 14;
       
    51 
       
    52 // Definition for montsh in year
       
    53 const TInt KMonthsInYear = 12;
       
    54 
       
    55 /**
       
    56  * Compares two times and returns ETrue if they have same date components
       
    57  * @param aLhs Left hand side component
       
    58  * @param aRhs Right hand side component
       
    59  */
       
    60 TBool IsSameDay(
       
    61         const TDateTime& aLhs,
       
    62         const TDateTime& aRhs )
       
    63     {
       
    64     TBool retValue(EFalse);
       
    65 
       
    66     if ( aLhs.Day() == aRhs.Day() &&
       
    67          aLhs.Month() == aRhs.Month() &&
       
    68          aLhs.Year() == aRhs.Year()   )
       
    69         {
       
    70         retValue = ETrue;
       
    71         }
       
    72 
       
    73     return retValue;
       
    74     }
       
    75 
       
    76 /**
       
    77  * Checks if instance is included in exception list.
       
    78  * @param aInstanceTime Reference to instance time.
       
    79  * @param aExDateList Reference to exception list.
       
    80  */
       
    81 TBool IsTimeIncluded(
       
    82         const TCalTime& aInstanceTime,
       
    83         const RArray<TCalTime>& aExDateList )
       
    84     {
       
    85     FUNC_LOG;
       
    86     TBool included( EFalse );
       
    87     TInt exceptionCount( aExDateList.Count() );
       
    88     if ( exceptionCount )
       
    89         {
       
    90         for (TInt i(0); (i < exceptionCount) && !included ; i++ )
       
    91             {
       
    92             const TCalTime& exceptionTime( aExDateList[i] );
       
    93             TDateTime exDate = exceptionTime.TimeLocalL().DateTime();
       
    94 
       
    95             if ( aInstanceTime.TimeLocalL() == exceptionTime.TimeLocalL() )
       
    96                 {
       
    97                 included = ETrue;
       
    98                 }
       
    99             }
       
   100         }
       
   101     return included;
       
   102     }
       
   103 
       
   104 /**
       
   105  * Calculates time for next instance for recurrent event.
       
   106  * @param aRecurrenceValue Defines the used recurrence.
       
   107  * @param aPrevInstanceStartTime Start time of the previous instance.
       
   108  */
       
   109 TTime TimeForNextInstaceStartTime(
       
   110         TESMRRecurrenceValue aRecurrenceValue,
       
   111         TCalTime& aPrevInstanceStartTime )
       
   112     {
       
   113     TTime nextStartTime = aPrevInstanceStartTime.TimeLocalL();
       
   114 
       
   115     switch ( aRecurrenceValue )
       
   116         {
       
   117         case ERecurrenceDaily:
       
   118             {
       
   119             nextStartTime += TTimeIntervalDays( KOne );
       
   120             }
       
   121             break;
       
   122         case ERecurrenceWeekly:
       
   123             {
       
   124             nextStartTime += TTimeIntervalDays( KDaysInWeek );
       
   125             }
       
   126             break;
       
   127         case ERecurrenceEverySecondWeek:
       
   128             {
       
   129             nextStartTime += TTimeIntervalDays( KDaysInTwoWeeks );
       
   130             }
       
   131             break;
       
   132         case ERecurrenceMonthly:
       
   133             {
       
   134             nextStartTime += TTimeIntervalMonths( KOne );
       
   135             }
       
   136             break;
       
   137         case ERecurrenceYearly:
       
   138             {
       
   139             nextStartTime += TTimeIntervalYears( KOne );
       
   140             }
       
   141             break;
       
   142         default:
       
   143             {
       
   144             nextStartTime = aPrevInstanceStartTime.TimeLocalL();
       
   145             }
       
   146             break;
       
   147         }
       
   148 
       
   149     return nextStartTime;
       
   150     }
       
   151 
       
   152 
       
   153 void CalculateUntilForUnknownRecurrenceL(
       
   154         TTime& aUntil,
       
   155         TCalRRule& aRule )
       
   156     {
       
   157     aUntil = aRule.Until().TimeLocalL();
       
   158     if ( Time::NullTTime() == aUntil )
       
   159         {
       
   160         aUntil = aRule.DtStart().TimeLocalL();
       
   161         TInt factor( aRule.Count() * aRule.Interval() );
       
   162 
       
   163         switch ( aRule.Type() )
       
   164             {
       
   165             case TCalRRule::EDaily:
       
   166                 {
       
   167                 aUntil += TTimeIntervalDays(factor );
       
   168                 }
       
   169                 break;
       
   170             case TCalRRule::EWeekly:
       
   171                 {
       
   172                 aUntil += TTimeIntervalDays(factor * KDaysInWeek );
       
   173                 }
       
   174                 break;
       
   175             case TCalRRule::EMonthly:
       
   176                 {
       
   177                 aUntil += TTimeIntervalMonths(factor );
       
   178                 }
       
   179                 break;
       
   180             case TCalRRule::EYearly:
       
   181                 {
       
   182                 aUntil += TTimeIntervalYears(factor );
       
   183                 }
       
   184                 break;
       
   185             }
       
   186         }
       
   187     }
       
   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 
       
   277 }  // namespace
       
   278 
       
   279 // ======== MEMBER FUNCTIONS ========
       
   280 
       
   281 // ---------------------------------------------------------------------------
       
   282 // CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler
       
   283 // ---------------------------------------------------------------------------
       
   284 //
       
   285 inline CESMRRecurrenceInfoHandler::CESMRRecurrenceInfoHandler(
       
   286         CCalEntry& aEntry,
       
   287         MESMRCalDbMgr* aCalDb ) :
       
   288         iEntry( aEntry ),
       
   289         iCalDb( aCalDb )
       
   290     {
       
   291     FUNC_LOG;
       
   292     // Not implementation yet
       
   293     }
       
   294 
       
   295 // ---------------------------------------------------------------------------
       
   296 // CESMRRecurrenceInfoHandler::~CESMRRecurrenceInfoHandler
       
   297 // ---------------------------------------------------------------------------
       
   298 //
       
   299 EXPORT_C CESMRRecurrenceInfoHandler::~CESMRRecurrenceInfoHandler()
       
   300     {
       
   301     FUNC_LOG;
       
   302     // Not implementation yet
       
   303     }
       
   304 
       
   305 // ---------------------------------------------------------------------------
       
   306 // CESMRRecurrenceInfoHandler::NewL
       
   307 // ---------------------------------------------------------------------------
       
   308 //
       
   309 EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewL(
       
   310         CCalEntry& aEntry )
       
   311     {
       
   312     FUNC_LOG;
       
   313 
       
   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 );
       
   332     CleanupStack::Pop( self );
       
   333 
       
   334 
       
   335     return self;
       
   336     }
       
   337 
       
   338 // ---------------------------------------------------------------------------
       
   339 // CESMRRecurrenceInfoHandler::NewLC
       
   340 // ---------------------------------------------------------------------------
       
   341 //
       
   342 EXPORT_C CESMRRecurrenceInfoHandler* CESMRRecurrenceInfoHandler::NewLC(
       
   343         CCalEntry& aEntry )
       
   344     {
       
   345     FUNC_LOG;
       
   346 
       
   347     CESMRRecurrenceInfoHandler* self =
       
   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 );
       
   368     CleanupStack::PushL( self );
       
   369     self->ConstructL();
       
   370 
       
   371 
       
   372     return self;
       
   373     }
       
   374 
       
   375 // ---------------------------------------------------------------------------
       
   376 // CESMRRecurrenceInfoHandler::ConstructL
       
   377 // ---------------------------------------------------------------------------
       
   378 //
       
   379 void CESMRRecurrenceInfoHandler::ConstructL()
       
   380     {
       
   381     FUNC_LOG;
       
   382     // Not implementation yet
       
   383     }
       
   384 
       
   385 // ---------------------------------------------------------------------------
       
   386 // CESMRRecurrenceInfoHandler::SetRecurrenceL
       
   387 //
       
   388 // ---------------------------------------------------------------------------
       
   389 //
       
   390 EXPORT_C void CESMRRecurrenceInfoHandler::SetRecurrenceL(
       
   391         TESMRRecurrenceValue aRecurrence,
       
   392         TTime aUntil )
       
   393     {
       
   394     FUNC_LOG;
       
   395 
       
   396     // Recurrence until time needs to be in Utc mode, because comparison in
       
   397     // NeedToSetRecurrenceL is based on UTC times
       
   398     TCalTime until;
       
   399     until.SetTimeLocalL( aUntil );
       
   400     TTime recUntilUtc = until.TimeUtcL();
       
   401 
       
   402     // Check input parameters
       
   403     if ( ERecurrenceNot != aRecurrence &&
       
   404          Time::NullTTime() == aUntil )
       
   405         {
       
   406         // No until parameter set --> Leave
       
   407         User::Leave( KErrArgument );
       
   408         }
       
   409     else if ( ERecurrenceNot == aRecurrence )
       
   410         {
       
   411         // Clear all (recurrence, exceptions) repeating properties
       
   412         iEntry.ClearRepeatingPropertiesL();
       
   413         }
       
   414     else if ( NeedToSetRecurrenceL(aRecurrence, recUntilUtc) )
       
   415         {
       
   416         // Calculate 'correct' until time
       
   417         // Date component is taken from input parameter and
       
   418         // time component from meeting's end time.
       
   419         TDateTime until = aUntil.DateTime();
       
   420         TDateTime endTime = iEntry.EndTimeL().TimeLocalL().DateTime();
       
   421         until.SetHour( endTime.Hour() );
       
   422         until.SetMinute( endTime.Minute() );
       
   423         until.SetSecond( endTime.Second() );
       
   424 
       
   425         TCalTime rEndTime;
       
   426         rEndTime.SetTimeLocalL( TTime(until) );
       
   427 
       
   428         TCalTime meetingStartTime = iEntry.StartTimeL();
       
   429 
       
   430         TCalRRule rRule;
       
   431         rRule.SetDtStart( meetingStartTime );
       
   432 
       
   433         // Clear recurrence properties before setting the correct one
       
   434         iEntry.ClearRepeatingPropertiesL();
       
   435 
       
   436         switch ( aRecurrence )
       
   437             {
       
   438             case ERecurrenceDaily:
       
   439                 {
       
   440                 // Set daily recurrence
       
   441                 rRule.SetType( TCalRRule::EDaily );
       
   442 
       
   443                 TTimeIntervalDays daysBetween =
       
   444                     rEndTime.TimeLocalL().DaysFrom(
       
   445                             meetingStartTime.TimeLocalL() );
       
   446 
       
   447                 // First occurence and days between
       
   448                 rRule.SetCount( daysBetween.Int() + KOne);
       
   449                 rRule.SetInterval( KOne );
       
   450                 }
       
   451                 break;
       
   452 
       
   453             case ERecurrenceWeekly:
       
   454                 {
       
   455                 // Set weekly recurrence.
       
   456                 rRule.SetType( TCalRRule::EWeekly );
       
   457                 TTimeIntervalDays weeksBetween =
       
   458                     rEndTime.TimeLocalL().DaysFrom(
       
   459                             meetingStartTime.TimeLocalL() );
       
   460 
       
   461                 weeksBetween = weeksBetween.Int() / KDaysInWeek;
       
   462 
       
   463                 RArray<TDay> dayArray;
       
   464                 CleanupClosePushL( dayArray );
       
   465                 dayArray.Append( rRule.DtStart().TimeLocalL().DayNoInWeek() );
       
   466                 rRule.SetByDay( dayArray );
       
   467                 CleanupStack::PopAndDestroy( &dayArray );
       
   468 
       
   469                 // First occurence and weeks between
       
   470                 rRule.SetCount(
       
   471                         weeksBetween.Int() + KOne);
       
   472                 rRule.SetInterval( KOne );
       
   473                 }
       
   474                 break;
       
   475 
       
   476             case ERecurrenceEverySecondWeek:
       
   477                 {
       
   478                 // Set bi-weekly recurrence. This is weekly recurrence
       
   479                 // with 2 weeks interval.
       
   480                 rRule.SetType( TCalRRule::EWeekly );
       
   481                 TTimeIntervalDays fortNightBetween =
       
   482                     rEndTime.TimeLocalL().DaysFrom(
       
   483                             meetingStartTime.TimeLocalL() );
       
   484 
       
   485                 fortNightBetween =
       
   486                         fortNightBetween.Int() / KDaysInTwoWeeks;
       
   487 
       
   488                 RArray<TDay> dayArray;
       
   489                 CleanupClosePushL( dayArray );
       
   490                 dayArray.Append( rRule.DtStart().TimeLocalL().DayNoInWeek() );
       
   491                 rRule.SetByDay( dayArray );
       
   492                 CleanupStack::PopAndDestroy( &dayArray );
       
   493 
       
   494                 // First occurence and fortnights between
       
   495                 rRule.SetCount(
       
   496                         fortNightBetween.Int() + KOne);
       
   497                 rRule.SetInterval( KTwo );
       
   498                 }
       
   499                 break;
       
   500 
       
   501             case ERecurrenceMonthly:
       
   502                 {
       
   503                 // Set monthly recurrence.
       
   504                 rRule.SetType( TCalRRule::EMonthly );
       
   505 
       
   506                 RArray<TInt> dateArray;
       
   507                 CleanupClosePushL( dateArray );
       
   508                 dateArray.Append(
       
   509                     rRule.DtStart().TimeLocalL().DayNoInMonth() );
       
   510                 rRule.SetByMonthDay( dateArray );
       
   511                 CleanupStack::PopAndDestroy( &dateArray );
       
   512 
       
   513                 TTimeIntervalMonths monthsBetween =
       
   514                     rEndTime.TimeLocalL().MonthsFrom(
       
   515                             meetingStartTime.TimeLocalL() );
       
   516 
       
   517                 // First occurence and months between
       
   518                 rRule.SetCount( monthsBetween.Int() + KOne);
       
   519                 rRule.SetInterval( KOne );
       
   520                 }
       
   521                 break;
       
   522 
       
   523             case ERecurrenceYearly:
       
   524                 {
       
   525                 // Set yearly recurrence.
       
   526                 rRule.SetType( TCalRRule::EYearly );
       
   527 
       
   528                 TTimeIntervalYears yearsBetween =
       
   529                     rEndTime.TimeLocalL().YearsFrom(
       
   530                             meetingStartTime.TimeLocalL() );
       
   531 
       
   532                 // First occurence and months between
       
   533                 rRule.SetCount( yearsBetween.Int() + KOne);
       
   534                 rRule.SetInterval( KOne );
       
   535                 }
       
   536             default:
       
   537                 break;
       
   538             }
       
   539         iEntry.SetRRuleL( rRule );
       
   540         }
       
   541 
       
   542     }
       
   543 
       
   544 // ---------------------------------------------------------------------------
       
   545 // CESMRRecurrenceInfoHandler::GetRecurrenceL
       
   546 //
       
   547 // ---------------------------------------------------------------------------
       
   548 //
       
   549 EXPORT_C void CESMRRecurrenceInfoHandler::GetRecurrenceL(
       
   550         TESMRRecurrenceValue& aRecurrence,
       
   551         TTime& aUntil) const
       
   552     {
       
   553     FUNC_LOG;
       
   554 
       
   555     TESMRRecurrenceValue recurrenceValue(ERecurrenceNot);
       
   556 
       
   557     // Let's get RDates of the entry also to see if entry is repeating
       
   558     RArray<TCalTime> rdates;
       
   559     CleanupClosePushL( rdates );
       
   560     iEntry.GetRDatesL( rdates );
       
   561 
       
   562     TBool hasRdates = rdates.Count() > 0;
       
   563 
       
   564     TCalRRule rRule;
       
   565     if ( iEntry.GetRRuleL(rRule) || hasRdates )
       
   566         {
       
   567         // Entry has recurrence
       
   568         recurrenceValue = ERecurrenceUnknown;
       
   569 
       
   570         TCalRRule::TType rType = rRule.Type();
       
   571         TInt interval          = rRule.Interval();
       
   572 
       
   573         switch ( rType )
       
   574             {
       
   575             case TCalRRule::EInvalid:
       
   576                 {
       
   577                 // Recurrence type has not yet been defined
       
   578                 // --> Consider it then unknown.
       
   579                 recurrenceValue = ERecurrenceUnknown;
       
   580                 }
       
   581                 break;
       
   582 
       
   583             case TCalRRule::EDaily:
       
   584                 {
       
   585                 HandleDailyRecurrenceL( recurrenceValue, rRule );
       
   586                 }
       
   587                 break;
       
   588 
       
   589             case TCalRRule::EWeekly:
       
   590                 {
       
   591                 HandleWeeklyRecurrenceL( recurrenceValue, rRule );
       
   592                 }
       
   593                 break;
       
   594 
       
   595             case TCalRRule::EMonthly:
       
   596                 {
       
   597                 HandleMonthlyRecurrenceL( recurrenceValue, rRule );
       
   598                 }
       
   599                 break;
       
   600 
       
   601             case TCalRRule::EYearly:
       
   602                 {
       
   603                 // Recurrence is based on a number of years
       
   604                 if ( KOne == interval)
       
   605                     {
       
   606                     recurrenceValue = ERecurrenceYearly;
       
   607                     }
       
   608                 }
       
   609                 break;
       
   610             default:
       
   611                 break;
       
   612             }
       
   613 
       
   614         if ( hasRdates )
       
   615             {
       
   616             // Getting the last RDates occurance time == Until time
       
   617             aUntil = rdates[ rdates.Count() - 1 ].TimeUtcL();
       
   618             }
       
   619         else
       
   620             {
       
   621             CalculateRecurrenceUntilDateL(
       
   622                     recurrenceValue,
       
   623                     aUntil,
       
   624                     rRule,
       
   625                     iEntry );
       
   626             }
       
   627         }
       
   628 
       
   629     CleanupStack::PopAndDestroy( &rdates );
       
   630     aRecurrence = recurrenceValue;
       
   631     }
       
   632 
       
   633 
       
   634 EXPORT_C void CESMRRecurrenceInfoHandler::RemoveInstanceL(
       
   635         TCalTime aInstanceTime )
       
   636     {
       
   637     FUNC_LOG;
       
   638 
       
   639     RArray<TCalTime> exDateList;
       
   640     CleanupClosePushL( exDateList );
       
   641 
       
   642     TDateTime instanceException = aInstanceTime.TimeLocalL().DateTime();
       
   643     instanceException.SetHour( KZero );
       
   644     instanceException.SetMinute( KZero );
       
   645     instanceException.SetSecond( KZero );
       
   646     instanceException.SetMicroSecond( KZero );
       
   647 
       
   648     TCalTime exceptionTime;
       
   649     exceptionTime.SetTimeUtcL( TTime(instanceException) );
       
   650 
       
   651     iEntry.GetExceptionDatesL( exDateList );
       
   652     exDateList.Append( exceptionTime );
       
   653     iEntry.SetExceptionDatesL( exDateList );
       
   654 
       
   655     CleanupStack::PopAndDestroy( &exDateList );
       
   656 
       
   657     }
       
   658 
       
   659 // ---------------------------------------------------------------------------
       
   660 // CESMRRecurrenceInfoHandler::AddExceptionL
       
   661 //
       
   662 // ---------------------------------------------------------------------------
       
   663 //
       
   664 EXPORT_C void CESMRRecurrenceInfoHandler::AddExceptionL(
       
   665         TCalTime aNewInstanceTime,
       
   666          TCalTime aOrginalInstanceTime )
       
   667     {
       
   668     FUNC_LOG;
       
   669 
       
   670     // Entry's time has been modified and exception
       
   671     // needs to be added to parent entry
       
   672     RArray<TCalTime> rDateList;
       
   673     CleanupClosePushL( rDateList );
       
   674 
       
   675     RArray<TCalTime> exDateList;
       
   676     CleanupClosePushL( exDateList );
       
   677 
       
   678     // Only this instance is edited --> Set RRULE to entry
       
   679     iEntry.GetRDatesL( rDateList );
       
   680     iEntry.GetExceptionDatesL( exDateList );
       
   681 
       
   682     rDateList.Append( aNewInstanceTime );
       
   683     exDateList.Append( aOrginalInstanceTime );
       
   684 
       
   685     iEntry.SetRDatesL( rDateList );
       
   686     iEntry.SetExceptionDatesL( exDateList );
       
   687 
       
   688     CleanupStack::PopAndDestroy( &exDateList );
       
   689     CleanupStack::PopAndDestroy( &rDateList );
       
   690 
       
   691     }
       
   692 
       
   693 // ---------------------------------------------------------------------------
       
   694 // CESMRRecurrenceInfoHandler::CopyRecurrenceInformationToL
       
   695 //
       
   696 // ---------------------------------------------------------------------------
       
   697 //
       
   698 EXPORT_C void CESMRRecurrenceInfoHandler::CopyRecurrenceInformationToL(
       
   699         CCalEntry& aDestination )
       
   700     {
       
   701     FUNC_LOG;
       
   702 
       
   703     aDestination.ClearRepeatingPropertiesL();
       
   704 
       
   705     TCalRRule rrule;
       
   706     if ( iEntry.GetRRuleL(rrule) )
       
   707         {
       
   708         aDestination.SetRRuleL( rrule );
       
   709 
       
   710         RArray<TCalTime> rDateList;
       
   711         CleanupClosePushL( rDateList );
       
   712 
       
   713         RArray<TCalTime> exDateList;
       
   714         CleanupClosePushL( exDateList );
       
   715 
       
   716         iEntry.GetRDatesL( rDateList );
       
   717         iEntry.GetExceptionDatesL( exDateList );
       
   718 
       
   719         aDestination.SetRDatesL( rDateList );
       
   720         aDestination.SetExceptionDatesL( exDateList );
       
   721 
       
   722         CleanupStack::PopAndDestroy( &exDateList );
       
   723         CleanupStack::PopAndDestroy( &rDateList );
       
   724         }
       
   725 
       
   726     }
       
   727 
       
   728 // ---------------------------------------------------------------------------
       
   729 // CESMRRecurrenceInfoHandler::CopyRecurrenceInformationFromL
       
   730 //
       
   731 // ---------------------------------------------------------------------------
       
   732 //
       
   733 EXPORT_C void CESMRRecurrenceInfoHandler::CopyRecurrenceInformationFromL(
       
   734         const CCalEntry& aSource )
       
   735     {
       
   736     FUNC_LOG;
       
   737 
       
   738     iEntry.ClearRepeatingPropertiesL();
       
   739 
       
   740     TCalRRule rrule;
       
   741     if ( aSource.GetRRuleL(rrule) )
       
   742         {
       
   743         iEntry.SetRRuleL( rrule );
       
   744 
       
   745         RArray<TCalTime> rDateList;
       
   746         CleanupClosePushL( rDateList );
       
   747 
       
   748         RArray<TCalTime> exDateList;
       
   749         CleanupClosePushL( exDateList );
       
   750 
       
   751         aSource.GetRDatesL( rDateList );
       
   752         aSource.GetExceptionDatesL( exDateList );
       
   753 
       
   754         iEntry.SetRDatesL( rDateList );
       
   755         iEntry.SetExceptionDatesL( exDateList );
       
   756 
       
   757         CleanupStack::PopAndDestroy( &exDateList );
       
   758         CleanupStack::PopAndDestroy( &rDateList );
       
   759         }
       
   760 
       
   761     }
       
   762 
       
   763 
       
   764 // ---------------------------------------------------------------------------
       
   765 // CESMRRecurrenceInfoHandler::GetFirstInstanceTimeL
       
   766 //
       
   767 // ---------------------------------------------------------------------------
       
   768 //
       
   769 EXPORT_C void CESMRRecurrenceInfoHandler::GetFirstInstanceTimeL(
       
   770         TCalTime& aStart,
       
   771         TCalTime& aEnd )
       
   772     {
       
   773     FUNC_LOG;
       
   774 
       
   775     TESMRRecurrenceValue recurrence( ERecurrenceNot );
       
   776     TTime until( Time::NullTTime() );
       
   777     GetRecurrenceL( recurrence, until );
       
   778 
       
   779     if ( ERecurrenceNot == recurrence )
       
   780         {
       
   781         aStart = iEntry.StartTimeL();
       
   782         aEnd = iEntry.EndTimeL();
       
   783         }
       
   784     else if ( ERecurrenceUnknown != recurrence )
       
   785         {
       
   786         aStart = iEntry.StartTimeL();
       
   787         aEnd = iEntry.EndTimeL();
       
   788 
       
   789         TTimeIntervalMinutes diff;
       
   790         aEnd.TimeLocalL().MinutesFrom(
       
   791                 aStart.TimeLocalL(),
       
   792                 diff );
       
   793 
       
   794         RArray<TCalTime> exDateList;
       
   795         CleanupClosePushL( exDateList );
       
   796         iEntry.GetExceptionDatesL( exDateList );
       
   797 
       
   798         TInt exceptionCount( exDateList.Count() );
       
   799         if ( exceptionCount )
       
   800             {
       
   801             TBool timeIncludedInExceptionList(
       
   802                     IsTimeIncluded( aStart, exDateList ) );
       
   803 
       
   804             while( timeIncludedInExceptionList )
       
   805                 {
       
   806                 TTime nextInstanceTime =
       
   807                         TimeForNextInstaceStartTime(
       
   808                                 recurrence,
       
   809                                 aStart );
       
   810 
       
   811                 aStart.SetTimeLocalL( nextInstanceTime);
       
   812                 timeIncludedInExceptionList =
       
   813                         IsTimeIncluded( aStart, exDateList );
       
   814                 }
       
   815             }
       
   816 
       
   817         TCalTime untilCalTime;
       
   818         untilCalTime.SetTimeUtcL( until );
       
   819         
       
   820         TDateTime nextTime = aStart.TimeLocalL().DateTime();
       
   821         TDateTime untilTime = untilCalTime.TimeLocalL().DateTime();
       
   822         
       
   823         if ( aStart.TimeUtcL() > untilCalTime.TimeUtcL() )
       
   824             {
       
   825             User::Leave( KErrCorrupt );
       
   826             }
       
   827 
       
   828         TTime end = aStart.TimeLocalL() + diff;
       
   829         aEnd.SetTimeLocalL( end );
       
   830 
       
   831         CleanupStack::PopAndDestroy( &exDateList );
       
   832         }
       
   833     else
       
   834         {
       
   835         // Unknown recurrence type
       
   836         aStart = iEntry.StartTimeL();
       
   837         aEnd = iEntry.EndTimeL();
       
   838         }
       
   839 
       
   840     }
       
   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 
       
  1493 // ---------------------------------------------------------------------------
       
  1494 // CESMRRecurrenceInfoHandler::CalculateRecurrenceUntilDateL
       
  1495 //
       
  1496 // ---------------------------------------------------------------------------
       
  1497 //
       
  1498 void CESMRRecurrenceInfoHandler::CalculateRecurrenceUntilDateL(
       
  1499             TESMRRecurrenceValue aRecurrenceType,
       
  1500             TTime& aUntil,
       
  1501             TCalRRule& aRule,
       
  1502             const CCalEntry& aEntry  ) const
       
  1503     {
       
  1504     FUNC_LOG;
       
  1505     
       
  1506     TCalRRule::TType rType = aRule.Type();
       
  1507     TInt count             = aRule.Count();
       
  1508     TCalTime until         = aRule.Until();
       
  1509     
       
  1510     if ( count == KZero &&
       
  1511          until.TimeUtcL() == Time::NullTTime() )
       
  1512         {
       
  1513         User::Leave( KErrNotFound );
       
  1514         }
       
  1515 
       
  1516     if ( !count )
       
  1517         {
       
  1518         aUntil = until.TimeUtcL();
       
  1519         }
       
  1520     else
       
  1521         {
       
  1522         aUntil = aEntry.StartTimeL().TimeUtcL();
       
  1523         switch( aRecurrenceType )
       
  1524             {
       
  1525             case ERecurrenceDaily:
       
  1526                 {
       
  1527                 --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 );                
       
  1541                 break;
       
  1542                 }
       
  1543             case ERecurrenceWeekly:
       
  1544                 {
       
  1545                 --count;
       
  1546                 aUntil += TTimeIntervalDays(count * KDaysInWeek);
       
  1547                 break;
       
  1548                 }
       
  1549             case ERecurrenceEverySecondWeek:
       
  1550                 {
       
  1551                 --count;
       
  1552                 aUntil += TTimeIntervalDays(count * KDaysInTwoWeeks);
       
  1553                 break;
       
  1554                 }
       
  1555             case ERecurrenceMonthly:
       
  1556                 {
       
  1557                 --count;
       
  1558                 aUntil += TTimeIntervalMonths(count);
       
  1559                 break;
       
  1560                 }
       
  1561             case ERecurrenceYearly:
       
  1562                 {
       
  1563                 --count;
       
  1564                 aUntil += TTimeIntervalYears(count);
       
  1565                 break;
       
  1566                 }
       
  1567             default:
       
  1568                 {
       
  1569                 // Check if until date can be calculated
       
  1570                 CalculateUntilForUnknownRecurrenceL( aUntil, aRule );
       
  1571                 break;
       
  1572                 }
       
  1573             }
       
  1574         }
       
  1575     }
       
  1576 
       
  1577 // ---------------------------------------------------------------------------
       
  1578 // CESMRRecurrenceInfoHandler::HandleDailyRecurrenceL
       
  1579 // ---------------------------------------------------------------------------
       
  1580 //
       
  1581 void CESMRRecurrenceInfoHandler::HandleDailyRecurrenceL(
       
  1582         TESMRRecurrenceValue& aRecurrenceValue,
       
  1583         TCalRRule& aRule ) const
       
  1584     {
       
  1585     FUNC_LOG;
       
  1586     TInt interval( aRule.Interval() );
       
  1587     aRecurrenceValue = ERecurrenceUnknown;
       
  1588 
       
  1589     // Recurrence is based on a number of days
       
  1590     if ( KOne == interval )
       
  1591         {
       
  1592         // Recurrence occurs daily
       
  1593         aRecurrenceValue = ERecurrenceDaily;
       
  1594         }
       
  1595     else if ( KDaysInWeek ==  interval)
       
  1596         {
       
  1597         // Interval is seven days
       
  1598         // --> recurrence occurs weekly
       
  1599         aRecurrenceValue = ERecurrenceWeekly;
       
  1600         }
       
  1601     else if ( KDaysInTwoWeeks == interval )
       
  1602         {
       
  1603         // Interval is fortnight -->
       
  1604         // recurrence occurs bi-weekly
       
  1605         aRecurrenceValue = ERecurrenceEverySecondWeek;
       
  1606         }
       
  1607     }
       
  1608 
       
  1609 // ---------------------------------------------------------------------------
       
  1610 // CESMRRecurrenceInfoHandler::HandleWeeklyRecurrenceL
       
  1611 // ---------------------------------------------------------------------------
       
  1612 //
       
  1613 void CESMRRecurrenceInfoHandler::HandleWeeklyRecurrenceL(
       
  1614         TESMRRecurrenceValue& aRecurrenceValue,
       
  1615         TCalRRule& aRule ) const
       
  1616     {
       
  1617     FUNC_LOG;
       
  1618     TInt interval( aRule.Interval() );
       
  1619 
       
  1620     RArray<TDay> byDays;
       
  1621     CleanupClosePushL( byDays );
       
  1622     aRule.GetByDayL(byDays);
       
  1623 
       
  1624     if ( byDays.Count() > KOne )
       
  1625         {
       
  1626         // Entry is repeated more than once every week or
       
  1627         // every second week.
       
  1628         aRecurrenceValue = ERecurrenceUnknown;
       
  1629         }
       
  1630     else if ( KOne == interval)
       
  1631         {
       
  1632         aRecurrenceValue = ERecurrenceWeekly;
       
  1633         }
       
  1634     else if ( KTwo == interval )
       
  1635         {
       
  1636         aRecurrenceValue = ERecurrenceEverySecondWeek;
       
  1637         }
       
  1638 
       
  1639     CleanupStack::PopAndDestroy( &byDays );
       
  1640     }
       
  1641 
       
  1642 // ---------------------------------------------------------------------------
       
  1643 // CESMRRecurrenceInfoHandler::HandleMonthlyRecurrenceL
       
  1644 // ---------------------------------------------------------------------------
       
  1645 //
       
  1646 void CESMRRecurrenceInfoHandler::HandleMonthlyRecurrenceL(
       
  1647         TESMRRecurrenceValue& aRecurrenceValue,
       
  1648         TCalRRule& aRule ) const
       
  1649     {
       
  1650     FUNC_LOG;
       
  1651     TInt interval( aRule.Interval() );
       
  1652 
       
  1653     aRecurrenceValue = ERecurrenceUnknown;
       
  1654 
       
  1655     // Recurrence is based on a number of months
       
  1656     // Recurrence is based on a number of weeks
       
  1657     if ( KOne == interval)
       
  1658         {
       
  1659         aRecurrenceValue = ERecurrenceMonthly;
       
  1660         }
       
  1661     else if ( KMonthsInYear == interval )
       
  1662         {
       
  1663         aRecurrenceValue = ERecurrenceYearly;
       
  1664         }
       
  1665     }
       
  1666 
       
  1667 // ---------------------------------------------------------------------------
       
  1668 // CESMRRecurrenceInfoHandler::HandleYearlyRecurrenceL
       
  1669 // ---------------------------------------------------------------------------
       
  1670 //
       
  1671 void CESMRRecurrenceInfoHandler::HandleYearlyRecurrenceL(
       
  1672         TESMRRecurrenceValue& aRecurrenceValue,
       
  1673         TCalRRule& aRule ) const
       
  1674     {
       
  1675     FUNC_LOG;
       
  1676     TInt interval( aRule.Interval() );
       
  1677 
       
  1678     // Recurrence is based on a number of years
       
  1679     if ( KOne == interval)
       
  1680         {
       
  1681         aRecurrenceValue = ERecurrenceYearly;
       
  1682         }
       
  1683     else
       
  1684         {
       
  1685         aRecurrenceValue = ERecurrenceUnknown;
       
  1686         }
       
  1687     }
       
  1688 
       
  1689 // ---------------------------------------------------------------------------
       
  1690 // CESMRRecurrenceInfoHandler::NeedToSetRecurrence
       
  1691 //
       
  1692 // ---------------------------------------------------------------------------
       
  1693 //
       
  1694 TBool CESMRRecurrenceInfoHandler::NeedToSetRecurrenceL(
       
  1695         TESMRRecurrenceValue aRecurrence,
       
  1696         TTime aUntil ) const
       
  1697     {
       
  1698     FUNC_LOG;
       
  1699     TBool retValue(ETrue);
       
  1700 
       
  1701     TESMRRecurrenceValue oldRecurrence;
       
  1702     TTime oldUntil;
       
  1703     GetRecurrenceL( oldRecurrence, oldUntil );
       
  1704 
       
  1705     if( oldRecurrence == aRecurrence &&
       
  1706         IsSameDay( aUntil.DateTime(), oldUntil.DateTime() )     )
       
  1707         {
       
  1708         // Recurrence is not changed --> No need to set
       
  1709         retValue = EFalse;
       
  1710         }
       
  1711 
       
  1712     return retValue;
       
  1713     }
       
  1714 
       
  1715 // EOF
       
  1716