pimappservices/calendar/shared/src/agmentry.cpp
changeset 0 f979ecb2b13e
child 18 c198609911f9
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 // Copyright (c) 1997-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 "agmentry.h"
       
    17 
       
    18 #include "agmattendee.h"
       
    19 #include "agmcategory.h"
       
    20 #include <calinterimapipanic.h>
       
    21 #include "agmcontent.h"
       
    22 #include "agmattachment.h"
       
    23 #include "agmdate.h"
       
    24 #include "agmrptdef.h"
       
    25 #include "agmutil.h"
       
    26 
       
    27 #include <calentry.h>
       
    28 //#include "calentryimpl.h"
       
    29 #include <e32math.h>
       
    30 
       
    31 #include <asshddefs.h>
       
    32 
       
    33 
       
    34 //---------------------------------- CAgnEntry ------------------------------------------
       
    35 
       
    36 EXPORT_C CAgnEntry* CAgnEntry::NewL(CCalEntry::TType aType)
       
    37 	{
       
    38 	__ASSERT_ALWAYS(aType>=CCalEntry::EAppt && aType<=CCalEntry::EAnniv, Panic(EAgmErrBadTypeEntry));
       
    39 	// allocate a CAgnEntry object, which invokes the CAgnSimpleEntry new operator, but passing no allocator
       
    40 	// this makes the CAgnSimpleEntry new operator use the default new operator
       
    41 	
       
    42 	return new (ELeave, NULL) CAgnEntry(aType);;
       
    43 	}
       
    44 
       
    45 EXPORT_C CAgnEntry* CAgnEntry::NewL(RReadStream& aStream)
       
    46 //Creates an entry and restores it from aStream
       
    47 	{
       
    48 	// type must be read first because NewL requires it
       
    49 	TUint8 typeData = aStream.ReadUint8L();
       
    50 		
       
    51 	CCalEntry::TType type=CCalEntry::TType(typeData);
       
    52 	
       
    53 	__ASSERT_ALWAYS(type==CCalEntry::EAppt || type==CCalEntry::EEvent ||
       
    54 					type==CCalEntry::EAnniv || type==CCalEntry::ETodo ||
       
    55 					type==CCalEntry::EReminder, User::Leave(KErrCorrupt));
       
    56 
       
    57 	CAgnEntry* entry = CAgnEntry::NewL(type);
       
    58 	CleanupStack::PushL(entry);
       
    59 	entry->InternalizeL(aStream);
       
    60 	CleanupStack::Pop();
       
    61 	return entry;
       
    62 	}
       
    63 		
       
    64 
       
    65 CAgnEntry::CAgnEntry(CCalEntry::TType aType) : CAgnSimpleEntry(aType)
       
    66 	{
       
    67 	iSummary = NULL;
       
    68 	iSummaryStreamId = KNullStreamId;
       
    69 	iDescription = NULL;
       
    70 	iDescriptionStreamId = KNullStreamId;
       
    71 	SetFlagOff(EAgnAlarmActionDeleted);
       
    72 	iDTStampUtc = Time::NullTTime();
       
    73 	iLatitude=KGEODefaultValue;
       
    74 	iLongitude=KGEODefaultValue;
       
    75 	}
       
    76 
       
    77 void CAgnEntry::ConstructL(HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum)
       
    78 	{
       
    79 	iGsData = CGsParentData::NewL(aUid, aSeqNum, aMethod); // takes ownership of aUid
       
    80 	}
       
    81 
       
    82 void CAgnEntry::ConstructL(HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
       
    83 	{
       
    84 	iGsData = CGsChildData::NewL(aUid, aSeqNum, aMethod, aRecurrenceId, aRange); // takes ownership of aUid
       
    85 	}
       
    86 
       
    87 EXPORT_C CAgnEntry* CAgnEntry::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum, const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
       
    88 	{
       
    89 	CAgnEntry* entry = new (ELeave, NULL) CAgnEntry(aType);
       
    90 	
       
    91 	CleanupStack::PushL(entry);
       
    92 	entry->ConstructL(aUid, aMethod, aSeqNum, aRecurrenceId, aRange);
       
    93 	CleanupStack::Pop(entry);
       
    94 	
       
    95 	return entry;
       
    96 	}
       
    97 
       
    98 EXPORT_C CAgnEntry* CAgnEntry::NewL(CCalEntry::TType aType, HBufC8* aUid, CCalEntry::TMethod aMethod, TUint aSeqNum)
       
    99 	{
       
   100 	CAgnEntry* entry = new (ELeave, NULL) CAgnEntry(aType);
       
   101 	
       
   102 	CleanupStack::PushL(entry);
       
   103 	entry->ConstructL(aUid, aMethod, aSeqNum);
       
   104 	CleanupStack::Pop(entry);
       
   105 	
       
   106 	return entry;
       
   107 	}
       
   108 	
       
   109 EXPORT_C CAgnEntry::~CAgnEntry()
       
   110 /** The destructor frees all resources owned by the entry, prior to its destruction. 
       
   111 @internalComponent
       
   112 */
       
   113 	{
       
   114 	if ( iAttendeeList )
       
   115 		{
       
   116 		iAttendeeList->ResetAndDestroy();
       
   117 		delete iAttendeeList;
       
   118 		}
       
   119 	delete iMeetingOrganizer;
       
   120 	
       
   121 	delete iLocation;
       
   122 	
       
   123 	if ( iCategoryList )
       
   124 		{
       
   125 		iCategoryList->ResetAndDestroy();
       
   126 		delete iCategoryList;
       
   127 		}		
       
   128 	
       
   129 	if (iAttachments)
       
   130 		{
       
   131 		iAttachments->ResetAndDestroy();
       
   132 		delete iAttachments;		
       
   133 		}
       
   134 
       
   135 	delete iDescription;
       
   136 	delete iSummary;
       
   137 	delete iAlarmSoundName;
       
   138 	delete iAlarmAction;	
       
   139 	
       
   140     delete iGsData;
       
   141 	}
       
   142 
       
   143 
       
   144 EXPORT_C const TDesC& CAgnEntry::Summary() const
       
   145 /** Gets a pointer to the rich text object owned by the entry.
       
   146 
       
   147 @internalComponent
       
   148 @return Pointer to the rich text object. The caller does not take ownership. */
       
   149 	{
       
   150 	if ( iSummary )
       
   151 		{
       
   152 		return *iSummary;
       
   153 		}
       
   154 		
       
   155 	return KNullDesC;
       
   156 	}
       
   157 
       
   158 
       
   159 EXPORT_C TBool CAgnEntry::CompareL(const CAgnEntry& aEntry) const
       
   160 /** Compares another entry for equality with this one.
       
   161 
       
   162 The entries' instance IDs and unique IDs are also compared.
       
   163 
       
   164 @internalComponent
       
   165 @param aEntry Pointer to an entry.
       
   166 @param aCompareId This argument is used internally, for test purposes only. 
       
   167 As it has a default value, it can be ignored by developers.
       
   168 @return ETrue if aEntry is the same as this entry, EFalse if not. Note. Replication 
       
   169 data is not included in the comparison, except for the replication status. 
       
   170 */
       
   171 	{
       
   172 	if ( ! (*this == aEntry) )
       
   173 		{
       
   174 		return EFalse;
       
   175 		}
       
   176 
       
   177 	if ( ReplicationStatus() != aEntry.ReplicationStatus() )
       
   178 		{
       
   179 		return EFalse;
       
   180 		}
       
   181 
       
   182 	if ( HasAlarm() )
       
   183 		{
       
   184 		if ( AlarmSoundName() != aEntry.AlarmSoundName() )
       
   185 			{
       
   186 			return EFalse;
       
   187 			}
       
   188 			
       
   189 		CAgnContent* content1 = AlarmAction();
       
   190 		CAgnContent* content2 = aEntry.AlarmAction();
       
   191 		if ( content1 == NULL )
       
   192 			{
       
   193 			if ( content2 != NULL )
       
   194 				{
       
   195 				return EFalse;
       
   196 				}
       
   197 			}
       
   198 		else
       
   199 			{
       
   200 			if ( content2 == NULL )
       
   201 				{
       
   202 				return EFalse;
       
   203 				}
       
   204 				
       
   205 			if ( content1->Type() != content2->Type() )
       
   206 				{
       
   207 				return EFalse;
       
   208 				}
       
   209 				
       
   210 			if ( content1->Content() != content2->Content() )
       
   211 				{
       
   212 				return EFalse;
       
   213 				}
       
   214 				
       
   215 			if ( content1->MimeType() != content2->MimeType() )
       
   216 				{
       
   217 				return EFalse;
       
   218 				}
       
   219 			}
       
   220 		}
       
   221 	
       
   222 	if ( BusyStatus() != aEntry.BusyStatus() )
       
   223 		{
       
   224 		return EFalse;
       
   225 		}
       
   226 	
       
   227 	// Compare GEO values
       
   228 	TReal entryLatitude;
       
   229 	TReal entryLongitude;
       
   230 	
       
   231 	aEntry.GeoValue(entryLatitude,entryLongitude);
       
   232 	
       
   233 	if ( iLatitude != entryLatitude || entryLongitude != iLongitude )
       
   234 		{
       
   235 		return EFalse;
       
   236 		}	
       
   237 		
       
   238 	// Compare the user integer.
       
   239 	if (UserInt() != aEntry.UserInt())
       
   240 	    {
       
   241 	    return EFalse;
       
   242 	    }	
       
   243 	
       
   244 	if ( DTStampUtcL() != aEntry.DTStampUtcL() )
       
   245 		{
       
   246 		return EFalse;
       
   247 		}
       
   248 
       
   249 	if ( Method() != aEntry.Method() )
       
   250 		{
       
   251 		return EFalse;
       
   252 		}
       
   253 
       
   254 	if ( SequenceNumber() != aEntry.SequenceNumber() )
       
   255 		{
       
   256 		return EFalse;
       
   257 		}
       
   258 	
       
   259 	if ( RecurrenceId() != aEntry.RecurrenceId() )
       
   260 		{
       
   261 		return EFalse;
       
   262 		}
       
   263 	
       
   264 	const TInt KNumOfCategories = CategoryCount();
       
   265 	
       
   266 	if ( aEntry.CategoryCount() != KNumOfCategories )
       
   267 		{
       
   268 		return EFalse;
       
   269 		}
       
   270 	
       
   271 	const RPointerArray<CAgnCategory>* categoryList1 = iCategoryList;
       
   272 	const RPointerArray<CAgnCategory>* categoryList2 = aEntry.iCategoryList;
       
   273 
       
   274 	if (categoryList1 && categoryList2)
       
   275 		{
       
   276 		TBool categoryFound = EFalse;
       
   277 
       
   278 		for ( TInt i = 0 ; i < KNumOfCategories; ++i )
       
   279 			{
       
   280 			categoryFound = EFalse;
       
   281 
       
   282 			for ( TInt j = 0; ! categoryFound && j < KNumOfCategories; ++j )
       
   283 				{
       
   284 				if ( (*categoryList1)[i]->Category() == (*categoryList2)[j]->Category() )
       
   285 					{
       
   286 					if ( (*categoryList1)[i]->Category() == CCalCategory::ECalExtended )
       
   287 						{
       
   288 						if ( (*categoryList1)[i]->ExtendedCategoryName() == (*categoryList2)[j]->ExtendedCategoryName() )
       
   289 							{
       
   290 							categoryFound = ETrue;
       
   291 							}
       
   292 						}
       
   293 					else
       
   294 						{
       
   295 						categoryFound = ETrue;
       
   296 						}
       
   297 					}
       
   298 				}
       
   299 
       
   300 			if ( !categoryFound )
       
   301 				{
       
   302 				return EFalse;
       
   303 				}
       
   304 			}
       
   305 		}
       
   306 
       
   307 	const TInt KNumOfAttendees = AttendeeCount();
       
   308 
       
   309 	if ( KNumOfAttendees != aEntry.AttendeeCount() )
       
   310 		{
       
   311 		return EFalse;
       
   312 		}
       
   313 
       
   314 	if ( KNumOfAttendees > 0 && KNumOfAttendees == aEntry.AttendeeCount() )
       
   315 		{
       
   316 		const RPointerArray<CAgnAttendee>& KAttendeeList1 = *iAttendeeList;
       
   317 		const RPointerArray<CAgnAttendee>& KAttendeeList2 = *aEntry.iAttendeeList;
       
   318 
       
   319 		for ( TInt i = 0; i < KNumOfAttendees; ++i )
       
   320 			{
       
   321 			const TPtrC& KAttendee1 = KAttendeeList1[i]->Address();
       
   322 
       
   323 			TBool attendeeFound = EFalse;
       
   324 			
       
   325 			for ( TInt j = 0; !attendeeFound && j < KNumOfAttendees; ++j )
       
   326 				{
       
   327 				const TPtrC& KAttendee2 = KAttendeeList2[j]->Address();
       
   328 				
       
   329 				if ( KAttendee1.CompareF(KAttendee2) == 0 )
       
   330 					{
       
   331 					attendeeFound = ETrue;
       
   332 					}
       
   333 				}
       
   334 				
       
   335 			if ( !attendeeFound )
       
   336 				{
       
   337 				return EFalse;
       
   338 				}
       
   339 			}
       
   340 		}
       
   341 
       
   342 	const TInt KNumAttachments = AttachmentCount();
       
   343 	if (KNumAttachments != aEntry.AttachmentCount())
       
   344 		{
       
   345 		return EFalse;
       
   346 		}
       
   347 	if (KNumAttachments > 0)
       
   348 		{
       
   349 		RArray<TBool> foundAttachmentAlready;
       
   350 		CleanupClosePushL(foundAttachmentAlready);
       
   351 		
       
   352 		for (TInt i = 0; i < KNumAttachments; ++i)
       
   353 			{
       
   354 			foundAttachmentAlready.AppendL(EFalse);
       
   355 			}
       
   356 		
       
   357 		for (TInt i = 0; i < KNumAttachments; ++i)
       
   358 			{
       
   359 			TBool attachmentFound = EFalse;
       
   360 			for (TInt j = 0; j < KNumAttachments; ++j)
       
   361 				{
       
   362 				if (!foundAttachmentAlready[j] && Attachment(i).CompareL(aEntry.Attachment(j)))
       
   363 					{
       
   364 					foundAttachmentAlready[j] = ETrue;
       
   365 					attachmentFound = ETrue;
       
   366 					break;
       
   367 					}
       
   368 				}
       
   369 			if (!attachmentFound)
       
   370 				{
       
   371 				CleanupStack::PopAndDestroy(); // foundAttachmentAlready.Close()
       
   372 				return EFalse;
       
   373 				}
       
   374 			}
       
   375 		
       
   376 		CleanupStack::PopAndDestroy(); // foundAttachmentAlready.Close()
       
   377 		}
       
   378 	
       
   379 	if ( PhoneOwner() == NULL )
       
   380 		{
       
   381 		if ( aEntry.PhoneOwner() != NULL )
       
   382 			{
       
   383 			return EFalse;
       
   384 			}
       
   385 		}
       
   386 	else
       
   387 		{
       
   388 		// PhoneOwner() != NULL
       
   389 		if ( aEntry.PhoneOwner() == NULL )
       
   390 			{
       
   391 			return EFalse;
       
   392 			}
       
   393 		else if ( PhoneOwner()->Address() != aEntry.PhoneOwner()->Address() )
       
   394 			{
       
   395 			return EFalse;
       
   396 			}
       
   397 		}
       
   398 
       
   399 	if ( Summary() != aEntry.Summary() )
       
   400 		{
       
   401 		return EFalse;
       
   402 		}
       
   403 
       
   404 	if ( Description() != aEntry.Description() )
       
   405 		{
       
   406 		return EFalse;
       
   407 		}
       
   408 
       
   409 	if ( Location() != aEntry.Location() )
       
   410 		{
       
   411 		return EFalse;
       
   412 		}
       
   413 	
       
   414 	return ETrue;
       
   415 	}
       
   416 
       
   417 
       
   418 EXPORT_C const TDesC& CAgnEntry::AlarmSoundName() const
       
   419 /** Gets the name of the alarm sound as set by SetAlarmSoundName(). 
       
   420 
       
   421 Returns NULL if the entry isn't alarmed.
       
   422 
       
   423 @internalComponent
       
   424 @return The name of the alarm sound. 
       
   425 */
       
   426 	{
       
   427 
       
   428 	if ( HasAlarm() && iAlarmSoundName )
       
   429 		{
       
   430 		return *iAlarmSoundName;
       
   431 		}		
       
   432 	
       
   433 	return KNullDesC();
       
   434 	}
       
   435 
       
   436 
       
   437 EXPORT_C void CAgnEntry::SetAlarmSoundNameL(const TDesC& aAlarmSoundName)
       
   438 /** Sets the name of the alarm sound.
       
   439 
       
   440 Note: if the length of the new alarm sound name is greater than KMaxAlarmSoundName 
       
   441 characters, it will be ignored.
       
   442 
       
   443 @internalComponent
       
   444 @param aAlarmSoundName The name of the alarm sound. 
       
   445 */
       
   446 	{
       
   447 	const TInt KLen = aAlarmSoundName.Length();
       
   448 	
       
   449 	if ( KLen > 0 && KLen <= KMaxAlarmSoundNameLength )
       
   450 		{
       
   451 		// delete and set always to NULL before AllocL because
       
   452 		// that call could leave and the pointer be not NULL
       
   453 				
       
   454 		delete iAlarmSoundName;
       
   455 		iAlarmSoundName = NULL;
       
   456 			
       
   457 		iAlarmSoundName = aAlarmSoundName.AllocL();
       
   458 		}
       
   459 	}
       
   460 
       
   461 
       
   462 EXPORT_C void CAgnEntry::ClearAlarm()
       
   463 /** Clear associated alarm
       
   464 
       
   465 @internalComponent
       
   466 */
       
   467 	{
       
   468 	delete iAlarmSoundName;
       
   469 	iAlarmSoundName = NULL;
       
   470 		
       
   471 	if ( iAlarmActionStreamId != KNullStreamId)
       
   472 		{
       
   473 		SetFlagOn(EAgnAlarmActionDeleted);
       
   474 		}
       
   475 	
       
   476     delete iAlarmAction;
       
   477     iAlarmAction = NULL;
       
   478 		
       
   479 	SetAlarmOffset(KAlarmNotSet);
       
   480 	}
       
   481 
       
   482  void CAgnEntry::ExternalizeGsDataL(RWriteStream& aStream, TBool aToBuffer) const
       
   483 	{
       
   484 	aStream.WriteInt8L(GsDataType());
       
   485 	
       
   486 	if(aToBuffer)
       
   487 		{
       
   488 		iGsData->ExternalizeToBufferL(aStream);		
       
   489 		}
       
   490 	else
       
   491 		{
       
   492 		iGsData->ExternalizeL(aStream);	
       
   493 		}
       
   494 	}
       
   495  
       
   496 EXPORT_C void CAgnEntry::PruneRDatesL(const TAgnCalendarTime& aRecurrenceId, CalCommon::TRecurrenceRange aRange)
       
   497 /**
       
   498 Used when adding a repeating child to a parent entry.
       
   499 Removes all sporadic dates either after or before the specified recurrence ID. 
       
   500 @internalComponent
       
   501 */
       
   502 	{
       
   503 	__ASSERT_DEBUG(iGsData->GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry));
       
   504 	__ASSERT_DEBUG(RptDef(), Panic(EAgmErrNotParentEntry));
       
   505 	__ASSERT_DEBUG(aRange == CalCommon::EThisAndFuture || aRange == CalCommon::EThisAndPrior, Panic(EAgmErrInvalidRecurrenceRange));
       
   506 	
       
   507 	if (RptDef()->HasSporadicDates())
       
   508 		{
       
   509 		const RArray<TAgnCalendarTime>* KSporadicDates = RptDef()->SporadicDateList();
       
   510 		
       
   511 		for (TInt i = KSporadicDates->Count() - 1; i >= 0; --i)
       
   512 			{
       
   513 			const TAgnCalendarTime& KSporadicDate = (*KSporadicDates)[i];
       
   514 			if ( (aRecurrenceId > KSporadicDate && aRange == CalCommon::EThisAndPrior ) ||
       
   515 				 (aRecurrenceId < KSporadicDate && aRange == CalCommon::EThisAndFuture ) )
       
   516 				{
       
   517 				RptDef()->RemoveSporadicDate(KSporadicDate);
       
   518 				}
       
   519 			}
       
   520 		}
       
   521 	}
       
   522 
       
   523 void CAgnEntry::InternalizeGsDataL(RReadStream& aStream, TBool aFromBuffer)
       
   524  	{
       
   525  	CGsData::TGsDataType dataType =  static_cast<CGsData::TGsDataType>(aStream.ReadInt8L());
       
   526 	
       
   527 	if(dataType == CGsData::EParent)
       
   528 		{
       
   529 		iGsData = CGsParentData::NewL();
       
   530 		}
       
   531 	else 
       
   532 		{
       
   533 		iGsData = CGsChildData::NewL();
       
   534 		}
       
   535 		
       
   536 	if(aFromBuffer)
       
   537 		{
       
   538 		iGsData->InternalizeFromBufferL(aStream);
       
   539 		}
       
   540 	else
       
   541 		{
       
   542 		iGsData->InternalizeL(aStream);
       
   543 		}
       
   544   	}
       
   545 	
       
   546 EXPORT_C void CAgnEntry::ExternalizeL(RWriteStream& aStream) const
       
   547 /** Externalises an entry's details and attributes, but not its rich text to a 
       
   548 write stream. 
       
   549 
       
   550 The presence of this function means that the standard templated operator<<() 
       
   551 (defined in s32strm.h) is available to externalise objects of this class.
       
   552 
       
   553 @internalComponent
       
   554 @param aStream Stream to which the object should be externalised. 
       
   555 */
       
   556 	{
       
   557 	ExternalizeEntryL(aStream);
       
   558 	ExternalizeGsDataL(aStream, EFalse);
       
   559 	}
       
   560 
       
   561 void CAgnEntry::ExternalizeEntryL(RWriteStream& aStream, TBool aToBuffer) const
       
   562 	{
       
   563 	CAgnSimpleEntry::doExternalizeL(aStream, aToBuffer);
       
   564 	aStream.WriteInt8L(iReplicationStatus);
       
   565 	
       
   566 	if ( HasAlarm() )
       
   567 		{
       
   568 		if (iAlarmSoundName)
       
   569 			{
       
   570 			aStream << *iAlarmSoundName;
       
   571 			}			
       
   572 		else
       
   573 			{
       
   574 			aStream << KNullDesC();
       
   575 			}		
       
   576 		}
       
   577 
       
   578 	// Make sure there is no server pointer
       
   579 	// - This may have been set up from a previous FetchEntry
       
   580 	__ASSERT_DEBUG(iSummaryStreamId == KNullStreamId ||
       
   581 			    !(iSummary && iSummary->Length() > 0 && iSummaryStreamId == KNullStreamId),
       
   582 				 Panic(EAgmNoNotesStreamId));
       
   583 
       
   584 	aStream << iSummaryStreamId;
       
   585 
       
   586 	TInt size = 0;
       
   587 	if ( iLocation )
       
   588 		{
       
   589 		size = iLocation->Length();
       
   590 		aStream.WriteUint32L(size);
       
   591 		aStream.WriteL(iLocation->Des(), size);
       
   592 		}
       
   593 	else
       
   594 		{
       
   595 		size = 0;
       
   596 		aStream.WriteUint32L(size);
       
   597 		}
       
   598 
       
   599 	TInt phoneOwnerIndex = 0;
       
   600 	
       
   601 	if ( iAttendeeList )
       
   602 		{
       
   603 		size = iAttendeeList->Count();
       
   604 		aStream.WriteUint32L(size);
       
   605 		
       
   606 		for ( TInt i = 0; i < size; ++i )
       
   607 			{
       
   608 			CAgnAttendee*& attendeeI = (*iAttendeeList)[i];			
       
   609 			
       
   610 			attendeeI->ExternalizeL(aStream);
       
   611 			
       
   612 			if ( iPhoneOwner == attendeeI )
       
   613 				{
       
   614 				phoneOwnerIndex = i + 1;
       
   615 				}
       
   616 			}
       
   617 		}
       
   618 	else
       
   619 		{		
       
   620 		size = 0;
       
   621 		aStream.WriteUint32L(size);
       
   622 		}
       
   623 
       
   624 	//	phone owner index. 0 implies no phoneowner
       
   625 	aStream.WriteUint32L(phoneOwnerIndex);
       
   626 
       
   627 	//	meeting organizer if present
       
   628 	if (iMeetingOrganizer)
       
   629 		{
       
   630 		aStream.WriteUint8L(ETrue);
       
   631 		iMeetingOrganizer->ExternalizeL(aStream);
       
   632 		}
       
   633 	else
       
   634 		{
       
   635 		aStream.WriteUint8L(EFalse);
       
   636 		}
       
   637 		
       
   638 	// Write the creation date field
       
   639 
       
   640 	aStream << iDTStampUtc.Int64();
       
   641 
       
   642 	// this does not change the file format
       
   643 	if ( iCategoryList )
       
   644 		{
       
   645 		size = iCategoryList->Count();
       
   646 		aStream.WriteUint32L(size);
       
   647 		
       
   648 		for ( TInt ccount = 0; ccount < size; ++ccount )
       
   649 			{
       
   650 			(*iCategoryList)[ccount]->ExternalizeL(aStream);
       
   651 			}
       
   652 		}
       
   653 	else
       
   654 		{		
       
   655 		size = 0;
       
   656 		aStream.WriteUint32L(size);
       
   657 		}
       
   658 	
       
   659 	// Write the Notes Stream Id - Null value indicates no Notes data.
       
   660 	// If the Notes exist, they should have been saved previously, so Stream id != 0 !!!
       
   661 	__ASSERT_DEBUG((iDescriptionStreamId == KNullStreamId) ||
       
   662 				    !(iDescription && iDescription->Length() > 0 && iDescriptionStreamId == KNullStreamId),
       
   663 					 Panic(EAgmNoNotesStreamId));
       
   664 	aStream << iDescriptionStreamId;
       
   665 	aStream << iAlarmActionStreamId;
       
   666 
       
   667 	aStream.WriteUint8L(iBusyStatus);
       
   668 	
       
   669 	// GEO properties
       
   670 	aStream.WriteReal64L(iLatitude);
       
   671 	aStream.WriteReal64L(iLongitude);
       
   672 	
       
   673 	const TInt KAttachmentCount = AttachmentCount();
       
   674 	aStream.WriteUint16L(KAttachmentCount);
       
   675 	for (TInt i = 0; i < KAttachmentCount; ++i)
       
   676 		{
       
   677 		if ( ! Attachment(i).FlagsSet(CAgnAttachment::EDataHasBeenSet))
       
   678 			{
       
   679 			// attachments with just content IDs should not be stored
       
   680 			User::Leave(KErrArgument);
       
   681 			}
       
   682 		else
       
   683 			{
       
   684 			aStream << Attachment(i);
       
   685 			}
       
   686 		}
       
   687 
       
   688     // Set the user integer of the stream.
       
   689 	aStream.WriteInt32L( UserInt() );
       
   690 	
       
   691 	// future DC proofing
       
   692 	aStream.WriteUint32L(0); // number of bytes until end of entry
       
   693 	}
       
   694 
       
   695 
       
   696 EXPORT_C void CAgnEntry::InternalizeL(RReadStream& aStream)
       
   697 	{
       
   698 	InternalizeEntryL(aStream, EFalse);
       
   699 	InternalizeGsDataL(aStream, EFalse);
       
   700 	}
       
   701 
       
   702 void CAgnEntry::InternalizeEntryL(RReadStream& aStream, TBool aFromBuffer)
       
   703 /** Internalises an entry's details and attributes, but not its rich text from 
       
   704 a read stream. 
       
   705 
       
   706 The presence of this function means that the standard templated operator>>() 
       
   707 (defined in s32strm.h) is available to internalise objects of this class.
       
   708 
       
   709 @internalComponent
       
   710 @param aStream Stream from which the object should be internalised. 
       
   711 */
       
   712 	{
       
   713 	CAgnSimpleEntry::doInternalizeL(aStream, aFromBuffer);
       
   714 	iReplicationStatus = static_cast<CCalEntry::TReplicationStatus>(aStream.ReadInt8L());
       
   715 	
       
   716 	delete iAlarmSoundName;
       
   717 	iAlarmSoundName = NULL;
       
   718 	
       
   719 	if ( HasAlarm() )
       
   720 		{
       
   721 		iAlarmSoundName = HBufC::NewL(aStream, KMaxAlarmSoundNameLength);
       
   722 		if ( iAlarmSoundName->Length() == 0 )
       
   723 			{
       
   724 			delete iAlarmSoundName;
       
   725 			iAlarmSoundName = NULL;
       
   726 			}
       
   727 		}
       
   728 
       
   729 	aStream >> iSummaryStreamId;
       
   730 
       
   731 	// Delete any location that may exist
       
   732 	delete iLocation;
       
   733 	iLocation = NULL;
       
   734 
       
   735 	TInt size = aStream.ReadUint32L();
       
   736 	if ( size )
       
   737 		{
       
   738 		iLocation = HBufC::NewL(size);
       
   739 		TPtr bufPtr = iLocation->Des();
       
   740 		aStream.ReadL(bufPtr, size);
       
   741 		}
       
   742 
       
   743 	size = aStream.ReadUint32L();
       
   744 	if ( iAttendeeList )
       
   745 		{
       
   746 		iAttendeeList->ResetAndDestroy();
       
   747 		}
       
   748 	else
       
   749 		{
       
   750 		if ( size )
       
   751 			{
       
   752 			CreateAttendeeListL();
       
   753 			}
       
   754 		}
       
   755 	iPhoneOwner = NULL;
       
   756 	iMeetingOrganizer = NULL;
       
   757 	
       
   758 	for ( TInt count = 0; count < size; ++count )
       
   759 		{
       
   760 		CAgnAttendee* attendee = CAgnAttendee::NewL(aStream);
       
   761 		CleanupStack::PushL(attendee);
       
   762 		iAttendeeList->AppendL(attendee);
       
   763 		CleanupStack::Pop(attendee);
       
   764 		}
       
   765 		
       
   766 	// populate the phoneowner/organizer fields if existing
       
   767 	TInt phoneOwnerIndex = aStream.ReadUint32L();
       
   768 	if (phoneOwnerIndex > 0)
       
   769 		{
       
   770 		iPhoneOwner = (*iAttendeeList)[phoneOwnerIndex-1];
       
   771 		}
       
   772 
       
   773 	//	meeting organizer if present
       
   774 	if (aStream.ReadUint8L())
       
   775 		{
       
   776 		iMeetingOrganizer = CAgnAttendee::NewL(aStream);
       
   777 		}
       
   778 	
       
   779 	TInt64 dtStamp;
       
   780 	aStream >> dtStamp;
       
   781 	iDTStampUtc = dtStamp;
       
   782 
       
   783 	size = aStream.ReadUint32L();
       
   784 	
       
   785 	if ( iCategoryList )
       
   786 		{
       
   787 		iCategoryList->ResetAndDestroy();
       
   788 		}
       
   789 	else
       
   790 		{
       
   791 		if ( size )
       
   792 			{
       
   793 			iCategoryList = new (ELeave) RPointerArray<CAgnCategory>;
       
   794 			}
       
   795 		}
       
   796 		
       
   797 	for ( TInt ccount = 0; ccount < size; ++ccount )
       
   798 		{
       
   799 		CAgnCategory* category = CAgnCategory::NewL(aStream);
       
   800 		CleanupStack::PushL(category);
       
   801 		iCategoryList->AppendL(category);
       
   802 		CleanupStack::Pop(category);
       
   803 		}
       
   804 		
       
   805 	// If it's the new file format read in the Stream Id for the notes text
       
   806 	aStream >> iDescriptionStreamId;
       
   807 
       
   808 	aStream >> iAlarmActionStreamId;
       
   809 		
       
   810 	iBusyStatus = static_cast<CCalEntry::TTransp>(aStream.ReadUint8L());
       
   811 	
       
   812 	// GEO properties	
       
   813 	TReal geoLatitude = aStream.ReadReal64L();
       
   814 	TReal geoLongitude = aStream.ReadReal64L();
       
   815 	
       
   816 	SetGeoValueL(geoLatitude, geoLongitude);
       
   817 	
       
   818 	TInt attachmentCount = aStream.ReadUint16L();
       
   819 	for (TInt i = 0; i < attachmentCount; ++i)
       
   820 		{
       
   821 		
       
   822 		CAgnAttachment* attachment = AttachmentFactory::NewAttachmentL(aStream);
       
   823 		CleanupStack::PushL(attachment);
       
   824 		AddAttachmentL(attachment);
       
   825 		CleanupStack::Pop(attachment);
       
   826 		}
       
   827 	
       
   828 	// Set the user integer of this entry from the stream.
       
   829 	SetUserInt(aStream.ReadInt32L());
       
   830 	
       
   831 	// future DC proofing
       
   832 	size = aStream.ReadUint32L(); // number of bytes until end of entry
       
   833 	while (size > 0)
       
   834 		{
       
   835 		aStream.ReadUint8L(); // ignore data
       
   836 		size--;
       
   837 		}
       
   838 	}
       
   839 
       
   840 EXPORT_C CAgnEntry* CAgnEntry::CloneL() const
       
   841 	{
       
   842 	CAgnEntry* entry = NULL;
       
   843 	HBufC8* guid = (this->Guid()).AllocLC();
       
   844 	if(this->GsDataType() == CGsData::EParent)
       
   845 		{
       
   846 		entry = CAgnEntry::NewL(this->Type(), guid, this->Method(), this->SequenceNumber());
       
   847 		}
       
   848 	else
       
   849 		{
       
   850 		entry = CAgnEntry::NewL(this->Type(), guid, this->Method(), this->SequenceNumber(), this->RecurrenceId(), this->RecurrenceRange());
       
   851 		}
       
   852 	CleanupStack::Pop(guid);
       
   853 	CleanupStack::PushL(entry);
       
   854 	entry->CopyFromL(*this, CCalEntry::ECopyAll);
       
   855 	CleanupStack::Pop(entry);
       
   856 	return entry;
       
   857 	}
       
   858 	
       
   859 EXPORT_C void CAgnEntry::CopyFromL(const CAgnEntry& aSource, CCalEntry::TCopyType aCopyType)
       
   860 /** Copy the details common to all entry types from aSource.
       
   861 If aCopyType is EShallowCopy it indicates that if aSources rich text is stored out of line and its
       
   862 not loaded then it isn't loaded and copied
       
   863 */
       
   864 	{
       
   865 	CopySimpleEntryL(aSource, aCopyType);
       
   866 
       
   867 	// NOTE: don't use the internal set methods with pointers because doing a CopyFrom
       
   868 	// we are supposed to carbon copy the original. If the original has a NULL
       
   869 	// pointer in a member, we have to do the same and not keep any old stuff
       
   870 	iReplicationStatus = aSource.iReplicationStatus;	
       
   871 
       
   872 	if( iAttendeeList )
       
   873 		{
       
   874 		iAttendeeList->ResetAndDestroy();
       
   875 		}
       
   876 	iPhoneOwner = NULL;
       
   877 	delete iMeetingOrganizer;
       
   878 	iMeetingOrganizer = NULL;
       
   879 
       
   880 	const TInt KAttendees = aSource.AttendeeCount();
       
   881 	for ( TInt count = 0; count < KAttendees; ++count )
       
   882 		{
       
   883 		CAgnAttendee& attendee = aSource.FetchAttendee(count);
       
   884 
       
   885 		CAgnAttendee* newAttendee = attendee.CloneL();
       
   886 		AddAttendeeL(newAttendee);
       
   887 		
       
   888 		if ( aSource.PhoneOwner() == &attendee )
       
   889 			{
       
   890 			SetPhoneOwnerL(newAttendee);
       
   891 			}
       
   892 		}
       
   893 	
       
   894 	if (aSource.Organizer())
       
   895 		{
       
   896 		iMeetingOrganizer = aSource.Organizer()->CloneL();
       
   897 		}
       
   898 
       
   899 	// Copy the Location
       
   900 	delete iLocation;
       
   901 	iLocation = NULL;
       
   902 
       
   903 	if ( aSource.iLocation )
       
   904 		{
       
   905 		iLocation = aSource.iLocation->AllocL();
       
   906 		}
       
   907 
       
   908 	iDTStampUtc = aSource.iDTStampUtc;
       
   909 	
       
   910 	if( iCategoryList )
       
   911 		{
       
   912 		iCategoryList->ResetAndDestroy();
       
   913 		}
       
   914 		
       
   915 	const TInt KCategories = aSource.CategoryCount();
       
   916 	for ( TInt ccount = 0; ccount < KCategories; ++ccount )
       
   917 		{
       
   918 		CAgnCategory& category = aSource.FetchCategory(ccount);
       
   919 
       
   920 		CAgnCategory* newCategory = CAgnCategory::NewL(category);
       
   921 		CleanupStack::PushL(newCategory);
       
   922 		AddCategoryL(newCategory);
       
   923 		CleanupStack::Pop(newCategory);
       
   924 		}
       
   925 		
       
   926 	iBusyStatus = aSource.BusyStatus();
       
   927 	
       
   928 	// GEO properties
       
   929 	TReal sourceLatitude;
       
   930 	TReal sourceLongitude;
       
   931 	aSource.GeoValue(sourceLatitude,sourceLongitude);
       
   932 	
       
   933 	iLatitude = sourceLatitude;
       
   934 	iLongitude = sourceLongitude;
       
   935 
       
   936 	// Copy the Notes buffer
       
   937 	
       
   938 	delete iDescription;
       
   939 	iDescription = NULL;
       
   940 	
       
   941 	if ( aSource.iDescription )
       
   942 		{
       
   943 		iDescription = aSource.iDescription->AllocL();
       
   944 		}
       
   945 		
       
   946 	iDescriptionStreamId = aSource.iDescriptionStreamId;
       
   947 
       
   948 
       
   949 	// Copy the Summary buffer
       
   950 
       
   951 	delete iSummary;
       
   952 	iSummary = NULL;
       
   953 
       
   954 	if ( aSource.iSummary )
       
   955 		{
       
   956 		iSummary = aSource.iSummary->AllocL();
       
   957 		}
       
   958 		
       
   959 	iSummaryStreamId = aSource.iSummaryStreamId;
       
   960 
       
   961 
       
   962 	// Copy the Alarm sound name
       
   963 
       
   964 	delete iAlarmSoundName;
       
   965 	iAlarmSoundName = NULL;
       
   966 
       
   967 	if ( aSource.iAlarmSoundName )
       
   968 		{
       
   969 		iAlarmSoundName = aSource.iAlarmSoundName->AllocL();
       
   970 		}
       
   971 
       
   972 
       
   973 	// Copy the Alarm action
       
   974 
       
   975 	delete iAlarmAction;
       
   976 	iAlarmAction = NULL;
       
   977 		
       
   978 	if ( aSource.iAlarmAction )
       
   979 		{
       
   980 		iAlarmAction = aSource.iAlarmAction->CloneL();			
       
   981 		}
       
   982 
       
   983 	iAlarmActionStreamId = aSource.iAlarmActionStreamId;
       
   984 	iFlags = aSource.iFlags;
       
   985 	
       
   986 	if ( iAttachments )
       
   987 		{
       
   988 		iAttachments->ResetAndDestroy();
       
   989 		delete iAttachments;
       
   990 		iAttachments = NULL;
       
   991 		}
       
   992 		
       
   993 	const TInt KAttachments = aSource.AttachmentCount();
       
   994 	for ( TInt i = 0; i < KAttachments; ++i )
       
   995 		{
       
   996 		CAgnAttachment& attachment = aSource.Attachment(i);
       
   997 		CAgnAttachment* attachmentCopy = AttachmentFactory::CloneL(attachment);
       
   998 		CleanupStack::PushL(attachmentCopy);
       
   999 		AddAttachmentL(attachmentCopy);
       
  1000 		CleanupStack::Pop(attachmentCopy);
       
  1001 		}
       
  1002 
       
  1003 	iGsData->CopyDataL(*aSource.iGsData);
       
  1004 	
       
  1005 	if(aCopyType == CCalEntry::ECopyAll)
       
  1006 		{
       
  1007 		HBufC8* guid = aSource.Guid().AllocL();
       
  1008 		SetGuid(guid);
       
  1009 		}		
       
  1010 	}
       
  1011 	
       
  1012 EXPORT_C CCalEntry::TReplicationStatus CAgnEntry::ReplicationStatus() const
       
  1013 /** Get ReplicationStatus
       
  1014 
       
  1015 @internalComponent
       
  1016 */
       
  1017 	{
       
  1018 	return static_cast<CCalEntry::TReplicationStatus>(iReplicationStatus);
       
  1019 	}
       
  1020 
       
  1021 
       
  1022 EXPORT_C void CAgnEntry::SetReplicationStatusL(CCalEntry::TReplicationStatus aReplicationStatus)
       
  1023 /** Set ReplicationStatus
       
  1024 
       
  1025 @internalComponent
       
  1026 @leave KErrArgument if passed parameter exceeds boundaries
       
  1027 */
       
  1028 	{
       
  1029 	if( aReplicationStatus < CCalEntry::EOpen || aReplicationStatus > CCalEntry::ERestricted )
       
  1030 		{
       
  1031 		User::Leave(KErrArgument);
       
  1032 		}
       
  1033 	
       
  1034 	iReplicationStatus = aReplicationStatus;
       
  1035 	}
       
  1036 
       
  1037 
       
  1038 EXPORT_C TBool CAgnEntry::SummaryIsLoaded() const
       
  1039 /** Check if summary text is loaded from stream
       
  1040 
       
  1041 @internalComponent
       
  1042 */
       
  1043 	{
       
  1044 	if ( ! iSummary && iSummaryStreamId != KNullStreamId )
       
  1045 		{
       
  1046 		return EFalse;
       
  1047 		}		
       
  1048 
       
  1049 	return ETrue;
       
  1050 	}
       
  1051 
       
  1052 
       
  1053 EXPORT_C void CAgnEntry::SetSummary(HBufC* aSummary)
       
  1054 /** Set summary
       
  1055 
       
  1056 @internalComponent
       
  1057 */
       
  1058 	{
       
  1059 	delete iSummary;
       
  1060 	iSummary = aSummary;
       
  1061 	}
       
  1062 
       
  1063 
       
  1064 EXPORT_C void CAgnEntry::SetLocationL(const TDesC& aLocation)
       
  1065 /** Sets the contents of the entry's location field. 
       
  1066 
       
  1067 Sets the entry's 'has extended' property.
       
  1068 
       
  1069 @internalComponent
       
  1070 @param aLocation Descriptor containing a location, e.g. for a meeting. 
       
  1071 */
       
  1072 	{
       
  1073 	delete iLocation;
       
  1074 	iLocation = NULL;
       
  1075 	iLocation = aLocation.AllocL();
       
  1076 	}
       
  1077 
       
  1078 
       
  1079 EXPORT_C const TDesC& CAgnEntry::Location() const
       
  1080 /** Gets the contents of the entry's location field.
       
  1081 
       
  1082 @internalComponent
       
  1083 @return The location field. NULL if the entry has no location field. 
       
  1084 */
       
  1085 	{
       
  1086 	if ( iLocation )
       
  1087 		{
       
  1088 		return *iLocation;
       
  1089 		}
       
  1090 		
       
  1091 	return KNullDesC();
       
  1092 	}
       
  1093 
       
  1094 
       
  1095 EXPORT_C TInt CAgnEntry::AttendeeCount() const
       
  1096 /** Gets the number of attendees that have been added to the entry.
       
  1097 
       
  1098 @internalComponent
       
  1099 @return Number of attendees added. 
       
  1100 */
       
  1101 	{
       
  1102 	if ( ! iAttendeeList )
       
  1103 		{
       
  1104 		return 0;
       
  1105 		}
       
  1106 	
       
  1107 	return iAttendeeList->Count();
       
  1108 	}
       
  1109 
       
  1110 EXPORT_C CAgnAttendee& CAgnEntry::FetchAttendee(TInt aIndex) const
       
  1111 /** Gets the attendee at the specified index within the entry's list of 
       
  1112 attendees. 
       
  1113 
       
  1114 The index specified must be valid (between zero and AttendeeCount() 
       
  1115 - 1), otherwise a panic occurs.
       
  1116 
       
  1117 @internalComponent
       
  1118 @param aIndex Index to identify the specified attendee.
       
  1119 @return The attendee details. */
       
  1120 	{
       
  1121 	return *(*iAttendeeList)[aIndex];
       
  1122 	}
       
  1123 
       
  1124 
       
  1125 EXPORT_C void CAgnEntry::AddAttendeeL(CAgnAttendee* aAttendee)
       
  1126 /** Appends an attendee to the entry's list of attendees.
       
  1127 
       
  1128 @internalComponent
       
  1129 @param aAttendee Pointer to the attendee details. 
       
  1130 */
       
  1131 	{
       
  1132 	CleanupStack::PushL(aAttendee);
       
  1133 	CreateAttendeeListL();
       
  1134 	
       
  1135 	// Add an attendee for this entry
       
  1136 	iAttendeeList->AppendL(aAttendee);
       
  1137 	CleanupStack::Pop(aAttendee);
       
  1138 	}
       
  1139 
       
  1140 void CAgnEntry::CreateAttendeeListL()
       
  1141 	{
       
  1142 	if ( !iAttendeeList )
       
  1143 		{
       
  1144 		iAttendeeList = new (ELeave) RPointerArray<CAgnAttendee>;
       
  1145 		}
       
  1146 	}
       
  1147 	
       
  1148 EXPORT_C void CAgnEntry::SetOrganizerL(CAgnAttendee* aAttendee)
       
  1149 /** Set attendee as organiser
       
  1150 
       
  1151 @internalComponent
       
  1152 */
       
  1153 	{
       
  1154 	if (iMeetingOrganizer == iPhoneOwner)
       
  1155 		{
       
  1156 		iPhoneOwner = NULL;
       
  1157 		}
       
  1158 	delete iMeetingOrganizer;
       
  1159 	iMeetingOrganizer = aAttendee;
       
  1160 	}
       
  1161 
       
  1162 EXPORT_C CAgnAttendee* CAgnEntry::Organizer() const
       
  1163 /** Get Organizer as attendee object
       
  1164 
       
  1165 @internalComponent
       
  1166 */
       
  1167 	{
       
  1168 	return iMeetingOrganizer;
       
  1169 	}
       
  1170 
       
  1171 EXPORT_C void CAgnEntry::DeleteAttendee(TInt aIndex)
       
  1172 /** Deletes the attendee at the index specified from the entry's list of attendees. 
       
  1173 
       
  1174 If there is no attendee at the index specified, a panic occurs.
       
  1175 
       
  1176 @internalComponent
       
  1177 @param aIndex Index of the attendee to delete. 
       
  1178 */
       
  1179 	{
       
  1180 	CAgnAttendee* attendee = (*iAttendeeList)[aIndex];
       
  1181 	
       
  1182 	if (iPhoneOwner == attendee)
       
  1183 		{
       
  1184 		iPhoneOwner = NULL;
       
  1185 		}
       
  1186 		
       
  1187 	if (iMeetingOrganizer == attendee)
       
  1188 		{
       
  1189 		iMeetingOrganizer = NULL;
       
  1190 		}
       
  1191 		
       
  1192 	iAttendeeList->Remove(aIndex);
       
  1193 	delete attendee;
       
  1194 	}
       
  1195 
       
  1196 
       
  1197 EXPORT_C CAgnAttendee* CAgnEntry::PhoneOwner() const
       
  1198 /** Get Phone owner as attendee object
       
  1199 
       
  1200 @internalComponent
       
  1201 */
       
  1202 	{
       
  1203 	return iPhoneOwner;
       
  1204 	}
       
  1205 
       
  1206 
       
  1207 EXPORT_C void CAgnEntry::SetPhoneOwnerL(CAgnAttendee* aAttendee)
       
  1208 /** Set Phone owner as attendee, this must be an existing attendee
       
  1209 
       
  1210 @internalComponent
       
  1211 @leave KErrNotFound if the passed attendee is not matching anyone in the current list
       
  1212 */
       
  1213 	{
       
  1214 	TInt ownerExists = KErrNotFound;
       
  1215 	
       
  1216 	if (iAttendeeList)
       
  1217 		{
       
  1218 		const TInt KCount = iAttendeeList->Count();
       
  1219 		
       
  1220 		for (TInt i = 0; i < KCount; ++i)
       
  1221 			{		
       
  1222 			if (aAttendee == (*iAttendeeList)[i])
       
  1223 				{
       
  1224 				ownerExists = i;
       
  1225 				}
       
  1226 			}
       
  1227 		}
       
  1228 		
       
  1229 	if (ownerExists == KErrNotFound && aAttendee != iMeetingOrganizer)	
       
  1230 		{
       
  1231 		User::Leave(KErrNotFound);
       
  1232 		}
       
  1233 		
       
  1234 	iPhoneOwner = aAttendee;
       
  1235 	}
       
  1236 
       
  1237 
       
  1238 EXPORT_C void CAgnEntry::SetDTStampUtcL(const TTime& aDTStampUtc)
       
  1239 /**
       
  1240 @internalComponent
       
  1241 */
       
  1242 	{
       
  1243 	iDTStampUtc = aDTStampUtc;
       
  1244 	}
       
  1245 
       
  1246 
       
  1247 EXPORT_C const TTime& CAgnEntry::DTStampUtcL() const
       
  1248 /**
       
  1249 @internalComponent
       
  1250 @return TTime
       
  1251 */
       
  1252 	{
       
  1253 	return iDTStampUtc;
       
  1254 	}
       
  1255 
       
  1256 EXPORT_C TInt CAgnEntry::CategoryCount() const
       
  1257 /** Gets the number of categories owned by the entry.
       
  1258 
       
  1259 @internalComponent
       
  1260 @return The number of categories. 
       
  1261 */
       
  1262 	{
       
  1263 	if ( !iCategoryList )
       
  1264 		{
       
  1265 		return 0;
       
  1266 		}
       
  1267 	
       
  1268 	return iCategoryList->Count();
       
  1269 	}
       
  1270 
       
  1271 
       
  1272 EXPORT_C void CAgnEntry::AddCategoryL(CAgnCategory* aCategory)
       
  1273 /** Appends a category to the entry's list of categories. 
       
  1274 
       
  1275 The entry takes ownership of the category specified.
       
  1276 
       
  1277 @internalComponent
       
  1278 @param aCategory The category to be added
       
  1279 @leave KErrAlreadyExists if category already present
       
  1280 */
       
  1281 	{
       
  1282 	// Add an category for this entry
       
  1283 	if ( !iCategoryList )
       
  1284 		{
       
  1285 		iCategoryList = new (ELeave) RPointerArray<CAgnCategory>;
       
  1286 		}		
       
  1287 
       
  1288 	// Need to check that the category isn't already in the list
       
  1289 	if ( ! CategoryExist(*aCategory) )
       
  1290 		{
       
  1291 		iCategoryList->AppendL(aCategory);
       
  1292 		}
       
  1293 	else
       
  1294 		{
       
  1295 		User::Leave(KErrAlreadyExists);
       
  1296 		}
       
  1297 	}
       
  1298 
       
  1299 TBool CAgnEntry::CategoryExist(CAgnCategory& aSearchCategory) const
       
  1300 /** Check if category is already present
       
  1301 
       
  1302 @internalComponent
       
  1303 */
       
  1304 	{
       
  1305 	if (!iCategoryList)
       
  1306 		{
       
  1307 		return EFalse;
       
  1308 		}
       
  1309 	
       
  1310 	//return ETrue if aSearchCategory belongs to this object, otherwise return EFalse
       
  1311 	const TInt KNumCatList = iCategoryList->Count();
       
  1312 	
       
  1313 	for ( TInt i = 0; i < KNumCatList; ++i )
       
  1314 		{
       
  1315 		CAgnCategory& category = FetchCategory(i);
       
  1316 		
       
  1317 		CCalCategory::TCalCategoryType categoryType = category.Category();
       
  1318 		
       
  1319 		if ( categoryType == aSearchCategory.Category()) 
       
  1320 			{
       
  1321 			if ( categoryType == CCalCategory::ECalExtended ) // Need to compare names
       
  1322 				{
       
  1323 				if ( category.ExtendedCategoryName().CompareF(aSearchCategory.ExtendedCategoryName()) == 0 )
       
  1324 					{
       
  1325 					return ETrue;
       
  1326 					}
       
  1327 				}
       
  1328 			else
       
  1329 				{
       
  1330 				return ETrue;
       
  1331 				}
       
  1332 			}
       
  1333 		}
       
  1334 
       
  1335 	return EFalse;
       
  1336 	}
       
  1337 
       
  1338 
       
  1339 EXPORT_C CAgnCategory& CAgnEntry::FetchCategory(TInt aIndex) const
       
  1340 /** Gets the indexed category.
       
  1341 
       
  1342 @internalComponent
       
  1343 @param aIndex Index into the entry's list of categories. Must be valid 
       
  1344 or a panic occurs.
       
  1345 @return Pointer to the category located at the index specified. 
       
  1346 */
       
  1347 	{
       
  1348 	__ASSERT_DEBUG(iCategoryList != NULL, Panic(EAgmErrCategoryListNotInitialised));
       
  1349 	__ASSERT_DEBUG(aIndex < iCategoryList->Count(), Panic(EAgmErrCategoryOutOfRange));
       
  1350 	
       
  1351 	return *(*iCategoryList)[aIndex];
       
  1352 	}
       
  1353 
       
  1354 
       
  1355 EXPORT_C void CAgnEntry::DeleteCategory(TInt aIndex)
       
  1356 /** Deletes the indexed category.
       
  1357 
       
  1358 @internalComponent
       
  1359 @param aIndex Index into the entry's list of categories. Must be valid 
       
  1360 or a panic occurs. 
       
  1361 */
       
  1362 	{
       
  1363 	__ASSERT_DEBUG(iCategoryList != NULL, Panic(EAgmErrCategoryListNotInitialised));
       
  1364 	CAgnCategory* category = (*iCategoryList)[aIndex];
       
  1365 	delete category;
       
  1366 	iCategoryList->Remove(aIndex);
       
  1367 	
       
  1368 	if ( iCategoryList->Count() == 0 )
       
  1369 		{
       
  1370 		iCategoryList->ResetAndDestroy();
       
  1371 		delete iCategoryList;
       
  1372 		iCategoryList=NULL;
       
  1373 		}
       
  1374 	}
       
  1375 
       
  1376 
       
  1377 EXPORT_C const TDesC& CAgnEntry::Description() const
       
  1378 /** Gets the notes text. 
       
  1379 
       
  1380 If no notes text has been set, a empty descriptor (KNullDesC) is returned.
       
  1381 
       
  1382 @internalComponent
       
  1383 @capability ReadUserData
       
  1384 @return The notes text. 
       
  1385 */
       
  1386 	{
       
  1387 	if ( iDescription )
       
  1388 		{
       
  1389 		return *iDescription;
       
  1390 		}
       
  1391 	return KNullDesC;
       
  1392 	}
       
  1393 
       
  1394 
       
  1395 EXPORT_C TBool CAgnEntry::DescriptionIsLoaded() const
       
  1396 /** Check notes is loaded
       
  1397 
       
  1398 @internalComponent
       
  1399 @capability ReadUserData
       
  1400 @return Boolean to indicate if loaded or not
       
  1401 */
       
  1402 	{
       
  1403 	if ( !iDescription && iDescriptionStreamId != KNullStreamId )
       
  1404 		{
       
  1405 		return EFalse;
       
  1406 		}		
       
  1407 
       
  1408 	return ETrue;
       
  1409 	}
       
  1410 
       
  1411 
       
  1412 EXPORT_C void CAgnEntry::SetDescription(HBufC* aDescription)
       
  1413 /** Sets the notes text. 
       
  1414 
       
  1415 This object takes ownership of aNotes.
       
  1416 
       
  1417 @internalComponent
       
  1418 @param aNotes Notes text. 
       
  1419 */
       
  1420 	{
       
  1421 	delete iDescription;
       
  1422 	iDescription = aDescription;
       
  1423 	}
       
  1424 
       
  1425 
       
  1426 EXPORT_C CAgnEntry::TAgnDataChange CAgnEntry::DescriptionChange() const
       
  1427 /** Check if the notes changed
       
  1428 
       
  1429 	1. If iDescription is NULL, The description has never been added  or never been loaded - No Change
       
  1430 	2. If iDescriptionStreamId is not KNullStreamId and iDecription is KNullDesC, The descrioption has been deleted (CAgnEntry::SetDescrioprion() can be used to delete description)
       
  1431 	3. If iDescriptionStreamId is not KNullStreamId and iDecription is not KNullDesC, The descrioption could be updated
       
  1432 	4. If iDescriptionStreamId is KNullStreamId and iDescription is not KNullDesC, The description has been added
       
  1433 
       
  1434 @internalComponent
       
  1435 @return TAgnDescriptionChange value indicating the type of change
       
  1436 */
       
  1437 	{
       
  1438 	TAgnDataChange change = EAgnDataNoChange;
       
  1439 	if ( iDescription )
       
  1440 		{
       
  1441 		if ( iDescriptionStreamId != KNullStreamId )
       
  1442 			{
       
  1443 			if ( *iDescription == KNullDesC )
       
  1444 				{
       
  1445 				change = EAgnDataDeleted;
       
  1446 				}
       
  1447 			else
       
  1448 				{
       
  1449 				change = EAgnDataUpdated;
       
  1450 				}
       
  1451 			}
       
  1452 		else if ( *iDescription != KNullDesC )
       
  1453 			{
       
  1454 			change = EAgnDataAdded;
       
  1455 			}
       
  1456 		}
       
  1457 
       
  1458 	return change;
       
  1459 	}
       
  1460 
       
  1461 
       
  1462 EXPORT_C CAgnEntry::TAgnDataChange CAgnEntry::SummaryChange() const
       
  1463 /** Check if the summary changed
       
  1464 
       
  1465 	1. If iSummary is NULL, The Summary has never been added or laoded- No Change
       
  1466 	2. If iSummaryStreamId is not KNullStreamId and iSummary is KNullDesC, The Summary has been deleted (CAgnEntry::SetSummary() can be used to delete description)
       
  1467 	3. If iSummaryStreamId is not KNullStreamId and iSummary is not KNullDesC, The Summary could be updated
       
  1468 	4. If iSummaryStreamId is KNullStreamId and iSummary is not KNullDesC, The Summary has been added
       
  1469 
       
  1470 @internalComponent
       
  1471 @return TAgnSummaryChange value indicating the type of change
       
  1472 */
       
  1473 	{
       
  1474 	TAgnDataChange change = EAgnDataNoChange;
       
  1475 	
       
  1476 	if ( iSummary )
       
  1477 		{
       
  1478 		if ( iSummaryStreamId != KNullStreamId )
       
  1479 			{
       
  1480 			if ( *iSummary == KNullDesC )
       
  1481 				{
       
  1482 				change = EAgnDataDeleted;
       
  1483 				}
       
  1484 			else
       
  1485 				{
       
  1486 				change = EAgnDataUpdated;
       
  1487 				}
       
  1488 			}
       
  1489 		else if ( *iSummary != KNullDesC )
       
  1490 			{
       
  1491 			change = EAgnDataAdded;
       
  1492 			}
       
  1493 		}
       
  1494 
       
  1495 	return change;
       
  1496 	}
       
  1497 
       
  1498 
       
  1499 EXPORT_C CAgnEntry::TAgnDataChange CAgnEntry::AlarmActionChange() const
       
  1500 /** Check if the alarm action changed
       
  1501 
       
  1502 	1. If iAlarmActionDeleted is true, alarm has been deleted
       
  1503 	2. If iAlarmActionStreamId is KNullStreamId and iAlarmAction is not NULL, alarm has been added
       
  1504 	3. If iAlarmActionStreamId is not KNullStreamId and iAlarmAction is not KNullDesC, The AlarmAction could be updated
       
  1505 
       
  1506 @internalComponent
       
  1507 @return TAgnAlarmActionChange value indicating the type of change
       
  1508 */
       
  1509 	{
       
  1510 	TAgnDataChange change = EAgnDataNoChange;
       
  1511 	
       
  1512 	if ( IsFlagSet(EAgnAlarmActionDeleted) )
       
  1513 		{
       
  1514 		change = EAgnDataDeleted;
       
  1515 		}
       
  1516 	else if ( iAlarmAction )
       
  1517 		{
       
  1518 		if ( iAlarmActionStreamId == KNullStreamId )
       
  1519 			{
       
  1520 			change = EAgnDataAdded;
       
  1521 			}
       
  1522 		else
       
  1523 			{
       
  1524 			change = EAgnDataUpdated;
       
  1525 			}
       
  1526 		}
       
  1527 
       
  1528 	return change;
       
  1529 	}
       
  1530 
       
  1531 
       
  1532 EXPORT_C const TStreamId& CAgnEntry::DescriptionStreamId() const
       
  1533 /** Gets the ID of the embedded stream store in which the description has been stored.
       
  1534 
       
  1535 @internalComponent
       
  1536 @return The ID for the stream store in which the description has been stored.
       
  1537 */
       
  1538 	{
       
  1539 	return iDescriptionStreamId;
       
  1540 	}
       
  1541 
       
  1542 
       
  1543 EXPORT_C void CAgnEntry::SetDescriptionStreamId(const TStreamId& aStreamId)
       
  1544 /** Sets the ID of the embedded stream store in which the description has been stored.
       
  1545 
       
  1546 @internalComponent
       
  1547 @param The ID for the stream store in which the description has been stored.
       
  1548 */
       
  1549 	{
       
  1550 	iDescriptionStreamId = aStreamId;
       
  1551 	}
       
  1552 
       
  1553 
       
  1554 EXPORT_C void CAgnEntry::SetSummaryStreamId(const TStreamId& aStreamId)
       
  1555 /** Sets the ID of the embedded stream store in which the summary has been stored.
       
  1556 
       
  1557 @internalComponent
       
  1558 @param The ID for the stream store in which the summary has been stored.
       
  1559 */
       
  1560 	{
       
  1561 	iSummaryStreamId = aStreamId;
       
  1562 	}
       
  1563 
       
  1564 EXPORT_C const TStreamId& CAgnEntry::SummaryStreamId() const
       
  1565 /** Gets the ID of the embedded stream store in which the summary has been stored.
       
  1566 
       
  1567 @internalComponent
       
  1568 @return The ID for the stream store in which the summary has been stored.
       
  1569 */
       
  1570 	{
       
  1571 	return iSummaryStreamId;
       
  1572 	}
       
  1573 
       
  1574 /**
       
  1575 @internalComponent
       
  1576 @capability None
       
  1577 @return   TPtrC8
       
  1578 */	
       
  1579 EXPORT_C const TDesC8& CAgnEntry::Guid() const
       
  1580 	{
       
  1581 	return iGsData->Guid();
       
  1582 	}
       
  1583 
       
  1584 EXPORT_C void CAgnEntry::SetMethod(CCalEntry::TMethod aMethod)
       
  1585 	{
       
  1586 	iGsData->SetMethod(aMethod);
       
  1587 	}
       
  1588 
       
  1589 EXPORT_C void CAgnEntry::SetGuid(HBufC8* aGuid)
       
  1590 /**
       
  1591 @internalComponent
       
  1592 */
       
  1593 	{
       
  1594 	iGsData->SetGuid(aGuid);
       
  1595 	}
       
  1596 
       
  1597 EXPORT_C CGsData::TGsDataType CAgnEntry::GsDataType() const
       
  1598 /**
       
  1599 @internalComponent
       
  1600 */
       
  1601 	{
       
  1602 	return iGsData->GsDataType();
       
  1603 	}
       
  1604 
       
  1605 EXPORT_C CCalEntry::TMethod CAgnEntry::Method() const
       
  1606 /**
       
  1607 @internalComponent
       
  1608 */
       
  1609 	{
       
  1610 	return iGsData->Method();
       
  1611 	}
       
  1612 
       
  1613 EXPORT_C TInt CAgnEntry::SequenceNumber() const
       
  1614 /**
       
  1615 @internalComponent
       
  1616 */
       
  1617 	{
       
  1618 	return iGsData->SequenceNumber();
       
  1619 	}
       
  1620 
       
  1621 
       
  1622 EXPORT_C void CAgnEntry::SetSequenceNumber(TInt aSeqNum)
       
  1623 	{
       
  1624 	iGsData->SetSequenceNumber(aSeqNum);
       
  1625 	}	
       
  1626 /**
       
  1627 @internalComponent
       
  1628 @capability None
       
  1629 @return   TTime
       
  1630 */
       
  1631 EXPORT_C TAgnCalendarTime CAgnEntry::RecurrenceId() const
       
  1632 	{
       
  1633 	return iGsData->RecurrenceId();
       
  1634 	}
       
  1635 
       
  1636 /** 
       
  1637 @internalComponent
       
  1638 */
       
  1639 EXPORT_C CalCommon::TRecurrenceRange CAgnEntry::RecurrenceRange() const
       
  1640 	{
       
  1641 	return iGsData->RecurrenceRange();
       
  1642 	}
       
  1643 		
       
  1644 EXPORT_C TCalLocalUid CAgnEntry::ParentId() const
       
  1645 	{
       
  1646 	__ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry));
       
  1647 
       
  1648 	return (static_cast<CGsChildData*>(iGsData)->ParentId());
       
  1649 	}
       
  1650 
       
  1651 EXPORT_C void CAgnEntry::SetParentId(TCalLocalUid aParentId)
       
  1652 	{
       
  1653 	__ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry));
       
  1654 
       
  1655 	static_cast<CGsChildData*>(iGsData)->SetParentId(aParentId);
       
  1656 	}
       
  1657 
       
  1658 EXPORT_C void CAgnEntry::UpdateRecurrenceIdL(const TAgnCalendarTime& aRecId)
       
  1659 	{
       
  1660 	__ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry));
       
  1661 	
       
  1662 	CGsChildData* childData = static_cast<CGsChildData*>(iGsData);
       
  1663 	TTimeIntervalHours hoursChange;
       
  1664 	aRecId.UtcL().HoursFrom(RecurrenceId().UtcL(), hoursChange);
       
  1665 	childData->SetRecurrenceId(aRecId);
       
  1666 	}
       
  1667 
       
  1668 EXPORT_C void CAgnEntry::SetRecurrenceRangeL(CalCommon::TRecurrenceRange aRange)
       
  1669 	{
       
  1670 	if (RptDef())
       
  1671 		{
       
  1672 		__ASSERT_DEBUG(aRange == CalCommon::EThisAndFuture || aRange == CalCommon::EThisAndPrior, User::Leave(KErrCorrupt));
       
  1673 		}
       
  1674 	else
       
  1675 		{
       
  1676 		__ASSERT_DEBUG(aRange == CalCommon::EThisOnly, User::Leave(KErrCorrupt));
       
  1677 		}
       
  1678 
       
  1679 	CGsChildData* childData = static_cast<CGsChildData*>(iGsData);
       
  1680 	childData->SetRecurrenceRange(aRange);
       
  1681 	}
       
  1682 
       
  1683 EXPORT_C TBool CAgnEntry::HasChildren() const
       
  1684 	{
       
  1685 	if (GsDataType() == CGsData::EParent && ChildIds().Count() > 0)
       
  1686 		{
       
  1687 		return ETrue;
       
  1688 		}
       
  1689 	return EFalse;
       
  1690 	}
       
  1691 
       
  1692 EXPORT_C const RArray<TGsChildRefData>& CAgnEntry::ChildIds() const
       
  1693 	{
       
  1694 	__ASSERT_DEBUG(GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry));
       
  1695 
       
  1696 	return (static_cast<CGsParentData*>(iGsData)->ChildIds());
       
  1697 	}
       
  1698 	
       
  1699 EXPORT_C void CAgnEntry::AddChildIdL(const TGsChildRefData& aChildRefData)
       
  1700 	{
       
  1701 	__ASSERT_DEBUG(GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry));
       
  1702 
       
  1703 	static_cast<CGsParentData*>(iGsData)->AddChildIdL(aChildRefData);
       
  1704 	}
       
  1705 	
       
  1706 EXPORT_C void CAgnEntry::RemoveChildId(TCalLocalUid aId)
       
  1707 	{
       
  1708 	__ASSERT_DEBUG(GsDataType() == CGsData::EParent, Panic(EAgmErrNotParentEntry));
       
  1709 
       
  1710 	static_cast<CGsParentData*>(iGsData)->RemoveChildId(aId);
       
  1711 	}
       
  1712 
       
  1713 EXPORT_C void CAgnEntry::SetRecurrenceIdFromParentL(const CAgnEntry& aParentEntry)
       
  1714 	{//Set the recurrence id and range by its parent data.
       
  1715 	__ASSERT_DEBUG(GsDataType() == CGsData::EChild, Panic(EAgmErrNotChildEntry));
       
  1716 	TAgnCalendarTime recurid = RecurrenceId();
       
  1717 	
       
  1718 	CGsChildData* childGsData = static_cast<CGsChildData*>(iGsData);
       
  1719 	if ( ! recurid.IsSet())
       
  1720 		{
       
  1721 		recurid = aParentEntry.GetChildRecurrenceId(LocalUid());
       
  1722 		childGsData->SetRecurrenceId(recurid);
       
  1723 		}
       
  1724 	}
       
  1725 
       
  1726  TAgnCalendarTime CAgnEntry::GetChildRecurrenceId(TCalLocalUid aChildId) const
       
  1727 	{//Get the recurrence id for one of its children
       
  1728 	const RArray<TGsChildRefData>& KChildIds = ChildIds();
       
  1729 
       
  1730 	const TInt KCount((KChildIds.Count()));
       
  1731 	TAgnCalendarTime recurId;
       
  1732 	
       
  1733 	for (TInt i = 0; i < KCount; ++i)
       
  1734 		{
       
  1735 		if (KChildIds[i].ChildId() == aChildId)
       
  1736 			{
       
  1737 			recurId = KChildIds[i].RecurrenceId();
       
  1738 			break;
       
  1739 			}
       
  1740 		}
       
  1741 	return recurId;
       
  1742 	}
       
  1743 
       
  1744 
       
  1745 EXPORT_C void CAgnEntry::SetAlarmAction(CAgnContent* aAlarmAction)
       
  1746 /** Set an alarm action object to the Agenda entry.
       
  1747 The Agenda Entry takes ownership of the passed object.
       
  1748 @internalComponent
       
  1749 */
       
  1750 	{
       
  1751 	if(iAlarmAction && !aAlarmAction && iAlarmActionStreamId != KNullStreamId)
       
  1752 		{
       
  1753 		SetFlagOn(EAgnAlarmActionDeleted);
       
  1754 		}
       
  1755 
       
  1756 	delete iAlarmAction;
       
  1757 
       
  1758 	// Take ownership of the content.
       
  1759 	iAlarmAction = aAlarmAction;
       
  1760 	}
       
  1761 
       
  1762 
       
  1763 EXPORT_C TBool CAgnEntry::AlarmActionIsLoaded() const
       
  1764 /** Check if Alarm action object is loaded from the stream
       
  1765 @internalComponent
       
  1766 */
       
  1767 	{
       
  1768 	if ( !iAlarmAction && iAlarmActionStreamId != KNullStreamId && ! IsFlagSet(EAgnAlarmActionDeleted) )
       
  1769 		{
       
  1770 		return EFalse;
       
  1771 		}		
       
  1772 
       
  1773 	return ETrue;
       
  1774 	}
       
  1775 
       
  1776 	
       
  1777 EXPORT_C CAgnContent* CAgnEntry::AlarmAction() const
       
  1778 /** Get the Alarm action object
       
  1779 @internalComponent
       
  1780 */
       
  1781 	{
       
  1782 	return iAlarmAction;
       
  1783 	}
       
  1784 
       
  1785 
       
  1786 EXPORT_C void CAgnEntry::SetAlarmActionStreamId(const TStreamId& aStreamId)
       
  1787 /** Set the Alarm action stream id
       
  1788 @internalComponent
       
  1789 */
       
  1790 	{
       
  1791 	iAlarmActionStreamId = aStreamId;
       
  1792 	}
       
  1793 
       
  1794 
       
  1795 EXPORT_C const TStreamId& CAgnEntry::AlarmActionStreamId() const
       
  1796 /** Get the Alarm action stream id
       
  1797 @internalComponent
       
  1798 */
       
  1799 	{
       
  1800 	return iAlarmActionStreamId;
       
  1801 	}
       
  1802 
       
  1803 EXPORT_C void CAgnEntry::AddAttachmentL(CAgnAttachment* aAttachment)
       
  1804 	{
       
  1805 	if (!iAttachments)
       
  1806 		{
       
  1807 		iAttachments = new (ELeave) RPointerArray<CAgnAttachment>;
       
  1808 		}
       
  1809 	if (aAttachment)
       
  1810 		{
       
  1811 		iAttachments->AppendL(aAttachment);	
       
  1812 		}
       
  1813 	}
       
  1814 
       
  1815 EXPORT_C TInt CAgnEntry::DeleteAttachmentL(const CAgnAttachment& aAttachment)
       
  1816 	{
       
  1817 	TInt ret = -1;
       
  1818 	if (iAttachments)
       
  1819 		{
       
  1820 		const TInt KAttachmentCount = iAttachments->Count();
       
  1821 		for (TInt i = 0; i < KAttachmentCount; ++i)
       
  1822 			{
       
  1823 			CAgnAttachment* attachToCompare = (*iAttachments)[i];
       
  1824 			if (attachToCompare->CompareL(aAttachment))
       
  1825 				{
       
  1826 				ret = i;
       
  1827 				delete attachToCompare;
       
  1828 				iAttachments->Remove(i);
       
  1829 				break;
       
  1830 				}
       
  1831 			}
       
  1832 		}
       
  1833 	return ret;
       
  1834 	}
       
  1835 
       
  1836 EXPORT_C CAgnAttachment& CAgnEntry::Attachment(TInt aIndex) const
       
  1837 	{
       
  1838 	return *(*iAttachments)[aIndex];
       
  1839 	}
       
  1840 
       
  1841 EXPORT_C TInt CAgnEntry::AttachmentCount() const
       
  1842 	{
       
  1843 	if (iAttachments)
       
  1844 		{
       
  1845 		return iAttachments->Count();
       
  1846 		}
       
  1847 	return 0;
       
  1848 	}
       
  1849 
       
  1850 /** 
       
  1851 Sets the user integer for this entry.
       
  1852 
       
  1853 @param aUserInt The new value of the user integer. 
       
  1854 @internalComponent
       
  1855 */
       
  1856 EXPORT_C void CAgnEntry::SetUserInt( TUint32 aUserInt )
       
  1857     {
       
  1858     CAgnSimpleEntry::SetUserInt(aUserInt);
       
  1859     }
       
  1860 
       
  1861 /**
       
  1862 Gets the user integer of this entry.
       
  1863 
       
  1864 @return The user integer.
       
  1865 @internalComponent
       
  1866 */
       
  1867 EXPORT_C TUint32 CAgnEntry::UserInt() const
       
  1868     {
       
  1869     return CAgnSimpleEntry::UserInt();
       
  1870     }
       
  1871 
       
  1872 EXPORT_C void CAgnEntry::ExternalizeToBufferL(RWriteStream& aWriteStream) const
       
  1873 /** Used for passing the data to the between client and server
       
  1874 @internalComponent
       
  1875 */
       
  1876 	{
       
  1877 	ExternalizeEntryL(aWriteStream, ETrue);
       
  1878 	ExternalizeGsDataL(aWriteStream, ETrue);
       
  1879 		
       
  1880 	if ( iDescription )
       
  1881 		{
       
  1882 		aWriteStream.WriteUint8L(ETrue);
       
  1883 		aWriteStream << *iDescription;	
       
  1884 		}
       
  1885 	else
       
  1886 		{
       
  1887 		aWriteStream.WriteUint8L(EFalse);	
       
  1888 		}
       
  1889 
       
  1890 	if ( iSummary )
       
  1891 		{
       
  1892 		aWriteStream.WriteUint8L(ETrue);
       
  1893 		aWriteStream << *iSummary;	
       
  1894 		}
       
  1895 	else
       
  1896 		{
       
  1897 		aWriteStream.WriteUint8L(EFalse);	
       
  1898 		}
       
  1899 	
       
  1900 	TBool hasAlarmContent = iAlarmAction?ETrue:EFalse;
       
  1901 	aWriteStream.WriteUint8L(hasAlarmContent);
       
  1902 	if ( hasAlarmContent )
       
  1903 		{
       
  1904 		aWriteStream << *iAlarmAction;
       
  1905 		}
       
  1906 
       
  1907 	aWriteStream.WriteUint8L(IsFlagSet(EAgnAlarmActionDeleted));
       
  1908 	}
       
  1909 
       
  1910 
       
  1911 EXPORT_C void CAgnEntry::InternalizeFromBufferL(RReadStream& aReadStream)
       
  1912 /** Used for passing the data to the between client and server
       
  1913 @internalComponent
       
  1914 */
       
  1915 	{
       
  1916 	InternalizeEntryL(aReadStream, ETrue);
       
  1917 	InternalizeGsDataL(aReadStream, ETrue);
       
  1918 
       
  1919 	delete iDescription;
       
  1920 	iDescription = NULL;
       
  1921 	if(aReadStream.ReadUint8L())//iDescription is not NULL
       
  1922 		{//The following does not allocate KMaxTInt cells on heap
       
  1923 		iDescription = HBufC::NewL(aReadStream, KMaxTInt); 	
       
  1924 		}
       
  1925 	
       
  1926 	delete iSummary;
       
  1927 	iSummary = NULL;
       
  1928 	
       
  1929 	if(aReadStream.ReadUint8L())//iSummary is not NULL
       
  1930 		{//The following does not allocate KMaxTInt cells on heap
       
  1931 		iSummary = HBufC::NewL(aReadStream, KMaxTInt); 	
       
  1932 		}
       
  1933 
       
  1934 	delete iAlarmAction;
       
  1935 	iAlarmAction = NULL;
       
  1936 	TBool hasAlarmContent = aReadStream.ReadUint8L();
       
  1937 	if ( hasAlarmContent )
       
  1938 		{
       
  1939 		iAlarmAction = new (ELeave) CAgnContent;
       
  1940 		aReadStream >> *iAlarmAction; 
       
  1941 		}
       
  1942 
       
  1943 	if (aReadStream.ReadUint8L())
       
  1944 		{
       
  1945 		SetFlagOn(EAgnAlarmActionDeleted);
       
  1946 		}
       
  1947 	else
       
  1948 		{
       
  1949 		SetFlagOff(EAgnAlarmActionDeleted);
       
  1950 		}
       
  1951 	// Externalize the entry details to the buffer
       
  1952 	// Any rich text components will be stored in the textStream buffer
       
  1953 	}
       
  1954 
       
  1955 
       
  1956 EXPORT_C CCalEntry::TTransp CAgnEntry::BusyStatus() const
       
  1957 /** Get transparency value
       
  1958 @internalComponent
       
  1959 */
       
  1960 	{
       
  1961 	return static_cast<CCalEntry::TTransp>(iBusyStatus);
       
  1962 	}
       
  1963 
       
  1964 
       
  1965 EXPORT_C void CAgnEntry::SetBusyStatusL(CCalEntry::TTransp aBusyStatus)
       
  1966 /** Set transparency value
       
  1967 @internalComponent
       
  1968 @leave KErrArgument if passed parameter is negative
       
  1969 */
       
  1970 	{
       
  1971 	if ( aBusyStatus < 0 )
       
  1972 		{
       
  1973 		User::Leave( KErrArgument );		
       
  1974 		}
       
  1975 		
       
  1976 	iBusyStatus = aBusyStatus;
       
  1977 	}
       
  1978 
       
  1979 EXPORT_C void CAgnEntry::GeoValue(TReal& aLatitude, TReal& aLongitude) const
       
  1980 	{
       
  1981 	aLatitude=iLatitude;
       
  1982 	aLongitude=iLongitude;
       
  1983 	}
       
  1984 
       
  1985 /** Set GEO - Latitude and Longitude values for the entry
       
  1986 Latitude is bound between +-0-90 degrees
       
  1987 Longitude is bound between +-0-180 degrees
       
  1988 @internalComponent
       
  1989 @leave KErrArgument if passed parameter is out of bounds.
       
  1990 */
       
  1991 EXPORT_C void CAgnEntry::SetGeoValueL(const TReal& aLatitude, const TReal& aLongitude)
       
  1992 	{
       
  1993 	// Bounds checking
       
  1994 	__ASSERT_ALWAYS(
       
  1995 	((aLatitude >= KCalGEOMinLatitude && aLatitude <= KCalGEOMaxLatitude) || aLatitude == KGEODefaultValue) 
       
  1996 	&& ((aLongitude >= KCalGEOMinLongitude && aLongitude <= KCalGEOMaxLongitude) || aLongitude == KGEODefaultValue), 
       
  1997 	User::Leave(KErrArgument));
       
  1998 	
       
  1999 	// Truncate to KGEOMaxDecimals decimal places
       
  2000 	TReal truncatedLatitude;
       
  2001 	TReal truncatedLongitude;
       
  2002 	Math::Round(truncatedLatitude,aLatitude,KCalGEOMaxDecimalPlaces);
       
  2003 	Math::Round(truncatedLongitude,aLongitude,KCalGEOMaxDecimalPlaces);
       
  2004 		
       
  2005 	iLatitude = truncatedLatitude;
       
  2006 	iLongitude = truncatedLongitude;
       
  2007 	}
       
  2008 
       
  2009 // verify entry is valid before storing it
       
  2010 EXPORT_C void CAgnEntry::VerifyBeforeStoreL()
       
  2011 	{
       
  2012 	//Check entry time
       
  2013 	if ( Type() != CCalEntry::ETodo )
       
  2014 		{
       
  2015 		__ASSERT_ALWAYS(StartTime().IsSet(), Panic(EAgmErrTimeNotSet));
       
  2016 		if ( Type() != CCalEntry::EReminder )
       
  2017 			{
       
  2018 			__ASSERT_ALWAYS(EndTime().IsSet(), Panic(EAgmErrTimeNotSet));
       
  2019 			}
       
  2020 		}
       
  2021 	//Check repeating rule
       
  2022 	if ( RptDef() )
       
  2023 		{
       
  2024 		// check entry's repeat rule valid
       
  2025 		if ( RptDef()->InvariantL() != KErrNone )
       
  2026 			{
       
  2027 			const TAgnRpt* rptRule = RptDef()->RRule();
       
  2028 			__ASSERT_ALWAYS(rptRule, User::Leave(KErrCorrupt)); // this can never be NULL if Invariant returns an error
       
  2029 			
       
  2030 			// if entry has only one instance, clear the repeat rule
       
  2031 			if ( rptRule->InstanceCountL() == 1 )
       
  2032 				{
       
  2033 				RptDef()->ClearRRule();
       
  2034 				}
       
  2035 			else
       
  2036 				{
       
  2037 				User::Leave(KErrArgument);
       
  2038 				}
       
  2039 			}
       
  2040 			
       
  2041 		else if (RptDef()->Exceptions())
       
  2042 			{
       
  2043 			RptDef()->PruneExceptionsL();
       
  2044 			}
       
  2045 
       
  2046 		//check the RDates here
       
  2047 		TInt i = 0;
       
  2048 		while (RptDef()->SporadicDateList() && i < RptDef()->SporadicDateList()->Count())
       
  2049 			{
       
  2050 			const TAgnCalendarTime& KSporadicDate = (*RptDef()->SporadicDateList())[i];
       
  2051 			if (RptDef()->IsARepeatRuleDateInstanceL(KSporadicDate.LocalL()))
       
  2052 				{
       
  2053 				RptDef()->RemoveSporadicDate(KSporadicDate);
       
  2054 				}
       
  2055 			else if (EntryTime() == KSporadicDate)
       
  2056 				{
       
  2057 				// the DTSTART may not be checked in IsARepeatRuleDateInstance, so check it explicitly
       
  2058 				RptDef()->RemoveSporadicDate(KSporadicDate);
       
  2059 				}
       
  2060 			else
       
  2061 				{
       
  2062 				// this sporadic date is ok
       
  2063 				++i;
       
  2064 				}
       
  2065 			}
       
  2066 
       
  2067 		const TAgnRpt* rptRule = RptDef()->RRule();
       
  2068 		if(!rptRule && !(RptDef()->HasSporadicDates()))
       
  2069 			{
       
  2070 			ClearRepeat();
       
  2071 			}
       
  2072 		}
       
  2073 	}
       
  2074 
       
  2075 void CAgnEntry::SetFlagOn(TFlags aFlag)
       
  2076 	{
       
  2077 	iFlags |= aFlag;
       
  2078 	}
       
  2079 
       
  2080 void CAgnEntry::SetFlagOff(TFlags aFlag)
       
  2081 	{
       
  2082 	iFlags &= ~aFlag;
       
  2083 	}
       
  2084 
       
  2085 TBool CAgnEntry::IsFlagSet(TFlags aFlag) const
       
  2086 	{
       
  2087 	return (iFlags & aFlag);
       
  2088 	}