javaextensions/pim/agnadapter/src.s60/cpimagntodoadapter.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:  Handles PIM API todo item <-> Agenda Model todo conversions
       
    15  *
       
    16 */
       
    17 
       
    18 
       
    19 // CLASS HEADER
       
    20 #include "cpimagntodoadapter.h"
       
    21 
       
    22 // INTERNAL INCLUDES
       
    23 #include "mpimtodoitem.h"
       
    24 #include "mpimitemdata.h"
       
    25 #include "pimpanics.h"
       
    26 #include "pimtypes.h"
       
    27 #include "logger.h"
       
    28 
       
    29 // EXTERNAL INCLUDES
       
    30 #include <e32math.h>
       
    31 #include <calentry.h>
       
    32 #include <calalarm.h>
       
    33 
       
    34 
       
    35 // UNNAMED LOCAL NAMESPACE
       
    36 namespace
       
    37 {
       
    38 // Seconds in a one minute
       
    39 const TInt KPIMSecondsInMinute = 60;
       
    40 // Maximum length of ToDo item string fields in S60
       
    41 const TInt KPIMToDoStringValueMaxLength = 160;
       
    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 // ============================ MEMBER FUNCTIONS ===============================
       
    50 
       
    51 // -----------------------------------------------------------------------------
       
    52 // CPIMAgnToDoAdapter::NewL
       
    53 // Two-phased constructor.
       
    54 // -----------------------------------------------------------------------------
       
    55 //
       
    56 CPIMAgnToDoAdapter* CPIMAgnToDoAdapter::NewL(
       
    57     java::util::FunctionServer* aFuncServer)
       
    58 {
       
    59     JELOG2(EPim);
       
    60     CPIMAgnToDoAdapter* self = new(ELeave) CPIMAgnToDoAdapter(aFuncServer);
       
    61     CleanupStack::PushL(self);
       
    62     self->ConstructL();
       
    63     CleanupStack::Pop(self);
       
    64     return self;
       
    65 }
       
    66 
       
    67 // destructor
       
    68 CPIMAgnToDoAdapter::~CPIMAgnToDoAdapter()
       
    69 {
       
    70     JELOG2(EPim);
       
    71 }
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CPIMAgnToDoAdapter::CreateItemToAgnL
       
    75 // Creates a new Agenda Model To-Do item from a PIM item data.
       
    76 // Returns: A To-do item based on PIM item data.
       
    77 //          The ownership of the To-do item is transferred to the caller.
       
    78 // -----------------------------------------------------------------------------
       
    79 //
       
    80 CCalEntry* CPIMAgnToDoAdapter::CreateItemToAgnL(const MPIMToDoItem& aItem)
       
    81 {
       
    82     JELOG2(EPim);
       
    83     // Create new calendar entry
       
    84     CCalEntry* entry = CreateCalendarEntryLC(CCalEntry::ETodo);
       
    85     // Export entry. No need to reset since this is a new entry
       
    86     ExportItemL(aItem, *entry, EFalse);
       
    87     CleanupStack::Pop(entry);
       
    88     return entry;
       
    89 }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 // CPIMAgnToDoAdapter::ReadAgnToItemL
       
    93 // Reads an Agenda Model To-do item and converts it to a framework PIM item.
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 void CPIMAgnToDoAdapter::ReadAgnToItemL(MPIMToDoItem& aItem, CCalEntry& aEntry)
       
    97 {
       
    98     JELOG2(EPim);
       
    99     MPIMItemData& itemData = aItem.ItemData();
       
   100     // Read string fields to PIM API ToDo entry (summary and note)
       
   101     ReadStringFieldsL(itemData, aEntry);
       
   102     // Read integer fields to PIM API ToDo entry (priority and class)
       
   103     ReadIntFieldsL(itemData, aEntry);
       
   104     // Read date fields to PIM API ToDo entry (due and completion date). Alarm
       
   105     // is read here also because it is related to the due date of the item
       
   106     ReadDateFieldsL(itemData, aEntry);
       
   107 }
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CPIMAgnToDoAdapter::UpdateItemToAgnL
       
   111 // Reads an Agenda Model To-do item and updates it based on the PIM item data.
       
   112 // -----------------------------------------------------------------------------
       
   113 //
       
   114 void CPIMAgnToDoAdapter::UpdateItemToAgnL(const MPIMToDoItem& aItem,
       
   115         CCalEntry& aEntry)
       
   116 {
       
   117     JELOG2(EPim);
       
   118     // Export PIM item data to the native entry. Reset the entry for new data
       
   119     ExportItemL(aItem, aEntry, ETrue);
       
   120 }
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CPIMAgnToDoAdapter::ExportItemL
       
   124 // (other items were commented in a header)
       
   125 // -----------------------------------------------------------------------------
       
   126 //
       
   127 void CPIMAgnToDoAdapter::ExportItemL(const MPIMToDoItem& aItem,
       
   128                                      CCalEntry& aEntry, TBool aResetEntry)
       
   129 {
       
   130     JELOG2(EPim);
       
   131     if (aResetEntry)
       
   132     {
       
   133         // Reset native entry for exporting new data
       
   134         aEntry.SetSummaryL(KNullDesC());
       
   135         aEntry.SetDescriptionL(KNullDesC());
       
   136         aEntry.SetPriorityL(0);
       
   137         aEntry.SetCompletedL(EFalse, aEntry.CompletedTimeL());
       
   138     }
       
   139 
       
   140     // Export item data to the native ToDo calendar entry
       
   141     const MPIMItemData& itemData = aItem.ItemData();
       
   142     CArrayFix<TPIMField>* fields = itemData.FieldsLC();
       
   143 
       
   144     // Add default values to the calendar entry
       
   145     AddDefaultValuesToEntryL(itemData, aEntry);
       
   146 
       
   147     // Convert each field to the native ToDo calendar entry
       
   148     TInt count = fields->Count();
       
   149     for (TInt i = 0; i < count; i++)
       
   150     {
       
   151         TPIMToDoField field = static_cast<TPIMToDoField>(fields->At(i));
       
   152         ConvertToAgnL(field, aEntry, itemData);
       
   153     }
       
   154     CleanupStack::PopAndDestroy(fields);
       
   155 }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CPIMAgnToDoAdapter::AddDefaultValuesToEntryL
       
   159 // (other items were commented in a header)
       
   160 // -----------------------------------------------------------------------------
       
   161 //
       
   162 void CPIMAgnToDoAdapter::AddDefaultValuesToEntryL(const MPIMItemData& aData,
       
   163         CCalEntry& aEntry) const
       
   164 {
       
   165     JELOG2(EPim);
       
   166     // Calendar creates medium priority ToDos by default
       
   167     if (!aData.CountValues(EPIMToDoPriority))
       
   168     {
       
   169         aEntry.SetPriorityL(EPIMToDoNativePriorityMedium);
       
   170     }
       
   171     // Calendar uses private synchronization by default
       
   172     if (!aData.CountValues(EPIMToDoClass))
       
   173     {
       
   174         aEntry.SetReplicationStatusL(CCalEntry::EPrivate);
       
   175     }
       
   176     // Calendar does not support timed ToDo so the time is set to 00:00 o'clock
       
   177     if (!aData.CountValues(EPIMToDoDue))
       
   178     {
       
   179         TTime thisTime;
       
   180         thisTime.HomeTime();
       
   181         // Set time to calendar specific due time. Currently this is the start
       
   182         // of the date. Note that No conversion needed since time is local
       
   183         TCalTime calThisTime;
       
   184         // Set time as local time since acquired above as local time
       
   185         calThisTime.SetTimeLocalL(StartOfDay(thisTime));
       
   186         aEntry.SetStartAndEndTimeL(calThisTime, calThisTime);
       
   187     }
       
   188     if (!aData.CountValues(EPIMToDoCompletionDate) && !aData.CountValues(
       
   189                 EPIMToDoCompleted))
       
   190     {
       
   191         aEntry.SetCompletedL(EFalse, aEntry.CompletedTimeL());
       
   192     }
       
   193 
       
   194 }
       
   195 
       
   196 // -----------------------------------------------------------------------------
       
   197 // CPIMAgnToDoAdapter::ReadStringFieldsL
       
   198 // (other items were commented in a header)
       
   199 // -----------------------------------------------------------------------------
       
   200 //
       
   201 void CPIMAgnToDoAdapter::ReadStringFieldsL(MPIMItemData& aData,
       
   202         CCalEntry& aEntry)
       
   203 {
       
   204     JELOG2(EPim);
       
   205     // Summary is converted to PIM API ToDo summary field
       
   206     const TDesC& sum = aEntry.SummaryL();
       
   207     if (sum != KNullDesC)
       
   208     {
       
   209         TPIMFieldData fieldData(EPIMToDoSummary, KPIMAttrNone, sum.AllocLC());
       
   210         aData.AddValueL(fieldData);
       
   211         CleanupStack::Pop(); // agnSummary.AllocLC()
       
   212     }
       
   213     // Description is converted to PIM API ToDo note field
       
   214     const TDesC& note = aEntry.DescriptionL();
       
   215     if (note != KNullDesC)
       
   216     {
       
   217         TPIMFieldData fieldData(EPIMToDoNote, KPIMAttrNone, note.AllocLC());
       
   218         aData.AddValueL(fieldData);
       
   219         CleanupStack::Pop(); // AllocLC
       
   220     }
       
   221 }
       
   222 
       
   223 // -----------------------------------------------------------------------------
       
   224 // CPIMAgnToDoAdapter::ReadIntFieldsL
       
   225 // (other items were commented in a header)
       
   226 // -----------------------------------------------------------------------------
       
   227 //
       
   228 void CPIMAgnToDoAdapter::ReadIntFieldsL(MPIMItemData& aData, CCalEntry& aEntry)
       
   229 {
       
   230     JELOG2(EPim);
       
   231     // Convert synchornization field to PIM API. The default value is private
       
   232     // and unrecognized priority values are mapped also to private due to
       
   233     // security reasons
       
   234     TPIMToDoClassValue value = EPIMToDoClassPrivate;
       
   235     const CCalEntry::TReplicationStatus status = aEntry.ReplicationStatusL();
       
   236     if (status == CCalEntry::EOpen)
       
   237     {
       
   238         // Open is mapped as public synhronization
       
   239         value = EPIMToDoClassPublic;
       
   240     }
       
   241     else if (status == CCalEntry::ERestricted)
       
   242     {
       
   243         // Open is mapped as user confidential synhronization
       
   244         value = EPIMToDoClassConfidential;
       
   245     }
       
   246     // Note that boolean and integer fields must be identified in the constructor
       
   247     TPIMFieldData classData(EPIMToDoClass, EPIMFieldInt, KPIMAttrNone, value);
       
   248     aData.AddValueL(classData);
       
   249 
       
   250     // Default value is zero acording to vCalendar specification. PIM API default
       
   251     // priority is medium which indicates normal native priority
       
   252     // See common/pimtodo.h for platform-specific native priorities.
       
   253     TUint nativePriority = aEntry.PriorityL();
       
   254     TPIMToDoPriority priority = EPIMToDoPriorityMedium;
       
   255     if (nativePriority == EPIMToDoNativePriorityHigh)
       
   256     {
       
   257         // Native priority value High is mapped to value 1
       
   258         priority = EPIMToDoPriorityHigh;
       
   259     }
       
   260     else if (nativePriority == EPIMToDoNativePriorityLow)
       
   261     {
       
   262         // Native priority value Low is mapped to value 7
       
   263         priority = EPIMToDoPriorityLow;
       
   264     }
       
   265     // Note that boolean and integer fields must be identified in the constructor
       
   266     TPIMFieldData
       
   267     prData(EPIMToDoPriority, EPIMFieldInt, KPIMAttrNone, priority);
       
   268     aData.AddValueL(prData);
       
   269 }
       
   270 
       
   271 // -----------------------------------------------------------------------------
       
   272 // CPIMAgnToDoAdapter::ReadDateFieldsL
       
   273 // (other items were commented in a header)
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 void CPIMAgnToDoAdapter::ReadDateFieldsL(MPIMItemData& aData, CCalEntry& aEntry)
       
   277 {
       
   278     JELOG2(EPim);
       
   279     TTime nullTime = Time::NullTTime();
       
   280     // The Agenda todo entry end field is the due date
       
   281     TTime due(aEntry.EndTimeL().TimeLocalL());
       
   282     if (due != nullTime)
       
   283     {
       
   284         // Set due to the PIM API specific due date, in this case, the start of date
       
   285         // Note that PIM API uses times as UTC times so the due date must be in
       
   286         // correct format. Previously requested as local time -> do not change
       
   287         TPIMDate pimDueDate(StartOfDay(due));
       
   288         // Date must be converted UTC time because acquired as local above
       
   289         ConvertTimeL(pimDueDate, EPIMDateUTC);
       
   290         TPIMFieldData dueFieldData(EPIMToDoDue, KPIMAttrNone, pimDueDate);
       
   291         aData.AddValueL(dueFieldData);
       
   292 
       
   293         // Get alarm. Ownership is transferred to the caller. Alarm cannot be set
       
   294         // if the due date is not set because the calculation is done as an offset
       
   295         // from the ToDo due date.
       
   296         CCalAlarm* calAlarm = aEntry.AlarmL();
       
   297         if (calAlarm)
       
   298         {
       
   299             TTimeIntervalMinutes nativeValue = calAlarm->TimeOffset();
       
   300             // The alarm is not needed anymore so it can be deleted
       
   301             delete calAlarm;
       
   302             calAlarm = NULL;
       
   303             // Change the time to the start of the due date
       
   304             TTime startOfDayLocal(StartOfDay(due));
       
   305             // Calculate the difference from the start of due date and start time including
       
   306             // the original alarm offset which was previously read
       
   307             TTimeIntervalMinutes temp(0);
       
   308             User::LeaveIfError(startOfDayLocal.MinutesFrom(due, temp));
       
   309             // Since it is not possible to substract TTimeIntervalMinutes
       
   310             // from TTime (probably a Symbian error), the difference has
       
   311             // to be calculated using the following way...
       
   312             TInt alarm = (nativeValue.Int() + temp.Int()) * KPIMSecondsInMinute;
       
   313             // Add alarm value to the item
       
   314             TPIMFieldData fieldData(EPIMToDoExtAlarm, EPIMFieldInt,
       
   315                                     KPIMAttrNone, alarm);
       
   316             // Add value to the PIM item data
       
   317             aData.AddValueL(fieldData);
       
   318         }
       
   319     }
       
   320 
       
   321     // Completion date. If the item has a completion date, the item is then completed
       
   322     // and completed flag is set to true in PIM API. Null time if not crossed out.
       
   323     TTime completed = aEntry.CompletedTimeL().TimeUtcL();
       
   324     if (completed != nullTime)
       
   325     {
       
   326         TPIMFieldData dateData(EPIMToDoCompletionDate, KPIMAttrNone, completed);
       
   327         aData.AddValueL(dateData);
       
   328         // Note that boolean and integer fields must be identified in the constructor
       
   329         TPIMFieldData flag(EPIMToDoCompleted, EPIMFieldBoolean, KPIMAttrNone,
       
   330                            ETrue);
       
   331         aData.AddValueL(flag);
       
   332     }
       
   333 }
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CPIMAgnToDoAdapter::ConvertToAgnL
       
   337 // Makes the conversion from framework PIM item data field to To-do item field.
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 void CPIMAgnToDoAdapter::ConvertToAgnL(TPIMToDoField aField, // The field to be converted
       
   341                                        CCalEntry& aEntry, const MPIMItemData& aItem)
       
   342 {
       
   343     JELOG2(EPim);
       
   344     TInt amount = aItem.CountValues(aField);
       
   345     for (TInt index = 0; index < amount; index++)
       
   346     {
       
   347         switch (aField)
       
   348         {
       
   349         case EPIMToDoCompletionDate: // fallthrough
       
   350         case EPIMToDoDue:
       
   351         {
       
   352             ConvertDateToAgnL(aField, index, aEntry, aItem);
       
   353             break;
       
   354         }
       
   355         case EPIMToDoSummary: // fallthrough
       
   356         case EPIMToDoNote:
       
   357         {
       
   358             ConvertStringToAgnL(aField, index, aEntry, aItem);
       
   359             break;
       
   360         }
       
   361         case EPIMToDoClass: // fallthrough
       
   362         case EPIMToDoExtAlarm:
       
   363         case EPIMToDoPriority:
       
   364         {
       
   365             ConvertIntToAgnL(aField, index, aEntry, aItem);
       
   366             break;
       
   367         }
       
   368         case EPIMToDoCompleted:
       
   369         {
       
   370             ConvertBooleanToAgnL(aField, index, aEntry, aItem);
       
   371             break;
       
   372         }
       
   373         case EPIMToDoUid: // fallthrough
       
   374         case EPIMToDoRevision:
       
   375         {
       
   376             // nothing
       
   377             break;
       
   378         }
       
   379         default:
       
   380         {
       
   381             __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory,
       
   382                                                EPIMPanicUnsupportedField));
       
   383         }
       
   384         }
       
   385     }
       
   386 }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CPIMAgnToDoAdapter::ConvertDateToAgnL
       
   390 // Makes date conversion from framework PIM item data field to To-do item field.
       
   391 // -----------------------------------------------------------------------------
       
   392 //
       
   393 void CPIMAgnToDoAdapter::ConvertDateToAgnL(TPIMToDoField aField, // Date field to be converted
       
   394         TInt aIndex, // Index of the date field
       
   395         CCalEntry& aEntry, const MPIMItemData& aItem) // The PIM item to read the field from
       
   396 {
       
   397     JELOG2(EPim);
       
   398     const TPIMFieldData fieldData = aItem.ValueL(aField, aIndex);
       
   399     const TPIMDate& date = fieldData.DateValue();
       
   400     switch (aField)
       
   401     {
       
   402     case EPIMToDoDue:
       
   403     {
       
   404         // Because undated to-dos are possible, the due date can be set
       
   405         // to a null value.
       
   406         if (date != Time::NullTTime() && !IsDateInValidAgendaRange(date))
       
   407         {
       
   408             User::Leave(KErrAbort);
       
   409         }
       
   410         // Java dates cannot be set to native null TTime
       
   411         else
       
   412         {
       
   413             // Convert due date and time to calendar specific due time
       
   414             // Note that PIM API dates are in UTC time format -> convert
       
   415             TTime dueDate(date);
       
   416             ConvertTimeL(dueDate, EPIMDateLocal);
       
   417             // Set time to native entry. Note that the time is local
       
   418             TCalTime calDate;
       
   419             calDate.SetTimeLocalL(StartOfDay(dueDate));
       
   420             aEntry.SetStartAndEndTimeL(calDate, calDate);
       
   421         }
       
   422         break;
       
   423     }
       
   424     case EPIMToDoCompletionDate:
       
   425     {
       
   426         if (date != Time::NullTTime())
       
   427         {
       
   428             __ASSERT_ALWAYS(IsDateInValidAgendaRange(date), User::Leave(
       
   429                                 KErrAbort));
       
   430             TCalTime calDate;
       
   431             calDate.SetTimeUtcL(date);
       
   432             aEntry.SetCompletedL(ETrue, calDate);
       
   433         }
       
   434         else
       
   435         {
       
   436             aEntry.SetCompletedL(EFalse, aEntry.CompletedTimeL());
       
   437         }
       
   438         break;
       
   439     }
       
   440     default:
       
   441     {
       
   442         __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory,
       
   443                                            EPIMPanicUnsupportedField));
       
   444     }
       
   445     }
       
   446 }
       
   447 
       
   448 // -----------------------------------------------------------------------------
       
   449 // CPIMAgnToDoAdapter::ConvertStringToAgnL
       
   450 // Makes string conversion from framework PIM item data field to To-do item field
       
   451 // -----------------------------------------------------------------------------
       
   452 //
       
   453 void CPIMAgnToDoAdapter::ConvertStringToAgnL(TPIMToDoField aField, // String field to be converted
       
   454         TInt aIndex, // Index of the date field
       
   455         CCalEntry& aEntry, // The Agenda Model entry
       
   456         const MPIMItemData& aItem) // The PIM item to read the field from
       
   457 {
       
   458     JELOG2(EPim);
       
   459     const TPIMFieldData fieldData = aItem.ValueL(aField, aIndex);
       
   460     const TDesC& string = fieldData.StringValue();
       
   461 
       
   462     // Check that string is not too long
       
   463     __ASSERT_ALWAYS(string.Length() <= KPIMToDoStringValueMaxLength,
       
   464                     User::Leave(KErrTooBig));
       
   465 
       
   466     switch (aField)
       
   467     {
       
   468     case EPIMToDoSummary:
       
   469     {
       
   470         aEntry.SetSummaryL(string);
       
   471         break;
       
   472     }
       
   473     case EPIMToDoNote:
       
   474     {
       
   475         aEntry.SetDescriptionL(string);
       
   476         break;
       
   477     }
       
   478     default:
       
   479     {
       
   480         // Should not happen
       
   481     }
       
   482     }
       
   483 
       
   484 }
       
   485 
       
   486 // -----------------------------------------------------------------------------
       
   487 // CPIMAgnToDoAdapter::ConvertIntToAgnL
       
   488 // Makes int conversion from framework PIM item data field to To-do item field.
       
   489 // -----------------------------------------------------------------------------
       
   490 //
       
   491 void CPIMAgnToDoAdapter::ConvertIntToAgnL(TPIMToDoField aField, // Int field to be converted
       
   492         TInt aIndex, // Index of the date field
       
   493         CCalEntry& aEntry, // The Agenda model entry typecasted to a Todo item
       
   494         const MPIMItemData& aItemData) // The PIM item to read the field from
       
   495 {
       
   496     JELOG2(EPim);
       
   497     const TPIMFieldData fieldData = aItemData.ValueL(aField, aIndex);
       
   498     switch (aField)
       
   499     {
       
   500     case EPIMToDoPriority:
       
   501     {
       
   502         TInt intField = fieldData.IntegerValue();
       
   503 
       
   504         if ((EPIMToDoPriorityHigh <= intField) && (intField
       
   505                 < EPIMToDoPriorityMedium))
       
   506         {
       
   507             aEntry.SetPriorityL(EPIMToDoNativePriorityHigh);
       
   508         }
       
   509         else if ((EPIMToDoPriorityMedium <= intField) && (intField
       
   510                  < EPIMToDoPriorityLow))
       
   511         {
       
   512             aEntry.SetPriorityL(EPIMToDoNativePriorityMedium);
       
   513         }
       
   514         else if ((EPIMToDoPriorityLow <= intField) && (intField
       
   515                  <= EPIMToDoPriorityMaxValue))
       
   516         {
       
   517             aEntry.SetPriorityL(EPIMToDoNativePriorityLow);
       
   518         }
       
   519         else
       
   520         {
       
   521             // From requirement specification: Imported to-do items with
       
   522             // priority set to zero must be mapped to the native priority
       
   523             // value Medium.
       
   524             aEntry.SetPriorityL(EPIMToDoNativePriorityMedium);
       
   525         }
       
   526         break;
       
   527     }
       
   528     case EPIMToDoClass:
       
   529     {
       
   530         CCalEntry::TReplicationStatus replicationStatus = CCalEntry::EPrivate;
       
   531 
       
   532         // Single value assumed
       
   533         TInt classValue = fieldData.IntegerValue();
       
   534 
       
   535         switch (classValue)
       
   536         {
       
   537         case EPIMToDoClassPrivate:
       
   538         {
       
   539             replicationStatus = CCalEntry::EPrivate;
       
   540             break;
       
   541         }
       
   542         case EPIMToDoClassConfidential:
       
   543         {
       
   544             replicationStatus = CCalEntry::ERestricted;
       
   545             break;
       
   546         }
       
   547         case EPIMToDoClassPublic:
       
   548         {
       
   549             replicationStatus = CCalEntry::EOpen;
       
   550             break;
       
   551         }
       
   552         default:
       
   553         {
       
   554             User::Leave(KErrArgument);
       
   555             break;
       
   556         }
       
   557         }
       
   558         aEntry.SetReplicationStatusL(replicationStatus);
       
   559         break;
       
   560     }
       
   561     case EPIMToDoExtAlarm:
       
   562     {
       
   563         CCalAlarm* agnAlarm = CCalAlarm::NewL();
       
   564         CleanupStack::PushL(agnAlarm);
       
   565         agnAlarm->SetTimeOffset(AlarmOffsetL(aItemData, aEntry));
       
   566         aEntry.SetAlarmL(agnAlarm);
       
   567         CleanupStack::PopAndDestroy(agnAlarm);
       
   568         break;
       
   569     }
       
   570     default:
       
   571     {
       
   572         // Should not happen
       
   573         __ASSERT_DEBUG(EFalse, User::Invariant());
       
   574     }
       
   575     }
       
   576 }
       
   577 
       
   578 // -----------------------------------------------------------------------------
       
   579 // CPIMAgnToDoAdapter::ConvertBooleanToAgnL
       
   580 // Makes boolean conversion from framework PIM item data field to To-do item field
       
   581 // -----------------------------------------------------------------------------
       
   582 //
       
   583 void CPIMAgnToDoAdapter::ConvertBooleanToAgnL(TPIMToDoField aField, // Boolean field to be converted
       
   584         TInt aIndex, // Index of the date field
       
   585         CCalEntry& aEntry, // The Agenda model entry typecasted to a Todo item
       
   586         const MPIMItemData& aItem) // The PIM item to read the field from
       
   587 {
       
   588     JELOG2(EPim);
       
   589     const TPIMFieldData fieldData = aItem.ValueL(aField, aIndex);
       
   590     TBool booleanField = fieldData.BooleanValue();
       
   591 
       
   592     if (booleanField) // completed flag is set to value TRUE
       
   593     {
       
   594         // Check if the completed date field is present
       
   595         if (aItem.CountValues(EPIMToDoCompletionDate) == 0)
       
   596         {
       
   597             // If completed date is not present, use the current time.
       
   598             TTime currentTime;
       
   599             currentTime.HomeTime();
       
   600             TCalTime calCurrentTime;
       
   601             // Set time as local time since acquired above as local time
       
   602             calCurrentTime.SetTimeLocalL(currentTime);
       
   603             aEntry.SetCompletedL(ETrue, calCurrentTime);
       
   604         }
       
   605         else
       
   606         {
       
   607             TPIMFieldData completionData = aItem.ValueL(EPIMToDoCompletionDate,
       
   608                                            aIndex);
       
   609             const TPIMDate& date = completionData.DateValue();
       
   610             if (date != Time::NullTTime())
       
   611             {
       
   612                 TCalTime calDate;
       
   613                 calDate.SetTimeUtcL(date);
       
   614                 aEntry.SetCompletedL(ETrue, calDate);
       
   615             }
       
   616             else
       
   617             {
       
   618                 // If completed date is set to null time, use the current time.
       
   619                 TTime currentTime;
       
   620                 currentTime.HomeTime();
       
   621                 TCalTime calCurrentTime;
       
   622                 // Set time as local time since acquired above as local time
       
   623                 calCurrentTime.SetTimeLocalL(currentTime);
       
   624                 aEntry.SetCompletedL(ETrue, calCurrentTime);
       
   625             }
       
   626         }
       
   627     }
       
   628     else // completed flag is set to value FALSE
       
   629     {
       
   630         aEntry.SetCompletedL(EFalse, aEntry.CompletedTimeL());
       
   631     }
       
   632 }
       
   633 
       
   634 // -----------------------------------------------------------------------------
       
   635 // CPIMAgnToDoAdapter::AlarmOffsetL
       
   636 // Calculates PIM alarm offset for native Calendar entry
       
   637 // The offset calculation is done by calculating the difference between the
       
   638 // due date and the alarm offset. After we know the alarm date and time we
       
   639 // calculate difference between calender specific todo due date (which now is
       
   640 // 00:00)
       
   641 //
       
   642 // For example:
       
   643 //
       
   644 // If our due time is 23:00 and the alarm offset is 900 seconds before it.
       
   645 // Then the alarm should launch at 22:45 at the same day. So, the offset which
       
   646 // we have to write to the native alarm is the difference between 00:00 and 22:45
       
   647 // which is a negative value because the alarm rises in the future. This all is
       
   648 // done because the calendar understands only the date of the due date and not the
       
   649 // exact time of it. The time is ignored and set to 00:00 by default.
       
   650 // -----------------------------------------------------------------------------
       
   651 //
       
   652 TTimeIntervalMinutes CPIMAgnToDoAdapter::AlarmOffsetL(
       
   653     const MPIMItemData& aItemData, CCalEntry& aEntry)
       
   654 {
       
   655     JELOG2(EPim);
       
   656     // Note that start time must be set before alarm can be calculated
       
   657     // Add start to the item so alarm can be properly converted. The
       
   658     // native entry does not accept alarm value if start is not present
       
   659     // Due has been already set to default time (current home time) if
       
   660     // ToDo due field is not present in the field so start should be present
       
   661     if (!aItemData.CountValues(EPIMToDoDue))
       
   662     {
       
   663         User::Leave(KErrArgument);
       
   664     }
       
   665     else
       
   666     {
       
   667         ConvertDateToAgnL(EPIMToDoDue, 0, aEntry, aItemData);
       
   668     }
       
   669 
       
   670     __ASSERT_DEBUG(aEntry.StartTimeL().TimeUtcL() != Time::NullTTime(),
       
   671                    User::Panic(KPIMPanicCategory, EPIMPanicInvalidState));
       
   672 
       
   673     // Get alarm value from the Java item. There should be only one alarm
       
   674     // value supported by the PIM API because native entries do not support
       
   675     // multiple alarm values.
       
   676     const TPIMFieldData alarmData = aItemData.ValueL(EPIMToDoExtAlarm, 0);
       
   677     TInt value = alarmData.IntegerValue();
       
   678 
       
   679     // Count the alarm value from the start date of the event
       
   680     TTime entryStart = aEntry.StartTimeL().TimeLocalL();
       
   681     const TPIMFieldData dateData = aItemData.ValueL(EPIMToDoDue, 0);
       
   682     TPIMDate dueDate(dateData.DateValue());
       
   683     ConvertTimeL(dueDate, EPIMDateLocal);
       
   684     TTimeIntervalSeconds temp(0);
       
   685     User::LeaveIfError(entryStart.SecondsFrom(dueDate, temp));
       
   686 
       
   687     // Add difference between PIM API start and start which has been
       
   688     // converted to the item (in case if the date has been changed, it is
       
   689     // reflected here)
       
   690     value += temp.Int();
       
   691 
       
   692     // Check that if the alarm has passed to the following day. In this case,
       
   693     // the alarm is transferred back to 12 o'clock of the current start date
       
   694     TTime alarmTime(entryStart - TTimeIntervalSeconds(value));
       
   695     // Temporary date. This date is used when calculating if the alarm
       
   696     // value has passed to the following date.
       
   697     TTime startOfNextDay(StartOfDay(dueDate + TTimeIntervalDays(1)));
       
   698     if (alarmTime >= startOfNextDay)
       
   699     {
       
   700         alarmTime = StartOfDay(entryStart);
       
   701         alarmTime += TTimeIntervalSeconds(KPIMDefaultAlarmInterval);
       
   702         User::LeaveIfError(entryStart.SecondsFrom(alarmTime, temp));
       
   703         value = temp.Int();
       
   704     }
       
   705     // Convert seconds to minutes
       
   706     return TTimeIntervalMinutes(value / KPIMSecondsInMinute);
       
   707 }
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CPIMAgnToDoAdapter::CPIMAgnToDoAdapter
       
   711 // -----------------------------------------------------------------------------
       
   712 //
       
   713 CPIMAgnToDoAdapter::CPIMAgnToDoAdapter(java::util::FunctionServer* aFuncServer) :
       
   714         CPIMAgnItemAdapter(aFuncServer)
       
   715 {
       
   716     JELOG2(EPim);
       
   717 }
       
   718 
       
   719 // End of File