--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pimappservices/calendarvcalplugin/src/agmvcali.cpp Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,1993 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+#include <s32file.h>
+#include <s32mem.h>
+#include <bassnd.h>
+#include <calentry.h>
+#include <vtzrules.h>
+#include "agnversit.h"
+#include <utf.h>
+#include <tz.h> //Conversion between local and UTC times
+#include <calalarm.h>
+#include <calcontent.h>
+#include <calrrule.h>
+#include <caluser.h>
+#include <calattachment.h>
+
+#include "agmvcal.h"
+
+const TInt KCountDigits = 8;
+_LIT(KDateStringFormat, "%F%D%M%Y%H%T%S%C"); // locale-independent formatting DDMMYYHHMMSSUUUUUU (day,month,year,hour,minute,second,usec
+_LIT(KVersitTokenMailTo,"MAILTO:");
+
+HBufC* AgnConvertUtil::EncodeL(const TDesC& aText,TUid aConversion)
+ {
+ HBufC8* text=HBufC8::NewLC(aText.Length()*2);
+ TPtr8 ptr = text->Des();
+ TInt i;
+ for (i=0; i < aText.Length(); i++)
+ {
+ ptr.Append(aText[i] & 0x00FF);
+ ptr.Append((aText[i] >> 8) & 0x00FF);
+ }
+ CCnaConverterList* convList=CCnaConverterList::NewLC();
+ CConverterBase* conv = convList->NewConverterL(aConversion);
+ if (!conv)
+ {
+ CleanupStack::PopAndDestroy(); // convList
+ User::Leave(KErrNotSupported);
+ }
+ CleanupStack::PushL(conv);
+ CBufFlat* decodeBuffer = CBufFlat::NewL(256);
+ CleanupStack::PushL(decodeBuffer);
+ CBufFlat* encodedBuffer = CBufFlat::NewL(256);
+ CleanupStack::PushL(encodedBuffer);
+ decodeBuffer->InsertL(0,ptr);
+ RBufReadStream readStream;
+ RBufWriteStream writeStream;
+ readStream.Open(*decodeBuffer);
+ writeStream.Open(*encodedBuffer);
+ conv->ConvertObjectL(readStream, writeStream);
+ readStream.Close();
+ TInt size=encodedBuffer->Size();
+ HBufC* writeBuf=HBufC::NewLC(size);
+ TPtr resulttext = writeBuf->Des();
+ for(i = 0; i < (size - 1); i += 2)
+ {
+ resulttext.Append((encodedBuffer->Ptr(0)[i + 1] << 8) |
+ encodedBuffer->Ptr(0)[i]);
+ }
+
+ writeStream.CommitL();
+ writeStream.Close();
+ CleanupStack::Pop(writeBuf); // writebuf
+ CleanupStack::PopAndDestroy(2,decodeBuffer); // buffers
+ CleanupStack::PopAndDestroy(2,convList); //conv+convList
+ CleanupStack::PopAndDestroy(text); //text
+ return (writeBuf);
+ }
+
+// This method imports a vCalendar entity from aParser and returns a pointer to a CAgnEntry
+// if successful or NULL if it wasn't possible to import the vCalendar. It reads the
+// relevant properties from aParser entity and builds up a corresponding agenda entry.
+// It allows to import vCal file without Summary and Description fields
+void CVCalToAgendaEntryConverter::ImportVCalL(CVersitParser& aParser, RPointerArray<CCalEntry>& aEntryArray)
+ {
+ CCalEntry::TType entryType = GetEntryTypeL(aParser);
+
+ // Group Scheduling Data
+
+ //Import UID
+ HBufC* guid16 = ImportDesPropertyL(aParser, KVersitTokenUID);
+
+ if (!guid16) // non cal entry
+ {
+ // create our a UID based on the current time (UTC, microsecond precision)
+ TTime now;
+ now.UniversalTime();
+ TBuf<KMaxTimeStringSize+KCountDigits> dateString;
+ now.FormatL(dateString,KDateStringFormat);
+
+ TInt threeDidgit=Math::Random() % 1000;
+ dateString.Append(threeDidgit);
+
+ guid16 = dateString.AllocL();
+ }
+
+ CleanupStack::PushL(guid16);
+
+ // the UID is stored as an 8-bit descriptor, so convert from 16-bit to 8-bit
+ HBufC8* guid8= CnvUtfConverter::ConvertFromUnicodeToUtf8L(guid16->Des());
+ CleanupStack::PopAndDestroy(guid16);
+ CleanupStack::PushL(guid8);
+
+ // Import Sequence Number
+ TInt seqNumber;
+
+ // if no sequence number
+ if (!ImportIntegerPropertyL(aParser, KVersitTokenSEQUENCE, seqNumber))
+ {
+ seqNumber = 0;
+ }
+
+ // Import Method
+ CCalEntry::TMethod methodStatus(CCalEntry::EMethodNone);
+ HBufC* method = ImportDesPropertyL(aParser, KVersitTokenXMETHOD);
+
+ if (method)
+ {
+ CleanupStack::PushL(method);
+ if (*method == KVCalTokenMethodStatusENone)
+ {
+ methodStatus = CCalEntry::EMethodNone;
+ }
+ else if (*method == KVCalTokenMethodStatusEPublish)
+ {
+ methodStatus = CCalEntry::EMethodPublish;
+ }
+ else if (*method == KVCalTokenMethodStatusERequest)
+ {
+ methodStatus = CCalEntry::EMethodRequest;
+ }
+ else if (*method == KVCalTokenMethodStatusEReply)
+ {
+ methodStatus = CCalEntry::EMethodReply;
+ }
+ else if (*method == KVCalTokenMethodStatusEAdd)
+ {
+ methodStatus = CCalEntry::EMethodAdd;
+ }
+ else if (*method == KVCalTokenMethodStatusECancel)
+ {
+ methodStatus = CCalEntry::EMethodCancel;
+ }
+ else if (*method == KVCalTokenMethodStatusERefresh)
+ {
+ methodStatus = CCalEntry::EMethodRefresh;
+ }
+ else if (*method == KVCalTokenMethodStatusECounter)
+ {
+ methodStatus = CCalEntry::EMethodCounter;
+ }
+ else if (*method == KVCalTokenMethodStatusEDeclineCounter)
+ {
+ methodStatus = CCalEntry::EMethodDeclineCounter;
+ }
+ else
+ {
+ // do nothing if method is invalid - it will be None by default
+ }
+
+
+ CleanupStack::PopAndDestroy(method);
+ }
+
+ // Import X-Recurrence-Id
+ TVersitDateTime::TRelativeTime relativeTime = TVersitDateTime::EIsUTC;
+ TTime recurrenceId;
+ TBool isRecurrenceIdPresent = ImportDateTimePropertyL(aParser, KVersitTokenXRECURRENCEID, recurrenceId, relativeTime);
+ if (!isRecurrenceIdPresent)
+ {
+ iEntry = CCalEntry::NewL(entryType,guid8, methodStatus, seqNumber);
+ }
+ else
+ {
+ TCalTime caltime;
+ if(GetTimeModeL(aParser) == TCalTime::EFloating)
+ {
+ caltime.SetTimeLocalFloatingL(recurrenceId);
+ }
+ else
+ {
+ caltime.SetTimeUtcL(recurrenceId);
+ }
+
+ iEntry = CCalEntry::NewL(entryType,guid8, methodStatus, seqNumber, caltime, CalCommon::EThisOnly);
+ }
+
+ CleanupStack::Pop(guid8); // ownership was passed to calGSData
+ // Fill in the entry description from the SUMMARY property
+ // If this doesn't exist, use the DESCRIPTION property, and if this
+ // doesn't exist, return a NULL entry
+
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVersitTokenSUMMARY, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
+
+ if (!properties)
+ {
+ // get properties but don't take ownership of the elements of the array
+ properties = aParser.PropertyL(KVersitTokenDESCRIPTION, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
+ }
+ CleanupStack::PushL(properties);
+
+ // Use the value found from the Summary/Description
+ // Both Summary and Description are not found in imported vCal file
+ //then insert empty enties for summary and description
+ // these empty entries will be descarded while exporting vCal file
+ TPtrC summary;
+ if (properties)
+ {
+ summary.Set(static_cast<CParserPropertyValueHBufC*>((*properties)[0]->Value())->Value());
+ }
+
+ HBufC* summaryBuf = AgnConvertUtil::EncodeL(summary,KUidTextToEtextNoTrim);
+ CleanupStack::PushL(summaryBuf);
+ if (summaryBuf)
+ {
+ iEntry->SetSummaryL(*summaryBuf);
+ }
+ CleanupStack::PopAndDestroy(summaryBuf);
+
+ HBufC* description =ImportDesPropertyL(aParser,KVersitTokenDESCRIPTION);
+ CleanupStack::PushL(description);
+ if (description != NULL)
+ {
+ iEntry->SetDescriptionL(*description); // Takes ownership
+ }
+ CleanupStack::PopAndDestroy(description);
+
+ TBool validEntry = EFalse;
+ if (entryType == CCalEntry::ETodo)
+ {
+ validEntry = ImportTodoPropertiesL(aParser);
+ }
+ else
+ {
+ validEntry = ImportEventPropertiesL(aParser);
+ }
+
+ if (!validEntry)
+ {
+ CleanupStack::PopAndDestroy(properties);
+ delete iEntry;
+ iEntry = NULL;
+ return;
+ }
+
+ // Import CLASS property
+ HBufC* property=ImportDesPropertyL(aParser, KVersitTokenCLASS);
+ if (property)
+ {
+ CleanupStack::PushL(property);
+ if (*property == KVCalTokenPUBLIC)
+ iEntry->SetReplicationStatusL(CCalEntry::EOpen);
+ else if (*property == KVCalTokenPRIVATE)
+ iEntry->SetReplicationStatusL(CCalEntry::EPrivate);
+ else if (*property == KVCalTokenCONFIDENTIAL)
+ iEntry->SetReplicationStatusL(CCalEntry::ERestricted);
+ CleanupStack::PopAndDestroy(property);
+ }
+ // Import LOCATION property
+ property=ImportDesPropertyL(aParser, KVersitTokenLOCATION);
+ if (property)
+ {
+ CleanupStack::PushL(property);
+ iEntry->SetLocationL(*property);
+ CleanupStack::PopAndDestroy(property);
+ }
+ // Import DTSTAMP
+ TTime timeProperty;
+ if (ImportDateTimePropertyL(aParser, KVersitTokenXDTSTAMP, timeProperty, relativeTime))
+ {
+ TCalTime caltimeProperty;
+ caltimeProperty.SetTimeUtcL(timeProperty);
+ iEntry->SetDTStampL(caltimeProperty);
+ }
+
+ // Attendee property
+ ImportAttendeePropertiesL(aParser, KVersitTokenATTENDEE);
+
+ // Categories property
+ ImportCategoriesPropertyL(aParser, KVersitTokenCATEGORIES);
+
+
+
+ TInt localId;
+ if (ImportIntegerPropertyL(aParser, KVersitTokenXLOCALUID, localId))
+ {
+ iEntry->SetLocalUidL(localId);
+ }
+
+ // Additional stuff to comply with Versit Specs 1.0
+ // All entries have a priority not just ToDo's
+ // Todo Functionality merged into this code block
+ TInt priority;
+ if (ImportIntegerPropertyL(aParser, KVersitTokenPRIORITY, priority))
+ {
+ iEntry->SetPriorityL(priority);
+ }
+
+ // All entries have a status - will default to Needs Action if cannot be read
+ CCalEntry::TStatus entryStatus=CCalEntry::ENullStatus;
+ ImportStatusPropertyL(aParser, entryStatus);
+ //Now sync completed and ECompleted status to keep entry consistenty
+ if(entryType==CCalEntry::ETodo && (iEntry->CompletedTimeL().TimeUtcL()) != Time::NullTTime())
+ {
+ iEntry->SetCompletedL(ETrue, iEntry->CompletedTimeL());
+ }
+ iEntry->SetStatusL(entryStatus);
+
+ //Get last changed date from vcal
+ if (ImportDateTimePropertyL(aParser, KVersitTokenLASTMODIFIED, timeProperty, relativeTime))
+ {
+ if (iTzZone && (relativeTime == TVersitDateTime::EIsVCardLocal))
+ {
+ iTzZone->ConvertToUtcL(timeProperty);
+ }
+ TCalTime lastModifiedDate;
+ lastModifiedDate.SetTimeUtcL(timeProperty);
+ iEntry->SetLastModifiedDateL(lastModifiedDate);
+ }
+ else
+ {
+ iEntry->SetLastModifiedDateL(); //set changed date to now
+ }
+
+ TInt transp;
+ if (ImportIntegerPropertyL(aParser, KVersitTokenTRANSP, transp))
+ {
+ iEntry->SetTimeTransparencyL(static_cast<CCalEntry::TTransp>(transp));
+ }
+
+ ImportAttachmentPropertyL(aParser);
+
+ // Import GEO
+ HBufC* geoString=ImportDesPropertyL(aParser,KVersitTokenGEO);
+
+ if (geoString != NULL)
+ {
+ CleanupStack::PushL(geoString);
+ // Determine the position of the delimiter for extraction of the geo latitude and longitude values
+ TInt delimiterPos = geoString->Locate(KVersitTokenCommaVal);
+
+ if(delimiterPos!=KErrNotFound)
+ {
+ // Extract the latitude
+ TLex geoLatitudeLex(geoString->Left(delimiterPos));
+ // Extract the latitude by excluding the delimiter
+ TLex geoLongitudeLex(geoString->Right(geoString->Length()-(delimiterPos+1)));
+
+ TReal geoLatitude;
+ TReal geoLongitude;
+
+ if((geoLatitudeLex.Val(geoLatitude)==KErrNone) && (geoLongitudeLex.Val(geoLongitude)==KErrNone))
+ {
+ CCalGeoValue* importedGeoValue=CCalGeoValue::NewL();
+ CleanupStack::PushL(importedGeoValue);
+ TRAPD(err, importedGeoValue->SetLatLongL(geoLatitude,geoLongitude));
+ if(err==KErrNone)
+ {
+ iEntry->SetGeoValueL(*importedGeoValue);
+ }
+ CleanupStack::PopAndDestroy(importedGeoValue);
+ }
+ }
+ CleanupStack::PopAndDestroy(geoString);
+ }
+
+ CleanupStack::PopAndDestroy(properties);
+ aEntryArray.AppendL(iEntry); // takes ownership of entry
+ iEntry = NULL;
+ }
+
+CVCalToAgendaEntryConverter::~CVCalToAgendaEntryConverter()
+ {
+ delete iEntry;
+ delete iTzZone;
+ }
+
+void CVCalToAgendaEntryConverter::SetTzConverter(RTz* aTzConverter)
+ {
+ iTzConverter = aTzConverter;
+ }
+
+void CVCalToAgendaEntryConverter::SetTzRules(CTzRules* aTzZone)
+ {
+ // this function should only ever be called once so this shouldn't be needed
+ if (iTzZone)
+ {
+ delete iTzZone;
+ iTzZone = NULL;
+ }
+ iTzZone = aTzZone;
+ }
+
+TCalTime::TTimeMode CVCalToAgendaEntryConverter::GetTimeModeL(CVersitParser& aParser)
+ {
+ TTime dummyTime;
+ TVersitDateTime::TRelativeTime relativeTime;
+
+ if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDTSTART, dummyTime, relativeTime))
+ {
+ if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDTEND, dummyTime, relativeTime))
+ {
+ if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDUE, dummyTime, relativeTime))
+ {
+ // no time
+ relativeTime = TVersitDateTime::EIsUTC;
+ }
+ }
+ }
+
+ if (iTzZone || relativeTime == TVersitDateTime::EIsUTC)
+ {
+ return TCalTime::EFixedUtc;
+ }
+ return TCalTime::EFloating;
+ }
+
+// Try and find out which Epoc Agenda entry type this belongs to.
+// At the moment, relies on having an 'X-EPOCAGENDAENTRYTYPE' field, and defaults to a appointment
+// type if this isn't present.
+// Maybe some heuristics should be used to try and ascertain which entry type is most appropriate
+// e.g. if the entry has a yearly repeat, then maybe it should be an anniversary type.
+//
+// A call to this function resets iVcalTokenTypeReminder flag (unless the vCal entry is actually a Reminder).
+//
+CCalEntry::TType CVCalToAgendaEntryConverter::GetEntryTypeL(CVersitParser& aParser)
+ {
+ // If the entry type is a Todo, return immediately
+ if (aParser.EntityName()==KVersitVarTokenVTODO)
+ {
+ return CCalEntry::ETodo;
+ }
+
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVCalToken8XDASHENTRYTYPE, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
+ if (properties)
+ {
+ TPtrC type = static_cast<CParserPropertyValueHBufC*>((*properties)[0]->Value())->Value();
+ delete properties;
+
+ if (type == KVCalTokenTypeAPPT)
+ {
+ return CCalEntry::EAppt;
+ }
+
+ if (type == KVCalTokenTypeEVENT)
+ {
+ return CCalEntry::EEvent;
+ }
+
+ if (type == KVCalTokenTypeANNIV)
+ {
+ return CCalEntry::EAnniv;
+ }
+
+ if (type == KVCalTokenTypeTODO)
+ {
+ return CCalEntry::ETodo;
+ }
+
+ if (type == KVCalTokenTypeREMINDER)
+ {
+ return CCalEntry::EReminder;
+ }
+
+ }
+
+ // return an appointment as default type
+ return (CCalEntry::EAppt);
+ }
+
+TBool CVCalToAgendaEntryConverter::IsValidTime(const TTime& aTime)
+ {
+ if (aTime < TCalTime::MinTime() || aTime > TCalTime::MaxTime())
+ {
+ return EFalse;
+ }
+ return ETrue;
+ }
+
+// Import Recurrence Dates property
+//
+void CVCalToAgendaEntryConverter::ImportRDatePropertyL(CVersitParser& aParser, const TDesC8& aToken)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyMultiDateTimeUid), EFalse);
+
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CArrayPtr<TVersitDateTime>* rDates = static_cast<CParserPropertyValueMultiDateTime*>((*properties)[0]->Value())->Value();
+
+ if (rDates)
+ {
+ RArray<TCalTime>calrdates;
+ CleanupClosePushL(calrdates);
+ const TInt KSize = rDates->Count();
+ for (TInt count = 0; count < KSize; ++count)
+ {
+ TVersitDateTime* time = (*rDates)[count];
+ TTime timeProperty(time->iDateTime);
+
+ if (IsValidTime(timeProperty))
+ {
+ TVersitDateTime::TRelativeTime relativeTime = time->iRelativeTime;
+ if (iTzZone && (relativeTime == TVersitDateTime::EIsVCardLocal))
+ {
+ //Convert to utc time using imported TZ rules
+ iTzZone->ConvertToUtcL(timeProperty);
+ relativeTime = TVersitDateTime::EIsUTC;
+ }
+
+ TCalTime calrdate;
+ if (relativeTime == TVersitDateTime::EIsVCardLocal)
+ {
+ calrdate.SetTimeLocalFloatingL(timeProperty);
+ }
+ else
+ {
+ __ASSERT_DEBUG(relativeTime == TVersitDateTime::EIsUTC, Panic(EAgnVersitPanicWrongTimeType));
+ calrdate.SetTimeUtcL(timeProperty); //assume time as UTC for release build
+ }
+ calrdates.Append(calrdate);
+ }
+ }
+ iEntry->SetRDatesL(calrdates);
+ CleanupStack::PopAndDestroy();//close RArray
+ }
+ CleanupStack::PopAndDestroy(properties);
+ }
+
+ }
+
+// Import the start and end dates of the vCalendar
+// This method returns EFalse if there is no start date or end date, or if the start date
+// is after the end date. If the start date is missing but an end date is present, the
+// start date is set to the end date. If the end date is missing but there is a start
+// date, the end date is set to the start date.
+//
+TBool CVCalToAgendaEntryConverter::GetStartAndEndDatesL(CVersitParser& aParser, TTime& aStartDate, TTime& aEndDate, TVersitDateTime::TRelativeTime& aRelativeTime)
+ {
+ TBool startValid = ETrue;
+ TBool endValid = ETrue;
+
+ if (!ImportDateTimePropertyL(aParser, KVersitTokenDTSTART, aStartDate,aRelativeTime))
+ {
+ startValid = EFalse;
+ }
+
+ TVersitDateTime::TRelativeTime relativeTime;
+
+ if (!ImportDateTimePropertyL(aParser, KVersitTokenDTEND, aEndDate, relativeTime))
+ {
+ endValid = EFalse;
+ }
+
+ if (!startValid && !endValid)
+ {
+ // Neither times exist, so return Invalid Entry
+ return EFalse;
+ }
+
+ if (startValid && !endValid)
+ {
+ // Start time but no end time
+ aEndDate = aStartDate;
+ }
+ else if (!startValid && endValid)
+ {
+ // End time but no start time
+ aStartDate = aEndDate;
+ aRelativeTime = relativeTime;
+ }
+
+ if (aStartDate>aEndDate)
+ return EFalse;
+
+ return ETrue;
+ }
+
+// Import appointment properties
+//
+TBool CVCalToAgendaEntryConverter::ImportEventPropertiesL(CVersitParser& aParser)
+ {
+ TTime startDate;
+ TTime endDate;
+ TVersitDateTime::TRelativeTime relativeTime;
+ if (!GetStartAndEndDatesL(aParser, startDate, endDate, relativeTime))
+ {
+ return EFalse;
+ }
+
+ if(iEntry->EntryTypeL()==CCalEntry::EReminder)
+ {
+ endDate = startDate;
+ }
+
+ TCalTime caltimeStart;
+ TCalTime caltimeEnd;
+ if (relativeTime == TVersitDateTime::EIsVCardLocal)
+ {
+ caltimeStart.SetTimeLocalFloatingL(startDate);
+ caltimeEnd.SetTimeLocalFloatingL(endDate);
+ }
+ else
+ {
+ __ASSERT_DEBUG(relativeTime==TVersitDateTime::EIsUTC, Panic(EAgnVersitPanicWrongTimeType));
+ caltimeStart.SetTimeUtcL(startDate); //assume time as UTC for release build
+ caltimeEnd.SetTimeUtcL(endDate); //assume time as UTC for release build
+ }
+
+ if (startDate > endDate && endDate != Time::NullTTime())
+ {
+ return EFalse;
+ }
+ iEntry->SetStartAndEndTimeL(caltimeStart,caltimeEnd);
+
+ // Attempt to import alarm/repeat properties
+ ImportRepeatPropertyL(aParser, KVersitTokenRRULE, startDate, relativeTime);
+ ImportAlarmPropertyL(aParser, startDate, relativeTime);
+ return ETrue;
+ }
+
+//
+TBool CVCalToAgendaEntryConverter::ImportTodoPropertiesL(CVersitParser& aParser)
+ {
+ TVersitDateTime::TRelativeTime relativeTime;//EIsUTC is the default
+ TTime startDate = Time::NullTTime();
+ TTime endDate = Time::NullTTime();
+
+ if (!ImportDateTimePropertyL(aParser, KVersitTokenDUE, endDate, relativeTime))
+ {
+ if (!ImportDateTimePropertyL(aParser, KVersitTokenDTEND, endDate, relativeTime))
+ {
+ endDate = Time::NullTTime();
+ }
+ }
+
+ if ( ! ImportDateTimePropertyL(aParser, KVersitTokenDTSTART, startDate, relativeTime))
+ {
+ startDate = endDate;
+ }
+
+ if (startDate > endDate && endDate != Time::NullTTime())
+ {
+ return EFalse;
+ }
+
+
+
+ if (endDate == Time::NullTTime())
+ {
+ endDate = startDate;
+ }
+ else if (startDate == Time::NullTTime() || startDate > endDate)
+ {
+ startDate = endDate;
+ }
+
+ TTime completedDate;
+ if (ImportDateTimePropertyL(aParser, KVCalTokenCOMPLETED,completedDate, relativeTime))
+ {
+ TCalTime calcompletedDate;
+ calcompletedDate.SetTimeUtcL(completedDate);
+ iEntry->SetCompletedL(ETrue, calcompletedDate);
+ }
+
+ TCalTime caltimeStart;
+ TCalTime caltimeEnd;
+
+ if (relativeTime == TVersitDateTime::EIsUTC)
+ {
+ caltimeStart.SetTimeUtcL(startDate);
+ caltimeEnd.SetTimeUtcL(endDate);
+ }
+ else
+ {
+ caltimeStart.SetTimeLocalFloatingL(startDate);
+ caltimeEnd.SetTimeLocalFloatingL(endDate);
+ }
+ iEntry->SetStartAndEndTimeL(caltimeStart,caltimeEnd);
+
+// Attempt to import alarm properties
+ ImportAlarmPropertyL(aParser, endDate, relativeTime);
+
+// Attempt to import repeat properties
+ ImportRepeatPropertyL(aParser, KVersitTokenRRULE, endDate, relativeTime);
+
+ return ETrue;
+ }
+
+// Import a date/time
+// This method returns true if a date/time exists and is within the standard agenda date range
+// If it doesn't exist or the date isn't valid this method returns EFalse.
+//
+TBool CVCalToAgendaEntryConverter::ImportDateTimePropertyL(CVersitParser& aParser, const TDesC8& aToken, TTime& aValue, TVersitDateTime::TRelativeTime& aRelativeTime)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyDateTimeUid), EFalse);
+
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ TVersitDateTime* time = static_cast<CParserPropertyValueDateTime*>((*properties)[0]->Value())->Value();
+ aValue = TTime(time->iDateTime);
+ TCalTime calTime;
+ if (IsValidTime(aValue))
+ {
+ aRelativeTime = time->iRelativeTime;
+ if (iTzZone && ( aRelativeTime== TVersitDateTime::EIsVCardLocal))
+ {
+ //Convert to utc time using imported TZ rules
+ iTzZone->ConvertToUtcL(aValue);
+ aRelativeTime = TVersitDateTime::EIsUTC;
+ }
+ CleanupStack::PopAndDestroy(properties);
+ return ETrue;
+ }
+
+ CleanupStack::PopAndDestroy(properties);
+ }
+
+ return EFalse;
+ }
+
+// Import an integer property
+//
+TBool CVCalToAgendaEntryConverter::ImportIntegerPropertyL(CVersitParser& aParser, const TDesC8& aToken, TInt& aValue)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyIntUid), EFalse);
+
+ if (properties)
+ {
+ aValue = static_cast<CParserPropertyValueInt*>((*properties)[0]->Value())->Value();
+ delete properties;
+ return ETrue;
+ }
+ else
+ {
+ // If there is no property available, return EFalse to signal that this property doesn't exist
+ return EFalse;
+ }
+ }
+
+// Import a descriptor property
+//
+HBufC* CVCalToAgendaEntryConverter::ImportDesPropertyL(CVersitParser& aParser, const TDesC8& aToken)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
+ // If there is no property available, return NULL to signal that this property doesn't exist
+ HBufC* aHBufC = NULL;
+
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CParserPropertyValueHBufC* propertyValue = static_cast<CParserPropertyValueHBufC*>((*properties)[0]->Value());
+ aHBufC=propertyValue->TakeValueOwnership();
+ CleanupStack::PopAndDestroy(properties);
+ if (aHBufC)
+ {
+ CleanupStack::PushL(aHBufC);
+ HBufC* temp=AgnConvertUtil::EncodeL(aHBufC->Des(),KUidTextToEtextNoTrim);
+ CleanupStack::PopAndDestroy(aHBufC);
+ aHBufC=temp;
+ }
+ }
+ return aHBufC;
+ }
+
+// Import an alarm property
+//
+TBool CVCalToAgendaEntryConverter::ImportAlarmPropertyL(CVersitParser& aParser, TTime& aEntryTime, TVersitDateTime::TRelativeTime& aRelativeTime)
+ {
+ // Get properties but don't take ownership of the elements of the array.
+ // Check if there is an AALARM first.
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVersitTokenAALARM,
+ TUid::Uid(KVCalPropertyAlarmUid), EFalse);
+
+ // If there is no AALARM then try with a DALARM. They are treated the same.
+ if (!properties)
+ {
+ properties = aParser.PropertyL(KVersitTokenDALARM,
+ TUid::Uid(KVCalPropertyAlarmUid), EFalse);
+ }
+
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CParserPropertyValueAlarm* alarmProperty = static_cast<CParserPropertyValueAlarm*>((*properties)[0]->Value());
+ CVersitAlarm* alarm = alarmProperty->Value();
+ if (!alarm->iRunTime)
+ {
+ CleanupStack::PopAndDestroy(properties);
+ return EFalse;
+ }
+ TTime alarmTime = TTime(alarm->iRunTime->iDateTime);
+ TVersitDateTime::TRelativeTime relativeTime = alarm->iRunTime->iRelativeTime;
+ if (iTzZone && (alarm->iRunTime->iRelativeTime == TVersitDateTime::EIsVCardLocal))
+ {
+ //Convert to utc time using imported TZ rules
+ iTzZone->ConvertToUtcL(alarmTime);
+ relativeTime = TVersitDateTime::EIsUTC;
+ }
+
+ if(aEntryTime==Time::NullTTime())
+ {//It is only possible if it is a undated doto entry, in which, the due time should be set before the alarm time is set
+ __ASSERT_DEBUG(iEntry->EntryTypeL()==CCalEntry::ETodo, Panic(EAgnVersitWrongAttribute));
+
+ aEntryTime = alarmTime;
+ aRelativeTime = relativeTime;
+
+ TCalTime endTime;
+ if (relativeTime==TVersitDateTime::EIsVCardLocal || relativeTime==TVersitDateTime::EIsMachineLocal)
+ {
+ endTime.SetTimeLocalFloatingL(aEntryTime);
+ }
+ else
+ {
+ __ASSERT_DEBUG(relativeTime==TVersitDateTime::EIsUTC, Panic(EAgnVersitPanicWrongTimeType));
+ endTime.SetTimeUtcL(aEntryTime);
+ }
+ iEntry->SetStartAndEndTimeL(iEntry->StartTimeL(), endTime);
+ }
+
+
+ TTimeIntervalMinutes minutes;
+ aEntryTime.MinutesFrom(alarmTime, minutes);
+
+ CCalAlarm* calalarm = CCalAlarm::NewL();
+ CleanupStack::PushL(calalarm);
+
+ const TInt KMinValidAlarmTime = -1440; // can have an alarm up to one day after an event
+ if(minutes.Int() >= KMinValidAlarmTime)
+ {
+ calalarm->SetTimeOffset(minutes);
+ }
+ else
+ {
+ // Alarm run-time is not valid - return EFalse since there is no valid alarm property
+ CleanupStack::PopAndDestroy(2,properties);
+ return EFalse;
+ }
+
+ HBufC* soundName=NULL;
+ // Check if the sound type is an Epoc Sound
+ CParserParam* param = ((*properties)[0])->Param(KVCalToken8TYPE);
+ if (param)
+ {
+ if (param->Value() == KVCalValue8EPOCSOUND)
+ {
+ soundName = alarm->iAudioContent;
+ if (soundName)
+ {
+ calalarm->SetAlarmSoundNameL(*soundName);
+ }
+ }
+ }
+
+ TBool hasExtenedAlarm = ImportExtendedAlarmPropertyL(calalarm, aParser, KVersitTokenXALARM);
+
+ if (!soundName && !hasExtenedAlarm)
+ {
+ TBaSystemSoundType type(KSystemSoundAlarmUID);
+ TBaSystemSoundInfo info;
+ RFs s;
+ User::LeaveIfError(s.Connect());
+ BaSystemSound::GetSound(s,type,info); //don't check err as info will always be filled in
+ s.Close();
+ calalarm->SetAlarmSoundNameL(info.FileName());
+ }
+
+ iEntry->SetAlarmL(calalarm);
+
+ CleanupStack::PopAndDestroy(2,properties);
+ return ETrue;
+ }
+ else
+ {
+ // If there is no property available, return EFalse to signal that this property doesn't exist
+ return EFalse;
+ }
+ }
+
+// Import an extended alarm property (X-EPOCALARM) - containing the rich alarm data; it does not import the
+// timing control parameters because the AALARM property would have been imported and written to the agenda
+// model entry; no need to re-populate the timing controls since both audio sound and extended alarm share the
+// same timing controls. The audio alarm timing controls override the rich alarm's timing controls (not used).
+TBool CVCalToAgendaEntryConverter::ImportExtendedAlarmPropertyL(CCalAlarm* aAlarm, CVersitParser& aParser, const TDesC8& aToken )
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVCalPropertyExtendedAlarmUid), EFalse);
+
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CParserPropertyValueExtendedAlarm* extendedAlarmProperty = static_cast<CParserPropertyValueExtendedAlarm*>((*properties)[0]->Value());
+ CVersitExtendedAlarm* extendedAlarm = extendedAlarmProperty->Value();
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* audioAlarmProperties = aParser.PropertyL(KVersitTokenAALARM, TUid::Uid(KVCalPropertyAlarmUid), EFalse);
+
+ if (extendedAlarm && audioAlarmProperties)
+ {
+ CleanupStack::PushL(audioAlarmProperties);
+
+ // Convert X-EPOC-ALARM to alarm content and add to entry
+ CCalContent* alarmAction = CCalContent::NewL();
+ CleanupStack::PushL(alarmAction);
+ HBufC8* content = NULL;
+ if (extendedAlarm->iContent != NULL)
+ {
+ content = extendedAlarm->iContent->AllocL();
+ CleanupStack::PushL(content);
+ }
+ HBufC8* mimeType = NULL;
+ if (extendedAlarm->iMimeType != NULL)
+ {
+ mimeType = extendedAlarm->iMimeType->AllocL();
+ CleanupStack::PushL(mimeType);
+ }
+ alarmAction->SetContentL(content, mimeType, static_cast<CCalContent::TDisposition>(extendedAlarm->iDisposition)); //Takes ownership of content & mimeType
+
+ if (mimeType != NULL)
+ {
+ CleanupStack::Pop(mimeType);
+ }
+ if (content != NULL)
+ {
+ CleanupStack::Pop(content);
+ }
+ aAlarm->SetAlarmAction(alarmAction); // takes ownership of alarmAction
+ CleanupStack::Pop(alarmAction);
+
+ CleanupStack::PopAndDestroy(audioAlarmProperties);
+ CleanupStack::PopAndDestroy(properties);
+ return ETrue;
+ }
+ else
+ {
+ // If there is no rich alarm available, return EFalse to signal that this property doesn't exist
+ CleanupStack::PopAndDestroy(properties);
+ return EFalse;
+ }
+ }
+ else
+ {
+ // If there is no property available, return EFalse to signal that this property doesn't exist
+ return EFalse;
+ }
+ }
+
+void CVCalToAgendaEntryConverter::ImportAttachmentPropertyL(CVersitParser& aParser)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(KVersitTokenATTACH, KNullUid, EFalse);//We past KNullUid since we don't know whether it is a binary or URI - versit will have the informantion.
+
+ if (!properties)
+ {
+ return;
+ }
+
+ CleanupStack::PushL(properties);
+ const TInt KCount = properties->Count(); // no. of attachments
+ for (TInt i = 0; i < KCount; ++i)
+ {
+ CParserParam* attachValueType = (*properties)[i]->Param(KVersitTokenVALUE);
+ TPtrC8 valueType;
+ if(attachValueType && attachValueType->Value().Length() > 0)
+ {
+ valueType.Set(attachValueType->Value());
+ }
+
+ CCalAttachment* attachment = NULL;
+ if(!attachValueType || valueType == KVersitTokenINLINE || valueType == KVersitTokenBINARY)
+ {
+ CParserPropertyValueBinary* attachValueBinary = static_cast<CParserPropertyValueBinary*>((*properties)[i]->Value());
+ if (attachValueBinary)
+ {
+ CBufSeg* binary=(CBufSeg*)(attachValueBinary->Value());
+ const TInt KBinaryLength = binary->Size();
+ if(KBinaryLength>0)
+ {
+ HBufC8* bufValue = HBufC8::NewLC(KBinaryLength);
+ TPtr8 pBufValue = bufValue->Des();
+ binary->Read(0, pBufValue, KBinaryLength);
+ attachment = CCalAttachment::NewFileL(bufValue);
+ CleanupStack::Pop(bufValue);
+ }
+ }
+ }
+ else
+ {
+ CParserPropertyValueHBufC* attachValueDes = static_cast<CParserPropertyValueHBufC*>((*properties)[i]->Value());
+ if (attachValueDes && attachValueDes->Value().Length() > 0)
+ {
+ TPtrC des16Value = attachValueDes->Value();
+ HBufC8* buf8Value = HBufC8::NewLC(des16Value.Length());
+ buf8Value->Des().Copy(des16Value);
+ if ( ! valueType.Compare(KVCalContentValueContentId) || ! valueType.Compare(KVCalContentValueContentIdShort))
+ {
+ attachment = CCalAttachment::NewFileByContentIdL(*buf8Value);
+ }
+ else
+ {
+ attachment = CCalAttachment::NewUriL(*buf8Value);
+ }
+ CleanupStack::PopAndDestroy(buf8Value);
+ }
+ }
+ if (attachment)
+ {
+ CleanupStack::PushL(attachment);
+ //Set paramenters
+ CParserParam* mimeTypeParam = (*properties)[i]->Param(KVersitAttachMimeType);
+ if(mimeTypeParam && mimeTypeParam->Value().Length() > 0)
+ {
+ attachment->SetMimeTypeL(mimeTypeParam->Value());
+ }
+
+ CParserParam* attachName = (*properties)[i]->Param(KVersitAttachLabel);
+ if(attachName && attachName->Value().Length() > 0)
+ {
+ TPtrC8 attachnameNarror = attachName->Value();
+ HBufC* attachname16 = HBufC::NewLC(attachnameNarror.Length());
+ TPtr pattachname16 = attachname16->Des();
+ User::LeaveIfError(CnvUtfConverter::ConvertToUnicodeFromUtf8(pattachname16, attachnameNarror));
+ attachment->SetLabelL(*attachname16);
+ CleanupStack::PopAndDestroy(attachname16);
+ }
+
+ CParserParam* attachDate = (*properties)[i]->Param(KVCalAttachFileDate);
+ if(attachDate && attachment->FileAttachment() && attachDate->Value().Length() > 0)
+ {
+ TPtrC8 pAttachDate = attachDate->Value();
+ TBuf<KMaxTimeStringSize>date16;
+ date16.Copy(pAttachDate);
+ TVersitDateTime* datetime = aParser.DecodeDateTimeL(date16);
+ CleanupStack::PushL(datetime);
+ TTime fileTtime(datetime->iDateTime);
+ if(iTzZone && datetime->iRelativeTime != TVersitDateTime::EIsUTC)
+ {
+ iTzZone->ConvertToUtcL(fileTtime);
+ }
+ attachment->FileAttachment()->SetLastModifiedTimeUtc(fileTtime);
+ CleanupStack::PopAndDestroy(datetime);
+ }
+ iEntry->AddAttachmentL(*attachment);
+ CleanupStack::Pop(attachment);
+ }
+ }// for loop
+
+ CleanupStack::PopAndDestroy(properties);
+ }
+
+// Import repeat property
+//
+void CVCalToAgendaEntryConverter::ImportRepeatPropertyL(CVersitParser& aParser, const TDesC8& aToken, const TTime& aRepeatTime, TVersitDateTime::TRelativeTime aRelativeTime)
+ {
+ if (aRepeatTime != Time::NullTTime())
+ {
+ ImportRepeatRuleL(aParser, aToken, aRepeatTime, aRelativeTime);
+
+ //check for RDates - this operation must be carried out after any rule has been imported
+ ImportRDatePropertyL(aParser, KVersitTokenRDATE);
+
+ ImportRepeatExceptionPropertiesL(aParser, KVersitTokenEXDATE);
+ }
+ }
+
+// Repeat end date behaviour
+// - If the repeat end date is within the agenda range it is set
+// - If the repeat end date is greater than the maximum agenda date then the entry is set to repeat forever
+// - If the repeat end date is less than the minimum agenda date then the entry is made non-repeating
+//
+// Current implementation follows these policies:
+// 1) time mode of repeat always matches time mode of the entry:
+// if entry's time mode is EFloating, then repeat's time mode is EFloating;
+// if entry's time mode is EFixedUTC, then repeat's time mode is EFixedTimeZone.
+// 2) time format of DTSTART determines time mode of the entry.
+// if DTSTART is not valid, then time format of DTEND/DUE is used.
+//
+void CVCalToAgendaEntryConverter::ImportRepeatRuleL(CVersitParser& aParser, const TDesC8& aToken, const TTime& aStartDate, TVersitDateTime::TRelativeTime aRelativeTime)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVCalPropertyRecurrenceUid), EFalse);
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CVersitRecurrence* recurrence = static_cast<CParserPropertyValueRecurrence*>((*properties)[0]->Value())->Value();
+ if (!recurrence)
+ {
+ CleanupStack::PopAndDestroy(properties);
+ return;
+ }
+
+ //Importing the start time of the repeating
+ //startTimeLoc & startTimeUtc will be same if it is floating entry or when iTzZone is not specified.
+ TTime startTimeLoc = aStartDate;
+ TTime startTimeUtc = aStartDate;
+ TBool isFloatingEntry = (!iTzZone && aRelativeTime != TVersitDateTime::EIsUTC);
+
+ if (iTzZone)
+ {
+ if (aRelativeTime == TVersitDateTime::EIsUTC)
+ {
+ iTzZone->ConvertToLocalL(startTimeLoc);
+ }
+ else
+ {
+ iTzZone->ConvertToUtcL(startTimeUtc);
+ }
+ }
+
+ TCalRRule repeat;
+ TCalTime calstart;
+
+ if (isFloatingEntry)
+ {
+ calstart.SetTimeLocalFloatingL(startTimeLoc);
+ }
+ else
+ {
+ calstart.SetTimeUtcL(startTimeUtc);
+ }
+
+ repeat.SetDtStart(calstart);
+
+ //Importing the recurrence of the repeating
+ switch(recurrence->iRepeatType)
+ {
+ case CVersitRecurrence::EDaily:
+ repeat.SetType(TCalRRule::EDaily);
+ break;
+ case CVersitRecurrence::EYearlyByMonth:
+ repeat.SetType(TCalRRule::EYearly);
+ break;
+ case CVersitRecurrence::EWeekly:
+ ImportWeeklyRepeatPropertiesL(static_cast<CVersitRecurrenceWeekly*>(recurrence), repeat, startTimeLoc.DayNoInWeek());
+ break;
+ case CVersitRecurrence::EMonthlyByPos:
+ ImportMonthlyByPosRepeatPropertiesL(static_cast<CVersitRecurrenceMonthlyByPos*>(recurrence), repeat, startTimeLoc);
+ break;
+ case CVersitRecurrence::EMonthlyByDay:
+ ImportMonthlyByDayRepeatPropertiesL(static_cast<CVersitRecurrenceMonthlyByDay*>(recurrence), repeat, startTimeLoc.DayNoInMonth());
+ break;
+ case CVersitRecurrence::EYearlyByDay:
+ // Not supported, since an event cannot repeat on the 100th day of a year, etc
+ // -- intentional drop through to default case --
+ default:
+ // Don't understand the repeat type,
+ // so cleanup and exit
+ CleanupStack::PopAndDestroy(properties);
+ return;
+ }
+
+ // We allow only TVersitDateTime::EIsUTC and EIsVCardLocal, because
+ // EIsMachineLocal is never returned by parser,and EIsCorrect is not used
+ __ASSERT_DEBUG(aRelativeTime == TVersitDateTime::EIsUTC ||
+ aRelativeTime == TVersitDateTime::EIsVCardLocal, Panic(EAgnVersitPanicWrongTimeType));
+
+ //Importing the until time of the repeating
+ TVersitDateTime* rptEndDate = recurrence->iEndDate;
+ TCalTime calUntil;
+ TBool isUntilTimeValid = EFalse;
+
+ if(!rptEndDate && recurrence->iDuration == 0)
+ {//If no until time has been set and the count is 0, the repeating is forever
+ calUntil.SetTimeUtcL(TCalTime::MaxTime());
+ repeat.SetCount(0);
+ isUntilTimeValid = ETrue;
+ }
+ else if(rptEndDate)
+ {//Set the until time
+ TDateTime untilDateTimeLoc = rptEndDate->iDateTime;
+ //Adjust the local repeating until time according to the local start time
+ if (!isFloatingEntry && iTzZone && rptEndDate->iRelativeTime == TVersitDateTime::EIsUTC)
+ {
+ TTime time(untilDateTimeLoc);//create a temp object of TTime
+ iTzZone->ConvertToLocalL(time);//convert the UTC until to local
+ untilDateTimeLoc = time.DateTime();// set the local until
+ }
+
+ untilDateTimeLoc.SetHour(startTimeLoc.DateTime().Hour());
+ untilDateTimeLoc.SetMinute(startTimeLoc.DateTime().Minute());
+ untilDateTimeLoc.SetSecond(startTimeLoc.DateTime().Second());
+ untilDateTimeLoc.SetMicroSecond(0);
+ isUntilTimeValid = ETrue;
+
+ if (isFloatingEntry)
+ {
+ if (TTime(untilDateTimeLoc) < TCalTime::MinTime())
+ {
+ isUntilTimeValid = EFalse;
+ }
+ else
+ {
+ if (TTime(untilDateTimeLoc) > TCalTime::MaxTime())
+ {
+ untilDateTimeLoc = TCalTime::MaxTime().DateTime();
+ }
+ calUntil.SetTimeLocalFloatingL(untilDateTimeLoc);
+ }
+ }
+ else
+ {
+ TTime untilUtc(untilDateTimeLoc);
+ if (iTzZone)
+ {
+ iTzZone->ConvertToUtcL(untilUtc);
+ }
+
+ if (untilUtc < TCalTime::MinTime())
+ {
+ isUntilTimeValid = EFalse;
+ }
+
+ else
+ {
+ if (untilUtc > TCalTime::MaxTime())
+ {
+ untilUtc = TCalTime::MaxTime().DateTime();
+ }
+ calUntil.SetTimeUtcL(untilUtc);
+ }
+ }
+
+ }
+
+ if (isUntilTimeValid)
+ {
+ repeat.SetUntil(calUntil);
+ }
+
+ if (recurrence->iDuration>0)
+ {
+ TInt instancesPerRepeat = CalculateInstancesPerRepeatL(repeat);
+
+ TInt count = recurrence->iDuration * instancesPerRepeat;
+
+ // it is possible to have both count and untiltime in an imported vcal
+ // we will import the shortest repeat of the two dates
+ if(repeat.Until().TimeLocalL() != Time::NullTTime())
+ {
+ TCalTime countUntilTime = iEntry->FindRptUntilTimeL(count);
+
+ if(countUntilTime.TimeLocalL() < repeat.Until().TimeLocalL())
+ {
+ // if until time is already set, it will be replaced
+ repeat.SetUntil(countUntilTime);
+ }
+ }
+ else
+ {
+ repeat.SetCount(count);
+ }
+
+ isUntilTimeValid = ETrue;
+ }
+
+ if (isUntilTimeValid)
+ {
+ //Importing the interval
+ repeat.SetInterval(recurrence->iInterval);
+
+ //Importing the repeating count
+
+ TRAPD(err, iEntry->SetRRuleL(repeat));
+ if (err != KErrArgument && err != KErrNotSupported)
+ {
+ User::LeaveIfError(err);
+ }
+
+ TCalRRule ruleGot;
+ if(iEntry->GetRRuleL(ruleGot))
+ {
+ if(iTzZone)
+ {
+ // If there are DAYLIGHT and TZ properties, use these rules when converting
+ // repeating dates to UTC for storage, otherwise the time zone device will be used
+ // instead.
+ iEntry->SetTzRulesL(*iTzZone);
+ }
+ }
+ }
+
+ CleanupStack::PopAndDestroy(properties);
+ }
+ }
+
+TInt CVCalToAgendaEntryConverter::CalculateInstancesPerRepeatL(const TCalRRule& aRRule) const
+ {
+ TInt instancesPerRepeat = 1;
+ switch (aRRule.Type())
+ {
+ case TCalRRule::EWeekly:
+ {
+ RArray<TDay> wkdays;
+ CleanupClosePushL(wkdays);
+ aRRule.GetByDayL(wkdays);
+ instancesPerRepeat = wkdays.Count();
+ CleanupStack::PopAndDestroy(&wkdays);
+ }
+ break;
+ case TCalRRule::EMonthly:
+ {
+ RArray<TCalRRule::TDayOfMonth> monthdays;
+ CleanupClosePushL(monthdays);
+ aRRule.GetByDayL(monthdays);
+ instancesPerRepeat = monthdays.Count();
+ CleanupStack::PopAndDestroy(&monthdays);
+ if (instancesPerRepeat == 0)
+ {
+ RArray<TInt> monthdates;
+ CleanupClosePushL(monthdates);
+ aRRule.GetByMonthDayL(monthdates);
+ instancesPerRepeat = monthdates.Count();
+ CleanupStack::PopAndDestroy(&monthdates);
+ }
+ }
+ break;
+ case TCalRRule::EYearly:
+ {
+ RArray<TCalRRule::TDayOfMonth> yrdays;
+ CleanupClosePushL(yrdays);
+ aRRule.GetByDayL(yrdays);
+ instancesPerRepeat = yrdays.Count();
+ CleanupStack::PopAndDestroy(&yrdays);
+ if (instancesPerRepeat == 0)
+ {
+ RArray<TMonth> yrmonths;
+ CleanupClosePushL(yrmonths);
+ aRRule.GetByMonthL(yrmonths);
+ instancesPerRepeat = yrmonths.Count();
+ CleanupStack::PopAndDestroy(&yrmonths);
+ }
+ }
+ break;
+ case TCalRRule::EDaily:
+ default:
+ // do nothing
+ break;
+ }
+ if (instancesPerRepeat == 0)
+ {
+ instancesPerRepeat = 1;
+ }
+ return instancesPerRepeat;
+ }
+
+void CVCalToAgendaEntryConverter::ImportWeeklyRepeatPropertiesL(CVersitRecurrenceWeekly* aRepeat, TCalRRule& aRpt, TDay aDefaultDayOfWeek)
+ {
+ aRpt.SetType(TCalRRule::EWeekly);
+ CWeekDayArray* weekdayArray = aRepeat->iArrayOfWeekDayOccurrences;
+ RArray<TDay> daysinweek;
+ CleanupClosePushL(daysinweek);
+
+ if (weekdayArray)
+ {
+ CArrayFix<TDay>* dayList = weekdayArray->iArray;
+
+ TInt size = dayList->Count();
+ for (TInt count=0; count<size; count++)
+ {
+ TDay day = (*dayList)[count];
+ daysinweek.AppendL(day);
+ }
+ }
+ else
+ {
+ daysinweek.AppendL(aDefaultDayOfWeek);
+ }
+
+ aRpt.SetByDay(daysinweek);
+ CleanupStack::PopAndDestroy();//close rarray
+ }
+
+
+void CVCalToAgendaEntryConverter::ImportMonthlyByDayRepeatPropertiesL(CVersitRecurrenceMonthlyByDay* aRepeat, TCalRRule& aRpt, TInt aDefaultDayOfMonth)
+ {
+ aRpt.SetType(TCalRRule::EMonthly);
+
+ // Specify which dates to repeat on
+ // Only days from the start of the month are supported
+ CArrayFix<TInt>* dayList = aRepeat->iArrayOfOccurrencesInDaysFromStartOfMonth;
+ CArrayFix<TInt>* endDayList = aRepeat->iArrayOfOccurrencesInDaysFromEndOfMonth;
+ RArray<TInt> monthdays;
+ CleanupClosePushL(monthdays);
+ if (dayList)
+ {
+ TInt size = dayList->Count();
+ for (TInt count=0; count<size; count++)
+ {
+ TInt day = (*dayList)[count]-1;
+ // Set only valid dates
+ // 0 = the first day of a month, 30 = the 31st day of the month
+ if (day >= 0 && day <= 30)
+ {
+ monthdays.AppendL(day);
+ }
+ }
+ }
+ else if(endDayList)
+ {
+ TInt size = endDayList->Count();
+ for (TInt count=0;count<size;++count)
+ {
+ TInt day = (*endDayList)[count];
+ if(day==1)
+ { //set 31st day in the monthlyByDates list as its the last day of the month
+ monthdays.AppendL(30);
+ break;
+ }
+ }
+ }
+
+
+ if(monthdays.Count()<1)
+ {
+ monthdays.AppendL(aDefaultDayOfMonth);
+ }
+
+ aRpt.SetByMonthDay(monthdays);
+ CleanupStack::PopAndDestroy();//close RArray
+ }
+
+
+void CVCalToAgendaEntryConverter::ImportMonthlyByPosRepeatPropertiesL(CVersitRecurrenceMonthlyByPos* aRepeat, TCalRRule& aRpt, const TTime& aDate)
+ {
+ aRpt.SetType(TCalRRule::EMonthly);
+
+ TInt size = aRepeat->iMonthPositions->Count();
+ RArray<TCalRRule::TDayOfMonth> dayofmonthArray;
+ CleanupClosePushL(dayofmonthArray);
+
+ if (size > 0)
+ {
+ for (TInt count=0; count<size; count++)
+ {
+ CArrayFix<TDay>* dayList = (*(aRepeat->iMonthPositions))[count]->iArrayOfWeekDays->iArray;
+ TInt weekNo = (*(aRepeat->iMonthPositions))[count]->iWeekNo;
+ TInt sign = (*(aRepeat->iMonthPositions))[count]->iSign;
+
+ if (weekNo == 1 && sign == CVersitRecurrenceMonthlyByPos::CMonthPosition::EWeeksFromEndOfMonth)
+ {
+ // If the poisiton is in the last week of the month
+ weekNo = -1;
+ }
+ else if (weekNo > 5 || sign == CVersitRecurrenceMonthlyByPos::CMonthPosition::EWeeksFromEndOfMonth)
+ {
+ // We can't model this setting, so ignore it
+ continue;
+ }
+
+ // Now set the days for the week setting
+ TInt dayCount = dayList->Count();
+ for (TInt ii=0; ii<dayCount; ii++)
+ {
+ TDay day = (*dayList)[ii];
+ TCalRRule::TDayOfMonth monthday(day, weekNo);
+ dayofmonthArray.AppendL(monthday);
+ }
+ }
+ }
+ else
+ {
+ TDay day = aDate.DayNoInWeek();
+ TInt week = aDate.DayNoInMonth() / 7 + 1;
+ TCalRRule::TDayOfMonth monthday(day, week);
+ dayofmonthArray.AppendL(monthday);
+ }
+
+ aRpt.SetByDay(dayofmonthArray);
+ CleanupStack::PopAndDestroy();//close the RArray
+ }
+
+void CVCalToAgendaEntryConverter::ImportRepeatExceptionPropertiesL(CVersitParser& aParser, const TDesC8& aToken)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyMultiDateTimeUid), EFalse);
+
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CArrayPtr<TVersitDateTime>* exDates = static_cast<CParserPropertyValueMultiDateTime*>((*properties)[0]->Value())->Value();
+ if (exDates)
+ {
+ TInt size = exDates->Count();
+ RArray<TCalTime> exceptionlist;
+ CleanupClosePushL(exceptionlist);
+
+ for (TInt count=0; count<size; count++)
+ {
+ TCalTime exception;
+ TVersitDateTime* time = (*exDates)[count];
+ TTime timeProperty(time->iDateTime);
+ if (IsValidTime(timeProperty))
+ {
+ TVersitDateTime::TRelativeTime relativeTime = time->iRelativeTime;
+
+ if (iTzZone && (relativeTime == TVersitDateTime::EIsVCardLocal))
+ {
+ //Convert to utc time
+ iTzZone->ConvertToUtcL(timeProperty);
+ relativeTime = TVersitDateTime::EIsUTC;
+ }
+
+ if (iEntry->StartTimeL().TimeMode() == TCalTime::EFloating)
+ {
+ exception.SetTimeLocalFloatingL(timeProperty);
+ }
+ else
+ {
+ // the EXDATE is floating but the entry is UTC
+ exception.SetTimeUtcL(timeProperty);
+ }
+
+ exceptionlist.AppendL(exception);
+ }
+ }
+ iEntry->SetExceptionDatesL(exceptionlist);
+ CleanupStack::PopAndDestroy();//close the RArray
+ }
+ CleanupStack::PopAndDestroy(properties);
+ }
+ }
+
+void CVCalToAgendaEntryConverter::ImportAttendeePropertiesL(CVersitParser& aParser, const TDesC8& aToken)
+ {
+ TBool mailto;
+ TInt propLen;
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyHBufCUid), EFalse);
+ CleanupStack::PushL(properties);
+
+ if (properties)
+ {
+ TInt size = properties->Count(); // no. of attendees
+ for (TInt count=0; count<size; count++)
+ {
+ CParserPropertyValueHBufC* attendeeProperty = static_cast<CParserPropertyValueHBufC*>((*properties)[count]->Value());
+
+ mailto = EFalse;
+ propLen = 0;
+ if (attendeeProperty->Value().FindF(KVersitTokenMailTo) == 0)
+ {
+ mailto = ETrue;
+ propLen = attendeeProperty->Value().Length() - KVersitTokenMailTo().Length();
+ }
+
+ CParserParam* sentBy = (*properties)[count]->Param(KICalAttendeeSentBy8);
+
+ CCalAttendee* attendee = NULL;
+ CCalUser* user = NULL;
+ CParserParam* role = (*properties)[count]->Param(KVCalAttendee8ROLE);
+
+ const TDesC& KAttendeeProperty = mailto ? attendeeProperty->Value().Right(propLen) : attendeeProperty->Value();
+ if (sentBy)
+ {
+ HBufC* sentByDesc = sentBy->ValueL();
+ CleanupStack::PushL(sentByDesc);
+ if (role && role->Value() == KVCalAttendeeRole8ORGANIZER)
+ {
+ user = CCalUser::NewL(KAttendeeProperty, *sentByDesc);
+ iEntry->SetOrganizerL(user);
+ }
+ else
+ {
+ attendee = CCalAttendee::NewL(KAttendeeProperty, *sentByDesc);
+ iEntry->AddAttendeeL(attendee);
+ }
+ CleanupStack::PopAndDestroy(sentByDesc);
+ }
+ else
+ {
+ if (role && role->Value() == KVCalAttendeeRole8ORGANIZER)
+ {
+ user = CCalUser::NewL(KAttendeeProperty);
+ iEntry->SetOrganizerL(user);
+ }
+ else
+ {
+ attendee = CCalAttendee::NewL(KAttendeeProperty);
+ iEntry->AddAttendeeL(attendee);
+ }
+ }
+
+ if (attendee)
+ {
+ CParserParam* calrole = (*properties)[count]->Param(KICalAttendeeCalRole8);
+ TBool roleSet = EFalse;
+ // Check for iCal roles values
+ if (calrole)
+ {
+ if(calrole->Value() == KICalAttendeeCalRole8CHAIR)
+ {
+ attendee->SetRoleL(CCalAttendee::EChair);
+ roleSet = ETrue;
+ }
+ else if(calrole->Value() == KICalAttendeeCalRole8REQUIRED)
+ {
+ attendee->SetRoleL(CCalAttendee::EReqParticipant);
+ roleSet = ETrue;
+ }
+ else if(calrole->Value() == KICalAttendeeCalRole8OPTIONAL)
+ {
+ attendee->SetRoleL(CCalAttendee::EOptParticipant);
+ roleSet = ETrue;
+ }
+ else if(calrole->Value() == KICalAttendeeCalRole8NONPARTICIPANT)
+ {
+ attendee->SetRoleL(CCalAttendee::ENonParticipant);
+ roleSet = ETrue;
+ }
+ }
+ if ( ! roleSet && role)
+ {
+ if (role->Value() == KVCalAttendeeRole8OWNER)
+ {
+ attendee->SetRoleL(CCalAttendee::EVCalOwner);
+ roleSet = ETrue;
+ }
+ else if (role->Value() == KVCalAttendeeRole8DELEGATE)
+ {
+ attendee->SetRoleL(CCalAttendee::EVCalDelegate);
+ roleSet = ETrue;
+ }
+ else if (role->Value() == KVCalAttendeeRole8ATTENDEE)
+ {
+ attendee->SetRoleL(CCalAttendee::EVCalAttendee);
+ roleSet = ETrue;
+ }
+ }
+ if ( ! roleSet)
+ {
+ attendee->SetRoleL(CCalAttendee::EReqParticipant);
+ }
+
+ // Check for vCal status values
+ CParserParam* calStatus = (*properties)[count]->Param(KICalAttendeeCalStatus8);
+ CParserParam* status = (*properties)[count]->Param(KVCalAttendee8STATUS);
+ if (calStatus)
+ {
+ if (calStatus->Value() == KVCalAttendeeStatus8ACCEPTED)
+ attendee->SetStatusL(CCalAttendee::EAccepted);
+ else if (calStatus->Value() == KVCalAttendeeStatus8NEEDSACTION)
+ attendee->SetStatusL(CCalAttendee::ENeedsAction);
+ else if (calStatus->Value() == KVCalAttendeeStatus8TENTATIVE)
+ attendee->SetStatusL(CCalAttendee::ETentative);
+ else if (calStatus->Value() == KVCalAttendeeStatus8CONFIRMED)
+ attendee->SetStatusL(CCalAttendee::EConfirmed);
+ else if (calStatus->Value() == KVCalAttendeeStatus8DECLINED)
+ attendee->SetStatusL(CCalAttendee::EDeclined);
+ else if (calStatus->Value() == KVCalAttendeeStatus8COMPLETED)
+ attendee->SetStatusL(CCalAttendee::ECompleted);
+ else if (calStatus->Value() == KVCalAttendeeStatus8DELEGATED)
+ attendee->SetStatusL(CCalAttendee::EDelegated);
+ else if (calStatus->Value() == KICalAttendeeCalStatus8INPROCESS)
+ attendee->SetStatusL(CCalAttendee::EInProcess);
+ }
+ else if (status)
+ {
+ if (status->Value() == KVCalAttendeeStatus8ACCEPTED)
+ attendee->SetStatusL(CCalAttendee::EAccepted);
+ else if (status->Value() == KVCalAttendeeStatus8NEEDSACTION)
+ attendee->SetStatusL(CCalAttendee::ENeedsAction);
+ else if (status->Value() == KVCalAttendeeStatus8SENT)
+ attendee->SetStatusL(CCalAttendee::EVCalSent);
+ else if (status->Value() == KVCalAttendeeStatus8XDASHRECEIVED)
+ attendee->SetStatusL(CCalAttendee::EVCalXReceived);
+ else if (status->Value() == KVCalAttendeeStatus8TENTATIVE)
+ attendee->SetStatusL(CCalAttendee::ETentative);
+ else if (status->Value() == KVCalAttendeeStatus8CONFIRMED)
+ attendee->SetStatusL(CCalAttendee::EConfirmed);
+ else if (status->Value() == KVCalAttendeeStatus8DECLINED)
+ attendee->SetStatusL(CCalAttendee::EDeclined);
+ else if (status->Value() == KVCalAttendeeStatus8COMPLETED)
+ attendee->SetStatusL(CCalAttendee::ECompleted);
+ else if (status->Value() == KVCalAttendeeStatus8DELEGATED)
+ attendee->SetStatusL(CCalAttendee::EDelegated);
+ }
+
+ // Check for RSVP parameter
+ CParserParam* rsvp = (*properties)[count]->Param(KVCalAttendee8RSVP);
+ if (rsvp)
+ {
+ if (rsvp->Value() == KVCalAttendeeRsvp8YES)
+ attendee->SetResponseRequested(ETrue);
+ else
+ attendee->SetResponseRequested(EFalse);
+ }
+
+ // Check for EXPECT parameter
+ CParserParam* expect = (*properties)[count]->Param(KVCalAttendee8EXPECT);
+ if (expect)
+ {
+ if (expect->Value() == KVCalAttendeeExpect8FYI)
+ attendee->SetVCalExpect(CCalAttendee::EVCalFyi);
+ else if (expect->Value() == KVCalAttendeeExpect8REQUIRE)
+ attendee->SetVCalExpect(CCalAttendee::EVCalRequire);
+ else if (expect->Value() == KVCalAttendeeExpect8REQUEST)
+ attendee->SetVCalExpect(CCalAttendee::EVCalRequest);
+ else if (expect->Value() == KVCalAttendeeExpect8IMMEDIATE)
+ attendee->SetVCalExpect(CCalAttendee::EVCalImmediate);
+ }
+ }
+
+ // Check for a common name
+ CParserParam* commonname = (*properties)[count]->Param(KICalAttendeeCommonName8);
+ if (commonname)
+ {
+ HBufC* commonNameDesC = commonname->ValueL();
+ CleanupStack::PushL(commonNameDesC);
+ if(user)
+ {
+ user->SetCommonNameL(*commonNameDesC);
+ }
+ else if (attendee)
+ {
+ attendee->SetCommonNameL(*commonNameDesC);
+ }
+ CleanupStack::PopAndDestroy(commonNameDesC);
+ }
+ //Set phone owner
+ CParserParam* phoneowner = (*properties)[count]->Param(KICalAttendee8XDASHPHONEOWNER);
+ if(phoneowner)
+ {
+ if(user)
+ {
+ iEntry->SetPhoneOwnerL(user);
+ }
+ else if (attendee)
+ {
+ iEntry->SetPhoneOwnerL(attendee);
+ }
+ }
+ }//for
+ }//if property
+
+ CleanupStack::PopAndDestroy(properties);
+ }
+
+// Import the categories property
+// For each category, try and match the name of the category with the standard category types.
+// If this fails, the category is assumed to be an extended category type and the "X-" prefix
+// is removed
+//
+void CVCalToAgendaEntryConverter::ImportCategoriesPropertyL(CVersitParser& aParser, const TDesC8& aToken)
+ {
+ // get properties but don't take ownership of the elements of the array
+ CArrayPtr<CParserProperty>* properties = aParser.PropertyL(aToken, TUid::Uid(KVersitPropertyCDesCArrayUid), EFalse);
+ if (properties)
+ {
+ CleanupStack::PushL(properties);
+ CDesCArray* categories = static_cast<CParserPropertyValueCDesCArray*>((*properties)[0]->Value())->Value();
+ for (TInt count=0; count < categories->Count(); count++)
+ {
+ TPtrC categoryName=categories->MdcaPoint(count);
+ CCalCategory* category = NULL;
+ //match category name to standard ones
+ CCalCategory::TCalCategoryType type = (CCalCategory::TCalCategoryType)(-1);
+ if (categoryName.CompareF(KVCalCategoriesAPPOINTMENT)==0)
+ {
+ type = CCalCategory::ECalAppointment;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesBUSINESS)==0)
+ {
+ type = CCalCategory::ECalBusiness;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesEDUCATION)==0)
+ {
+ type = CCalCategory::ECalEducation;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesHOLIDAY)==0)
+ {
+ type = CCalCategory::ECalHoliday;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesMEETING)==0)
+ {
+ type = CCalCategory::ECalMeeting;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesMISCELLANEOUS)==0)
+ {
+ type = CCalCategory::ECalMiscellaneous;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesPERSONAL)==0)
+ {
+ type = CCalCategory::ECalPersonal;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesPHONECALL)==0)
+ {
+ type = CCalCategory::ECalPhoneCall;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesSICKDAY)==0)
+ {
+ type = CCalCategory::ECalSickDay;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesSPECIALOCCASION)==0)
+ {
+ type = CCalCategory::ECalSpecialOccasion;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesTRAVEL)==0)
+ {
+ type = CCalCategory::ECalTravel;
+ }
+ else if(categoryName.CompareF(KVCalCategoriesVACATION)==0)
+ {
+ type = CCalCategory::ECalVacation;
+ }
+ if(type>-1)
+ {
+ category = CCalCategory::NewL(type);
+ }
+ else if(categoryName.Length() > 0)
+ {
+ if (categoryName.Find(KVCalTokenXDash) == 0)
+ {
+ categoryName.Set(categoryName.Right(categoryName.Length() - 2));
+ }
+
+ if(categoryName.Length() > 0)
+ {
+ category = CCalCategory::NewL(categoryName);
+ }
+ }
+
+ if(category)
+ {
+ // AddCategoryL() takes ownership at the end of the function call (after calling leaving functions)
+ iEntry->AddCategoryL(category);
+ }
+ }
+ CleanupStack::PopAndDestroy(properties);
+ }
+ }
+
+
+
+
+// Utility method to ensure proper cleanup in OOM
+//
+void ResetAndDestroyArrayOfEntries(TAny* aObject)
+ {
+ CArrayPtrFlat<CCalEntry>* array=reinterpret_cast<CArrayPtrFlat<CCalEntry>*>(aObject);
+ if (array)
+ array->ResetAndDestroy();
+ delete array;
+ }
+
+
+void CVCalToAgendaEntryConverter::SetImportVCalendarValues(TBool aImportVCalendar)
+ {
+ iImportVCalendarValues = aImportVCalendar;
+ }
+
+void CVCalToAgendaEntryConverter::ImportStatusPropertyL(CVersitParser& aParser, CCalEntry::TStatus& aStatus)
+ {
+ if (iImportVCalendarValues)
+ {
+ ImportVCalStatusPropertyL(aParser, aStatus);
+ }
+ else
+ {
+ ImportICalStatusPropertyL(aParser, aStatus);
+ }
+ }
+
+void CVCalToAgendaEntryConverter::ImportICalStatusPropertyL(CVersitParser& aParser, CCalEntry::TStatus& aStatus)
+ {
+ HBufC* property=ImportDesPropertyL(aParser, KVCalTokenSTATUS);
+ if (!property)
+ {
+ aStatus = CCalEntry::ENullStatus;
+ return;
+ }
+// BB mapped according to CCalEntryImpl::StatusL() which should be reconsidered
+ if (property->Length() ==0) // Property value not found - use default setting
+ {
+ aStatus = CCalEntry::ENullStatus;
+ }
+ else if (property->CompareF(KVCalStatusNEEDSACTION) == 0)
+ {
+ if (iEntry->EntryTypeL()==CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::ETodoNeedsAction;
+ }
+ else
+ {
+ aStatus = CCalEntry::EConfirmed;
+ }
+ }
+ else if (property->CompareF(KVCalStatusSENT) ==0 || property->CompareF(KVCalStatusDELEGATED)==0 || property->CompareF(KVCalStatusCONFIRMED) ==0 || property->CompareF(KVCalStatusACCEPTED) == 0)
+ {
+ if (iEntry->EntryTypeL()==CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::ETodoInProcess;
+ }
+ else
+ {
+ aStatus = CCalEntry::EConfirmed;
+ }
+
+ }
+ else if (property->CompareF(KVCalStatusTENTATIVE)==0)
+ {
+ if (iEntry->EntryTypeL()==CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::ETodoNeedsAction;
+ }
+ else
+ {
+ aStatus = CCalEntry::ETentative;
+ }
+
+ }
+ else if (property->CompareF(KVCalStatusDECLINED)==0)
+ {
+ aStatus = CCalEntry::ECancelled;
+ }
+ else if (property->CompareF(KVCalStatusCOMPLETED)==0)
+ {
+ if(iEntry->EntryTypeL()==CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::ETodoCompleted;
+ }
+ else
+ {
+ aStatus = CCalEntry::EConfirmed;
+ }
+
+ }
+ else // No Match found so use the default
+ aStatus = CCalEntry::ENullStatus;
+ delete property;
+ }
+
+void CVCalToAgendaEntryConverter::ImportVCalStatusPropertyL(CVersitParser& aParser, CCalEntry::TStatus& aStatus)
+ {
+ HBufC* property=ImportDesPropertyL(aParser, KVCalTokenSTATUS);
+ if (!property || property->Length() == 0)
+ {
+ aStatus = CCalEntry::ENullStatus;
+ }
+ else if (property->CompareF(KVCalStatusNEEDSACTION) == 0)
+ {
+ aStatus = CCalEntry::EVCalNeedsAction;
+ }
+ else if (property->CompareF(KVCalStatusSENT) == 0)
+ {
+ aStatus = CCalEntry::EVCalSent;
+ }
+ else if (property->CompareF(KVCalStatusDELEGATED)== 0)
+ {
+ aStatus = CCalEntry::EVCalDelegated;
+ }
+ else if (property->CompareF(KVCalStatusCONFIRMED) == 0 && iEntry->EntryTypeL() != CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::EConfirmed;
+ }
+ else if (property->CompareF(KVCalStatusACCEPTED) == 0)
+ {
+ aStatus = CCalEntry::EVCalAccepted;
+ }
+ else if (property->CompareF(KVCalStatusTENTATIVE)==0 && iEntry->EntryTypeL() != CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::ETentative;
+ }
+ else if (property->CompareF(KVCalStatusDECLINED)==0)
+ {
+ aStatus = CCalEntry::EVCalDeclined;
+ }
+ else if (property->CompareF(KVCalStatusCOMPLETED)==0 && iEntry->EntryTypeL() == CCalEntry::ETodo)
+ {
+ aStatus = CCalEntry::ETodoCompleted;
+ }
+ delete property;
+ }
+