pimappservices/calendar/client/src/calentryimpl.cpp
changeset 0 f979ecb2b13e
child 18 c198609911f9
child 30 d68a4b5d5885
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "calentryimpl.h"
       
    17 
       
    18 #include "calclient.h"
       
    19 #include "agsalarm.h"
       
    20 #include "agmattachment.h"
       
    21 #include "agmdate.h"
       
    22 #include "agmentry.h"
       
    23 #include "agmpanic.h"
       
    24 #include "agmcategory.h"
       
    25 #include "agmattendee.h"
       
    26 #include "agmcontent.h"
       
    27 #include <calalarm.h>
       
    28 #include "calcategoryimpl.h"
       
    29 #include <calcontent.h>
       
    30 #include <calrrule.h>
       
    31 #include <calsession.h>
       
    32 #include "calsessionimpl.h"
       
    33 #include "caluserimpl.h"
       
    34 
       
    35 const TInt KAttendeeGranularity = 2;
       
    36 const TInt KCategoryGranularity = 1;
       
    37 const TInt KAttachmentGranularity = 1;
       
    38 
       
    39 
       
    40 CCalEntryImpl::~CCalEntryImpl()
       
    41 	{
       
    42 	if(iSessionImpl)
       
    43 		{
       
    44 		iSessionImpl->DecrementReferenceCount();
       
    45 		}
       
    46 
       
    47 	if (iLiteEntry)
       
    48  		{
       
    49 		iLiteEntry->DecrementRefCount();
       
    50  		}
       
    51 	if(iCalAttachmentList)
       
    52 		{
       
    53 		iCalAttachmentList->ResetAndDestroy();
       
    54 		delete iCalAttachmentList; 	
       
    55 		}
       
    56 	if(iCalAttendeeList)
       
    57 		{
       
    58 		iCalAttendeeList->ResetAndDestroy();
       
    59 		delete iCalAttendeeList;
       
    60 		}
       
    61 	if(iCalCategoryList)
       
    62 		{
       
    63 		iCalCategoryList->ResetAndDestroy();
       
    64 		delete iCalCategoryList;
       
    65 		}
       
    66 	delete iCalOrganizer;
       
    67 	delete iFullEntry;
       
    68 	}
       
    69 
       
    70 CCalEntryImpl::CCalEntryImpl()
       
    71 	{
       
    72 	}
       
    73 
       
    74 CCalEntryImpl::CCalEntryImpl(CAgnEntry& aEntry, CCalSessionImpl& aSessionImpl)
       
    75 	: iFullEntry(&aEntry), iSessionImpl(&aSessionImpl)
       
    76 	{
       
    77 	iSessionImpl->IncrementReferenceCount();
       
    78 	}
       
    79 
       
    80 
       
    81 CCalEntryImpl::CCalEntryImpl(CCalLiteEntry& aEntry, CCalSessionImpl& aSessionImpl)
       
    82 	: iLiteEntry(&aEntry), iSessionImpl(&aSessionImpl)
       
    83  	{
       
    84  	iSessionImpl->IncrementReferenceCount();
       
    85 	iLiteEntry->IncrementRefCount();
       
    86  	}
       
    87 
       
    88 void CCalEntryImpl::ClearSimpleEntry()
       
    89 	{
       
    90 	if (iSessionImpl && iLiteEntry)
       
    91 		{
       
    92 		iLiteEntry->DecrementRefCount();
       
    93 		iLiteEntry = NULL;
       
    94 		}
       
    95 	}
       
    96 	
       
    97 CCalEntryImpl* CCalEntryImpl::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum)
       
    98 	{
       
    99 	__ASSERT_ALWAYS(aUid && aUid->Length() > 0, User::Leave(KErrArgument));
       
   100 
       
   101 	CCalEntryImpl* self = new (ELeave) CCalEntryImpl();
       
   102 	CleanupStack::PushL(self);
       
   103 	self->ConstructL(aType, aUid, aMethod, aSeqNum); // takes ownership of aUid
       
   104 	CleanupStack::Pop(self);
       
   105 	return self;
       
   106 	}
       
   107 
       
   108 CCalEntryImpl* CCalEntryImpl::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod,
       
   109 			TUint aSeqNum, const TCalTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
       
   110 	{
       
   111 	__ASSERT_ALWAYS(aUid && aUid->Length() > 0, User::Leave(KErrArgument));
       
   112 
       
   113 	CCalEntryImpl* self = new (ELeave) CCalEntryImpl();
       
   114 	CleanupStack::PushL(self);
       
   115 	self->ConstructL(aType, aUid, aMethod, aSeqNum, CalUtils::TCalTimeToTAgnCalendarTimeL(aRecurrenceId), aRange);
       
   116 	   // takes ownership of aUid
       
   117 	CleanupStack::Pop(self);
       
   118 	return self;
       
   119 	}
       
   120 
       
   121 CCalEntryImpl* CCalEntryImpl::NewL(CAgnEntry& aEntry, CCalSessionImpl& aSessionImpl)
       
   122 	{
       
   123 	CCalEntryImpl* self = new (ELeave) CCalEntryImpl(aEntry, aSessionImpl);
       
   124 	return self;
       
   125 	}
       
   126 
       
   127 CCalEntryImpl* CCalEntryImpl::NewL(CCalLiteEntry& aEntry, CCalSessionImpl& aSessionImpl)
       
   128 	{
       
   129 	CCalEntryImpl* self = new (ELeave) CCalEntryImpl(aEntry, aSessionImpl);
       
   130 	return self;
       
   131 	}
       
   132 
       
   133 void CCalEntryImpl::ConstructL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
       
   134 	{
       
   135 	// Create appropriate CAgnEntry type child entry.
       
   136 	iFullEntry = CAgnEntry::NewL(aType, aUid, aMethod, aSeqNum, aRecurrenceId, aRange); // takes ownership of aUid
       
   137 	}
       
   138 
       
   139 
       
   140 void CCalEntryImpl::ConstructL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum)
       
   141 	{
       
   142 	// Create appropriate CAgnEntry type parent entry.
       
   143 	iFullEntry = CAgnEntry::NewL(aType, aUid, aMethod,aSeqNum);
       
   144 	}
       
   145 
       
   146 void CCalEntryImpl::LoadFullEntryL()
       
   147 	{
       
   148 	if (iLiteEntry)
       
   149 		{
       
   150 		// iFullEntry should be NULL at this point
       
   151 		__ASSERT_DEBUG(iFullEntry == NULL, User::Leave(KErrCorrupt));
       
   152 		
       
   153 		// extract full CAgnEntry from TAgnLiteEntry and store it in iFullEntry
       
   154 		TCalLocalUid id = iLiteEntry->LiteEntry().LocalUid();
       
   155 		iFullEntry = iSessionImpl->Server().FetchEntryL(id, iSessionImpl->FileId());
       
   156 		__ASSERT_ALWAYS(iFullEntry, User::Leave(KErrNotFound));
       
   157 		iFullEntry->SetCollectionId(iLiteEntry->LiteEntry().CollectionId());
       
   158 		ClearSimpleEntry();
       
   159 		}
       
   160 	}
       
   161 
       
   162 // return the CAgnEntry associated with this entry, loading it from the server if necessary
       
   163 CAgnEntry* CCalEntryImpl::GetFullEntryL()
       
   164 	{
       
   165 	LoadFullEntryL();
       
   166 	return iFullEntry;
       
   167 	}
       
   168 
       
   169 void CCalEntryImpl::PopulateCategoryListL()
       
   170 	{
       
   171 	if (!iCalCategoryList)
       
   172 		{
       
   173 		LoadFullEntryL();
       
   174 		iCalCategoryList = new (ELeave) RPointerArray<CCalCategory>(KCategoryGranularity);
       
   175 
       
   176 		const TInt KCategoryCount = iFullEntry->CategoryCount();
       
   177 		for (TInt i = 0; i < KCategoryCount; ++i)
       
   178 			{
       
   179 			CAgnCategory& agnCategory = iFullEntry->FetchCategory(i); // ownership not taken
       
   180 			CCalCategoryImpl* impl = CCalCategoryImpl::NewL(&agnCategory); // doesn't take ownership of agnCategory
       
   181 			CleanupStack::PushL(impl);
       
   182 			CCalCategory* category = CCalCategory::NewL(impl); // takes ownership of impl
       
   183 			CleanupStack::Pop(impl);
       
   184 			CleanupStack::PushL(category);
       
   185 			iCalCategoryList->AppendL(category); // takes ownership of category
       
   186 			CleanupStack::Pop(category);
       
   187 			}
       
   188 		}
       
   189 	}
       
   190 
       
   191 void CCalEntryImpl::PopulateAttendeeListL()
       
   192 	{
       
   193 	if(!iCalAttendeeList)
       
   194 		{
       
   195 		LoadFullEntryL();
       
   196 
       
   197 		iCalAttendeeList = new(ELeave) RPointerArray<CCalAttendee>(KAttendeeGranularity);
       
   198 
       
   199 		const TInt KAttendeeCount = iFullEntry->AttendeeCount();
       
   200 		for(TInt i = 0; i < KAttendeeCount; ++i)
       
   201 			{
       
   202 			CAgnAttendee& agnAttendee = iFullEntry->FetchAttendee(i);
       
   203 			
       
   204 			CCalUserImpl* impl = CCalUserImpl::NewL(&agnAttendee);	// doesn't take ownership of agnAttendee
       
   205 			CleanupStack::PushL(impl);
       
   206 			CCalAttendee* calAttendee = CCalAttendee::NewL(impl);	// takes ownership of impl
       
   207 			CleanupStack::Pop(impl);
       
   208 			
       
   209 			CleanupStack::PushL(calAttendee);
       
   210 			iCalAttendeeList->AppendL(calAttendee);
       
   211 			CleanupStack::Pop(calAttendee);
       
   212 			}
       
   213 		}
       
   214 	}
       
   215 
       
   216 
       
   217 void CCalEntryImpl::AddAttendeeL(CCalAttendee* aAttendee)
       
   218 	{
       
   219     if (!aAttendee)
       
   220         {
       
   221         User::Leave( KErrArgument );
       
   222         }
       
   223 
       
   224 	CleanupStack::PushL(aAttendee);
       
   225 	__ASSERT_ALWAYS(aAttendee != NULL, User::Leave(KErrArgument));
       
   226 	PopulateAttendeeListL();
       
   227 
       
   228 	CCalUserImpl* userImpl = aAttendee->Impl();
       
   229 	CAgnAttendee* attendee = userImpl->Attendee();
       
   230 	
       
   231 	// add attendee to CAgnEntry (no longer owned by CCalAttendee)
       
   232 	userImpl->SetOwnsCAgnAttendee(EFalse);		
       
   233 	iFullEntry->AddAttendeeL(attendee);		
       
   234 	
       
   235 	// store attendee in attendee array too
       
   236 	iCalAttendeeList->AppendL(aAttendee);
       
   237 	CleanupStack::Pop(aAttendee);
       
   238 	}
       
   239 
       
   240 RPointerArray<CCalAttendee>& CCalEntryImpl::AttendeesL()
       
   241 	{
       
   242 	PopulateAttendeeListL();
       
   243 	return *iCalAttendeeList;
       
   244 	}
       
   245 
       
   246 void CCalEntryImpl::DeleteAttendeeL(TInt aIndex)
       
   247 	{
       
   248 	LoadFullEntryL();
       
   249 
       
   250 	if(iCalAttendeeList)
       
   251 		{
       
   252 		if (aIndex < 0 || aIndex >= iCalAttendeeList->Count())
       
   253 			{
       
   254 			User::Leave(KErrArgument);
       
   255 			}
       
   256 		delete (*iCalAttendeeList)[aIndex];
       
   257 		iCalAttendeeList->Remove(aIndex);
       
   258 		}
       
   259 
       
   260 	iFullEntry->DeleteAttendee(aIndex);
       
   261 	}
       
   262 
       
   263 void CCalEntryImpl::SetOrganizerL(CCalUser* aUser)
       
   264 	{
       
   265 	CleanupStack::PushL(aUser);
       
   266 	__ASSERT_ALWAYS(aUser != NULL, User::Leave(KErrArgument));
       
   267 	LoadFullEntryL();
       
   268 	
       
   269 	aUser->Impl()->SetOwnsCAgnAttendee(EFalse);
       
   270 	iFullEntry->SetOrganizerL(aUser->Impl()->Attendee());	//	takes ownership of user immediately
       
   271 
       
   272 	delete iCalOrganizer;
       
   273 	iCalOrganizer = aUser;
       
   274 	CleanupStack::Pop(aUser);
       
   275 	}
       
   276 
       
   277 void CCalEntryImpl::SetPhoneOwnerL(const CCalUser* aOwner)
       
   278 	{
       
   279 	__ASSERT_ALWAYS(aOwner != NULL, User::Leave(KErrArgument));
       
   280 	LoadFullEntryL();
       
   281 	CCalUserImpl* userImpl = aOwner->Impl();
       
   282 	iFullEntry->SetPhoneOwnerL(userImpl->Attendee());
       
   283 	}
       
   284 
       
   285 CCalUser* CCalEntryImpl::PhoneOwnerL()
       
   286 	{
       
   287 	LoadFullEntryL();
       
   288 
       
   289 	CAgnAttendee* agnPhoneOwner = iFullEntry->PhoneOwner();
       
   290 
       
   291 	if(agnPhoneOwner)
       
   292 		{	
       
   293 		//check to see if phone owner is the organizer
       
   294 		if(OrganizerL())
       
   295 			{
       
   296 			if(agnPhoneOwner == iCalOrganizer->Impl()->Attendee())
       
   297 				{
       
   298 				return iCalOrganizer;
       
   299 				}
       
   300 			}
       
   301 
       
   302 		PopulateAttendeeListL();
       
   303 		
       
   304 		// see if the phone owner is one of the other attendees
       
   305 		const TInt KAttendeeCount = iCalAttendeeList->Count();
       
   306 		for(TInt i = 0; i < KAttendeeCount; ++i)
       
   307 			{
       
   308 			CCalAttendee* calAttendee = (*iCalAttendeeList)[i];
       
   309 			if(agnPhoneOwner == calAttendee->Impl()->Attendee())
       
   310 				{
       
   311 				return calAttendee;
       
   312 				}
       
   313 			}
       
   314 		}
       
   315 	return NULL;
       
   316 	}
       
   317 
       
   318 
       
   319 CCalUser* CCalEntryImpl::OrganizerL()
       
   320 	{
       
   321 	LoadFullEntryL();
       
   322 	if( ! iCalOrganizer)
       
   323 		{
       
   324 		CAgnAttendee* organizer = iFullEntry->Organizer();
       
   325 		
       
   326 		if(organizer)
       
   327 			{
       
   328 			CCalUserImpl* impl = CCalUserImpl::NewL(organizer);
       
   329 			CleanupStack::PushL(impl);
       
   330 			impl->SetOwnsCAgnAttendee(EFalse);
       
   331 			iCalOrganizer = CCalUser::NewL(impl);
       
   332 			CleanupStack::Pop(impl);
       
   333 			}
       
   334 		}
       
   335 
       
   336 	return iCalOrganizer;
       
   337 	}
       
   338 
       
   339 CTzRules* CCalEntryImpl::GetTzRulesL()
       
   340 	{
       
   341 	CAgnRptDef* rptDef = SimpleEntry()->RptDef();
       
   342 	
       
   343 	if (rptDef == NULL)
       
   344 		{
       
   345 		return NULL;
       
   346 		}
       
   347 	return rptDef->CloneTzRulesL();
       
   348 	}
       
   349 
       
   350 void CCalEntryImpl::SetTzRulesL(const CTzRules& aTzRules)
       
   351 	{
       
   352 	LoadFullEntryL();
       
   353 	
       
   354 	if (TimeMode() == MAgnCalendarTimeMode::EFloating)
       
   355 		{
       
   356 		User::Leave(KErrArgument);
       
   357 		}
       
   358 
       
   359 	CAgnRptDef* rptDef = SimpleEntry()->RptDef(); // doesn't take ownership
       
   360 	
       
   361 	if (!rptDef)
       
   362 		{
       
   363 		User::Leave(KErrNotFound);
       
   364 		}
       
   365    
       
   366 	rptDef->SetTimeZoneL(aTzRules); // rptDef doesn't take ownership of aTzRules
       
   367 	}
       
   368 
       
   369 void CCalEntryImpl::SetTzRulesL()
       
   370 	{
       
   371 	LoadFullEntryL();
       
   372 	
       
   373 	if (TimeMode() == MAgnCalendarTimeMode::EFloating)
       
   374 		{
       
   375 		User::Leave(KErrArgument);
       
   376 		}
       
   377 
       
   378 	CAgnRptDef* rptDef = SimpleEntry()->RptDef();
       
   379 	if (rptDef == NULL)
       
   380 		{
       
   381 		User::Leave(KErrNotFound);
       
   382 		}
       
   383 	rptDef->SetTimeZoneL();
       
   384 	}
       
   385 
       
   386 void CCalEntryImpl::SetRDatesL(const RArray<TCalTime>& aRDates)
       
   387 	{
       
   388 	LoadFullEntryL();
       
   389 	SetDatesL(ETrue, aRDates);
       
   390 	}
       
   391 
       
   392 void CCalEntryImpl::SetExceptionDatesL(const RArray<TCalTime>& aExDates)
       
   393 	{
       
   394 	LoadFullEntryL();
       
   395 	
       
   396 	if (iFullEntry->RptDef() == NULL)
       
   397 		{
       
   398 		User::Leave(KErrNotFound);
       
   399 		}
       
   400 
       
   401 	SetDatesL(EFalse, aExDates);
       
   402 	}
       
   403 	
       
   404 //if aDateType is ETrue, add dates to sporadic date list
       
   405 //if aDateType is EFalse, add dates to exception list
       
   406 void CCalEntryImpl::SetDatesL(TBool aDateType, const RArray<TCalTime>& aDates)
       
   407 	{
       
   408 	const TCalTime::TTimeMode KEntryTimeMode = static_cast<TCalTime::TTimeMode>(TimeMode());
       
   409 	const TInt KDateCount = aDates.Count();
       
   410 	TInt i = 0;
       
   411 	for (i = 0; i < KDateCount; i++)
       
   412 		{
       
   413 		if (aDates[i].TimeMode() != KEntryTimeMode)
       
   414 			{
       
   415 			User::Leave(KErrArgument);
       
   416 			}
       
   417 		}
       
   418 
       
   419 	CAgnRptDef* rptDef = SimpleEntry()->RptDef();
       
   420 
       
   421 	TBool entryHasNoRptDef(rptDef == NULL);
       
   422 	if (entryHasNoRptDef)
       
   423 		{
       
   424 		rptDef = CAgnRptDef::NewL(*SimpleEntry());
       
   425 		CleanupStack::PushL(rptDef);
       
   426 		}
       
   427 	else
       
   428 		{
       
   429 		if (aDateType)
       
   430 			{
       
   431 			rptDef->RemoveAllSporadicDates();
       
   432 			}
       
   433 		else
       
   434 			{
       
   435 			rptDef->RemoveAllExceptions();
       
   436 			}
       
   437 		}
       
   438 
       
   439 	// store the dates
       
   440 	for (i = 0; i < KDateCount; ++i)
       
   441 		{
       
   442 		TAgnCalendarTime agnTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aDates[i]);
       
   443 		if (aDateType)
       
   444 			{
       
   445 			rptDef->AddSporadicDateL(agnTime);
       
   446 			}
       
   447 		else
       
   448 			{
       
   449 			rptDef->AddExceptionL(agnTime);
       
   450 			}
       
   451 		}
       
   452 
       
   453 	// if the rptDef didn't exist in the entry already, add it
       
   454 	if (entryHasNoRptDef)
       
   455 		{
       
   456 		iFullEntry->SetRptDefL(*rptDef); // makes a copy of rptDef
       
   457 		CleanupStack::PopAndDestroy(rptDef);
       
   458 		}
       
   459 	}
       
   460 
       
   461 void CCalEntryImpl::GetRDatesL(RArray<TCalTime>& aRDates)
       
   462 	{
       
   463 	aRDates.Reset();
       
   464 	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
       
   465 	if (KRptDef)
       
   466 		{
       
   467 		FetchDatesL(KRptDef->SporadicDateList(), aRDates);
       
   468 		}
       
   469 	}
       
   470 
       
   471 void CCalEntryImpl::GetExceptionDatesL(RArray<TCalTime>& aExDates)
       
   472 	{
       
   473 	aExDates.Reset();
       
   474 	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
       
   475 	if (KRptDef)
       
   476 		{
       
   477 		FetchDatesL(KRptDef->Exceptions(), aExDates);
       
   478 		}
       
   479 	}
       
   480 	
       
   481 void CCalEntryImpl::FetchDatesL(const RArray<TAgnCalendarTime>* aDateList, RArray<TCalTime>& aRDates)
       
   482 	{
       
   483 	// aDateList may be NULL
       
   484 	if (aDateList)
       
   485 		{
       
   486 		const TInt KDateCount = aDateList->Count();
       
   487 		for (TInt i = 0; i < KDateCount; ++i)
       
   488 			{
       
   489 			TCalTime calTime = CalUtils::TAgnCalendarTimeToTCalTimeL((*aDateList)[i]);
       
   490 			aRDates.AppendL(calTime);
       
   491 			}
       
   492 		}
       
   493 	}
       
   494 
       
   495 CCalEntry::TMethod CCalEntryImpl::MethodL()
       
   496 	{
       
   497 	LoadFullEntryL();
       
   498 	return iFullEntry->Method();
       
   499 	}
       
   500 	
       
   501 TCalTime CCalEntryImpl::RecurrenceIdL()
       
   502 	{
       
   503 	// If this entry has been committed to store, the Rec-Id can be retrieved from the
       
   504 	// CAgnEntryModel by passing the appropraite CAgnEntry.
       
   505 	// Else try to retrieve it from CAgnEntry's temporary GS data.
       
   506 
       
   507 	LoadFullEntryL();
       
   508 	return CalUtils::TAgnCalendarTimeToTCalTimeL(iFullEntry->RecurrenceId());
       
   509 	}
       
   510 	
       
   511 CalCommon::TRecurrenceRange CCalEntryImpl::RecurrenceRangeL()
       
   512    	{
       
   513    	LoadFullEntryL();
       
   514 	return iFullEntry->RecurrenceRange();
       
   515    	}
       
   516 	
       
   517 const TDesC8& CCalEntryImpl::UidL()
       
   518 	{
       
   519 	LoadFullEntryL();
       
   520 	// Does not transfer ownership
       
   521 	if(iFullEntry->Guid() == KNullDesC8)
       
   522 		{
       
   523 		// this entry must be a child entry whose GUID has not been loaded
       
   524 		__ASSERT_ALWAYS(iFullEntry->GsDataType() == CGsData::EChild, User::Leave(KErrCorrupt)); 
       
   525 		
       
   526 		// get parent entry
       
   527 		TCalLocalUid parentId = iFullEntry->ParentId();
       
   528 		CAgnEntry* parentEntry = iSessionImpl->Server().FetchEntryL(parentId, iSessionImpl->FileId());
       
   529 		__ASSERT_ALWAYS(parentEntry, User::Leave(KErrNotFound));
       
   530 		CleanupStack::PushL(parentEntry);
       
   531 		HBufC8* guidHbuf = parentEntry->Guid().AllocL();
       
   532 		CleanupStack::PopAndDestroy(parentEntry);	
       
   533 
       
   534 		iFullEntry->SetGuid(guidHbuf);
       
   535 		}
       
   536 		
       
   537 	return iFullEntry->Guid();
       
   538 	}
       
   539 
       
   540 
       
   541 TInt CCalEntryImpl::SequenceNumberL()
       
   542 	{
       
   543 	LoadFullEntryL();
       
   544 	return iFullEntry->SequenceNumber();
       
   545 	}
       
   546 
       
   547 
       
   548 void CCalEntryImpl::SetMethodL(CCalEntry::TMethod aMethod)
       
   549 	{
       
   550 	LoadFullEntryL();
       
   551 	iFullEntry->SetMethod(aMethod);
       
   552 	}
       
   553 
       
   554 const RPointerArray<CCalCategory>& CCalEntryImpl::CategoryListL()
       
   555 	{
       
   556 	PopulateCategoryListL();
       
   557 
       
   558 	return *iCalCategoryList;
       
   559 	}
       
   560 
       
   561 void CCalEntryImpl::AddCategoryL(CCalCategory* aCategory)
       
   562 	{
       
   563 	CleanupStack::PushL(aCategory);
       
   564 	__ASSERT_ALWAYS(aCategory != NULL, User::Leave(KErrArgument));
       
   565 	
       
   566  	PopulateCategoryListL();
       
   567 
       
   568 	// add the category to the list
       
   569  	iCalCategoryList->AppendL(aCategory);
       
   570 	CleanupStack::Pop(aCategory);
       
   571 
       
   572 	TInt err(KErrNone);
       
   573 
       
   574 	// add category to CAgnEntry
       
   575 	TRAP(err , iFullEntry->AddCategoryL( aCategory->Impl()->AgnCategory() ) ); // this can leave before taking ownership
       
   576 
       
   577  	if (err != KErrNone)
       
   578  		{
       
   579  		delete (*iCalCategoryList)[iCalCategoryList->Count() - 1];
       
   580  		iCalCategoryList->Remove(iCalCategoryList->Count() - 1);
       
   581  		User::Leave(err);
       
   582  		}
       
   583 
       
   584  	aCategory->Impl()->SetOwnAgnCategory(EFalse);
       
   585 	}
       
   586 
       
   587 void CCalEntryImpl::DeleteCategoryL(TInt aIndex)
       
   588 	{
       
   589 	LoadFullEntryL();
       
   590 	
       
   591 	if (aIndex < 0 || aIndex >= iFullEntry->CategoryCount())
       
   592 		{
       
   593 		User::Leave(KErrArgument);
       
   594 		}
       
   595 			
       
   596 	iFullEntry->DeleteCategory(aIndex);
       
   597 	if(iCalCategoryList)
       
   598 		{
       
   599 		delete (*iCalCategoryList)[aIndex];
       
   600 		iCalCategoryList->Remove(aIndex);
       
   601 		
       
   602 		// check count of CAgnCategory and CCalCategory is the same
       
   603 		__ASSERT_DEBUG(iCalCategoryList->Count() == iFullEntry->CategoryCount(), Panic(EAgmErrCategoryCountCorrupt)); 
       
   604 		}
       
   605 	}
       
   606 
       
   607 TBool CCalEntryImpl::GetRRuleL(TCalRRule& aRule)
       
   608 	{
       
   609 	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
       
   610 	if (KRptDef == NULL || KRptDef->RRule() == NULL)
       
   611 		{
       
   612 		return EFalse;
       
   613 		}
       
   614 
       
   615 	const TAgnRpt* KRpt = KRptDef->RRule();
       
   616 
       
   617 	// get the DTSTART property
       
   618 	if (SimpleEntry()->Type() == CCalEntry::ETodo)
       
   619 		{
       
   620 		aRule.SetDtStart(EndTimeL());
       
   621 		}
       
   622 	else
       
   623 		{
       
   624 		aRule.SetDtStart(StartTimeL());
       
   625 		}
       
   626 
       
   627 	TInt repCount = 0;
       
   628 	TCalTime untilCaltime = CalUtils::TAgnCalendarTimeToTCalTimeL(KRpt->UntilTimeL());
       
   629 		
       
   630 	if (untilCaltime.TimeLocalL() == TCalTime::MaxTime())
       
   631 		{
       
   632 		//Idealy, only UTC maximum time should be used to indicate the repeating forever. However, for a behaviour compatible reason,
       
   633 		//when the client sets local or UTC repeating until time to be maximum time, it is treated as repeating forever. 
       
   634 		untilCaltime.SetTimeUtcL(TCalTime::MaxTime());
       
   635 		}
       
   636 	else
       
   637 		{
       
   638 		repCount = KRpt->InstanceCountL();
       
   639 		}
       
   640 
       
   641 	aRule.SetUntilAndCount(untilCaltime, repCount);	
       
   642 	
       
   643 	// get the INTERVAL property
       
   644 	aRule.SetInterval(KRpt->Interval());
       
   645 
       
   646 	// get the TCalRRule's type, and type-specific data
       
   647 	switch (KRpt->Type())
       
   648 		{
       
   649 		case TAgnRpt::EDaily:
       
   650 			aRule.SetType(TCalRRule::EDaily);
       
   651 			break;
       
   652 		case TAgnRpt::EYearlyByDate:
       
   653 			aRule.SetType(TCalRRule::EYearly);
       
   654 			break;
       
   655 		case TAgnRpt::EYearlyByDay:
       
   656 			{
       
   657 			aRule.SetType(TCalRRule::EYearly);
       
   658 
       
   659 			TDay day;
       
   660 			TAgnRpt::TWeekInMonth weekInMonth;
       
   661 			TMonth month;
       
   662 			TInt year;
       
   663 
       
   664 			const TAgnYearlyByDayRpt* KYearlyRpt = static_cast<const TAgnYearlyByDayRpt*>(KRpt);
       
   665 			KYearlyRpt->GetStartDayL(day, weekInMonth, month, year);
       
   666 			TInt8 week = CalUtils::AgnWeekInMonthToWeekNumberL(weekInMonth);
       
   667 			TCalRRule::TDayOfMonth dayOfMonth(day, week);
       
   668 
       
   669 			RArray<TCalRRule::TDayOfMonth> dayOfMonthArray;
       
   670 			CleanupClosePushL(dayOfMonthArray);
       
   671 			dayOfMonthArray.AppendL(dayOfMonth);
       
   672 			aRule.SetByDay(dayOfMonthArray);
       
   673 			CleanupStack::PopAndDestroy(&dayOfMonthArray);
       
   674 
       
   675 			RArray<TMonth> monthArray;
       
   676 			CleanupClosePushL(monthArray);
       
   677 			monthArray.AppendL(month);
       
   678 			aRule.SetByMonth(monthArray);
       
   679 			CleanupStack::PopAndDestroy(&monthArray);
       
   680 			}
       
   681 			break;
       
   682 		case TAgnRpt::EWeekly:
       
   683 			{
       
   684 			aRule.SetType(TCalRRule::EWeekly);
       
   685 			const TAgnWeeklyRpt* KWeeklyRpt = static_cast<const TAgnWeeklyRpt*>(KRpt);
       
   686 			aRule.SetWkSt(KWeeklyRpt->FirstDayOfWeek());
       
   687 
       
   688 			RArray<TDay> array;
       
   689 			CleanupClosePushL(array);
       
   690 			TDay day = EMonday;
       
   691 			while (day <= ESunday)
       
   692 				{
       
   693 				if (KWeeklyRpt->IsDaySet(day))
       
   694 					{
       
   695 					array.AppendL(day);
       
   696 					}
       
   697 				day = static_cast<TDay>(static_cast<TInt>(day) + 1);
       
   698 				}
       
   699 			aRule.SetByDay(array);
       
   700 			CleanupStack::PopAndDestroy(&array);
       
   701 			}
       
   702 			break;
       
   703 		case TAgnRpt::EMonthlyByDays:
       
   704 			{
       
   705 			aRule.SetType(TCalRRule::EMonthly);
       
   706 			const TAgnMonthlyByDaysRpt* KMonthlyByDayRpt = static_cast<const TAgnMonthlyByDaysRpt*>(KRpt);
       
   707 
       
   708 			RArray<TCalRRule::TDayOfMonth> dayArray;
       
   709 			CleanupClosePushL(dayArray);
       
   710 			
       
   711 			TAgnRpt::TWeekInMonth week = TAgnRpt::EFirst;
       
   712 			while (week <= TAgnRpt::ELast)
       
   713 				{
       
   714 				TDay day = EMonday;
       
   715 				while (day <= ESunday)
       
   716 					{
       
   717 					if (KMonthlyByDayRpt->IsDaySet(day, week))
       
   718 						{
       
   719 						TInt8 weekInt = CalUtils::AgnWeekInMonthToWeekNumberL(week);
       
   720 						TCalRRule::TDayOfMonth dayOfMonth(day, weekInt);
       
   721 						dayArray.AppendL(dayOfMonth);
       
   722 						}
       
   723 					day = static_cast<TDay>(static_cast<TInt>(day) + 1);
       
   724 					}
       
   725 			
       
   726 				week = static_cast<TAgnRpt::TWeekInMonth>(static_cast<TInt>(week) + 1);
       
   727 				}
       
   728 			//coverity [dead_error_begin]
       
   729 			aRule.SetByDay(dayArray);
       
   730 
       
   731 			CleanupStack::PopAndDestroy(&dayArray); // dayArray.Close()
       
   732 			}
       
   733 			break;
       
   734 		case TAgnRpt::EMonthlyByDates:
       
   735 			{
       
   736 			aRule.SetType(TCalRRule::EMonthly);
       
   737 			const TAgnMonthlyByDatesRpt* KMonthlyByDateRpt = static_cast<const TAgnMonthlyByDatesRpt*>(KRpt);
       
   738 
       
   739 			RArray<TInt> array;
       
   740 			CleanupClosePushL(array);
       
   741 			for (TInt i = 0; i < 31; ++i) // dates run from 0 to 30
       
   742 				{
       
   743 				if (KMonthlyByDateRpt->IsDateSet(i))
       
   744 					{
       
   745 					array.AppendL(i);
       
   746 					}
       
   747 				}
       
   748 			aRule.SetByMonthDay(array);
       
   749 			CleanupStack::PopAndDestroy(&array);
       
   750 			}
       
   751 			break;
       
   752 		default:
       
   753 			CalUtils::Panic(EInvalidRepeatRuleType);
       
   754 			break;
       
   755 		}
       
   756 
       
   757 	return ETrue;
       
   758 	}
       
   759 
       
   760 TBool CCalEntryImpl::CompareL(const CCalEntry& aEntry)
       
   761 	{
       
   762 	// load full CAgnEntries before comparison
       
   763 	LoadFullEntryL();
       
   764 	aEntry.Impl()->LoadFullEntryL();
       
   765 	
       
   766 	// Load both entry's summary, description and alarm action data before comparing - these properties
       
   767 	// are stored in separate streams so may not be loaded at this point
       
   768 	SummaryL();
       
   769 	aEntry.SummaryL();
       
   770 	DescriptionL();
       
   771 	aEntry.DescriptionL();
       
   772 	delete AlarmL();
       
   773 	delete aEntry.AlarmL();
       
   774 	
       
   775 	return (iFullEntry->CompareL(*aEntry.Impl()->GetFullEntryL()));
       
   776 	}
       
   777 
       
   778 void CCalEntryImpl::CopyFromL(CCalEntryImpl& aOther, CCalEntry::TCopyType aCopyType)
       
   779 	{
       
   780 	TCalCollectionId collectionId = 0;
       
   781 	if (iLiteEntry)
       
   782 		{
       
   783 		TUint8 collectionId = aOther.SimpleEntry()->CollectionId();
       
   784 		}
       
   785 	aOther.LoadFullEntryL();
       
   786 	// Delete old state.
       
   787 	ClearSimpleEntry();
       
   788 
       
   789 	if(iCalAttendeeList)
       
   790 		{
       
   791 		iCalAttendeeList->ResetAndDestroy();
       
   792 		delete iCalAttendeeList; 	
       
   793 		iCalAttendeeList = NULL;
       
   794 		}
       
   795 
       
   796 	if(iCalCategoryList)
       
   797 		{
       
   798 		iCalCategoryList->ResetAndDestroy();
       
   799 		delete iCalCategoryList; 
       
   800 		iCalCategoryList = NULL;
       
   801 		}
       
   802 
       
   803 	delete iCalOrganizer;
       
   804 	iCalOrganizer = NULL;
       
   805 
       
   806 	if(iSessionImpl)
       
   807 		{
       
   808         // Use this entry's existing uid.
       
   809 		iSessionImpl->DecrementReferenceCount();
       
   810 		}
       
   811 	iSessionImpl = aOther.iSessionImpl;
       
   812 	if (iSessionImpl)
       
   813 		{
       
   814 		iSessionImpl->IncrementReferenceCount();
       
   815 		}
       
   816 
       
   817 	// ensure other entry has a full CAgnEntry
       
   818 	aOther.LoadFullEntryL();
       
   819 	
       
   820 	// ensure other entry has summary, description and alarm action properties loaded - these
       
   821 	// are stored in separate streams
       
   822 	aOther.SummaryL();
       
   823 	aOther.DescriptionL();
       
   824 	delete aOther.AlarmL();
       
   825 	
       
   826 	iFullEntry->CopyFromL(*aOther.iFullEntry, aCopyType);
       
   827 	iFullEntry->SetLastModifiedDate();
       
   828 	iFullEntry->SetCollectionId(collectionId);
       
   829 	}
       
   830 
       
   831 void CCalEntryImpl::SetAlarmL(CCalAlarm* aAlarm)
       
   832 	{
       
   833 	LoadFullEntryL();
       
   834 	
       
   835 	if ( aAlarm == NULL ) 
       
   836 		{
       
   837 		// if aAlarm is NULL, clear the alarm data
       
   838 		iFullEntry->ClearAlarm();
       
   839 		}
       
   840 	else
       
   841 		{
       
   842 		// This method does not take ownership of aAlarm, so need to copy the alarm details
       
   843 		// before adding to the entry.
       
   844 		
       
   845 		// the alarm must be on the same day in local time as the event
       
   846 		TDateTime dt = iFullEntry->EntryTime().LocalL().DateTime();
       
   847 		TInt minutes = dt.Hour()*60 + dt.Minute();
       
   848 		__ASSERT_ALWAYS(minutes - aAlarm->TimeOffset().Int() <= KAgnMinutesInADay, User::Leave(KErrNotSupported));
       
   849 
       
   850 		iFullEntry->SetAlarmOffset(aAlarm->TimeOffset());
       
   851 	 	iFullEntry->SetAlarmSoundNameL(aAlarm->AlarmSoundNameL());
       
   852 
       
   853 		CCalContent* alarmAction = aAlarm->AlarmAction(); // doesn't take ownership
       
   854 		
       
   855 		if ( alarmAction )
       
   856 			{
       
   857 			CAgnContent* agnAlarmAction = static_cast<CAgnContent*>(alarmAction->Impl());
       
   858 			
       
   859 			if ( agnAlarmAction )
       
   860 				{
       
   861 				CAgnContent* alarmActionCopy = agnAlarmAction->CloneL();
       
   862 				iFullEntry->SetAlarmAction(alarmActionCopy); // entry takes ownership of alarmActionCopy
       
   863 				}					
       
   864 			}
       
   865 		else
       
   866 		    {
       
   867 		    iFullEntry->SetAlarmAction(NULL); 
       
   868 		    }
       
   869 		}
       
   870 	}
       
   871 
       
   872 CCalAlarm* CCalEntryImpl::AlarmL()
       
   873 	{
       
   874 	LoadFullEntryL();
       
   875 	
       
   876 	if (!iFullEntry->HasAlarm())
       
   877 		{
       
   878 		return NULL;
       
   879 		}
       
   880         
       
   881 	TTime time = iFullEntry->EntryTime().LocalL();
       
   882 	
       
   883 	// Invalid or non-existant entries are set on import to NULL time
       
   884 	// That being the case, we return NULL for the Alarm.
       
   885 	TDateTime timeOfEvent;
       
   886 	if(time == Time::NullTTime())
       
   887 		{
       
   888 		return NULL;
       
   889 		}
       
   890 	else
       
   891 		{
       
   892 		timeOfEvent = time.DateTime();
       
   893 		}
       
   894 
       
   895 	CCalAlarm* alarm = CCalAlarm::NewL();
       
   896 	CleanupStack::PushL(alarm);
       
   897 	
       
   898 	alarm->SetTimeOffset(iFullEntry->AlarmOffset().Int());
       
   899 	alarm->SetAlarmSoundNameL(iFullEntry->AlarmSoundName());
       
   900 	
       
   901 	if(!iFullEntry->AlarmActionIsLoaded())
       
   902 		{
       
   903 		CAgnContent* agnAlarmaction = iSessionImpl->Server().RestoreAlarmActionL(iFullEntry->AlarmActionStreamId(), iSessionImpl->FileId());
       
   904 		// Restore should always return something, even if it's only a Null Descriptor
       
   905 		iFullEntry->SetAlarmAction(agnAlarmaction);
       
   906 		}
       
   907 
       
   908 	if (iFullEntry->AlarmAction())
       
   909 		{
       
   910 		CCalContent* alarmAction = CCalContent::NewL();
       
   911 		CleanupStack::PushL(alarmAction);
       
   912 		CAgnContent* agnAlarmActionCopy = iFullEntry->AlarmAction()->CloneL();
       
   913 		alarmAction->SetImpl(agnAlarmActionCopy); // Takes ownership of agnAlarmAction.
       
   914 		alarm->SetAlarmAction(alarmAction); // Takes ownership of alarmAction.
       
   915 		CleanupStack::Pop(alarmAction);
       
   916 		}
       
   917 
       
   918 	CleanupStack::Pop(alarm);
       
   919 	return alarm;
       
   920 	}
       
   921 
       
   922 void CCalEntryImpl::SetCommonRptDataL(const TCalRRule& aRpt, CAgnRptDef& aRptRule)
       
   923 	{
       
   924 	// set repeat rule data which is not specific to the rule type
       
   925 	// Both repeating count and until time could be set. If so, the one come earlist will be set as repeating until time.
       
   926 	// Note that the repeating until time will be adjusted in TAgnRpt::UntilTimeL() when the entry is stored (CCalEntryViewImpl::DoStore and 
       
   927 	// CAgnSimpleEntry::AdjustStartUntilTimeForRepEntryL)By then, the TZ rule has been set to a repeating entry.
       
   928 	aRptRule.SetInterval(aRpt.Interval());
       
   929 	const_cast<TAgnRpt*> (aRptRule.RRule())->SetCount(aRpt.Count());
       
   930 
       
   931     TTime untilTime = aRpt.Until().TimeLocalL();
       
   932     if (untilTime != Time::NullTTime())
       
   933     	{
       
   934 		TAgnCalendarTime untilTimeTAgn = CalUtils::TCalTimeToTAgnCalendarTimeL(aRpt.Until());
       
   935 		aRptRule.SetUntilTime(untilTimeTAgn);
       
   936     	}
       
   937 	}
       
   938 
       
   939 void CCalEntryImpl::SetRRuleL(const TCalRRule& aRpt)
       
   940 	{
       
   941 	if (aRpt.Until().TimeLocalL() != Time::NullTTime() && aRpt.DtStart().TimeLocalL() >= aRpt.Until().TimeLocalL())
       
   942 		{
       
   943 		// if Until time is set to earlier than the start time and is non-NULL, leave
       
   944 		User::Leave(KErrArgument);
       
   945 		}
       
   946 	LoadFullEntryL();
       
   947 
       
   948 	//Leaves if this is a todo entry and its end date has not been set or this is a non-todo entry and its start date has not been set
       
   949 	//since repeating pattern is based on those time attributes.
       
   950 	if ( ! iFullEntry->EntryTime().IsSet())
       
   951 		{
       
   952 		User::Leave(KErrArgument);
       
   953 		}
       
   954 
       
   955 	TBool createdNewRptDef = EFalse;
       
   956 	CAgnRptDef* rptDef = iFullEntry->RptDef();
       
   957 	if(rptDef == NULL)
       
   958 		{
       
   959 		rptDef = CAgnRptDef::NewL(*iFullEntry);
       
   960 		CleanupStack::PushL(rptDef);
       
   961 		createdNewRptDef = ETrue;
       
   962 		}
       
   963 
       
   964 	switch (aRpt.Type())
       
   965 		{
       
   966 		case TCalRRule::EDaily:
       
   967 			{
       
   968 			TAgnDailyRpt daily(*rptDef);
       
   969 			rptDef->SetRRuleL(daily);
       
   970 			}
       
   971 			break;
       
   972 		case TCalRRule::EWeekly:
       
   973 			{
       
   974 			TAgnWeeklyRpt weekly(*rptDef);
       
   975 			weekly.SetFirstDayOfWeek(aRpt.WkSt());
       
   976 			RArray<TDay> array;
       
   977 			CleanupClosePushL(array);
       
   978 			aRpt.GetByDayL(array);
       
   979 			const TInt KWeeklyDayCount = array.Count();
       
   980 			for (TInt i = 0; i < KWeeklyDayCount; ++i)
       
   981 				{
       
   982 				weekly.SetDay(array[i]);
       
   983 				}
       
   984 			CleanupStack::PopAndDestroy(&array);
       
   985 			
       
   986 			rptDef->SetRRuleL(weekly);
       
   987 			}
       
   988 			break;
       
   989 		case TCalRRule::EMonthly:
       
   990 			{
       
   991 			RArray<TInt> array;
       
   992 			CleanupClosePushL(array);
       
   993 			aRpt.GetByMonthDayL(array);
       
   994 			if (array.Count() <= 0)
       
   995 				{
       
   996 				// may be monthly by week
       
   997 				RArray<TCalRRule::TDayOfMonth> dayArray;
       
   998 				CleanupClosePushL(dayArray);
       
   999 				aRpt.GetByDayL(dayArray);
       
  1000 				const TInt KMonthlyDayCount = dayArray.Count();
       
  1001 				if (KMonthlyDayCount > 0)
       
  1002 					{
       
  1003 					TAgnMonthlyByDaysRpt monthlyByDayAndWeek(*rptDef);
       
  1004 					for (TInt i = 0; i < KMonthlyDayCount; ++i)
       
  1005 						{
       
  1006 						TCalRRule::TDayOfMonth dayOfMonth = dayArray[i];
       
  1007 						TAgnRpt::TWeekInMonth weekNum = CalUtils::WeekNumberToAgnWeekInMonthL(dayOfMonth.WeekInMonth());
       
  1008 						monthlyByDayAndWeek.SetDay(dayOfMonth.Day(), weekNum);
       
  1009 						}
       
  1010 					
       
  1011 					rptDef->SetRRuleL(monthlyByDayAndWeek);
       
  1012 					}
       
  1013 				CleanupStack::PopAndDestroy(&dayArray); // dayArray.Close()
       
  1014 				}
       
  1015 			else
       
  1016 				{
       
  1017 				TAgnMonthlyByDatesRpt monthlyByDate(*rptDef);
       
  1018 				const TInt KMonthlyDateCount = array.Count();
       
  1019 				for (TInt i = 0; i < KMonthlyDateCount; ++i)
       
  1020 					{
       
  1021 					monthlyByDate.SetDate(array[i]);
       
  1022 					}
       
  1023 				
       
  1024 				rptDef->SetRRuleL(monthlyByDate);
       
  1025 				}
       
  1026 			CleanupStack::PopAndDestroy(&array); // array.Reset();
       
  1027 			}
       
  1028 			break;
       
  1029 		case TCalRRule::EYearly:
       
  1030 			{
       
  1031 			RArray<TCalRRule::TDayOfMonth> dayArray;
       
  1032 			CleanupClosePushL(dayArray);
       
  1033 			aRpt.GetByDayL(dayArray);
       
  1034 			if (dayArray.Count() > 0)
       
  1035 				{
       
  1036 				RArray<TMonth> monthArray;
       
  1037 				CleanupClosePushL(monthArray);
       
  1038 				aRpt.GetByMonthL(monthArray);
       
  1039 				if (monthArray.Count() > 0)
       
  1040 					{
       
  1041 					TDay day = dayArray[0].Day();
       
  1042 					TAgnRpt::TWeekInMonth week = CalUtils::WeekNumberToAgnWeekInMonthL(dayArray[0].WeekInMonth());
       
  1043 					TMonth month = monthArray[0];
       
  1044 
       
  1045 					TAgnYearlyByDayRpt yearlyByDay(*rptDef);
       
  1046 
       
  1047 					// Check that the first month to repeat on is earlier than the repeat dtstart date...
       
  1048 					TDateTime rptStartTime = aRpt.DtStart().TimeUtcL().DateTime();
       
  1049 					TInt year = rptStartTime.Year();
       
  1050 					if (month < rptStartTime.Month())
       
  1051 						{
       
  1052 						// ...if not, start the following year
       
  1053 						year++;
       
  1054 						}
       
  1055 						
       
  1056 					TTime newStartDay = yearlyByDay.FindStartDayL(day, week, month, year);
       
  1057 					TCalTime newStartDaycal;
       
  1058 					newStartDaycal.SetTimeLocalL(newStartDay);
       
  1059 					const_cast<TCalRRule&>(aRpt).SetDtStart(newStartDaycal);
       
  1060 					TTime untilTimeLocal = yearlyByDay.UntilTimeL().LocalL();
       
  1061 					TDateTime rptUntilTime = untilTimeLocal.DateTime();
       
  1062 					if (aRpt.Count() != 0 || year < rptUntilTime.Year() ||
       
  1063 						(year == rptUntilTime.Year() && month < rptUntilTime.Month())
       
  1064 						)
       
  1065 						{
       
  1066                         // The count has been set
       
  1067                         // or the first month to repeat on is not later than the repeat until date
       
  1068 						rptDef->SetRRuleL(yearlyByDay);
       
  1069 						}
       
  1070 					}
       
  1071 				else
       
  1072 					{
       
  1073 					User::Leave(KErrArgument);	
       
  1074 					}	
       
  1075 				CleanupStack::PopAndDestroy(&monthArray);
       
  1076 				}
       
  1077 			else
       
  1078 				{
       
  1079 				TAgnYearlyByDateRpt yearlyByDate(*rptDef);
       
  1080 				rptDef->SetRRuleL(yearlyByDate);
       
  1081 				}
       
  1082 			CleanupStack::PopAndDestroy(&dayArray);
       
  1083 			}
       
  1084 			break;
       
  1085 		default:
       
  1086 			User::Leave(KErrNotSupported);
       
  1087 			break;
       
  1088 		}
       
  1089 	
       
  1090 	if (rptDef->RRule())
       
  1091 		{
       
  1092 		SetCommonRptDataL(aRpt, *rptDef);
       
  1093 		}
       
  1094 	
       
  1095 	if (createdNewRptDef)
       
  1096 		{
       
  1097 		if (rptDef->RRule())
       
  1098 			{
       
  1099 			iFullEntry->SetRptDefL(*rptDef);
       
  1100 			}
       
  1101 		CleanupStack::PopAndDestroy(rptDef);
       
  1102 		}
       
  1103 	
       
  1104 	//Move the entry start date is same as repeating date
       
  1105 	
       
  1106 	TDateTime newEntryDateTime;
       
  1107 	if(EntryTypeL() == CCalEntry::ETodo)
       
  1108 		{
       
  1109 		newEntryDateTime = EndTimeL().TimeLocalL().DateTime();	
       
  1110 		}
       
  1111 	else
       
  1112 		{
       
  1113 		newEntryDateTime = StartTimeL().TimeLocalL().DateTime();		
       
  1114 		}
       
  1115 
       
  1116 	newEntryDateTime.SetYear(aRpt.DtStart().TimeLocalL().DateTime().Year());
       
  1117 	newEntryDateTime.SetMonth(aRpt.DtStart().TimeLocalL().DateTime().Month());
       
  1118 	newEntryDateTime.SetDay(aRpt.DtStart().TimeLocalL().DateTime().Day());
       
  1119 	
       
  1120 	//adjust the entrytime (it the entry start time for non-todos and end time for todos) 
       
  1121 	iFullEntry->MoveStartTimeLocalL(newEntryDateTime);
       
  1122 	}
       
  1123 
       
  1124 void CCalEntryImpl::ClearRepeatingPropertiesL()
       
  1125 	{
       
  1126 	SimpleEntry()->ClearRepeat();
       
  1127 	}
       
  1128 
       
  1129 TCalTime CCalEntryImpl::NextInstanceForLocalUIDL(const TCalTime& aTime)
       
  1130 	{
       
  1131 	const TTime KTimeUtc = aTime.TimeUtcL() + TTimeIntervalMicroSeconds(1);
       
  1132 	TTime nextTimeUtc = Time::NullTTime();
       
  1133 	
       
  1134 	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
       
  1135 	if (KRptDef)
       
  1136 		{
       
  1137 		if (KRptDef->NudgeNextInstanceUtcL(KTimeUtc, nextTimeUtc) == EFalse)
       
  1138 			{
       
  1139 			nextTimeUtc = Time::NullTTime();
       
  1140 			}
       
  1141 		}
       
  1142 	else
       
  1143 		{
       
  1144 		TTime entryTimeUtc = SimpleEntry()->EntryTime().UtcL();
       
  1145 		if (KTimeUtc < entryTimeUtc)
       
  1146 			{
       
  1147 			nextTimeUtc = entryTimeUtc;
       
  1148 			}
       
  1149 		}
       
  1150 	
       
  1151 	TCalTime calTime;
       
  1152 	calTime.SetTimeUtcL(nextTimeUtc);
       
  1153 	return calTime;
       
  1154 	}
       
  1155 
       
  1156 TCalTime CCalEntryImpl::PreviousInstanceForLocalUIDL(const TCalTime& aTime)
       
  1157 	{
       
  1158 	const TTime KTimeUtc = aTime.TimeUtcL() - TTimeIntervalMicroSeconds(1);
       
  1159 	TTime prevTimeUtc = Time::NullTTime();
       
  1160 	
       
  1161 	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
       
  1162 	if (KRptDef)
       
  1163 		{
       
  1164 		if (KRptDef->NudgePreviousInstanceUtcL(KTimeUtc, prevTimeUtc) == EFalse)
       
  1165 			{
       
  1166 			prevTimeUtc = Time::NullTTime();
       
  1167 			}
       
  1168 		}
       
  1169 	else
       
  1170 		{
       
  1171 		TTime entryTimeUtc = SimpleEntry()->EntryTime().UtcL();
       
  1172 		if (KTimeUtc > entryTimeUtc)
       
  1173 			{
       
  1174 			prevTimeUtc = entryTimeUtc;
       
  1175 			}
       
  1176 		}
       
  1177 	
       
  1178 	TCalTime calTime;
       
  1179 	calTime.SetTimeUtcL(prevTimeUtc);
       
  1180 	return calTime;
       
  1181 	}
       
  1182 	
       
  1183 TCalTime CCalEntryImpl::LastModifiedDateL()
       
  1184 	{
       
  1185 	TTime lastModifiedEntry = SimpleEntry()->LastModifiedDateUtc();
       
  1186 	if(iSessionImpl && SimpleEntry()->RptDef() && SimpleEntry()->TimeMode()!= MAgnCalendarTimeMode::EFloating)
       
  1187 		{
       
  1188 		TTime lastModifiedTzChange = iSessionImpl->TzRulesLastModifiedDateL();
       
  1189 		if(lastModifiedTzChange>lastModifiedEntry)
       
  1190 			{
       
  1191 			lastModifiedEntry = lastModifiedTzChange;
       
  1192 			}
       
  1193 		}
       
  1194 	TCalTime lastModifiedTime;
       
  1195 	lastModifiedTime.SetTimeUtcL(lastModifiedEntry);
       
  1196 	return lastModifiedTime;
       
  1197 	}
       
  1198 
       
  1199 TCalTime CCalEntryImpl::DTStampL()
       
  1200 	{
       
  1201 	LoadFullEntryL();
       
  1202 	TCalTime dTStampTime;
       
  1203 	dTStampTime.SetTimeUtcL(iFullEntry->DTStampUtcL());
       
  1204 	return dTStampTime;
       
  1205 	}
       
  1206 
       
  1207 void CCalEntryImpl::SetLocationL(const TDesC& aLocation)
       
  1208 	{
       
  1209 	LoadFullEntryL();
       
  1210 	iFullEntry->SetLocationL(aLocation);
       
  1211 	}
       
  1212 
       
  1213 const TDesC& CCalEntryImpl::LocationL()
       
  1214 	{
       
  1215 	LoadFullEntryL();
       
  1216 	return iFullEntry->Location();
       
  1217 	}
       
  1218 
       
  1219 void CCalEntryImpl::SetPriorityL(TUint aPriority)
       
  1220 	{
       
  1221 	LoadFullEntryL();
       
  1222 	iFullEntry->SetPriority(aPriority);
       
  1223 	}
       
  1224 
       
  1225 TUint CCalEntryImpl::PriorityL()
       
  1226 	{
       
  1227 	return SimpleEntry()->Priority();
       
  1228 	}
       
  1229 
       
  1230 TCalTime CCalEntryImpl::StartTimeL()
       
  1231 	{
       
  1232 	return CalUtils::TAgnCalendarTimeToTCalTimeL(SimpleEntry()->StartTime());
       
  1233 	}
       
  1234 
       
  1235 TCalTime CCalEntryImpl::EndTimeL()
       
  1236 	{
       
  1237 	TCalTime calEndTime; // initialised to Null time on construction
       
  1238 	if (SimpleEntry()->Type() != CCalEntry::EReminder)
       
  1239 		{
       
  1240 		calEndTime = CalUtils::TAgnCalendarTimeToTCalTimeL(SimpleEntry()->EndTime());
       
  1241 		}
       
  1242 	return calEndTime;
       
  1243 	}
       
  1244 
       
  1245 void CCalEntryImpl::SetStartAndEndTimeL(const TCalTime& aStartTime, const TCalTime& aEndTime)
       
  1246 	{
       
  1247 	LoadFullEntryL();
       
  1248 	TCalTime::TTimeMode mode = aStartTime.TimeMode();
       
  1249 	if (aEndTime.TimeUtcL() != Time::NullTTime())
       
  1250 		{
       
  1251 		if (aStartTime.TimeUtcL() != Time::NullTTime())
       
  1252 			{
       
  1253 			// both times are non-null so check the modes
       
  1254 			__ASSERT_ALWAYS(aStartTime.TimeMode() == aEndTime.TimeMode(), User::Leave(KErrArgument));
       
  1255 
       
  1256 			// both times are non-null so check that end time is not earlier than start time
       
  1257 			__ASSERT_ALWAYS(aStartTime.TimeUtcL() <= aEndTime.TimeUtcL(), User::Leave(KErrArgument));
       
  1258 			}
       
  1259 		else
       
  1260 			{
       
  1261 			// start time non-null so fetch mode from end time
       
  1262 			mode = aEndTime.TimeMode();
       
  1263 			}
       
  1264 		}
       
  1265 	__ASSERT_ALWAYS(mode == TCalTime::EFixedUtc || mode == TCalTime::EFloating, User::Leave(KErrArgument));
       
  1266 
       
  1267 	// either this is a parent entry, or time mode should match recurrence ID
       
  1268 	__ASSERT_ALWAYS(RecurrenceIdL().TimeUtcL() == Time::NullTTime() ||
       
  1269 					mode == RecurrenceIdL().TimeMode(),
       
  1270 					User::Leave(KErrArgument));		
       
  1271 
       
  1272 	TAgnCalendarTime agnStartTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aStartTime);
       
  1273 	TAgnCalendarTime agnEndTime = CalUtils::TCalTimeToTAgnCalendarTimeL(aEndTime);
       
  1274 
       
  1275 	const CCalEntry::TType KType = SimpleEntry()->Type();
       
  1276 		
       
  1277 	switch (KType)
       
  1278 		{
       
  1279 		case CCalEntry::ETodo:
       
  1280 			// for todos, if end time is not set, set start time to null as well - this is an undated entry
       
  1281 			if ( ! agnEndTime.IsSet())
       
  1282 				{
       
  1283 				agnStartTime = agnEndTime;
       
  1284 				}
       
  1285 			break;
       
  1286 		case CCalEntry::EReminder:
       
  1287 			// for reminders, end time is the same as start time
       
  1288 			agnEndTime = agnStartTime;
       
  1289 			break;
       
  1290 		case CCalEntry::EAppt:
       
  1291 		case CCalEntry::EAnniv:
       
  1292 		case CCalEntry::EEvent:
       
  1293 			// for other entries, if end time is not set, make it the same as the start time
       
  1294 			if ( ! agnEndTime.IsSet())
       
  1295 				{
       
  1296 				agnEndTime = agnStartTime;
       
  1297 				}
       
  1298 			break;
       
  1299 		default:
       
  1300 			// bad entry type
       
  1301 			User::Leave(KErrArgument);
       
  1302 			break;
       
  1303 		}
       
  1304 		
       
  1305 	iFullEntry->SetStartAndEndTimeL(agnStartTime, agnEndTime);
       
  1306 	}
       
  1307 
       
  1308 MAgnCalendarTimeMode::TTimeMode CCalEntryImpl::TimeMode() const
       
  1309 	{
       
  1310 	return SimpleEntry()->TimeMode();
       
  1311 	}
       
  1312 
       
  1313 TCalTime CCalEntryImpl::CompletedTimeL()
       
  1314 	{
       
  1315 	TTime completedDateUtc(Time::NullTTime());
       
  1316 	if (SimpleEntry()->Type() == CCalEntry::ETodo)
       
  1317 		{
       
  1318 		completedDateUtc = SimpleEntry()->CompletedDateUtc();
       
  1319 		}
       
  1320 	TCalTime calCompletedDate;
       
  1321 	calCompletedDate.SetTimeUtcL(completedDateUtc);
       
  1322 	return calCompletedDate;
       
  1323 	}
       
  1324 
       
  1325 void CCalEntryImpl::SetCompletedL(TBool aCompleted, const TCalTime& aDate)
       
  1326 	{
       
  1327 	LoadFullEntryL();
       
  1328 	if (SimpleEntry()->Type() == CCalEntry::ETodo)
       
  1329 		{
       
  1330 		if (aCompleted)
       
  1331 			{
       
  1332 			SimpleEntry()->SetCompletedDateUtcL(aDate.TimeUtcL());
       
  1333 			SetStatusL(CCalEntry::ETodoCompleted);
       
  1334 			}
       
  1335 		else
       
  1336 			{
       
  1337 			SimpleEntry()->SetIncomplete(); // resets completed date to null time
       
  1338 			SetStatusL(CCalEntry::ETodoNeedsAction);
       
  1339 			}
       
  1340 		}
       
  1341 	else
       
  1342 		{
       
  1343 		User::Leave(KErrNotSupported);
       
  1344 		}
       
  1345 	}
       
  1346 
       
  1347 void CCalEntryImpl::SetSummaryL(const TDesC& aSummary)
       
  1348 	{
       
  1349 	LoadFullEntryL();
       
  1350 	HBufC* summ = aSummary.AllocL();
       
  1351 	iFullEntry->SetSummary(summ); // takes ownership of aSummary
       
  1352 	}
       
  1353 
       
  1354 const TDesC& CCalEntryImpl::SummaryL()
       
  1355 	{
       
  1356 	LoadFullEntryL();
       
  1357 
       
  1358 	if(!iFullEntry->SummaryIsLoaded())
       
  1359 		{
       
  1360 		__ASSERT_DEBUG(iFullEntry->SummaryStreamId() != KNullStreamId, Panic(EAgmNoNotesStreamId));
       
  1361 		HBufC* summary = iSessionImpl->Server().RestoreTextL(iFullEntry->SummaryStreamId(), iSessionImpl->FileId());
       
  1362 		// Restore should always return something, even if it's only a Null Descriptor
       
  1363 		iFullEntry->SetSummary(summary);
       
  1364 		}
       
  1365 
       
  1366 	return iFullEntry->Summary();
       
  1367 	}
       
  1368 
       
  1369 void CCalEntryImpl::SetDescriptionL(const TDesC& aDescription)
       
  1370 	{
       
  1371 	LoadFullEntryL();
       
  1372 	HBufC* desc = aDescription.AllocL();
       
  1373 	iFullEntry->SetDescription(desc); // takes ownership of aDescription
       
  1374 	}
       
  1375 
       
  1376 const TDesC& CCalEntryImpl::DescriptionL()
       
  1377 	{
       
  1378 	LoadFullEntryL();
       
  1379 	
       
  1380 	if(!iFullEntry->DescriptionIsLoaded())
       
  1381 		{
       
  1382 		__ASSERT_DEBUG(iFullEntry->DescriptionStreamId() != KNullStreamId, Panic(EAgmNoNotesStreamId));
       
  1383 		HBufC* description = iSessionImpl->Server().RestoreTextL(iFullEntry->DescriptionStreamId(), iSessionImpl->FileId());
       
  1384 		// Restore should always return something, even if it's only a Null Descriptor
       
  1385 		iFullEntry->SetDescription(description);
       
  1386 		}
       
  1387 
       
  1388 	return iFullEntry->Description();
       
  1389 	}
       
  1390 
       
  1391 CCalEntry::TType CCalEntryImpl::EntryTypeL()
       
  1392 	{
       
  1393 	return SimpleEntry()->Type();
       
  1394 	}
       
  1395 
       
  1396 void CCalEntryImpl::SetStatusL(CCalEntry::TStatus aStatus)
       
  1397 	{
       
  1398 	LoadFullEntryL();
       
  1399 	switch (aStatus)
       
  1400 		{
       
  1401 		case CCalEntry::ETentative:
       
  1402 		case CCalEntry::EConfirmed:
       
  1403 			__ASSERT_ALWAYS(EntryTypeL() != CCalEntry::ETodo, User::Leave(KErrNotSupported));
       
  1404 			break;
       
  1405 		case CCalEntry::ECancelled:
       
  1406 			SimpleEntry()->SetIncomplete();
       
  1407 			break;
       
  1408 		
       
  1409 		case CCalEntry::ETodoCompleted:
       
  1410 		case CCalEntry::ETodoNeedsAction:
       
  1411 		case CCalEntry::ETodoInProcess:
       
  1412 			__ASSERT_ALWAYS(EntryTypeL() == CCalEntry::ETodo, User::Leave(KErrNotSupported));
       
  1413 			break;
       
  1414 		default:
       
  1415 			// do nothing
       
  1416 			break;
       
  1417 		}
       
  1418 	if (aStatus == CCalEntry::ETodoCompleted)
       
  1419 		{
       
  1420 		if (iFullEntry->CompletedDateUtc() == Time::NullTTime())
       
  1421 			{
       
  1422 			TTime time;
       
  1423 			time.UniversalTime();
       
  1424 			iFullEntry->SetCompletedDateUtcL(time);
       
  1425 			}
       
  1426 		}
       
  1427 	
       
  1428 	iFullEntry->SetStatus(aStatus);
       
  1429 	}
       
  1430 
       
  1431 void CCalEntryImpl::SetReplicationStatusL(CCalEntry::TReplicationStatus aReplicationStatus)
       
  1432 	{
       
  1433 	LoadFullEntryL();
       
  1434 	iFullEntry->SetReplicationStatusL(aReplicationStatus);
       
  1435 	}
       
  1436 
       
  1437 CCalEntry::TReplicationStatus CCalEntryImpl::ReplicationStatusL()
       
  1438 	{
       
  1439 	LoadFullEntryL();
       
  1440 	return iFullEntry->ReplicationStatus();
       
  1441 	}
       
  1442 
       
  1443 CCalEntry::TStatus CCalEntryImpl::StatusL()
       
  1444 	{
       
  1445 	return SimpleEntry()->Status();
       
  1446 	}
       
  1447 
       
  1448 void CCalEntryImpl::SetSequenceNumberL(TInt aSeqNum)
       
  1449 	{
       
  1450 	LoadFullEntryL();
       
  1451 	iFullEntry->SetSequenceNumber(aSeqNum);
       
  1452 	}
       
  1453 
       
  1454 void CCalEntryImpl::SetLastModifiedDateL()
       
  1455 	{
       
  1456 	LoadFullEntryL();
       
  1457 	iFullEntry->SetLastModifiedDate();
       
  1458 	}
       
  1459 	
       
  1460 void CCalEntryImpl::SetLastModifiedDateL(const TCalTime& aModifiedTime)
       
  1461 	{
       
  1462 	LoadFullEntryL();
       
  1463 	iFullEntry->SetLastModifiedDateUtc(aModifiedTime.TimeUtcL());
       
  1464 	}
       
  1465 	
       
  1466 void CCalEntryImpl::SetDTStampL(const TCalTime& aDTStampTime)
       
  1467 	{
       
  1468 	LoadFullEntryL();
       
  1469 	iFullEntry->SetDTStampUtcL(aDTStampTime.TimeUtcL());
       
  1470 	}
       
  1471 
       
  1472 TAgnEntryId CCalEntryImpl::AgnEntryIdL()
       
  1473 	{
       
  1474 	return SimpleEntry()->EntryId();
       
  1475 	}
       
  1476 
       
  1477 void CCalEntryImpl::SetLocalUidL(TCalLocalUid aLocalId)
       
  1478 	{
       
  1479 	LoadFullEntryL();
       
  1480 	iFullEntry->SetLocalUid(aLocalId);
       
  1481 	}
       
  1482 
       
  1483 TCalLocalUid CCalEntryImpl::LocalUidL()
       
  1484 	{
       
  1485 	if(iLiteEntry)
       
  1486 		{
       
  1487 		return iLiteEntry->LiteEntry().LocalUid();
       
  1488 		}
       
  1489 	else
       
  1490 		{
       
  1491 		return iFullEntry->LocalUid();
       
  1492 		}
       
  1493 	}
       
  1494 
       
  1495 TUint8 CCalEntryImpl::ShortFileIdL()
       
  1496 	{
       
  1497 	if(iLiteEntry)
       
  1498 		{
       
  1499 		return iLiteEntry->LiteEntry().CollectionId();
       
  1500 		}
       
  1501 	else
       
  1502 		{
       
  1503 		return iFullEntry->CollectionId();
       
  1504 		}	
       
  1505 	}
       
  1506 
       
  1507 CCalEntry::TTransp CCalEntryImpl::BusyStatusL()
       
  1508 	{
       
  1509 	LoadFullEntryL();
       
  1510 	return iFullEntry->BusyStatus();
       
  1511 	}
       
  1512 
       
  1513 void CCalEntryImpl::SetBusyStatusL(CCalEntry::TTransp aBusyStatus)
       
  1514 	{
       
  1515 	LoadFullEntryL();
       
  1516 	iFullEntry->SetBusyStatusL(aBusyStatus);
       
  1517 	}
       
  1518 
       
  1519 CCalGeoValue* CCalEntryImpl::GeoValueL()
       
  1520 	{
       
  1521 	LoadFullEntryL();
       
  1522 	TReal geoLatitude;
       
  1523 	TReal geoLongitude;
       
  1524 	iFullEntry->GeoValue(geoLatitude,geoLongitude);
       
  1525 	if(geoLatitude != KGEODefaultValue && geoLongitude != KGEODefaultValue)
       
  1526 		{
       
  1527 		CCalGeoValue* geoValue = CCalGeoValue::NewL();
       
  1528 		CleanupStack::PushL(geoValue);
       
  1529 		geoValue->SetLatLongL(geoLatitude,geoLongitude);
       
  1530 		CleanupStack::Pop(geoValue);
       
  1531 		return geoValue;
       
  1532 		}
       
  1533 	return NULL;		
       
  1534 	}
       
  1535 
       
  1536 void CCalEntryImpl::SetGeoValueL(const CCalGeoValue& aGeoValue)
       
  1537 	{
       
  1538 	LoadFullEntryL();
       
  1539 	TReal geoLatitude;
       
  1540 	TReal geoLongitude;
       
  1541 	aGeoValue.GetLatLong(geoLatitude,geoLongitude);
       
  1542 	iFullEntry->SetGeoValueL(geoLatitude,geoLongitude);
       
  1543 	}
       
  1544 
       
  1545 void CCalEntryImpl::ClearGeoValueL()
       
  1546 	{
       
  1547 	LoadFullEntryL();
       
  1548 	iFullEntry->SetGeoValueL(KGEODefaultValue,KGEODefaultValue);
       
  1549 	}
       
  1550 	
       
  1551 TCalTime CCalEntryImpl::FindRptUntilTimeL(TInt aCount)
       
  1552 	{
       
  1553 	const CAgnRptDef* KRptDef = SimpleEntry()->RptDef();
       
  1554 	
       
  1555 	TTime untilTime = Time::NullTTime();
       
  1556 	
       
  1557 	if (KRptDef)
       
  1558 		{
       
  1559 		untilTime = KRptDef->RRule()->FindRptUntilTimeLocalL(aCount);
       
  1560 		}
       
  1561 	
       
  1562 	TCalTime calUntilTime;
       
  1563 	calUntilTime.SetTimeLocalL(untilTime);
       
  1564 	
       
  1565 	return calUntilTime;
       
  1566 	}
       
  1567 
       
  1568 
       
  1569   void CCalEntryImpl::AddAttachmentL(CCalAttachment* aAttachment)
       
  1570    	{
       
  1571    	__ASSERT_ALWAYS(aAttachment, User::Leave(KErrArgument));
       
  1572    	
       
  1573 	PopulateAttachmentListL();
       
  1574 	iCalAttachmentList->AppendL(aAttachment);
       
  1575 	
       
  1576 	TRAPD(err , iFullEntry->AddAttachmentL(&aAttachment->Impl()));
       
  1577  
       
  1578 	if (err != KErrNone)
       
  1579  		{
       
  1580 		TInt count = iCalAttachmentList->Count();
       
  1581  		iCalAttachmentList->Remove(count - 1);
       
  1582  		User::Leave(err);
       
  1583  		}
       
  1584  		
       
  1585    	aAttachment->Impl().ClearFlag(CAgnAttachment::EOwnedByCalAttachment);
       
  1586 
       
  1587    	}
       
  1588 
       
  1589 void CCalEntryImpl::PopulateAttachmentListL()
       
  1590 	{
       
  1591    	if (!iCalAttachmentList)
       
  1592    		{
       
  1593 
       
  1594 		LoadFullEntryL();
       
  1595 		iCalAttachmentList = new (ELeave) RPointerArray<CCalAttachment>(KAttachmentGranularity);
       
  1596 
       
  1597 		const TInt KAttachmentCount = iFullEntry->AttachmentCount();
       
  1598 		for (TInt i = 0; i < KAttachmentCount; ++i)
       
  1599 			{
       
  1600 			CAgnAttachment& agnAttachment = iFullEntry->Attachment(i);
       
  1601 			CCalAttachment* calAttachment = CCalAttachment::NewL(agnAttachment, *iSessionImpl);
       
  1602 			CleanupStack::PushL(calAttachment);
       
  1603 			agnAttachment.ClearFlag(CAgnAttachment::EOwnedByCalAttachment);
       
  1604 			iCalAttachmentList->AppendL(calAttachment);
       
  1605 			CleanupStack::Pop(calAttachment);
       
  1606 			}
       
  1607    		}
       
  1608 
       
  1609    	}	
       
  1610 	
       
  1611 void CCalEntryImpl::DeleteAttachmentL(const CCalAttachment& aAttachment)
       
  1612 	{
       
  1613 	LoadFullEntryL();
       
  1614 	TInt index = iFullEntry->DeleteAttachmentL(aAttachment.Impl());
       
  1615 	if(iCalAttachmentList && index >= 0 && index < iCalAttachmentList->Count())
       
  1616 		{
       
  1617 		delete (*iCalAttachmentList)[index];
       
  1618 		iCalAttachmentList->Remove(index);
       
  1619 		__ASSERT_DEBUG(iCalAttachmentList->Count() == iFullEntry->AttachmentCount(), Panic(EAgmErrAttachmentCountCorrupt)); 
       
  1620 		}
       
  1621 	}
       
  1622 	
       
  1623 CCalAttachment* CCalEntryImpl::AttachmentL(TInt aIndex)
       
  1624 	{
       
  1625 	PopulateAttachmentListL();
       
  1626 
       
  1627 	if (aIndex < 0 || aIndex >= iCalAttachmentList->Count() )
       
  1628 		{
       
  1629 		return NULL;
       
  1630 		}
       
  1631 		
       
  1632 	return (*iCalAttachmentList)[aIndex];
       
  1633 	}
       
  1634 
       
  1635 TInt CCalEntryImpl::AttachmentCountL()
       
  1636 	{
       
  1637 	LoadFullEntryL();
       
  1638 	return iFullEntry->AttachmentCount();
       
  1639 	}
       
  1640 	
       
  1641 CAgnSimpleEntry* CCalEntryImpl::SimpleEntry()
       
  1642 	{
       
  1643 	if (!iFullEntry)
       
  1644 		{
       
  1645 		return &iLiteEntry->LiteEntry();
       
  1646 		}
       
  1647 	return iFullEntry;
       
  1648 	}
       
  1649 
       
  1650 const CAgnSimpleEntry* CCalEntryImpl::SimpleEntry() const
       
  1651 	{
       
  1652 	if (!iFullEntry)
       
  1653 		{
       
  1654 		return &iLiteEntry->LiteEntry();
       
  1655 		}
       
  1656 	return iFullEntry;
       
  1657 	}
       
  1658 
       
  1659 void CCalEntryImpl::SetUserIntL( TUint32 aUserInt )
       
  1660     {
       
  1661     SimpleEntry()->SetUserInt(aUserInt);
       
  1662     }
       
  1663 
       
  1664 TUint32 CCalEntryImpl::UserIntL()
       
  1665     {
       
  1666     return SimpleEntry()->UserInt();
       
  1667     }
       
  1668 
       
  1669 
       
  1670 //  CCalEntryIdImpl //
       
  1671 
       
  1672 CCalEntryIdImpl* CCalEntryIdImpl::NewL(TDesC8* aFlatData)
       
  1673 	{
       
  1674 	CCalEntryIdImpl* self = new(ELeave) CCalEntryIdImpl();
       
  1675 	CleanupStack::PushL(self);
       
  1676 	self->ConstructL(aFlatData);
       
  1677 	CleanupStack::Pop(self);
       
  1678 	return self;
       
  1679 	}
       
  1680 
       
  1681 CCalEntryIdImpl::CCalEntryIdImpl()
       
  1682 	{
       
  1683 	}
       
  1684 
       
  1685 CCalEntryIdImpl::~CCalEntryIdImpl()
       
  1686 	{
       
  1687 	delete iFlatData;
       
  1688 	}
       
  1689 
       
  1690 void CCalEntryIdImpl::ConstructL(TDesC8* aFlatData)
       
  1691 	{
       
  1692 	__ASSERT_ALWAYS(aFlatData != NULL, User::Leave(KErrArgument));
       
  1693 	
       
  1694 	iFlatData = aFlatData;
       
  1695 	iUniqueId = reinterpret_cast<const TAgnAlarmInfo*>(aFlatData->Ptr());
       
  1696 	}
       
  1697 
       
  1698 TPtrC8 CCalEntryIdImpl::IdL()
       
  1699 	{
       
  1700 	return iUniqueId->iGlobalIdentifier;
       
  1701 	}
       
  1702 
       
  1703 TPtrC CCalEntryIdImpl::StoreFileNameL()
       
  1704 	{
       
  1705 	return iUniqueId->iFileName;
       
  1706 	}
       
  1707 
       
  1708 TCalTime CCalEntryIdImpl::RecurrenceIdL()
       
  1709 	{
       
  1710 	TCalTime time;
       
  1711 	
       
  1712 	if(iUniqueId->iTimeMode ==MAgnCalendarTimeMode::EFloating)
       
  1713  		{
       
  1714  		time.SetTimeLocalFloatingL(iUniqueId->iRecurrenceId);
       
  1715  		}
       
  1716  	else
       
  1717  		{
       
  1718  		time.SetTimeUtcL(iUniqueId->iRecurrenceId);
       
  1719  		}
       
  1720  	
       
  1721  	return time;
       
  1722 	}
       
  1723 
       
  1724 TCalTime CCalEntryIdImpl::InstanceTimeL()
       
  1725 	{
       
  1726 	TCalTime time;
       
  1727 
       
  1728 	if(iUniqueId->iTimeMode == MAgnCalendarTimeMode::EFloating)
       
  1729 		{
       
  1730 		time.SetTimeLocalL(iUniqueId->iInstanceTime);
       
  1731 		}
       
  1732 	else
       
  1733 		{
       
  1734 		time.SetTimeUtcL(iUniqueId->iInstanceTime);		
       
  1735 		}
       
  1736 		
       
  1737 	return time;
       
  1738 	}
       
  1739 
       
  1740 TCalLocalUid CCalEntryIdImpl::LocalUidL()
       
  1741 	{
       
  1742 	return iUniqueId->iAgnUniqueId;
       
  1743 	}
       
  1744 	
       
  1745 
       
  1746 /** Construct a new CCalLiteEntry 
       
  1747 
       
  1748 @param aLiteEntry The TAgnLiteEntry to be shared between CCalEntry objects.
       
  1749 @param aSession A reference to the CCalSession
       
  1750 @internalComponent
       
  1751 */
       
  1752 CCalLiteEntry* CCalLiteEntry::NewL(CAgnSimpleEntry& aSimpleEntry, RAgendaServ& aAgendaServ)
       
  1753 	{
       
  1754 	CCalLiteEntry* self = new(ELeave) CCalLiteEntry(aSimpleEntry, aAgendaServ);
       
  1755 	return self;
       
  1756 	}
       
  1757 
       
  1758 /** Constructor
       
  1759 
       
  1760 @param aLiteEntry The TAgnLiteEntry to be shared between CCalEntry objects.
       
  1761 @param aSession A reference to the CCalSession
       
  1762 @internalComponent
       
  1763 */	
       
  1764 CCalLiteEntry::CCalLiteEntry(CAgnSimpleEntry& aLiteEntry, RAgendaServ& aAgendaServ)
       
  1765 	: iAgendaServ(aAgendaServ), iLiteEntry(aLiteEntry)
       
  1766 	{
       
  1767 	iAgendaServ.IncreaseRef();
       
  1768 	}
       
  1769 
       
  1770 /** Deletes the TAgnLiteEntry that is contained 
       
  1771 
       
  1772 @internalComponent
       
  1773 */	
       
  1774 CCalLiteEntry::~CCalLiteEntry()
       
  1775 	{
       
  1776 	iAgendaServ.DeleteSimpleEntry(&iLiteEntry);
       
  1777 	iAgendaServ.DecreaseRef();
       
  1778 	}
       
  1779 	
       
  1780 /** Get a reference to the TAgnLiteEntry
       
  1781 
       
  1782 @return A reference to the TAgnLiteEntry
       
  1783 @internalComponent
       
  1784 */
       
  1785 CAgnSimpleEntry& CCalLiteEntry::LiteEntry() const
       
  1786 	{
       
  1787 	return iLiteEntry;
       
  1788 	}
       
  1789 
       
  1790 /** Increments the reference count
       
  1791 
       
  1792 This should only be called by a CCalEntry object that is being created from a CCalLiteEntry 
       
  1793 @internalComponent
       
  1794 */	
       
  1795 void CCalLiteEntry::IncrementRefCount()
       
  1796 	{
       
  1797 	++iRefCount;
       
  1798 	}
       
  1799 
       
  1800 /** Decrements the reference count and deletes this CCalLiteEntry if there are no more entries refering to it
       
  1801 
       
  1802 This should only be called by a CCalEntry object
       
  1803 @internalComponent
       
  1804 */	
       
  1805 void CCalLiteEntry::DecrementRefCount()
       
  1806 	{
       
  1807 	__ASSERT_ALWAYS(iRefCount > 0, User::Invariant());
       
  1808 	if (--iRefCount == 0)
       
  1809 		{
       
  1810 		delete this;
       
  1811 		}
       
  1812 	}