javaextensions/pim/agnadapter/src.s60/cpimagneventadapter.cpp
changeset 21 2a9601315dfc
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     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:  Base class for PIM Event item adapters
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // CLASS HEADER
       
    20 #include "cpimagneventadapter.h"
       
    21 
       
    22 // INTERNAL INCLUDES
       
    23 #include "pimcommon.h"
       
    24 #include "agneventsupport.h"
       
    25 #include "cpimrepeatrule.h"
       
    26 #include "pimrepeatruleconverter.h"
       
    27 #include "mpimitemdata.h"
       
    28 #include "mpimeventitem.h"
       
    29 #include "pimpanics.h"
       
    30 #include "logger.h"
       
    31 
       
    32 // EXTERNAL INCLUDES
       
    33 #include <calentryview.h>
       
    34 #include <calalarm.h>
       
    35 #include <calrrule.h>
       
    36 
       
    37 
       
    38 // UNNAMED LOCAL NAMESPACE
       
    39 namespace
       
    40 {
       
    41 const TInt KPIMSecondsInMinute = 60;
       
    42 // Alarm offset for TTime in seconds from the start of the date. This is
       
    43 // the default alarm value which is set to the item if the user defined
       
    44 // alarm value is too small (meaning that it has been passed to the next
       
    45 // day when start of the event occurs
       
    46 const TInt KPIMDefaultAlarmInterval = 43200;
       
    47 }
       
    48 
       
    49 // LOCAL FUNCTION PROTOTYPES
       
    50 void CopyExceptionDatesToAgnL(const MPIMRepeatRuleData& aPimRepeatRuleData,
       
    51                               CCalEntry& aAgnEntry);
       
    52 
       
    53 void CopyExceptionDatesToPimL(const CCalEntry& aAgnEntry,
       
    54                               MPIMRepeatRuleData& aPimRepeatRuleData);
       
    55 
       
    56 // ============================= LOCAL FUNCTIONS ===============================
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CopyExceptionDatesToAgnL
       
    60 // Copies PIM API exception dates to an Agenda entry.
       
    61 // Returns: void
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 void CopyExceptionDatesToAgnL(const MPIMRepeatRuleData& aPimRepeatRuleData,
       
    65                               CCalEntry& aAgnEntry)
       
    66 {
       
    67     JELOG2(EPim);
       
    68     RArray<TCalTime> agnExceptionDates;
       
    69     CleanupClosePushL(agnExceptionDates);
       
    70     const CArrayFix<TPIMDate>& pimExceptionDates =
       
    71         aPimRepeatRuleData.GetExceptDatesL();
       
    72     const TInt numExceptDates = pimExceptionDates.Count();
       
    73     TCalTime agnExceptionDate;
       
    74     for (TInt i = 0; i < numExceptDates; i++)
       
    75     {
       
    76         agnExceptionDate.SetTimeUtcL(pimExceptionDates[i]);
       
    77         User::LeaveIfError(agnExceptionDates.Append(agnExceptionDate));
       
    78     }
       
    79     aAgnEntry.SetExceptionDatesL(agnExceptionDates);
       
    80     CleanupStack::PopAndDestroy(); // pimExceptionDates close
       
    81 }
       
    82 
       
    83 // -----------------------------------------------------------------------------
       
    84 // CopyExceptionDatesToPimL
       
    85 // Copies Agenda exception dates to a PIM API repeat rule.
       
    86 // Returns: void
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 void CopyExceptionDatesToPimL(const CCalEntry& aAgnEntry,
       
    90                               MPIMRepeatRuleData& aPimRepeatRuleData)
       
    91 {
       
    92     JELOG2(EPim);
       
    93     RArray<TCalTime> agnExceptionDates;
       
    94     aAgnEntry.GetExceptionDatesL(agnExceptionDates);
       
    95     CleanupClosePushL(agnExceptionDates);
       
    96     const TInt numExceptions = agnExceptionDates.Count();
       
    97     for (TInt i = 0; i < numExceptions; i++)
       
    98     {
       
    99         TCalTime agnExceptionDate = agnExceptionDates[i];
       
   100         TTime pimExceptionDate = agnExceptionDate.TimeUtcL();
       
   101         aPimRepeatRuleData.AddExceptDateL(pimExceptionDate);
       
   102     }
       
   103 
       
   104     CleanupStack::PopAndDestroy(); // agnExceptionDates close
       
   105 }
       
   106 
       
   107 // ============================ MEMBER FUNCTIONS ===============================
       
   108 
       
   109 // destructor
       
   110 CPIMAgnEventAdapter::~CPIMAgnEventAdapter()
       
   111 {
       
   112 }
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // CPIMAgnEventAdapter::CPIMAgnEventAdapter
       
   116 // C++ constructor can NOT contain any code, that
       
   117 // might leave.
       
   118 // -----------------------------------------------------------------------------
       
   119 //
       
   120 CPIMAgnEventAdapter::CPIMAgnEventAdapter(
       
   121     java::util::FunctionServer* aFuncServer) :
       
   122         CPIMAgnItemAdapter(aFuncServer)
       
   123 {
       
   124     JELOG2(EPim);
       
   125 }
       
   126 
       
   127 // -----------------------------------------------------------------------------
       
   128 // CPIMAgnEventAdapter::ReadFieldsFromAgnL
       
   129 // Reads Agenda entry's fields and converts them into PIM Item fields.
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 void CPIMAgnEventAdapter::ReadFieldsFromAgnL(MPIMEventItem& aItem,
       
   133         CCalEntry& aEntry, const TPIMField aSupportedFields[], // supported field types
       
   134         TInt aSize) // size of the array
       
   135 {
       
   136     JELOG2(EPim);
       
   137     for (int i = 0; i < aSize; i++)
       
   138     {
       
   139         switch (aSupportedFields[i])
       
   140         {
       
   141         case EPIMEventSummary:
       
   142         {
       
   143             ReadSummaryFromAgnL(aItem, aEntry);
       
   144             break;
       
   145         }
       
   146         case EPIMEventLocation:
       
   147         {
       
   148             ReadLocationFromAgnL(aItem, aEntry);
       
   149             break;
       
   150         }
       
   151         case EPIMEventNote:
       
   152         {
       
   153             ReadNoteFromAgnL(aItem, aEntry);
       
   154             break;
       
   155         }
       
   156         case EPIMEventAlarm:
       
   157         {
       
   158             ReadAlarmFromAgnL(aItem, aEntry);
       
   159             break;
       
   160         }
       
   161         case EPIMEventStart:
       
   162         {
       
   163             ReadStartFromAgnL(aItem, aEntry);
       
   164             break;
       
   165         }
       
   166         case EPIMEventEnd:
       
   167         {
       
   168             ReadEndFromAgnL(aItem, aEntry);
       
   169             break;
       
   170         }
       
   171         case EPIMEventClass:
       
   172         {
       
   173             ReadClassFromAgnL(aItem, aEntry);
       
   174             break;
       
   175         }
       
   176         case EPIMEventRevision: // fallthrough
       
   177         case EPIMEventUid:
       
   178         {
       
   179             // nothing
       
   180             break;
       
   181         }
       
   182         default:
       
   183         {
       
   184             User::Leave(KErrArgument);
       
   185         }
       
   186         }
       
   187     }
       
   188 }
       
   189 
       
   190 // -----------------------------------------------------------------------------
       
   191 // CPIMAgnEventAdapter::ConvertFieldsToAgnL
       
   192 // Reads PIM Item fields and converts them into Agenda entry's fields.
       
   193 // -----------------------------------------------------------------------------
       
   194 //
       
   195 void CPIMAgnEventAdapter::ConvertFieldsToAgnL(const MPIMEventItem& aItem,
       
   196         CCalEntry& aEntry)
       
   197 {
       
   198     JELOG2(EPim);
       
   199     CArrayFix<TPIMField>* fields = aItem.ItemData().FieldsLC();
       
   200     TInt amount = fields->Count();
       
   201 
       
   202     for (int i = 0; i < amount; i++)
       
   203     {
       
   204         TPIMEventField field = static_cast<TPIMEventField>(fields->At(i));
       
   205         switch (field)
       
   206         {
       
   207         case EPIMEventSummary: // Fallthrough
       
   208         case EPIMEventLocation: // Fallthrough
       
   209         case EPIMEventNote:
       
   210         {
       
   211             ConvertStringFieldToAgnL(aItem, aEntry, field);
       
   212             break;
       
   213         }
       
   214         case EPIMEventAlarm:
       
   215         {
       
   216             ConvertAlarmToAgnL(aItem, aEntry);
       
   217             break;
       
   218         }
       
   219         case EPIMEventStart: // Fallthrough
       
   220         case EPIMEventEnd:
       
   221         {
       
   222             ConvertDateFieldToAgnL(aItem, aEntry, field);
       
   223             break;
       
   224         }
       
   225         case EPIMEventClass:
       
   226         {
       
   227             ConvertClassToAgnL(aItem, aEntry);
       
   228             break;
       
   229         }
       
   230         case EPIMEventRevision: // fallthrough
       
   231         case EPIMEventUid:
       
   232         {
       
   233             // nothing
       
   234             break;
       
   235         }
       
   236         default:
       
   237         {
       
   238             User::Leave(KErrArgument);
       
   239         }
       
   240         }
       
   241     }
       
   242     CleanupStack::PopAndDestroy(fields);
       
   243 }
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // CPIMAgnEventAdapter::ClearPIMFieldsL
       
   247 // Clears the fields supported by PIM API from this Agenda Model entry.
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CPIMAgnEventAdapter::ClearPIMFieldsL(CCalEntry& aEntry,
       
   251         const TPIMField aSupportedFields[], // Array of supported field types
       
   252         TInt aSize) // Size of the array of supported fields
       
   253 {
       
   254     JELOG2(EPim);
       
   255     for (int i = 0; i < aSize; i++)
       
   256     {
       
   257         switch (aSupportedFields[i])
       
   258         {
       
   259         case EPIMEventSummary:
       
   260         {
       
   261             aEntry.SetSummaryL(KNullDesC);
       
   262             break;
       
   263         }
       
   264         case EPIMEventLocation:
       
   265         {
       
   266             aEntry.SetLocationL(KNullDesC);
       
   267             break;
       
   268         }
       
   269         case EPIMEventNote:
       
   270         {
       
   271             aEntry.SetDescriptionL(KNullDesC);
       
   272             break;
       
   273         }
       
   274         case EPIMEventAlarm:
       
   275         {
       
   276             aEntry.SetAlarmL(NULL);
       
   277             break;
       
   278         }
       
   279         case EPIMEventStart: // Fallthrough
       
   280         case EPIMEventEnd: // Fallthrough
       
   281         case EPIMEventUid: // Fallthrough
       
   282         case EPIMEventClass: // Fallthrough
       
   283         case EPIMEventRevision:
       
   284         {
       
   285             break; // For these fields there is no need to do anything
       
   286         }
       
   287         default:
       
   288         {
       
   289             User::Leave(KErrArgument);
       
   290         }
       
   291         }
       
   292     }
       
   293 }
       
   294 
       
   295 // -----------------------------------------------------------------------------
       
   296 // CPIMAgnEventAdapter::ReadSummaryFromAgnL
       
   297 // Reads Agenda entry's summary field and converts it into PIM Item field.
       
   298 // -----------------------------------------------------------------------------
       
   299 //
       
   300 void CPIMAgnEventAdapter::ReadSummaryFromAgnL(MPIMEventItem& aItem,
       
   301         CCalEntry& aEntry)
       
   302 {
       
   303     JELOG2(EPim);
       
   304     const TDesC& agnSummary = aEntry.SummaryL();
       
   305     if (agnSummary != KNullDesC)
       
   306     {
       
   307         TPIMFieldData fieldData(EPIMEventSummary, KPIMAttrNone,
       
   308                                 agnSummary.AllocLC());
       
   309         aItem.ItemData().AddValueL(fieldData);
       
   310         CleanupStack::Pop(); // agnSummary.AllocLC()
       
   311     }
       
   312 }
       
   313 
       
   314 // -----------------------------------------------------------------------------
       
   315 // CPIMAgnEventAdapter::ReadLocationFromAgnL
       
   316 // Reads Agenda entry's location field and converts it into PIM Item field.
       
   317 // -----------------------------------------------------------------------------
       
   318 //
       
   319 void CPIMAgnEventAdapter::ReadLocationFromAgnL(MPIMEventItem& aItem,
       
   320         CCalEntry& aEntry)
       
   321 {
       
   322     JELOG2(EPim);
       
   323     const TDesC& agnLocation = aEntry.LocationL();
       
   324     if (agnLocation != KNullDesC)
       
   325     {
       
   326         TPIMFieldData fieldData(EPIMEventLocation, KPIMAttrNone,
       
   327                                 agnLocation.AllocLC());
       
   328         aItem.ItemData().AddValueL(fieldData);
       
   329         CleanupStack::Pop(); // agnLocation.AllocLC()
       
   330     }
       
   331 }
       
   332 
       
   333 // -----------------------------------------------------------------------------
       
   334 // CPIMAgnEventAdapter::ReadNoteFromAgnL
       
   335 // Reads Agenda entry's notes field and converts it into PIM Item field.
       
   336 // -----------------------------------------------------------------------------
       
   337 //
       
   338 void CPIMAgnEventAdapter::ReadNoteFromAgnL(MPIMEventItem& aItem,
       
   339         CCalEntry& aEntry)
       
   340 {
       
   341     JELOG2(EPim);
       
   342     const TDesC& note = aEntry.DescriptionL();
       
   343     if (note != KNullDesC)
       
   344     {
       
   345         TPIMFieldData fieldData(EPIMEventNote, KPIMAttrNone, note.AllocLC());
       
   346         aItem.ItemData().AddValueL(fieldData);
       
   347         CleanupStack::Pop(); // notes.AllocLC( )
       
   348     }
       
   349 }
       
   350 
       
   351 // -----------------------------------------------------------------------------
       
   352 // CPIMAgnEventAdapter::ConvertStringFieldToAgnL
       
   353 // Makes string conversion from framework PIM item data field to Appt item field
       
   354 // -----------------------------------------------------------------------------
       
   355 //
       
   356 void CPIMAgnEventAdapter::ConvertStringFieldToAgnL(const MPIMEventItem& aItem,
       
   357         CCalEntry& aEntry, const TPIMEventField aField) const
       
   358 {
       
   359     JELOG2(EPim);
       
   360     const MPIMItemData& itemData = aItem.ItemData();
       
   361     TInt amount = itemData.CountValues(aField);
       
   362     for (TInt i = 0; i < amount; i++)
       
   363     {
       
   364         const TPIMFieldData fieldData = itemData.ValueL(aField, i);
       
   365         const TDesC& stringValue = fieldData.StringValue();
       
   366         EnsureValidStringValueL(stringValue);
       
   367         // Add correct data to the field
       
   368         switch (aField)
       
   369         {
       
   370         case EPIMEventNote:
       
   371         {
       
   372             aEntry.SetDescriptionL(stringValue);
       
   373             break;
       
   374         }
       
   375         case EPIMEventSummary:
       
   376         {
       
   377             aEntry.SetSummaryL(stringValue);
       
   378             break;
       
   379         }
       
   380         case EPIMEventLocation:
       
   381         {
       
   382             aEntry.SetLocationL(stringValue);
       
   383             break;
       
   384         }
       
   385         default:
       
   386         {
       
   387             __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory,
       
   388                                                EPIMPanicUnsupportedStringField));
       
   389             break;
       
   390         }
       
   391         }
       
   392 
       
   393     }
       
   394 }
       
   395 
       
   396 // -----------------------------------------------------------------------------
       
   397 // CPIMAgnEventAdapter::ConvertDateFieldToAgnL
       
   398 // Converts a PIM date field to native Calendar entry
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 void CPIMAgnEventAdapter::ConvertDateFieldToAgnL(const MPIMEventItem& aItem,
       
   402         CCalEntry& aEntry, const TPIMEventField aField)
       
   403 {
       
   404     JELOG2(EPim);
       
   405     __ASSERT_DEBUG(aField == EPIMEventStart || aField == EPIMEventEnd,
       
   406                    User::Panic(KPIMPanicCategory, EPIMPanicUnsupportedDateField));
       
   407 
       
   408     TCalTime end;
       
   409     TCalTime start;
       
   410 
       
   411     // Get date from the Java item
       
   412     const MPIMItemData& itemData = aItem.ItemData();
       
   413     // Get date from index 0 since native entries support only one value
       
   414     const TPIMFieldData fieldData = itemData.ValueL(aField, 0);
       
   415     const TPIMDate date = fieldData.DateValue();
       
   416 
       
   417     // Check that the date is inside the valid range
       
   418     __ASSERT_ALWAYS(IsDateInValidAgendaRange(date), User::Leave(KErrAbort));
       
   419     // By default, set both end and start to the same time and check if there
       
   420     // is the other part of the date field present in the item
       
   421     start.SetTimeUtcL(date);
       
   422     end.SetTimeUtcL(date);
       
   423 
       
   424     if (aField == EPIMEventStart && itemData.CountValues(EPIMEventEnd) > 0
       
   425             && itemData.ValueL(EPIMEventEnd, 0).DateValue() >= date)
       
   426     {
       
   427         const TPIMFieldData endData = itemData.ValueL(EPIMEventEnd, 0);
       
   428         const TPIMDate endDate = endData.DateValue();
       
   429         // Check that the date is inside the valid range
       
   430         __ASSERT_ALWAYS(IsDateInValidAgendaRange(endDate), User::Leave(
       
   431                             KErrAbort));
       
   432         // Set end date to the calendar date in UTC since
       
   433         // PIM API does not support local time format
       
   434         end.SetTimeUtcL(endDate);
       
   435     }
       
   436     else if (aField == EPIMEventEnd && itemData.CountValues(EPIMEventStart) > 0
       
   437              && itemData.ValueL(EPIMEventStart, 0).DateValue() <= date)
       
   438     {
       
   439         const TPIMFieldData startData = itemData.ValueL(EPIMEventStart, 0);
       
   440         const TPIMDate startDate = startData.DateValue();
       
   441         // Check that the date is inside the valid range
       
   442         __ASSERT_ALWAYS(IsDateInValidAgendaRange(startDate), User::Leave(
       
   443                             KErrAbort));
       
   444         // Set end date to the calendar date in UTC since
       
   445         // PIM API does not support local time format
       
   446         start.SetTimeUtcL(startDate);
       
   447     }
       
   448 
       
   449     // Set values to the native calendar entry
       
   450     aEntry.SetStartAndEndTimeL(start, end);
       
   451 }
       
   452 
       
   453 // -----------------------------------------------------------------------------
       
   454 // CPIMAgnEventAdapter::ReadAlarmFromAgnL
       
   455 // Reads alarm offset from the native Calendar entry. In case of Anniversary,
       
   456 // the offset is calculated from the midnight since native Calendar supports
       
   457 // only dates in these types of entries
       
   458 // -----------------------------------------------------------------------------
       
   459 //
       
   460 void CPIMAgnEventAdapter::ReadAlarmFromAgnL(MPIMEventItem& aItem,
       
   461         CCalEntry& aEntry)
       
   462 {
       
   463     JELOG2(EPim);
       
   464     CCalAlarm* calAlarm = aEntry.AlarmL();
       
   465     // The previous function call returns NULL if there is no alarm
       
   466     // set in the item. The ownership is transferred to the caller
       
   467     // if the alarm values has been added to the item.
       
   468     if (calAlarm)
       
   469     {
       
   470         TTimeIntervalMinutes nativeValue = calAlarm->TimeOffset();
       
   471         // The alarm is not needed anymore so it can be deleted
       
   472         delete calAlarm;
       
   473         calAlarm = NULL;
       
   474         //            nativeValue.Int() );
       
   475         // Convert the alarm value based on the start time of the entry
       
   476         CCalEntry::TType entryType = aEntry.EntryTypeL();
       
   477         // Events (memos) and anniversaries do not have time in the native
       
   478         // side, therefore alarm field in those entries need to be calculated
       
   479         // from the end of the day
       
   480         if (entryType == CCalEntry::EAnniv)
       
   481         {
       
   482             TTime start(aEntry.StartTimeL().TimeLocalL());
       
   483             // Change the time to the end of the start date
       
   484             TTime startOfDayLocal(start);
       
   485             startOfDayLocal = StartOfDay(startOfDayLocal);
       
   486             // Calculate the difference from end of day and start time including
       
   487             // the original alarm offset which was previously read
       
   488             TTimeIntervalMinutes temp(0);
       
   489             User::LeaveIfError(startOfDayLocal.MinutesFrom(start, temp));
       
   490             // Since it is not possible to substract TTimeIntervalMinutes
       
   491             // from TTime (probably a Symbian error), the difference has
       
   492             // to be calculated using the following way...
       
   493             nativeValue = nativeValue.Int() + temp.Int();
       
   494         }
       
   495         TInt alarmValue = nativeValue.Int() * KPIMSecondsInMinute;
       
   496         //            alarmValue );
       
   497         // Add alarm value to the item
       
   498         TPIMFieldData fieldData(EPIMEventAlarm, EPIMFieldInt, KPIMAttrNone,
       
   499                                 alarmValue);
       
   500         aItem.ItemData().AddValueL(fieldData);
       
   501     }
       
   502 }
       
   503 
       
   504 // -----------------------------------------------------------------------------
       
   505 // CPIMAgnEventAdapter::ConvertAlarmToAgnL
       
   506 // Converts alarm from PIM item to a native entry. The alarm is calculated
       
   507 // from the start date of the event and if it is not present, the alarm field
       
   508 // is ignored because there is no possibility to calculate it
       
   509 // -----------------------------------------------------------------------------
       
   510 //
       
   511 void CPIMAgnEventAdapter::ConvertAlarmToAgnL(const MPIMEventItem& aItem,
       
   512         CCalEntry& aEntry)
       
   513 {
       
   514     JELOG2(EPim);
       
   515     const MPIMItemData& itemData = aItem.ItemData();
       
   516 
       
   517     // Note that start time must be set before alarm can be calculated
       
   518     // Add start to the item so alarm can be properly converted. The
       
   519     // native entry does not accept alarm value if start is not present
       
   520 
       
   521     if (itemData.CountValues(EPIMEventStart) == 0)
       
   522     {
       
   523         User::Leave(KErrArgument);
       
   524     }
       
   525     else
       
   526     {
       
   527         ConvertDateFieldToAgnL(aItem, aEntry, EPIMEventStart);
       
   528     }
       
   529 
       
   530     __ASSERT_DEBUG(aEntry.StartTimeL().TimeUtcL() != Time::NullTTime(),
       
   531                    User::Panic(KPIMPanicCategory, EPIMPanicInvalidState));
       
   532 
       
   533     // Get alarm value from the Java item. There should be only one alarm
       
   534     // value supported by the PIM API because native entries do not support
       
   535     // multiple alarm values.
       
   536     const TPIMFieldData alarmData = itemData.ValueL(EPIMEventAlarm, 0);
       
   537     TInt value = alarmData.IntegerValue();
       
   538 
       
   539     // Count the alarm value from the start date of the event
       
   540     TTime entryStart = aEntry.StartTimeL().TimeLocalL();
       
   541     const TPIMFieldData startData = itemData.ValueL(EPIMEventStart, 0);
       
   542     TPIMDate startTime = startData.DateValue();
       
   543     ConvertTimeL(startTime, EPIMDateLocal);
       
   544     TTimeIntervalSeconds temp(0);
       
   545     User::LeaveIfError(entryStart.SecondsFrom(startTime, temp));
       
   546 
       
   547     // Add difference between PIM API start and start which has been
       
   548     // converted to the item (in case if the date has been changed, it is
       
   549     // reflected here)
       
   550     value += temp.Int();
       
   551 
       
   552     // Check that if the alarm has passed to the following day. In this case,
       
   553     // the alarm is transferred back to 12 o'clock of the current start date
       
   554     TTime alarmTime(entryStart - TTimeIntervalSeconds(value));
       
   555     // Temporary date. This date is used when calculating if the alarm
       
   556     // value has passed to the following date.
       
   557     TTime startOfNextDay(StartOfDay(startTime + TTimeIntervalDays(1)));
       
   558     if (alarmTime >= startOfNextDay)
       
   559     {
       
   560         alarmTime = StartOfDay(entryStart);
       
   561         alarmTime += TTimeIntervalSeconds(KPIMDefaultAlarmInterval);
       
   562         User::LeaveIfError(entryStart.SecondsFrom(alarmTime, temp));
       
   563         value = temp.Int();
       
   564     }
       
   565     // Convert the alarm value to the native entry
       
   566     SetAlarmToEntryL(aEntry, value);
       
   567 }
       
   568 
       
   569 // -----------------------------------------------------------------------------
       
   570 // CPIMAgnEventAdapter::ReadRepeatFromAgnL
       
   571 // Reads entry's repeat details and converts them into PIM repeat rule.
       
   572 // -----------------------------------------------------------------------------
       
   573 //
       
   574 void CPIMAgnEventAdapter::ReadRepeatFromAgnL(MPIMEventItem& aItem,
       
   575         CCalEntry& aEntry)
       
   576 {
       
   577     JELOG2(EPim);
       
   578     MPIMRepeatRuleData* repeatRuleData = aItem.GetRepeat();
       
   579 
       
   580     TCalRRule agnRRule;
       
   581     if (aEntry.GetRRuleL(agnRRule))
       
   582     {
       
   583         repeatRuleData->clear();
       
   584 
       
   585         PIMRepeatRuleConverter::ConvertSupportedRepeatToPIML(*repeatRuleData,
       
   586                 agnRRule);
       
   587 
       
   588         CopyExceptionDatesToPimL(aEntry, *repeatRuleData);
       
   589 
       
   590         // Anniv does not need to have an end date, so clear that field to be sure
       
   591         if (aEntry.EntryTypeL() == CCalEntry::EAnniv)
       
   592         {
       
   593             repeatRuleData->ClearFieldL(EPIMRepeatRuleEnd);
       
   594         }
       
   595 
       
   596         aItem.SetRepeating(ETrue);
       
   597     }
       
   598     else
       
   599     {
       
   600         repeatRuleData->clear();
       
   601         aItem.SetRepeating(EFalse);
       
   602     }
       
   603 }
       
   604 
       
   605 // -----------------------------------------------------------------------------
       
   606 // CPIMAgnEventAdapter::ConvertRepeatToAgnL
       
   607 // Makes conversion from framework PIM item repeat rule to native entry repeat.
       
   608 // -----------------------------------------------------------------------------
       
   609 //
       
   610 void CPIMAgnEventAdapter::ConvertRepeatToAgnL(
       
   611     const MPIMEventItem& aEventItemData, CCalEntry& aAgnEntry)
       
   612 {
       
   613     JELOG2(EPim);
       
   614     const MPIMRepeatRuleData* repeatRuleData = aEventItemData.GetRepeat();
       
   615 
       
   616     TTime eventStart = aAgnEntry.StartTimeL().TimeUtcL();
       
   617 
       
   618     TCalRRule agnRRule = PIMRepeatRuleConverter::ConvertSupportedRepeatToAgnL(
       
   619                              *repeatRuleData, eventStart);
       
   620 
       
   621     if ((aAgnEntry.EntryTypeL() == CCalEntry::EAnniv) && (agnRRule.Type()
       
   622             != TCalRRule::EYearly))
       
   623     {
       
   624         User::Leave(KErrArgument);
       
   625     }
       
   626 
       
   627     if (agnRRule.Type() == TCalRRule::EWeekly)
       
   628     {
       
   629         __ASSERT_ALWAYS(agnRRule.Interval() <= 2, User::Leave(KErrArgument));
       
   630     }
       
   631     else // other than weekly
       
   632     {
       
   633         __ASSERT_ALWAYS(agnRRule.Interval() == 1, User::Leave(KErrArgument));
       
   634     }
       
   635 
       
   636     // Use local time to check the day since UTC times provide incorrect
       
   637     // results if the compared dates are near midnight
       
   638     TTime untilLocal = agnRRule.Until().TimeLocalL();
       
   639     TTime startLocal = aAgnEntry.StartTimeL().TimeLocalL();
       
   640     // Validate that repeat rule is correct. The end of the repeat rule
       
   641     // must be greater than the event start and it must not be within
       
   642     // the same day as the start of the event
       
   643     if (untilLocal != Time::NullTTime())
       
   644     {
       
   645         __ASSERT_ALWAYS(untilLocal >= startLocal, User::Leave(KErrAbort));
       
   646         TTimeIntervalDays intervalDays = untilLocal.DaysFrom(startLocal);
       
   647         // Interval smaller than one day. Check that the day is not the same
       
   648         if (intervalDays < TTimeIntervalDays(1))
       
   649         {
       
   650             __ASSERT_ALWAYS(untilLocal.DateTime().Day()
       
   651                             != startLocal.DateTime().Day(), User::Leave(KErrAbort));
       
   652         }
       
   653     }
       
   654 
       
   655     // Repeat Rules OK
       
   656     aAgnEntry.SetRRuleL(agnRRule);
       
   657     CopyExceptionDatesToAgnL(*repeatRuleData, aAgnEntry);
       
   658 }
       
   659 
       
   660 // -----------------------------------------------------------------------------
       
   661 // CPIMAgnEventAdapter::ReadClassFromAgnL
       
   662 // Reads entry's class details and converts them into PIM class.
       
   663 // -----------------------------------------------------------------------------
       
   664 //
       
   665 void CPIMAgnEventAdapter::ReadClassFromAgnL(MPIMEventItem& aItem,
       
   666         CCalEntry& aEntry)
       
   667 {
       
   668     JELOG2(EPim);
       
   669     TPIMEventClassValue eClassValue = EPIMEventClassPrivate;
       
   670     const CCalEntry::TReplicationStatus replicationStatus =
       
   671         aEntry.ReplicationStatusL();
       
   672 
       
   673     // Map calendar entry values to pim value
       
   674     switch (replicationStatus)
       
   675     {
       
   676     case CCalEntry::EOpen:
       
   677     {
       
   678         eClassValue = EPIMEventClassPublic;
       
   679         break;
       
   680     }
       
   681     case CCalEntry::EPrivate:
       
   682     {
       
   683         eClassValue = EPIMEventClassPrivate;
       
   684         break;
       
   685     }
       
   686     case CCalEntry::ERestricted:
       
   687     {
       
   688         eClassValue = EPIMEventClassConfidential;
       
   689         break;
       
   690     }
       
   691     default:
       
   692     {
       
   693         User::Leave(KErrArgument);
       
   694         break;
       
   695     }
       
   696     }
       
   697     TPIMFieldData fieldData(EPIMEventClass, EPIMFieldInt, KPIMAttrNone,
       
   698                             eClassValue);
       
   699     // Set value for the class item
       
   700     aItem.ItemData().AddValueL(fieldData);
       
   701 }
       
   702 // -----------------------------------------------------------------------------
       
   703 // CPIMAgnEventAdapter::ConvertClassToAgnL
       
   704 // Makes conversion from framework PIM item class to native entry class.
       
   705 // -----------------------------------------------------------------------------
       
   706 //
       
   707 void CPIMAgnEventAdapter::ConvertClassToAgnL(const MPIMEventItem& aItem,
       
   708         CCalEntry& aEntry)
       
   709 {
       
   710     JELOG2(EPim);
       
   711     CCalEntry::TReplicationStatus replicationStatus = CCalEntry::EPrivate;
       
   712 
       
   713     // There should and MUST be only one value in the
       
   714     // class field so get the value from the first index
       
   715     const TPIMFieldData& fieldData = aItem.ItemData().ValueL(EPIMEventClass, 0);
       
   716     TInt eClassValue = fieldData.IntegerValue();
       
   717 
       
   718     // Map pim class value to calendar entry value
       
   719     switch (eClassValue)
       
   720     {
       
   721     case EPIMEventClassPrivate:
       
   722     {
       
   723         replicationStatus = CCalEntry::EPrivate;
       
   724         break;
       
   725     }
       
   726     case EPIMEventClassConfidential:
       
   727     {
       
   728         replicationStatus = CCalEntry::ERestricted;
       
   729         break;
       
   730     }
       
   731     case EPIMEventClassPublic:
       
   732     {
       
   733         replicationStatus = CCalEntry::EOpen;
       
   734         break;
       
   735     }
       
   736     default:
       
   737     {
       
   738         User::Leave(KErrArgument);
       
   739         break;
       
   740     }
       
   741     }
       
   742     aEntry.SetReplicationStatusL(replicationStatus);
       
   743 }
       
   744 
       
   745 // -----------------------------------------------------------------------------
       
   746 // CPIMAgnEventAdapter::SetAlarmToEntryL
       
   747 // Sets the native entry alarm field.
       
   748 // -----------------------------------------------------------------------------
       
   749 //
       
   750 void CPIMAgnEventAdapter::SetAlarmToEntryL(CCalEntry& aEntry, const TInt aValue) const
       
   751 {
       
   752     JELOG2(EPim);
       
   753     TTimeIntervalMinutes offMin(aValue / KPIMSecondsInMinute);
       
   754     CCalAlarm* agnAlarm = CCalAlarm::NewL();
       
   755     agnAlarm->SetTimeOffset(offMin);
       
   756 
       
   757     CleanupStack::PushL(agnAlarm);
       
   758     aEntry.SetAlarmL(agnAlarm);
       
   759     CleanupStack::PopAndDestroy(agnAlarm);
       
   760 }
       
   761 
       
   762 // -----------------------------------------------------------------------------
       
   763 // CPIMAgnEventAdapter::EnsureValidStringValueL
       
   764 // -----------------------------------------------------------------------------
       
   765 //
       
   766 void CPIMAgnEventAdapter::EnsureValidStringValueL(const TDesC& aStringValue) const
       
   767 {
       
   768     JELOG2(EPim);
       
   769     if (aStringValue.Length() > KPIMAgnStringFieldMaxLength)
       
   770     {
       
   771         User::Leave(KErrTooBig);
       
   772     }
       
   773 }
       
   774 
       
   775 // -----------------------------------------------------------------------------
       
   776 // CPIMAgnEventAdapter::AddDefaultValuesToEntryL
       
   777 // -----------------------------------------------------------------------------
       
   778 //
       
   779 void CPIMAgnEventAdapter::AddDefaultValuesToEntryL(const MPIMEventItem& aItem,
       
   780         CCalEntry& aEntry) const
       
   781 {
       
   782     JELOG2(EPim);
       
   783     const MPIMItemData& data = aItem.ItemData();
       
   784     // Default calendar synchronisation is private
       
   785     if (data.CountValues(EPIMEventClass) == 0)
       
   786     {
       
   787         aEntry.SetReplicationStatusL(CCalEntry::EPrivate);
       
   788     }
       
   789 }
       
   790 
       
   791 // End of File