javaextensions/pim/agnadapter/src.s60/pimrepeatruleconverter.cpp
branchRCL_3
changeset 14 04becd199f91
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2008 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:  PIM item repeat rule converter class.
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include    "pimrepeatruleconverter.h"
       
    21 #include "logger.h"
       
    22 
       
    23 // CONSTANTS
       
    24 const TInt KPIMRepeatDatesArrayGranularity = 8;
       
    25 
       
    26 // ============================ MEMBER FUNCTIONS ==============================
       
    27 
       
    28 // ----------------------------------------------------------------------------
       
    29 // PIMRepeatRuleConverter::Dates
       
    30 // Calculates which dates occur on given date subset.
       
    31 // Returns: the dates without exception dates.
       
    32 // ----------------------------------------------------------------------------
       
    33 //
       
    34 CArrayFixFlat<TPIMDate>* PIMRepeatRuleConverter::DatesL(
       
    35     const MPIMRepeatRuleData& aRepeatRuleData, const TPIMDate& aStartDate,
       
    36     const TPIMDate& aSubsetBeginning, const TPIMDate& aSubsetEnding,
       
    37     CArrayFixFlat<TPIMDate>& aExceptionDates,
       
    38     const TPIMDate& aRepeatRuleEndDate, const TPIMField& aRepeatRuleCount)
       
    39 {
       
    40     JELOG2(EPim);
       
    41     CArrayFixFlat<TPIMDate> * repeatDates =
       
    42         new(ELeave) CArrayFixFlat<TPIMDate> (KPIMRepeatDatesArrayGranularity);
       
    43     CleanupStack::PushL(repeatDates);
       
    44 
       
    45     CArrayFix<TPIMField>* fields = aRepeatRuleData.GetFieldsL();
       
    46     CleanupStack::PushL(fields);
       
    47 
       
    48     // Make sure that only date part of the TTime is included, not the time part
       
    49     TDateTime startDateTime = aStartDate.DateTime();
       
    50     TTime newStartDate(startDateTime);
       
    51 
       
    52     TDateTime subsetBeginningDateTime = aSubsetBeginning.DateTime();
       
    53     TTime newSubsetBeginning(subsetBeginningDateTime);
       
    54 
       
    55     TDateTime subsetEndingDateTime = aSubsetEnding.DateTime();
       
    56     TTime newSubsetEnding(subsetEndingDateTime);
       
    57 
       
    58     TTime date = newStartDate;
       
    59     TInt countIndex = 0;
       
    60     TInt newInterval;
       
    61     if (IsRepeatFieldPresentL(EPIMRepeatRuleInterval, *fields))
       
    62     {
       
    63         newInterval = aRepeatRuleData.GetIntL(EPIMRepeatRuleInterval);
       
    64     }
       
    65     else
       
    66     {
       
    67         newInterval = 1;
       
    68     }
       
    69 
       
    70     TInt frequency = EPIMRepeatRuleDaily; // default if not present
       
    71 
       
    72     if (IsRepeatFieldPresentL(EPIMRepeatRuleFrequency, *fields))
       
    73     {
       
    74         frequency = aRepeatRuleData.GetIntL(EPIMRepeatRuleFrequency);
       
    75     }
       
    76 
       
    77     switch (frequency)
       
    78     {
       
    79     case(EPIMRepeatRuleDaily):
       
    80     {
       
    81         // Calculate the first repeat after the subset beginning date
       
    82         if (newSubsetBeginning > date)
       
    83         {
       
    84             while (date < newSubsetBeginning)
       
    85             {
       
    86                 date = date + TTimeIntervalDays(newInterval);
       
    87                 countIndex++;
       
    88             }
       
    89         }
       
    90 
       
    91         // First fill the array with all repeat dates
       
    92         for (; date < newSubsetEnding + TTimeIntervalDays(1); date = date
       
    93                 + TTimeIntervalDays(newInterval))
       
    94         {
       
    95             if (!AddRepeatDateL(*fields, date, newSubsetBeginning,
       
    96                                 newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
    97                                 &repeatDates, &countIndex))
       
    98             {
       
    99                 break;
       
   100             }
       
   101         }
       
   102         break;
       
   103     }
       
   104 
       
   105     case(EPIMRepeatRuleWeekly):
       
   106     {
       
   107         // Calculate the first repeat after the subset beginning date
       
   108         if (newSubsetBeginning > date)
       
   109         {
       
   110             while (date < newSubsetBeginning)
       
   111             {
       
   112                 date = date + TTimeIntervalDays(7 * newInterval);
       
   113                 countIndex++;
       
   114             }
       
   115         }
       
   116         // First fill the array with all repeat dates
       
   117         for (; date < newSubsetEnding + TTimeIntervalDays(1); date = date
       
   118                 + TTimeIntervalDays(7 * newInterval))
       
   119         {
       
   120             if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInWeek, *fields))
       
   121             {
       
   122                 if (!CheckDaysInWeekL(*fields, date, newSubsetBeginning,
       
   123                                       newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   124                                       aRepeatRuleData.GetIntL(EPIMRepeatRuleDayInWeek),
       
   125                                       &repeatDates, &countIndex))
       
   126                 {
       
   127                     break;
       
   128                 }
       
   129             }
       
   130             else
       
   131             {
       
   132                 if (!AddRepeatDateL(*fields, date, newSubsetBeginning,
       
   133                                     newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   134                                     &repeatDates, &countIndex))
       
   135                 {
       
   136                     break;
       
   137                 }
       
   138             }
       
   139         }
       
   140         break;
       
   141     }
       
   142 
       
   143     case(EPIMRepeatRuleMonthly):
       
   144     {
       
   145         // If DAY_IN_MONTH is present, shift the start date into it
       
   146         if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInMonth, *fields))
       
   147         {
       
   148             TInt repeatRuleDayInMonth = aRepeatRuleData.GetIntL(
       
   149                                             EPIMRepeatRuleDayInMonth);
       
   150 
       
   151             if (repeatRuleDayInMonth >= (newStartDate.DayNoInMonth() + 1))
       
   152             {
       
   153                 // The following check puts the DAY_IN_MONTH field to
       
   154                 // correct place when handling different lenght months
       
   155                 if (repeatRuleDayInMonth > (newStartDate.DaysInMonth() + 1))
       
   156                 {
       
   157                     date = newStartDate + TTimeIntervalDays(
       
   158                                newStartDate.DaysInMonth()
       
   159                                - (newStartDate.DayNoInMonth() + 1));
       
   160                 }
       
   161                 else
       
   162                 {
       
   163                     date = newStartDate + TTimeIntervalDays(
       
   164                                repeatRuleDayInMonth
       
   165                                - (newStartDate.DayNoInMonth() + 1));
       
   166                 }
       
   167             }
       
   168             else
       
   169             {
       
   170                 date = newStartDate - TTimeIntervalDays(
       
   171                            (newStartDate.DayNoInMonth() + 1) - repeatRuleDayInMonth);
       
   172             }
       
   173         }
       
   174         // Calculate the first repeat after the subset beginning date
       
   175         if (newSubsetBeginning > date)
       
   176         {
       
   177             while (date < newSubsetBeginning)
       
   178             {
       
   179                 date = date + TTimeIntervalMonths(newInterval);
       
   180                 countIndex++;
       
   181             }
       
   182         }
       
   183         // First fill the array with all repeat dates
       
   184         for (; date < newSubsetEnding + TTimeIntervalDays(1); date = date
       
   185                 + TTimeIntervalMonths(newInterval))
       
   186         {
       
   187             if (IsRepeatFieldPresentL(EPIMRepeatRuleWeekInMonth, *fields)
       
   188                     && IsRepeatFieldPresentL(EPIMRepeatRuleDayInWeek, *fields))
       
   189             {
       
   190                 if (!CheckWeeksInMonthL(*fields, date, newSubsetBeginning,
       
   191                                         newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   192                                         aRepeatRuleData.GetIntL(EPIMRepeatRuleWeekInMonth),
       
   193                                         aRepeatRuleData.GetIntL(EPIMRepeatRuleDayInWeek),
       
   194                                         &repeatDates, &countIndex))
       
   195                 {
       
   196                     break;
       
   197                 }
       
   198             }
       
   199             else
       
   200             {
       
   201                 // The following check puts the DAY_IN_MONTH field to
       
   202                 // correct place when handling different lenght months
       
   203                 if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInMonth, *fields))
       
   204                 {
       
   205                     TInt repeatRuleDayInMonth = aRepeatRuleData.GetIntL(
       
   206                                                     EPIMRepeatRuleDayInMonth);
       
   207 
       
   208                     if (repeatRuleDayInMonth > (date.DayNoInMonth() + 1))
       
   209                     {
       
   210                         if (repeatRuleDayInMonth < (date.DaysInMonth() + 1))
       
   211                         {
       
   212                             date = date + TTimeIntervalDays(
       
   213                                        repeatRuleDayInMonth
       
   214                                        - (date.DayNoInMonth() + 1));
       
   215                         }
       
   216                         else
       
   217                         {
       
   218                             date = date + TTimeIntervalDays(date.DaysInMonth()
       
   219                                                             - (date.DayNoInMonth() + 1));
       
   220                         }
       
   221                     }
       
   222                 }
       
   223                 if (!AddRepeatDateL(*fields, date, newSubsetBeginning,
       
   224                                     newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   225                                     &repeatDates, &countIndex))
       
   226                 {
       
   227                     break;
       
   228                 }
       
   229             }
       
   230         }
       
   231         break;
       
   232     }
       
   233 
       
   234     case(EPIMRepeatRuleYearly):
       
   235     {
       
   236         // If DAY_IN_YEAR is present, shift the start date into it
       
   237         if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInYear, *fields))
       
   238         {
       
   239             TInt repeatRuleDayInYear = aRepeatRuleData.GetIntL(
       
   240                                            EPIMRepeatRuleDayInYear);
       
   241 
       
   242             if (repeatRuleDayInYear >= newStartDate.DayNoInYear())
       
   243             {
       
   244                 date = newStartDate + TTimeIntervalDays(repeatRuleDayInYear
       
   245                                                         - newStartDate.DayNoInYear());
       
   246 
       
   247                 // If DAY_IN_YEAR was set to 366 and this is not a leap year
       
   248                 // substract one day from the calculated value
       
   249                 if (repeatRuleDayInYear == 366 && !Time::IsLeapYear(
       
   250                             newStartDate.DateTime().Year()))
       
   251                 {
       
   252                     date = date - TTimeIntervalDays(1);
       
   253                 }
       
   254             }
       
   255             else
       
   256             {
       
   257                 date = newStartDate - TTimeIntervalDays(
       
   258                            newStartDate.DayNoInYear() - repeatRuleDayInYear);
       
   259             }
       
   260         }
       
   261         // Calculate the first repeat after the subset beginning date
       
   262         if (newSubsetBeginning > date)
       
   263         {
       
   264             while (date < newSubsetBeginning)
       
   265             {
       
   266                 date = date + TTimeIntervalYears(newInterval);
       
   267                 countIndex++;
       
   268             }
       
   269         }
       
   270         // First fill the array with all repeat dates
       
   271         for (; date < newSubsetEnding + TTimeIntervalDays(1); date = date
       
   272                 + TTimeIntervalYears(newInterval))
       
   273         {
       
   274             TInt repeatRuleWeekInMonth = 0;
       
   275             TInt repeatRuleDayInWeek = 0;
       
   276             TInt repeatRuleMonthInYear = 0;
       
   277             TInt repeatRuleDayInMonth = 0;
       
   278 
       
   279             if (IsRepeatFieldPresentL(EPIMRepeatRuleMonthInYear, *fields))
       
   280             {
       
   281                 repeatRuleMonthInYear = aRepeatRuleData.GetIntL(
       
   282                                             EPIMRepeatRuleMonthInYear);
       
   283             }
       
   284 
       
   285             if (IsRepeatFieldPresentL(EPIMRepeatRuleWeekInMonth, *fields))
       
   286             {
       
   287                 repeatRuleWeekInMonth = aRepeatRuleData.GetIntL(
       
   288                                             EPIMRepeatRuleWeekInMonth);
       
   289             }
       
   290 
       
   291             if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInWeek, *fields))
       
   292             {
       
   293                 repeatRuleDayInWeek = aRepeatRuleData.GetIntL(
       
   294                                           EPIMRepeatRuleDayInWeek);
       
   295             }
       
   296 
       
   297             if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInMonth, *fields))
       
   298             {
       
   299                 repeatRuleDayInMonth = aRepeatRuleData.GetIntL(
       
   300                                            EPIMRepeatRuleDayInMonth);
       
   301             }
       
   302 
       
   303             if (IsRepeatFieldPresentL(EPIMRepeatRuleMonthInYear, *fields))
       
   304             {
       
   305                 if (!CheckMonthsInYearL(*fields, date, newSubsetBeginning,
       
   306                                         newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   307                                         repeatRuleWeekInMonth, repeatRuleDayInWeek,
       
   308                                         repeatRuleMonthInYear, repeatRuleDayInMonth, &repeatDates,
       
   309                                         &countIndex))
       
   310                 {
       
   311                     break;
       
   312                 }
       
   313             }
       
   314             else
       
   315             {
       
   316                 // The following check moves the DAY_IN_YEAR field from 365
       
   317                 // to 366 if DAY_IN_YEAR is set 366 and this is a leap year
       
   318                 if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInYear, *fields))
       
   319                 {
       
   320                     if (aRepeatRuleData.GetIntL(EPIMRepeatRuleDayInYear)
       
   321                             > date.DayNoInYear())
       
   322                     {
       
   323                         if (Time::IsLeapYear(date.DateTime().Year()))
       
   324                         {
       
   325                             date = date + TTimeIntervalDays(1);
       
   326                         }
       
   327                     }
       
   328                 }
       
   329                 if (!AddRepeatDateL(*fields, date, newSubsetBeginning,
       
   330                                     newSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   331                                     &repeatDates, &countIndex))
       
   332                 {
       
   333                     break;
       
   334                 }
       
   335             }
       
   336         }
       
   337         break;
       
   338     }
       
   339 
       
   340     } // switch( iRepeatRuleFrequency )
       
   341 
       
   342     // Finally remove any possible exception dates from the repeat dates array
       
   343     TInt exceptionDateFinder;
       
   344     TInt fetchIndex = 0;
       
   345     TKeyArrayFix key(0, ECmpTInt64);
       
   346     for (TInt index = 0; index < aExceptionDates.Count(); index++)
       
   347     {
       
   348         const TPIMDate& exceptDate = aExceptionDates.At(index);
       
   349         exceptionDateFinder = repeatDates->Find(exceptDate, key, fetchIndex);
       
   350         if (exceptionDateFinder == 0) // 0 means that the element was found
       
   351         {
       
   352             repeatDates->Delete(fetchIndex);
       
   353             // Deleting elements from the array does not cause the
       
   354             // array buffer to be automatically compressed.
       
   355             // Compress() method returns excess space to the heap.
       
   356             repeatDates->Compress();
       
   357         }
       
   358     }
       
   359 
       
   360     CleanupStack::PopAndDestroy(fields);
       
   361     CleanupStack::Pop(repeatDates);
       
   362     return repeatDates;
       
   363 }
       
   364 
       
   365 // -----------------------------------------------------------------------------
       
   366 // PIMRepeatRuleConverter::IsValidAgendaDate
       
   367 // Tells whether given date is ok for Agenda
       
   368 // (between 1st January 1980 and 31st December 2100).
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 TBool PIMRepeatRuleConverter::IsValidAgendaDate(const TPIMDate& aDate)
       
   372 {
       
   373     JELOG2(EPim);
       
   374     return ((aDate >= TCalTime::MinTime()) && (aDate <= TCalTime::MaxTime()));
       
   375 }
       
   376 
       
   377 // -----------------------------------------------------------------------------
       
   378 // PIMRepeatRuleConverter::ConvertRepeatToAgnL
       
   379 // Converts a PIM repeat rule to Agenda Model repeat definition.
       
   380 // Frequency is resolved first, as it affects rule formation.
       
   381 // Then frequency-dependent parts are resolved by frequencty.
       
   382 // Finally common parts are resolved.
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 TCalRRule PIMRepeatRuleConverter::ConvertSupportedRepeatToAgnL(
       
   386     const MPIMRepeatRuleData& aSrcPimRRule, TPIMDate aStartDate)
       
   387 {
       
   388     JELOG2(EPim);
       
   389     TCalTime calStartDate;
       
   390     calStartDate.SetTimeUtcL(aStartDate);
       
   391 
       
   392     TCalRRule dstAgnRRule;
       
   393 
       
   394     if (IsRepeatFieldPresentL(EPIMRepeatRuleFrequency, aSrcPimRRule))
       
   395     {
       
   396         const TInt pimFrequency = aSrcPimRRule.GetIntL(EPIMRepeatRuleFrequency);
       
   397 
       
   398         if (pimFrequency == EPIMRepeatRuleDaily)
       
   399         {
       
   400             dstAgnRRule.SetType(TCalRRule::EDaily);
       
   401         }
       
   402         else if (pimFrequency == EPIMRepeatRuleWeekly)
       
   403         {
       
   404             dstAgnRRule.SetType(TCalRRule::EWeekly);
       
   405             RArray<TDay> weekDays; // put in current weekday
       
   406             CleanupClosePushL(weekDays);
       
   407             User::LeaveIfError(weekDays.Append(aStartDate.DayNoInWeek()));
       
   408             dstAgnRRule.SetByDay(weekDays);
       
   409             CleanupStack::PopAndDestroy(&weekDays);
       
   410         }
       
   411         else if (pimFrequency == EPIMRepeatRuleMonthly)
       
   412         {
       
   413             dstAgnRRule.SetType(TCalRRule::EMonthly);
       
   414             RArray<TInt> monthDays; // put in current month day number
       
   415             CleanupClosePushL(monthDays);
       
   416             User::LeaveIfError(monthDays.Append(aStartDate.DayNoInMonth()));
       
   417             dstAgnRRule.SetByMonthDay(monthDays);
       
   418             CleanupStack::PopAndDestroy(&monthDays);
       
   419         }
       
   420         else if (pimFrequency == EPIMRepeatRuleYearly)
       
   421         {
       
   422             dstAgnRRule.SetType(TCalRRule::EYearly);
       
   423         }
       
   424         else
       
   425         {
       
   426             User::Leave(KErrCorrupt); // invalid frequency
       
   427         }
       
   428     }
       
   429     else // frequency not present
       
   430     {
       
   431         User::Leave(KErrAbort);
       
   432     }
       
   433 
       
   434     AddCommonRulesToAgnL(aSrcPimRRule, aStartDate, dstAgnRRule);
       
   435     return dstAgnRRule;
       
   436 }
       
   437 
       
   438 // -----------------------------------------------------------------------------
       
   439 // PIMRepeatRuleConverter::ConvertRepeatToPIM
       
   440 // Converts an Agenda Model repeat definition to PIM repeat rule
       
   441 // -----------------------------------------------------------------------------
       
   442 //
       
   443 void PIMRepeatRuleConverter::ConvertSupportedRepeatToPIML(
       
   444     MPIMRepeatRuleData& aDstPimRRule, TCalRRule& aSrcAgnRRule)
       
   445 {
       
   446     JELOG2(EPim);
       
   447     aDstPimRRule.clear();
       
   448 
       
   449     // Frequency
       
   450     if (aSrcAgnRRule.Type() == TCalRRule::EDaily)
       
   451     {
       
   452         aDstPimRRule.SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleDaily);
       
   453     }
       
   454     else if (aSrcAgnRRule.Type() == TCalRRule::EWeekly)
       
   455     {
       
   456         aDstPimRRule.SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleWeekly);
       
   457     }
       
   458     else if (aSrcAgnRRule.Type() == TCalRRule::EMonthly)
       
   459     {
       
   460         aDstPimRRule.SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleMonthly);
       
   461     }
       
   462     else if (aSrcAgnRRule.Type() == TCalRRule::EYearly)
       
   463     {
       
   464         aDstPimRRule.SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleYearly);
       
   465     }
       
   466     else
       
   467     {
       
   468         User::Leave(KErrCorrupt); // repeatrule without frequency
       
   469     }
       
   470 
       
   471     // Interval
       
   472     aDstPimRRule.SetIntL(EPIMRepeatRuleInterval, aSrcAgnRRule.Interval());
       
   473 
       
   474     // End time
       
   475     TCalTime calEndDate = aSrcAgnRRule.Until();
       
   476     TTime pimEndDate(calEndDate.TimeUtcL());
       
   477     aDstPimRRule.SetDateL(EPIMRepeatRuleEnd, pimEndDate);
       
   478 }
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // PIMRepeatRuleConverter::IsRepeatFieldPresentL
       
   482 // Checks if a field is present in the repeat rule.
       
   483 // Use the other overload instead if you are checking multiple fields.
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 TBool PIMRepeatRuleConverter::IsRepeatFieldPresentL(TPIMField aRepeatRuleField,
       
   487         const MPIMRepeatRuleData& aRepeat)
       
   488 {
       
   489     JELOG2(EPim);
       
   490     CArrayFix<TPIMField>* repeatFields = aRepeat.GetFieldsL();
       
   491     CleanupStack::PushL(repeatFields);
       
   492     TBool retVal = IsRepeatFieldPresentL(aRepeatRuleField, *repeatFields);
       
   493     CleanupStack::PopAndDestroy(repeatFields);
       
   494     return retVal;
       
   495 }
       
   496 
       
   497 // -----------------------------------------------------------------------------
       
   498 // PIMRepeatRuleConverter::IsRepeatFieldPresentL
       
   499 // Checks if a field is present in the array of repeat fields.
       
   500 // Optimizes speed if called repeatedly instead of the overload
       
   501 // which takes a MPIMRepeatRuleData.
       
   502 // -----------------------------------------------------------------------------
       
   503 //
       
   504 TBool PIMRepeatRuleConverter::IsRepeatFieldPresentL(TPIMField aRepeatRuleField,
       
   505         const CArrayFix<TPIMField>& aRepeatFields)
       
   506 {
       
   507     JELOG2(EPim);
       
   508     TInt fetchIndex = 0;
       
   509     TKeyArrayFix key(0, ECmpTInt);
       
   510     TInt found = aRepeatFields.Find(aRepeatRuleField, key, fetchIndex);
       
   511     return (found == KErrNone);
       
   512 }
       
   513 
       
   514 // -----------------------------------------------------------------------------
       
   515 // PIMRepeatRuleConverter::AddRepeatDateL
       
   516 // Checks if a single date is qualified as a repeat date, and adds it to array.
       
   517 // -----------------------------------------------------------------------------
       
   518 //
       
   519 TBool PIMRepeatRuleConverter::AddRepeatDateL(
       
   520     const CArrayFix<TPIMField>& /*aFields*/, TTime aDate,
       
   521     TTime aSubsetBeginning, TTime aSubsetEnding,
       
   522     const TTime& aRepeatRuleEndDate, const TInt aRepeatRuleCount,
       
   523     CArrayFixFlat<TPIMDate>** aRepeatDates, TInt* aCountIndex)
       
   524 {
       
   525     JELOG2(EPim);
       
   526     if (aDate < aSubsetBeginning)
       
   527     {
       
   528         return ETrue; // Here it is possible to still continue (no date added)
       
   529     }
       
   530     if (aDate > aSubsetEnding)
       
   531     {
       
   532         return EFalse; // Not possible to continue (subset end reached)
       
   533     }
       
   534     if ((aRepeatRuleEndDate != Time::NullTTime()) && (aDate
       
   535             > aRepeatRuleEndDate))
       
   536     {
       
   537         return EFalse; // Not possible to continue (repeat rule end reached)
       
   538     }
       
   539 
       
   540     (*aCountIndex)++;
       
   541     if (aRepeatRuleCount > 0 && (*aCountIndex) > aRepeatRuleCount)
       
   542     {
       
   543         return EFalse; // Not possible to continue (repeat rule count full)
       
   544     }
       
   545 
       
   546     (*aRepeatDates)->AppendL(aDate);
       
   547     return ETrue;
       
   548 }
       
   549 
       
   550 // -----------------------------------------------------------------------------
       
   551 // PIMRepeatRuleConverter::AddCommonRulesToAgnL
       
   552 // Adds common parts of supported repeat rules to Agenda repeat.
       
   553 // -----------------------------------------------------------------------------
       
   554 //
       
   555 void PIMRepeatRuleConverter::AddCommonRulesToAgnL(
       
   556     const MPIMRepeatRuleData& aSrcPimRRule, const TTime& aSrcStartDate,
       
   557     TCalRRule& aDstAgnRRule)
       
   558 {
       
   559     JELOG2(EPim);
       
   560     // Interval
       
   561     TInt interval = 1;
       
   562     if (IsRepeatFieldPresentL(EPIMRepeatRuleInterval, aSrcPimRRule))
       
   563     {
       
   564         interval = aSrcPimRRule.GetIntL(EPIMRepeatRuleInterval);
       
   565     }
       
   566     aDstAgnRRule.SetInterval(interval);
       
   567 
       
   568     // Start date
       
   569     TCalTime calStartDate;
       
   570     calStartDate.SetTimeUtcL(aSrcStartDate);
       
   571     aDstAgnRRule.SetDtStart(calStartDate);
       
   572 
       
   573     // End date
       
   574     if (IsRepeatFieldPresentL(EPIMRepeatRuleEnd, aSrcPimRRule))
       
   575     {
       
   576         TTime pimEndDate = aSrcPimRRule.GetDateL(EPIMRepeatRuleEnd);
       
   577         TCalTime calEndDate;
       
   578         calEndDate.SetTimeUtcL(pimEndDate);
       
   579         aDstAgnRRule.SetUntil(calEndDate);
       
   580     }
       
   581 }
       
   582 
       
   583 // -----------------------------------------------------------------------------
       
   584 // PIMRepeatRuleConverter::CheckDaysInWeekL
       
   585 // Checks if any week days are qualified as repeat dates, and adds them to array
       
   586 // DAY_IN_WEEK requires that one or more weekdays are set,
       
   587 // otherwise cannot process
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 TBool PIMRepeatRuleConverter::CheckDaysInWeekL(
       
   591     const CArrayFix<TPIMField>& aFields, TTime aDate, TTime aSubsetBeginning,
       
   592     TTime aSubsetEnding, TTime aRepeatRuleEndDate, TInt aRepeatRuleCount,
       
   593     const TInt aRepeatRuleDayInWeek, CArrayFixFlat<TPIMDate>** aRepeatDates,
       
   594     TInt* aCountIndex)
       
   595 {
       
   596     JELOG2(EPim);
       
   597     if (!IsRepeatFieldPresentL(EPIMRepeatRuleDayInWeek, aFields))
       
   598     {
       
   599         return EFalse;
       
   600     }
       
   601 
       
   602     TTime checkDay;
       
   603     TLocale locale;
       
   604 
       
   605     // Set the day to the 1st day of the week.
       
   606     if (locale.StartOfWeek() == EMonday)
       
   607     {
       
   608         checkDay = aDate - TTimeIntervalDays(aDate.DayNoInWeek());
       
   609     }
       
   610     else // In case the start of week is set to sunday, substract one day more
       
   611     {
       
   612         if (aDate.DayNoInWeek() == ESunday)
       
   613         {
       
   614             checkDay = aDate; // The day was already sunday, do not substract
       
   615         }
       
   616         else
       
   617         {
       
   618             checkDay = aDate - TTimeIntervalDays(aDate.DayNoInWeek() + 1);
       
   619         }
       
   620     }
       
   621 
       
   622     // If the start of the week is set to sunday, start from here
       
   623     if (locale.StartOfWeek() == ESunday)
       
   624     {
       
   625         if (aRepeatRuleDayInWeek & EPIMRepeatRuleSunday)
       
   626         {
       
   627             if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   628                                 aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   629                                 aRepeatDates, aCountIndex))
       
   630             {
       
   631                 return EFalse;
       
   632             }
       
   633         }
       
   634         checkDay = checkDay + TTimeIntervalDays(1);
       
   635     }
       
   636 
       
   637     // If the start of the week is set to monday, start from here
       
   638     if (aRepeatRuleDayInWeek & EPIMRepeatRuleMonday)
       
   639     {
       
   640         if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
   641                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
   642         {
       
   643             return EFalse;
       
   644         }
       
   645     }
       
   646     checkDay = checkDay + TTimeIntervalDays(1);
       
   647     if (aRepeatRuleDayInWeek & EPIMRepeatRuleTuesday)
       
   648     {
       
   649         if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
   650                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
   651         {
       
   652             return EFalse;
       
   653         }
       
   654     }
       
   655     checkDay = checkDay + TTimeIntervalDays(1);
       
   656     if (aRepeatRuleDayInWeek & EPIMRepeatRuleWednesday)
       
   657     {
       
   658         if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
   659                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
   660         {
       
   661             return EFalse;
       
   662         }
       
   663     }
       
   664     checkDay = checkDay + TTimeIntervalDays(1);
       
   665     if (aRepeatRuleDayInWeek & EPIMRepeatRuleThursday)
       
   666     {
       
   667         if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
   668                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
   669         {
       
   670             return EFalse;
       
   671         }
       
   672     }
       
   673     checkDay = checkDay + TTimeIntervalDays(1);
       
   674     if (aRepeatRuleDayInWeek & EPIMRepeatRuleFriday)
       
   675     {
       
   676         if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
   677                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
   678         {
       
   679             return EFalse;
       
   680         }
       
   681     }
       
   682     checkDay = checkDay + TTimeIntervalDays(1);
       
   683     if (aRepeatRuleDayInWeek & EPIMRepeatRuleSaturday)
       
   684     {
       
   685         if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
   686                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
   687         {
       
   688             return EFalse;
       
   689         }
       
   690     }
       
   691 
       
   692     // If the start of the week is set to monday, sunday is the last day of week
       
   693     if (locale.StartOfWeek() == EMonday)
       
   694     {
       
   695         checkDay = checkDay + TTimeIntervalDays(1);
       
   696         if (aRepeatRuleDayInWeek & EPIMRepeatRuleSunday)
       
   697         {
       
   698             if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   699                                 aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   700                                 aRepeatDates, aCountIndex))
       
   701             {
       
   702                 return EFalse;
       
   703             }
       
   704         }
       
   705     }
       
   706 
       
   707     return ETrue;
       
   708 }
       
   709 
       
   710 // -----------------------------------------------------------------------------
       
   711 // PIMRepeatRuleConverter::CheckDaysInWeekNoMonthChangeL
       
   712 // Checks if any week days are qualified as repeat dates, and adds them to array
       
   713 // If the month changes to a different month during the week (the week is either
       
   714 // in the beginning of the month or at the end of the month), only those days
       
   715 // that belong to this month are checked and the rest are discarded.
       
   716 // DAY_IN_WEEK requires that one or more weekdays are set,
       
   717 // otherwise cannot process
       
   718 // -----------------------------------------------------------------------------
       
   719 //
       
   720 TBool PIMRepeatRuleConverter::CheckDaysInWeekNoMonthChangeL(const CArrayFix<
       
   721         TPIMField>& aFields, TTime aDate, TTime aSubsetBeginning,
       
   722         TTime aSubsetEnding, TTime aRepeatRuleEndDate, TInt aRepeatRuleCount,
       
   723         const TInt aRepeatRuleDayInWeek, CArrayFixFlat<TPIMDate>** aRepeatDates,
       
   724         TInt* aCountIndex)
       
   725 {
       
   726     JELOG2(EPim);
       
   727     if (!IsRepeatFieldPresentL(EPIMRepeatRuleDayInWeek, aFields))
       
   728     {
       
   729         return EFalse;
       
   730     }
       
   731 
       
   732     TTime checkDay = aDate;
       
   733 
       
   734     // First it is needed to check are there accepted dates before the given
       
   735     // date value on the same week (and on the same month)
       
   736     while (checkDay.WeekNoInYear() == aDate.WeekNoInYear()
       
   737             && checkDay.DateTime().Month() == aDate.DateTime().Month())
       
   738     {
       
   739         checkDay = checkDay - TTimeIntervalDays(1);
       
   740     }
       
   741 
       
   742     // In the loop the day went to previous month or previous week, add one day
       
   743     checkDay = checkDay + TTimeIntervalDays(1);
       
   744 
       
   745     // Store the first accepted day for further comparison.
       
   746     TTime firstAcceptedDay = checkDay;
       
   747 
       
   748     // Calculate how many accepted dates in this week there are in total
       
   749     TInt acceptedDaysThisWeek = 0;
       
   750     while (checkDay.WeekNoInYear() == aDate.WeekNoInYear()
       
   751             && checkDay.DateTime().Month() == aDate.DateTime().Month())
       
   752     {
       
   753         acceptedDaysThisWeek++;
       
   754         checkDay = checkDay + TTimeIntervalDays(1);
       
   755     }
       
   756 
       
   757     // Finally go through all the accepted days this week
       
   758     for (checkDay = firstAcceptedDay; checkDay < firstAcceptedDay
       
   759             + TTimeIntervalDays(acceptedDaysThisWeek); checkDay = checkDay
       
   760                     + TTimeIntervalDays(1))
       
   761     {
       
   762         switch (checkDay.DayNoInWeek())
       
   763         {
       
   764         case EMonday:
       
   765         {
       
   766             if (aRepeatRuleDayInWeek & EPIMRepeatRuleMonday)
       
   767             {
       
   768                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   769                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   770                                     aRepeatDates, aCountIndex))
       
   771                 {
       
   772                     return EFalse;
       
   773                 }
       
   774             }
       
   775             break;
       
   776         }
       
   777         case ETuesday:
       
   778         {
       
   779             if (aRepeatRuleDayInWeek & EPIMRepeatRuleTuesday)
       
   780             {
       
   781                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   782                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   783                                     aRepeatDates, aCountIndex))
       
   784                 {
       
   785                     return EFalse;
       
   786                 }
       
   787             }
       
   788             break;
       
   789         }
       
   790         case EWednesday:
       
   791         {
       
   792             if (aRepeatRuleDayInWeek & EPIMRepeatRuleWednesday)
       
   793             {
       
   794                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   795                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   796                                     aRepeatDates, aCountIndex))
       
   797                 {
       
   798                     return EFalse;
       
   799                 }
       
   800             }
       
   801             break;
       
   802         }
       
   803         case EThursday:
       
   804         {
       
   805             if (aRepeatRuleDayInWeek & EPIMRepeatRuleThursday)
       
   806             {
       
   807                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   808                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   809                                     aRepeatDates, aCountIndex))
       
   810                 {
       
   811                     return EFalse;
       
   812                 }
       
   813             }
       
   814             break;
       
   815         }
       
   816         case EFriday:
       
   817         {
       
   818             if (aRepeatRuleDayInWeek & EPIMRepeatRuleFriday)
       
   819             {
       
   820                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   821                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   822                                     aRepeatDates, aCountIndex))
       
   823                 {
       
   824                     return EFalse;
       
   825                 }
       
   826             }
       
   827             break;
       
   828         }
       
   829         case ESaturday:
       
   830         {
       
   831             if (aRepeatRuleDayInWeek & EPIMRepeatRuleSaturday)
       
   832             {
       
   833                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   834                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   835                                     aRepeatDates, aCountIndex))
       
   836                 {
       
   837                     return EFalse;
       
   838                 }
       
   839             }
       
   840             break;
       
   841         }
       
   842         case ESunday:
       
   843         {
       
   844             if (aRepeatRuleDayInWeek & EPIMRepeatRuleSunday)
       
   845             {
       
   846                 if (!AddRepeatDateL(aFields, checkDay, aSubsetBeginning,
       
   847                                     aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   848                                     aRepeatDates, aCountIndex))
       
   849                 {
       
   850                     return EFalse;
       
   851                 }
       
   852             }
       
   853             break;
       
   854         }
       
   855         default:
       
   856         {
       
   857             return EFalse;
       
   858         }
       
   859         } //switch
       
   860     } // for
       
   861 
       
   862     return ETrue;
       
   863 }
       
   864 
       
   865 // -----------------------------------------------------------------------------
       
   866 // PIMRepeatRuleConverter::CheckWeeksInMonthL
       
   867 // Checks if any weeks in month are set to contain repeat dates
       
   868 // WEEK_IN_MONTH requires that DAY_IN_WEEK is set, otherwise cannot process
       
   869 // -----------------------------------------------------------------------------
       
   870 //
       
   871 TBool PIMRepeatRuleConverter::CheckWeeksInMonthL(
       
   872     const CArrayFix<TPIMField>& aFields, TTime aDate, TTime aSubsetBeginning,
       
   873     TTime aSubsetEnding, TTime aRepeatRuleEndDate, TInt aRepeatRuleCount,
       
   874     const TInt aRepeatRuleWeekInMonth, const TInt aRepeatRuleDayInWeek,
       
   875     CArrayFixFlat<TPIMDate>** aRepeatDates, TInt* aCountIndex)
       
   876 {
       
   877     JELOG2(EPim);
       
   878     TTime checkDay;
       
   879 
       
   880     // Make sure the date is set to the 1st day of this month.
       
   881     if (aDate.DayNoInMonth() > 0)
       
   882     {
       
   883         checkDay = aDate - TTimeIntervalDays(aDate.DayNoInMonth());
       
   884     }
       
   885 
       
   886     TInt firstWeekNumber = checkDay.WeekNoInYear();
       
   887     TInt lastWeekNumber = (checkDay + TTimeIntervalDays(checkDay.DaysInMonth()
       
   888                            - 1)).WeekNoInYear();
       
   889     TInt weeksInMonth = lastWeekNumber - firstWeekNumber + 1;
       
   890 
       
   891     // If there are only 4 weeks in month: This can happen when all weeks are
       
   892     // full weeks (7 days in each) and there are only 28 days in this month.
       
   893     if (weeksInMonth == 4)
       
   894     {
       
   895         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFirst
       
   896                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleFourthLast)
       
   897         {
       
   898             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   899                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   900                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   901             {
       
   902                 return EFalse;
       
   903             }
       
   904         }
       
   905         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
   906 
       
   907         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleSecond
       
   908                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleThirdLast)
       
   909         {
       
   910             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   911                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   912                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   913             {
       
   914                 return EFalse;
       
   915             }
       
   916         }
       
   917         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
   918 
       
   919         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleThird
       
   920                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleSecondLast)
       
   921         {
       
   922             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   923                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   924                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   925             {
       
   926                 return EFalse;
       
   927             }
       
   928         }
       
   929         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
   930 
       
   931         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFourth
       
   932                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleLast)
       
   933         {
       
   934             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   935                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   936                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   937             {
       
   938                 return EFalse;
       
   939             }
       
   940         }
       
   941     }
       
   942 
       
   943     // If there are 5 weeks in month: This is the most common situation.
       
   944     // The first week and the last week can be incomplete (and so they have
       
   945     // to be handled with the different method), but the three weeks in the
       
   946     // middle are guaranteed to be full weeks with 7 days each.
       
   947     if (weeksInMonth == 5)
       
   948     {
       
   949         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFirst
       
   950                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleFifthLast)
       
   951         {
       
   952             if (!CheckDaysInWeekNoMonthChangeL(aFields, checkDay,
       
   953                                                aSubsetBeginning, aSubsetEnding, aRepeatRuleEndDate,
       
   954                                                aRepeatRuleCount, aRepeatRuleDayInWeek, aRepeatDates,
       
   955                                                aCountIndex))
       
   956             {
       
   957                 return EFalse;
       
   958             }
       
   959         }
       
   960         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
   961 
       
   962         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleSecond
       
   963                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleFourthLast)
       
   964         {
       
   965             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   966                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   967                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   968             {
       
   969                 return EFalse;
       
   970             }
       
   971         }
       
   972         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
   973 
       
   974         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleThird
       
   975                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleThirdLast)
       
   976         {
       
   977             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   978                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   979                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   980             {
       
   981                 return EFalse;
       
   982             }
       
   983         }
       
   984         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
   985 
       
   986         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFourth
       
   987                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleSecondLast)
       
   988         {
       
   989             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
   990                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
   991                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
   992             {
       
   993                 return EFalse;
       
   994             }
       
   995         }
       
   996 
       
   997         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFifth
       
   998                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleLast)
       
   999         {
       
  1000             // Here we need to go exactly to the 1st day of next week
       
  1001             TTime fourthWeek = checkDay;
       
  1002             while (checkDay.WeekNoInYear() == fourthWeek.WeekNoInYear())
       
  1003             {
       
  1004                 checkDay = checkDay + TTimeIntervalDays(1);
       
  1005             }
       
  1006             if (!CheckDaysInWeekNoMonthChangeL(aFields, checkDay,
       
  1007                                                aSubsetBeginning, aSubsetEnding, aRepeatRuleEndDate,
       
  1008                                                aRepeatRuleCount, aRepeatRuleDayInWeek, aRepeatDates,
       
  1009                                                aCountIndex))
       
  1010             {
       
  1011                 return EFalse;
       
  1012             }
       
  1013         }
       
  1014     }
       
  1015 
       
  1016     // If there are 6 weeks in month: This happens only a few times a year.
       
  1017     // The first week and the last week can be incomplete (and so they have
       
  1018     // to be handled with the different method), but the four weeks in the
       
  1019     // middle are guaranteed to be full weeks with 7 days each.
       
  1020     if (weeksInMonth == 6)
       
  1021     {
       
  1022         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFirst)
       
  1023         {
       
  1024             if (!CheckDaysInWeekNoMonthChangeL(aFields, checkDay,
       
  1025                                                aSubsetBeginning, aSubsetEnding, aRepeatRuleEndDate,
       
  1026                                                aRepeatRuleCount, aRepeatRuleDayInWeek, aRepeatDates,
       
  1027                                                aCountIndex))
       
  1028             {
       
  1029                 return EFalse;
       
  1030             }
       
  1031         }
       
  1032         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
  1033 
       
  1034         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleSecond
       
  1035                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleFifthLast)
       
  1036         {
       
  1037             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
  1038                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
  1039                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
  1040             {
       
  1041                 return EFalse;
       
  1042             }
       
  1043         }
       
  1044         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
  1045 
       
  1046         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleThird
       
  1047                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleFourthLast)
       
  1048         {
       
  1049             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
  1050                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
  1051                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
  1052             {
       
  1053                 return EFalse;
       
  1054             }
       
  1055         }
       
  1056         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
  1057 
       
  1058         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFourth
       
  1059                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleThirdLast)
       
  1060         {
       
  1061             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
  1062                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
  1063                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
  1064             {
       
  1065                 return EFalse;
       
  1066             }
       
  1067         }
       
  1068         checkDay = checkDay + TTimeIntervalDays(7); // Move one week forward
       
  1069 
       
  1070         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleFifth
       
  1071                 || aRepeatRuleWeekInMonth & EPIMRepeatRuleSecondLast)
       
  1072         {
       
  1073             if (!CheckDaysInWeekL(aFields, checkDay, aSubsetBeginning,
       
  1074                                   aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
  1075                                   aRepeatRuleDayInWeek, aRepeatDates, aCountIndex))
       
  1076             {
       
  1077                 return EFalse;
       
  1078             }
       
  1079         }
       
  1080 
       
  1081         if (aRepeatRuleWeekInMonth & EPIMRepeatRuleLast)
       
  1082         {
       
  1083             // Here we need to go exactly to the 1st day of next week
       
  1084             TTime fifthWeek = checkDay;
       
  1085             while (checkDay.WeekNoInYear() == fifthWeek.WeekNoInYear())
       
  1086             {
       
  1087                 checkDay = checkDay + TTimeIntervalDays(1);
       
  1088             }
       
  1089             if (!CheckDaysInWeekNoMonthChangeL(aFields, checkDay,
       
  1090                                                aSubsetBeginning, aSubsetEnding, aRepeatRuleEndDate,
       
  1091                                                aRepeatRuleCount, aRepeatRuleDayInWeek, aRepeatDates,
       
  1092                                                aCountIndex))
       
  1093             {
       
  1094                 return EFalse;
       
  1095             }
       
  1096         }
       
  1097     }
       
  1098 
       
  1099     return ETrue;
       
  1100 }
       
  1101 
       
  1102 // -----------------------------------------------------------------------------
       
  1103 // PIMRepeatRuleConverter::CheckMonthsInYearL
       
  1104 // Checks if any months in year are set to contain repeat dates
       
  1105 // MONTH_IN_YEAR requires that either DAY_IN_MONTH is set, or
       
  1106 // both WEEK_IN_MONTH and DAY_IN_WEEK are set: otherwise cannot process
       
  1107 // -----------------------------------------------------------------------------
       
  1108 //
       
  1109 TBool PIMRepeatRuleConverter::CheckMonthsInYearL(
       
  1110     const CArrayFix<TPIMField>& aFields, TTime aDate, TTime aSubsetBeginning,
       
  1111     TTime aSubsetEnding, TTime aRepeatRuleEndDate, TInt aRepeatRuleCount,
       
  1112     TInt aRepeatRuleWeekInMonth, TInt aRepeatRuleDayInWeek,
       
  1113     TInt aRepeatRuleMonthInYear, TInt aRepeatRuleDayInMonth, CArrayFixFlat<
       
  1114     TPIMDate>** aRepeatDates, TInt* aCountIndex)
       
  1115 {
       
  1116     JELOG2(EPim);
       
  1117     // Set the day to the 1st day of the 1st month.
       
  1118     TTime checkDay = aDate - TTimeIntervalDays(aDate.DayNoInYear() - 1);
       
  1119 
       
  1120     if (aRepeatRuleMonthInYear & EPIMRepeatRuleJanuary)
       
  1121     {
       
  1122         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1123                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1124                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1125                          aCountIndex))
       
  1126         {
       
  1127             return EFalse;
       
  1128         }
       
  1129     }
       
  1130     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1131 
       
  1132     if (aRepeatRuleMonthInYear & EPIMRepeatRuleFebruary)
       
  1133     {
       
  1134         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1135                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1136                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1137                          aCountIndex))
       
  1138         {
       
  1139             return EFalse;
       
  1140         }
       
  1141     }
       
  1142     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1143 
       
  1144     if (aRepeatRuleMonthInYear & EPIMRepeatRuleMarch)
       
  1145     {
       
  1146         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1147                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1148                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1149                          aCountIndex))
       
  1150         {
       
  1151             return EFalse;
       
  1152         }
       
  1153     }
       
  1154     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1155 
       
  1156     if (aRepeatRuleMonthInYear & EPIMRepeatRuleApril)
       
  1157     {
       
  1158         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1159                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1160                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1161                          aCountIndex))
       
  1162         {
       
  1163             return EFalse;
       
  1164         }
       
  1165     }
       
  1166     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1167 
       
  1168     if (aRepeatRuleMonthInYear & EPIMRepeatRuleMay)
       
  1169     {
       
  1170         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1171                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1172                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1173                          aCountIndex))
       
  1174         {
       
  1175             return EFalse;
       
  1176         }
       
  1177     }
       
  1178     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1179 
       
  1180     if (aRepeatRuleMonthInYear & EPIMRepeatRuleJune)
       
  1181     {
       
  1182         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1183                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1184                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1185                          aCountIndex))
       
  1186         {
       
  1187             return EFalse;
       
  1188         }
       
  1189     }
       
  1190     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1191 
       
  1192     if (aRepeatRuleMonthInYear & EPIMRepeatRuleJuly)
       
  1193     {
       
  1194         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1195                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1196                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1197                          aCountIndex))
       
  1198         {
       
  1199             return EFalse;
       
  1200         }
       
  1201     }
       
  1202     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1203 
       
  1204     if (aRepeatRuleMonthInYear & EPIMRepeatRuleAugust)
       
  1205     {
       
  1206         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1207                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1208                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1209                          aCountIndex))
       
  1210         {
       
  1211             return EFalse;
       
  1212         }
       
  1213     }
       
  1214     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1215 
       
  1216     if (aRepeatRuleMonthInYear & EPIMRepeatRuleSeptember)
       
  1217     {
       
  1218         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1219                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1220                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1221                          aCountIndex))
       
  1222         {
       
  1223             return EFalse;
       
  1224         }
       
  1225     }
       
  1226     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1227 
       
  1228     if (aRepeatRuleMonthInYear & EPIMRepeatRuleOctober)
       
  1229     {
       
  1230         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1231                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1232                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1233                          aCountIndex))
       
  1234         {
       
  1235             return EFalse;
       
  1236         }
       
  1237     }
       
  1238     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1239 
       
  1240     if (aRepeatRuleMonthInYear & EPIMRepeatRuleNovember)
       
  1241     {
       
  1242         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1243                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1244                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1245                          aCountIndex))
       
  1246         {
       
  1247             return EFalse;
       
  1248         }
       
  1249     }
       
  1250     checkDay = checkDay + TTimeIntervalMonths(1);
       
  1251 
       
  1252     if (aRepeatRuleMonthInYear & EPIMRepeatRuleDecember)
       
  1253     {
       
  1254         if (!CheckMonthL(aFields, checkDay, aSubsetBeginning, aSubsetEnding,
       
  1255                          aRepeatRuleEndDate, aRepeatRuleCount, aRepeatRuleWeekInMonth,
       
  1256                          aRepeatRuleDayInWeek, aRepeatRuleDayInMonth, aRepeatDates,
       
  1257                          aCountIndex))
       
  1258         {
       
  1259             return EFalse;
       
  1260         }
       
  1261     }
       
  1262 
       
  1263     return ETrue;
       
  1264 }
       
  1265 
       
  1266 // -----------------------------------------------------------------------------
       
  1267 // PIMRepeatRuleConverter::CheckMonthL
       
  1268 // Checks if this month has set to contain repeat dates
       
  1269 // MONTH_IN_YEAR requires that either DAY_IN_MONTH is set, or
       
  1270 // both WEEK_IN_MONTH and DAY_IN_WEEK are set: otherwise cannot process
       
  1271 // -----------------------------------------------------------------------------
       
  1272 //
       
  1273 TBool PIMRepeatRuleConverter::CheckMonthL(const CArrayFix<TPIMField>& aFields,
       
  1274         TTime aDate, TTime aSubsetBeginning, TTime aSubsetEnding,
       
  1275         TTime aRepeatRuleEndDate, TInt aRepeatRuleCount,
       
  1276         TInt aRepeatRuleWeekInMonth, TInt aRepeatRuleDayInWeek,
       
  1277         TInt aRepeatRuleDayInMonth, CArrayFixFlat<TPIMDate>** aRepeatDates,
       
  1278         TInt* aCountIndex)
       
  1279 {
       
  1280     JELOG2(EPim);
       
  1281     // Make sure the date is set to the 1st day of this month.
       
  1282     if (aDate.DayNoInMonth() > 0)
       
  1283     {
       
  1284         aDate = aDate - TTimeIntervalDays(aDate.DayNoInMonth());
       
  1285     }
       
  1286 
       
  1287     if (IsRepeatFieldPresentL(EPIMRepeatRuleWeekInMonth, aFields))
       
  1288     {
       
  1289         if (!CheckWeeksInMonthL(aFields, aDate, aSubsetBeginning,
       
  1290                                 aSubsetEnding, aRepeatRuleEndDate, aRepeatRuleCount,
       
  1291                                 aRepeatRuleWeekInMonth, aRepeatRuleDayInWeek, aRepeatDates,
       
  1292                                 aCountIndex))
       
  1293         {
       
  1294             return EFalse;
       
  1295         }
       
  1296     }
       
  1297     else if (IsRepeatFieldPresentL(EPIMRepeatRuleDayInMonth, aFields))
       
  1298     {
       
  1299         // Shift the date to the correct place. If the day is bigger than
       
  1300         // there are days in this month, use the last day of the month instead.
       
  1301         if (aRepeatRuleDayInMonth < (aDate.DaysInMonth() + 1))
       
  1302         {
       
  1303             aDate = aDate + TTimeIntervalDays(aRepeatRuleDayInMonth - 1);
       
  1304         }
       
  1305         else
       
  1306         {
       
  1307             aDate = aDate + TTimeIntervalDays(aDate.DaysInMonth() - 1);
       
  1308         }
       
  1309 
       
  1310         if (!AddRepeatDateL(aFields, aDate, aSubsetBeginning, aSubsetEnding,
       
  1311                             aRepeatRuleEndDate, aRepeatRuleCount, aRepeatDates, aCountIndex))
       
  1312         {
       
  1313             return EFalse;
       
  1314         }
       
  1315     }
       
  1316     else
       
  1317     {
       
  1318         // WEEK_IN_MONTH or DAY_IN_MONTH has to be present if MONTH_IN_YEAR used
       
  1319         return EFalse;
       
  1320     }
       
  1321 
       
  1322     return ETrue;
       
  1323 }
       
  1324 
       
  1325 //  End of File