agendainterface/agendautil/src/agendautil_p.cpp
changeset 55 2c54b51f39c4
parent 51 0b38fc5b94c6
child 57 bb2d3e476f29
equal deleted inserted replaced
51:0b38fc5b94c6 55:2c54b51f39c4
    30 #include <f32file.h>
    30 #include <f32file.h>
    31 #include <s32file.h>
    31 #include <s32file.h>
    32 #include <asshddefs.h>
    32 #include <asshddefs.h>
    33 
    33 
    34 // User includes
    34 // User includes
       
    35 #include <agendaentry.h>
    35 #include "agendautil_p.h"
    36 #include "agendautil_p.h"
    36 #include "agendaentry.h"
       
    37 #include "agendaentry_p.h"
    37 #include "agendaentry_p.h"
    38 #include "CleanupResetAndDestroy.h"
    38 #include "CleanupResetAndDestroy.h"
    39 
    39 
    40 // Constants
    40 // Constants
    41 //recognition string for ical
    41 //recognition string for ical
   199 
   199 
   200 	emit q->entriesChanged(ids);
   200 	emit q->entriesChanged(ids);
   201 }
   201 }
   202 
   202 
   203 /*!
   203 /*!
   204 	Adds a new entry with the calendar database.
   204 	To store the new entry or update the entry in the Calendar db.
   205 
   205 
   206 	\param entry Reference to a new AgendaEntry to be added.
   206 	\param entry The entry to be added/updated
   207 	\return ulong The local uid of the entry added in the db.
   207 	\param range The recurrence range of entry
   208  */
   208 	\return ulong The local uid of the entry added/updated in the db.
   209 ulong AgendaUtilPrivate::addEntry(const AgendaEntry& entry)
   209 */
       
   210 ulong AgendaUtilPrivate::store(AgendaEntry &entry, AgendaUtil::RecurrenceRange range)
   210 {
   211 {
   211 	// Will be filled with the lUID of the new entry created.
   212 	// Will be filled with the lUID of the new entry created.
   212 	TCalLocalUid localUid = 0;
   213 	TCalLocalUid localUid = 0;
   213 	int success = 0;
       
   214 
   214 
   215 	// First check if the session to the calendar database is prepared or not.
   215 	// First check if the session to the calendar database is prepared or not.
   216 	if (!mInstanceViewCreated) {
   216 	if (!mInstanceViewCreated) {
   217 		// Something went wrong
   217 		// Something went wrong
   218 		return localUid;
   218 		return localUid;
   219 	}
   219 	}
   220 
   220 	CCalEntry *calEntry = 0;
   221 	// Get the global uid.
   221 	
   222 	CCalenInterimUtils2* calenInterimUtils2 = CCalenInterimUtils2::NewL();
   222 	TRAP(
   223 	HBufC8* globalUid = calenInterimUtils2->GlobalUidL();
   223 			iError,
   224 	if (AgendaEntry::TypeNote == entry.type()) {
   224 			// Get the global uid.
       
   225 			CCalenInterimUtils2* calenInterimUtils2 = CCalenInterimUtils2::NewL();
       
   226 			bool isChild = !(entry.recurrenceId().isNull());
       
   227 			
       
   228 			//Flag to decide whether entry is added or updated
       
   229 			bool entryAdded = false;
       
   230 			
       
   231 			// if the entry id is zero means need to create a new entry
       
   232 			if ((AgendaUtil::ThisAndAll == range) && (0 == entry.id())) {
       
   233 		
       
   234 				entryAdded = true;
       
   235 				
       
   236 				HBufC8* globalUid = calenInterimUtils2->GlobalUidL();
       
   237 				CleanupStack::PushL(globalUid);
       
   238 				calEntry
       
   239 						= CCalEntry::NewL(
       
   240 										  static_cast<CCalEntry::TType> (entry.type()),
       
   241 										  globalUid,
       
   242 										  static_cast<CCalEntry::TMethod> (entry.method()),
       
   243 										  0);
       
   244 		
       
   245 				CleanupStack::Pop(globalUid);
       
   246 			} else if (((AgendaUtil::ThisOnly == range) && isChild)
       
   247 					|| ((AgendaUtil::ThisAndAll == range) && (entry.id() > 0))) {
       
   248 				
       
   249 				// Updating the entry/Exceptional entry
       
   250 				calEntry = iCalEntryView->FetchL(entry.id());
       
   251 				
       
   252 				CleanupStack::PushL(calEntry);
       
   253 				// Repeat rule 
       
   254 				TCalRRule rrule;
       
   255 				TBool isRepeating = calEntry->GetRRuleL( rrule );
       
   256 		
       
   257 				// If the repeat rule is cleared then Clear the Repeat rule from CCalEntry
       
   258 				if ((AgendaUtil::ThisAndAll == range) 
       
   259 						&& isRepeating && !(entry.isRepeating())) {
       
   260 					calEntry->ClearRepeatingPropertiesL();
       
   261 				}
       
   262 				CleanupStack::Pop(calEntry);	
       
   263 			} else {
       
   264 				// Creating a exceptional entry
       
   265 				if ((AgendaUtil::ThisOnly == range) && !isChild) {
       
   266 					// Get the entry corresponding to the id.
       
   267 					CCalEntry *parentEntry = iCalEntryView->FetchL(entry.id());
       
   268 					CleanupStack::PushL(parentEntry);
       
   269 					// We are creating an exception, hence get the global Uid
       
   270 					HBufC8* guid = parentEntry->UidL().AllocLC();
       
   271 					
       
   272 					QDateTime instanceOriginalDateTime = entry.startTime();
       
   273 					
       
   274 					// create new (child) entry
       
   275 					// Use original instance time for recurrenceID as this entry hasn't got one.
       
   276 					TCalTime originalCalTime;
       
   277 					TDateTime originalDateTime(instanceOriginalDateTime.date().year(),
       
   278 								TMonth(instanceOriginalDateTime.date().month() - 1),
       
   279 								instanceOriginalDateTime.date().day() -1,
       
   280 								0,
       
   281 								0,
       
   282 								0,
       
   283 								0);
       
   284 					
       
   285 					TTime originalDateTimeTTime(originalDateTime);
       
   286 					// Use floating time for non-timed entries so that
       
   287 					// the time will be same regardless of the timezone
       
   288 					if(entry.isTimedEntry()) {
       
   289 					    originalCalTime.SetTimeLocalL(originalDateTimeTTime);					    					    
       
   290 					}else {
       
   291 					    originalCalTime.SetTimeLocalFloatingL(originalDateTimeTTime);
       
   292 					}
       
   293 					// create the new child now
       
   294 					calEntry = CCalEntry::NewL(parentEntry->EntryTypeL(), 
       
   295 											   guid,
       
   296 											   parentEntry->MethodL(),
       
   297 											   parentEntry->SequenceNumberL(),
       
   298 											   originalCalTime,
       
   299 											   CalCommon::EThisOnly);
       
   300 		
       
   301 					// reset local UID and clear the repeat rule for exceptional entry
       
   302 					calEntry->SetLocalUidL(TCalLocalUid(0));
       
   303 					calEntry->ClearRepeatingPropertiesL();
       
   304 					
       
   305 					CleanupStack::Pop(guid);
       
   306 					CleanupStack::PopAndDestroy(parentEntry);
       
   307 					
       
   308 					// clear repeat rule properties
       
   309 					AgendaRepeatRule repeatrule;
       
   310 					entry.setRepeatRule(repeatrule);
       
   311 				}
       
   312 		
       
   313 			}
       
   314 			
       
   315 			// Converting agenda entry to CCalEntry to store it to database
       
   316 			createCCalEntryFromAgendaEntry(entry, *calEntry);
       
   317 			
       
   318 			calenInterimUtils2->StoreL(*iCalEntryView, *calEntry, true);
       
   319 			localUid = calEntry->LocalUidL();
       
   320 			
       
   321 			// Emit signal upon successful creation of entry.
       
   322 			if (0 < localUid) {
       
   323 				// if creating new entry then emit signal entryAdded else entryUpdated
       
   324 				if (entryAdded) {
       
   325 				emit q->entryAdded(localUid);
       
   326 				} else {
       
   327 					q->entryUpdated(localUid);
       
   328 				}
       
   329 			}
       
   330 			
       
   331 			delete calenInterimUtils2;
       
   332 			delete calEntry;
       
   333 	)
       
   334 	return localUid;
       
   335 
       
   336 }
       
   337 
       
   338 /*!
       
   339 	Clones the `entry' passed in the argument and saves it as type `type'.
       
   340 
       
   341 	\param entry Entry which should be used for cloning.
       
   342 	\param type The new type of the entry.
       
   343 	\return ulong The local UID of the new entry.
       
   344 
       
   345 	\sa deleteEntry()
       
   346  */
       
   347 ulong AgendaUtilPrivate::cloneEntry(
       
   348 		const AgendaEntry &entry, AgendaEntry::Type type)
       
   349 {
       
   350 	// First prepare the session with agenda server.
       
   351 	if (!mInstanceViewCreated) {
       
   352 		// Something went wrong.
       
   353 		return 0;
       
   354 	}
       
   355 
       
   356 	if (entry.isNull()
       
   357 			|| type == AgendaEntry::TypeUnknown) {
       
   358 		return 0;
       
   359 	}
       
   360 
       
   361 	// Will be filled with the lUID of the new entry created.
       
   362 	TCalLocalUid localUid = 0;
       
   363 	int success = 0;
       
   364 	CCalEntry *originalEntry = 0;
       
   365 	HBufC8* globalUid = 0;
       
   366 
       
   367 	// Get the stored entry first.
       
   368 	TRAP(
       
   369 			iError,
       
   370 
       
   371 			originalEntry = iCalEntryView->FetchL(entry.id());
       
   372 	)
       
   373 
       
   374 	if (!originalEntry) {
       
   375 		return 0;
       
   376 	}
       
   377 
       
   378 	// Now save the GUID of the saved entry.
       
   379 	TRAP(
       
   380 			iError,
       
   381 			globalUid = originalEntry->UidL().AllocL();
       
   382 	)
       
   383 
       
   384 	delete originalEntry;
       
   385 
       
   386 	// Now start cloning and create a new entry.
       
   387 	if (AgendaEntry::TypeNote == type) {
   225 		TRAP(
   388 		TRAP(
   226 				iError,
   389 				iError,
   227 
   390 
   228 				RPointerArray<CCalEntry> entryArray;
   391 				RPointerArray<CCalEntry> entryArray;
   229                 CleanupResetAndDestroyPushL(entryArray);
   392 				CleanupClosePushL(entryArray);
   230 				CleanupStack::PushL(globalUid);
       
   231 
   393 
   232 				// Construct a CCalEntry object and start filling the details.
   394 				// Construct a CCalEntry object and start filling the details.
   233 				CCalEntry* newEntry = 0;
   395 				CCalEntry* newEntry = 0;
   234 				newEntry = CCalEntry::NewL(
   396 				newEntry = CCalEntry::NewL(
   235 						static_cast<CCalEntry::TType>(entry.type()),
   397 						static_cast<CCalEntry::TType>(type),
   236 						globalUid,
   398 						globalUid,
   237 						static_cast<CCalEntry::TMethod>(entry.method()),
   399 						static_cast<CCalEntry::TMethod>(entry.method()),
   238 						0);
   400 						0);
   239 
       
   240 				CleanupStack::Pop(globalUid);
       
   241 
   401 
   242 				// Add description.
   402 				// Add description.
   243 				TPtrC description(reinterpret_cast<const TUint16*>(
   403 				TPtrC description(reinterpret_cast<const TUint16*>(
   244 						entry.description().utf16()));
   404 						entry.description().utf16()));
   245 				newEntry->SetDescriptionL(description);
   405 				newEntry->SetDescriptionL(description);
   246 
   406 
   247 				// Set the favourite property.
   407 				// Set the favourite property.
   248 				newEntry->SetFavouriteL(entry.favourite());
   408 				newEntry->SetFavouriteL(entry.favourite());
   249 
       
   250 				// Set the last modification time.
       
   251 				TCalTime calTime;
       
   252 				QDateTime dateTime = entry.lastModifiedDateTime();
       
   253 				TDateTime tempDateTime(
       
   254 						dateTime.date().year(),
       
   255 						static_cast<TMonth>(dateTime.date().month() - 1),
       
   256 						dateTime.date().day() - 1, dateTime.time().hour(),
       
   257 						dateTime.time().minute(), 0, 0);
       
   258 				TTime tempTime(tempDateTime);
       
   259 				calTime.SetTimeLocalL(tempTime);
       
   260 				newEntry->SetLastModifiedDateL(calTime);
       
   261 
       
   262 				// Set the dtstamp time.It is used to set the cretaion time.
       
   263 				TCalTime creationCalTime;
       
   264 				QDateTime dtStamp = entry.dtStamp();
       
   265 				TDateTime creationDateTime(
       
   266 						dtStamp.date().year(),
       
   267 						static_cast<TMonth>(dtStamp.date().month() - 1),
       
   268 						dtStamp.date().day() - 1, dtStamp.time().hour(),
       
   269 						dtStamp.time().minute(), 0, 0);
       
   270 				TTime creationTTime(creationDateTime);
       
   271 				creationCalTime.SetTimeLocalL(creationTTime);
       
   272 				newEntry->SetDTStampL(creationCalTime);
       
   273 
   409 
   274 				// Finally set the entry to the database using the entry view.
   410 				// Finally set the entry to the database using the entry view.
   275 				entryArray.AppendL(newEntry);
   411 				entryArray.AppendL(newEntry);
   276 				iCalEntryView->StoreL(entryArray, success);
   412 				iCalEntryView->StoreL(entryArray, success);
   277 				localUid = newEntry->LocalUidL();
   413 				localUid = newEntry->LocalUidL();
   282 	} else {
   418 	} else {
   283 		TRAP(
   419 		TRAP(
   284 				iError,
   420 				iError,
   285 
   421 
   286 				RPointerArray<CCalEntry> entryArray;
   422 				RPointerArray<CCalEntry> entryArray;
   287                 CleanupResetAndDestroyPushL(entryArray);
   423 				CleanupClosePushL(entryArray);
   288                 CleanupStack::PushL(globalUid);
   424 
   289 				// Construct a CCalEntry object and start filling the details.
   425 				// Construct a CCalEntry object and start filling the details.
   290 				CCalEntry* newEntry = 0;
   426 				CCalEntry* newEntry = 0;
   291 				newEntry = CCalEntry::NewL(
   427 				newEntry = CCalEntry::NewL(
   292 						static_cast<CCalEntry::TType>(entry.type()),
   428 						static_cast<CCalEntry::TType>(type),
   293 						globalUid,
   429 						globalUid,
   294 						static_cast<CCalEntry::TMethod>(entry.method()),
   430 						static_cast<CCalEntry::TMethod>(entry.method()),
   295 						0);
   431 						0);
   296 
       
   297 				CleanupStack::Pop(globalUid);
       
   298 
   432 
   299 				// Add the summary.
   433 				// Add the summary.
   300 				if (!entry.summary().isNull()) {
   434 				if (!entry.summary().isNull()) {
   301 					TPtrC summary(reinterpret_cast<const TUint16*>(
   435 					TPtrC summary(reinterpret_cast<const TUint16*>(
   302 							entry.summary().utf16()));
   436 							entry.summary().utf16()));
   310 				TDateTime startDateTime(
   444 				TDateTime startDateTime(
   311 						date.year(), static_cast<TMonth>(date.month() - 1),
   445 						date.year(), static_cast<TMonth>(date.month() - 1),
   312 						date.day() - 1, time.hour(), time.minute(), 0, 0);
   446 						date.day() - 1, time.hour(), time.minute(), 0, 0);
   313 				TTime entryStartTime(startDateTime);
   447 				TTime entryStartTime(startDateTime);
   314 				TCalTime calStartTime;
   448 				TCalTime calStartTime;
   315 				calStartTime.SetTimeLocalL(entryStartTime);
       
   316 
   449 
   317 				date = entry.endTime().date();
   450 				date = entry.endTime().date();
   318 				time = entry.endTime().time();
   451 				time = entry.endTime().time();
   319 
   452 
   320 				TDateTime endDateTime(
   453 				TDateTime endDateTime(
   321 						date.year(), static_cast<TMonth>(date.month() - 1),
   454 						date.year(), static_cast<TMonth>(date.month() - 1),
   322 						date.day() - 1, time.hour(), time.minute(), 0, 0);
   455 						date.day() - 1, time.hour(), time.minute(), 0, 0);
   323 				TTime entryEndTime(endDateTime);
   456 				TTime entryEndTime(endDateTime);
   324 				TCalTime calEndTime;
   457 				TCalTime calEndTime;
   325 				calEndTime.SetTimeLocalL(entryEndTime);
   458 				
       
   459 				bool isNonFloating = false;
       
   460                 // Use floating time for non-timed entries so that
       
   461                 // the time will be same regardless of the timezone
       
   462 				if(type == AgendaEntry::TypeAppoinment|| type == AgendaEntry::TypeReminder) {
       
   463 				    calStartTime.SetTimeLocalL(entryStartTime); 
       
   464 				    calEndTime.SetTimeLocalL(entryEndTime);
       
   465 				    isNonFloating = true;
       
   466 				}else {
       
   467 				    calStartTime.SetTimeLocalFloatingL(entryStartTime);
       
   468 				    calEndTime.SetTimeLocalFloatingL(entryEndTime); 
       
   469 				    isNonFloating = false;
       
   470 				}
   326 				newEntry->SetStartAndEndTimeL(calStartTime, calEndTime);
   471 				newEntry->SetStartAndEndTimeL(calStartTime, calEndTime);
   327 
   472 
   328 				// Add attendees to the entry.
   473 				// Add attendees to the entry.
   329 				addAttendeesToEntry(entry.d->m_attendees, *newEntry);
   474 				addAttendeesToEntry(entry.d->m_attendees, *newEntry);
   330 
   475 
   361 				// Set the repeat type if applicable.
   506 				// Set the repeat type if applicable.
   362 				if (AgendaRepeatRule::InvalidRule
   507 				if (AgendaRepeatRule::InvalidRule
   363 						!= entry.repeatRule().type()) {
   508 						!= entry.repeatRule().type()) {
   364 					AgendaRepeatRule agendaRepeatRule = entry.repeatRule();
   509 					AgendaRepeatRule agendaRepeatRule = entry.repeatRule();
   365 					TCalRRule repeatRule = 
   510 					TCalRRule repeatRule = 
   366 							createTCalRRuleFromAgendaRRule(agendaRepeatRule);
   511 							createTCalRRuleFromAgendaRRule(agendaRepeatRule, isNonFloating);
   367 					newEntry->SetRRuleL(repeatRule);
   512 					newEntry->SetRRuleL(repeatRule);
   368 				}
   513 				}
   369 
   514 
   370 				// Save the status of the entry.
   515 				// Save the status of the entry.
   371 				newEntry->SetStatusL((CCalEntry::TStatus) entry.status());
   516 				newEntry->SetStatusL((CCalEntry::TStatus) entry.status());
   384 					
   529 					
   385 					// set it to CCalentry
   530 					// set it to CCalentry
   386 					newEntry->SetGeoValueL(*geoValue);
   531 					newEntry->SetGeoValueL(*geoValue);
   387 					delete geoValue;
   532 					delete geoValue;
   388 				}
   533 				}
   389 				
       
   390 				// Finally set the entry to the database using the entry view.
       
   391 				entryArray.AppendL(newEntry);
       
   392 				iCalEntryView->StoreL(entryArray, success);
       
   393 				localUid = newEntry->LocalUidL();
       
   394 
       
   395 				// Cleanup.
       
   396 				CleanupStack::PopAndDestroy(&entryArray);
       
   397 		)
       
   398 	}
       
   399 	
       
   400 	delete calenInterimUtils2;
       
   401 	
       
   402 	// Emit signal upon successful creation of entry.
       
   403 	if (0 < localUid && 1 == success) {
       
   404 		emit q->entryAdded(localUid);
       
   405 	}
       
   406 	return localUid;
       
   407 }
       
   408 
       
   409 /*!
       
   410 	Clones the `entry' passed in the argument and saves it as type `type'.
       
   411 
       
   412 	\param entry Entry which should be used for cloning.
       
   413 	\param type The new type of the entry.
       
   414 	\return ulong The local UID of the new entry.
       
   415 
       
   416 	\sa deleteEntry()
       
   417  */
       
   418 ulong AgendaUtilPrivate::cloneEntry(
       
   419 		const AgendaEntry &entry, AgendaEntry::Type type)
       
   420 {
       
   421 	// First prepare the session with agenda server.
       
   422 	if (!mInstanceViewCreated) {
       
   423 		// Something went wrong.
       
   424 		return 0;
       
   425 	}
       
   426 
       
   427 	if (entry.isNull()
       
   428 			|| type == AgendaEntry::TypeUnknown) {
       
   429 		return 0;
       
   430 	}
       
   431 
       
   432 	// Will be filled with the lUID of the new entry created.
       
   433 	TCalLocalUid localUid = 0;
       
   434 	int success = 0;
       
   435 	CCalEntry *originalEntry = 0;
       
   436 	HBufC8* globalUid = 0;
       
   437 
       
   438 	// Get the stored entry first.
       
   439 	TRAP(
       
   440 			iError,
       
   441 
       
   442 			originalEntry = iCalEntryView->FetchL(entry.id());
       
   443 	)
       
   444 
       
   445 	if (!originalEntry) {
       
   446 		return 0;
       
   447 	}
       
   448 
       
   449 	// Now save the GUID of the saved entry.
       
   450 	TRAP(
       
   451 			iError,
       
   452 			globalUid = originalEntry->UidL().AllocL();
       
   453 	)
       
   454 
       
   455 	delete originalEntry;
       
   456 
       
   457 	// Now start cloning and create a new entry.
       
   458 	if (AgendaEntry::TypeNote == type) {
       
   459 		TRAP(
       
   460 				iError,
       
   461 
       
   462 				RPointerArray<CCalEntry> entryArray;
       
   463 				CleanupClosePushL(entryArray);
       
   464 
       
   465 				// Construct a CCalEntry object and start filling the details.
       
   466 				CCalEntry* newEntry = 0;
       
   467 				newEntry = CCalEntry::NewL(
       
   468 						static_cast<CCalEntry::TType>(type),
       
   469 						globalUid,
       
   470 						static_cast<CCalEntry::TMethod>(entry.method()),
       
   471 						0);
       
   472 
       
   473 				// Add description.
       
   474 				TPtrC description(reinterpret_cast<const TUint16*>(
       
   475 						entry.description().utf16()));
       
   476 				newEntry->SetDescriptionL(description);
       
   477 
       
   478 				// Set the favourite property.
       
   479 				newEntry->SetFavouriteL(entry.favourite());
       
   480 
       
   481 				// Finally set the entry to the database using the entry view.
       
   482 				entryArray.AppendL(newEntry);
       
   483 				iCalEntryView->StoreL(entryArray, success);
       
   484 				localUid = newEntry->LocalUidL();
       
   485 
       
   486 				// Cleanup.
       
   487 				CleanupStack::PopAndDestroy(&entryArray);
       
   488 		)
       
   489 	} else {
       
   490 		TRAP(
       
   491 				iError,
       
   492 
       
   493 				RPointerArray<CCalEntry> entryArray;
       
   494 				CleanupClosePushL(entryArray);
       
   495 
       
   496 				// Construct a CCalEntry object and start filling the details.
       
   497 				CCalEntry* newEntry = 0;
       
   498 				newEntry = CCalEntry::NewL(
       
   499 						static_cast<CCalEntry::TType>(type),
       
   500 						globalUid,
       
   501 						static_cast<CCalEntry::TMethod>(entry.method()),
       
   502 						0);
       
   503 
       
   504 				// Add the summary.
       
   505 				if (!entry.summary().isNull()) {
       
   506 					TPtrC summary(reinterpret_cast<const TUint16*>(
       
   507 							entry.summary().utf16()));
       
   508 					newEntry->SetSummaryL(summary);
       
   509 				}
       
   510 
       
   511 				// Set the entry Start/End Date and time.
       
   512 				QDate date = entry.startTime().date();
       
   513 				QTime time = entry.startTime().time();
       
   514 
       
   515 				TDateTime startDateTime(
       
   516 						date.year(), static_cast<TMonth>(date.month() - 1),
       
   517 						date.day() - 1, time.hour(), time.minute(), 0, 0);
       
   518 				TTime entryStartTime(startDateTime);
       
   519 				TCalTime calStartTime;
       
   520 				calStartTime.SetTimeLocalL(entryStartTime);
       
   521 
       
   522 				date = entry.endTime().date();
       
   523 				time = entry.endTime().time();
       
   524 
       
   525 				TDateTime endDateTime(
       
   526 						date.year(), static_cast<TMonth>(date.month() - 1),
       
   527 						date.day() - 1, time.hour(), time.minute(), 0, 0);
       
   528 				TTime entryEndTime(endDateTime);
       
   529 				TCalTime calEndTime;
       
   530 				calEndTime.SetTimeLocalL(entryEndTime);
       
   531 				newEntry->SetStartAndEndTimeL(calStartTime, calEndTime);
       
   532 
       
   533 				// Add attendees to the entry.
       
   534 				addAttendeesToEntry(entry.d->m_attendees, *newEntry);
       
   535 
       
   536 				// Add categories to the entry.
       
   537 				addCategoriesToEntry(entry.d->m_categories, *newEntry);
       
   538 
       
   539 				// Add description to the entry.
       
   540 				TPtrC description(reinterpret_cast<const TUint16*>(
       
   541 						entry.description().utf16()));
       
   542 				newEntry->SetDescriptionL(description);
       
   543 
       
   544 				// Set the favourite property.
       
   545 				newEntry->SetFavouriteL(entry.favourite());
       
   546 
       
   547 				// Add Alarm to the entry.
       
   548 				AgendaAlarm alarm = entry.alarm();
       
   549 				if (!alarm.isNull()) {
       
   550 					setAlarmToEntry(alarm, *newEntry);
       
   551 				}
       
   552 
       
   553 				// Set the priority.
       
   554 				int priority = entry.priority();
       
   555 				if (entry.priority() != -1) {
       
   556 					newEntry->SetPriorityL(priority);
       
   557 				}
       
   558 
       
   559 				// Set the location.
       
   560 				if (!entry.location().isNull()) {
       
   561 					TPtrC location(reinterpret_cast<const TUint16*>(
       
   562 							entry.location().utf16()));
       
   563 					newEntry->SetLocationL(location);
       
   564 				}
       
   565 
       
   566 				// Set the repeat type if applicable.
       
   567 				if (AgendaRepeatRule::InvalidRule
       
   568 						!= entry.repeatRule().type()) {
       
   569 					AgendaRepeatRule agendaRepeatRule = entry.repeatRule();
       
   570 					TCalRRule repeatRule = 
       
   571 							createTCalRRuleFromAgendaRRule(agendaRepeatRule);
       
   572 					newEntry->SetRRuleL(repeatRule);
       
   573 				}
       
   574 
       
   575 				// Save the status of the entry.
       
   576 				newEntry->SetStatusL((CCalEntry::TStatus) entry.status());
       
   577 				newEntry->SetLastModifiedDateL();
       
   578 				
       
   579 				// Save the geo value if any
       
   580 				AgendaGeoValue entryGeoValue = entry.geoValue();
       
   581 				if (!entryGeoValue.isNull()) {
       
   582 					CCalGeoValue* geoValue = CCalGeoValue::NewL();
       
   583 					double latitude;
       
   584 					double longitude;
       
   585 					entryGeoValue.getLatLong(latitude, longitude);
       
   586 					
       
   587 					// set the values to symbian geo value
       
   588 					geoValue->SetLatLongL(latitude, longitude);
       
   589 					
       
   590 					// set it to CCalentry
       
   591 					newEntry->SetGeoValueL(*geoValue);
       
   592 					delete geoValue;
       
   593 				}
       
   594 								
   534 								
   595 				// Finally set the entry to the database using the entry view.
   535 				// Finally set the entry to the database using the entry view.
   596 				entryArray.AppendL(newEntry);
   536 				entryArray.AppendL(newEntry);
   597 				iCalEntryView->StoreL(entryArray, success);
   537 				iCalEntryView->StoreL(entryArray, success);
   598 				localUid = newEntry->LocalUidL();
   538 				localUid = newEntry->LocalUidL();
   692 			}
   632 			}
   693 	)
   633 	)
   694 	
   634 	
   695 	// Emit the signal to notify the deletion of entry.
   635 	// Emit the signal to notify the deletion of entry.
   696 	emit q->entryDeleted(entry.id());
   636 	emit q->entryDeleted(entry.id());
   697 }
       
   698 
       
   699 /*!
       
   700 	Updates a given entry in the calendar database.
       
   701 
       
   702 	\param entry The entry to be updated.
       
   703 	\return bool true if updation was successful, false otherwise.
       
   704  */
       
   705 bool AgendaUtilPrivate::updateEntry(const AgendaEntry& entry, bool isChild)
       
   706 {
       
   707 	// First prepare the session with agenda server.
       
   708 	if (!mInstanceViewCreated) {
       
   709 		// Something went wrong.
       
   710 		return false;
       
   711 	}
       
   712 
       
   713 	if (entry.isNull()) {
       
   714 		// Invalid entry.
       
   715 		return false;
       
   716 	}
       
   717 
       
   718 	int success = 0;
       
   719 
       
   720 	if (AgendaEntry::TypeNote == entry.type()) {
       
   721 		TRAP(
       
   722 				iError,
       
   723 
       
   724 				// Get the entry corresponding to the id.
       
   725 				AgendaEntry storedEntry = fetchById(entry.id());
       
   726 				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
       
   727 
       
   728 				// Update the description.
       
   729 				if (storedEntry.description() != entry.description()
       
   730 						&& !entry.description().isNull()) {
       
   731 					calEntry->SetDescriptionL(
       
   732 							TPtrC(reinterpret_cast<const TUint16 *> (
       
   733 									entry.description().utf16())));
       
   734 				}
       
   735 
       
   736 				// Update the method.
       
   737 				if (storedEntry.method() != entry.method() &&
       
   738 						AgendaEntry::MethodUnknown != entry.method()) {
       
   739 					calEntry->SetMethodL(
       
   740 							static_cast<CCalEntry::TMethod> (entry.method()));
       
   741 				}
       
   742 
       
   743 				// Update the last modification time.
       
   744 				if (entry.lastModifiedDateTime().isValid()) {
       
   745 					if (entry.lastModifiedDateTime() !=
       
   746 							storedEntry.lastModifiedDateTime()) {
       
   747 						QDateTime dateTime = entry.lastModifiedDateTime();
       
   748 						QDate lastDate = dateTime.date();
       
   749 						QTime lastTime = dateTime.time();
       
   750 
       
   751 						TDateTime lastModDateTime(
       
   752 								lastDate.year(),
       
   753 								static_cast<TMonth> (lastDate.month() - 1),
       
   754 								lastDate.day() - 1, lastTime.hour(),
       
   755 								lastTime.minute(), 0, 0);
       
   756 
       
   757 						TTime lastModTime(lastModDateTime);
       
   758 						TCalTime lastModCalTime;
       
   759 						lastModCalTime.SetTimeLocalL(lastModTime);
       
   760 						calEntry->SetLastModifiedDateL(lastModCalTime);
       
   761 					}
       
   762 				}
       
   763 
       
   764 				// Update the DTStamp time as the entry is modified.
       
   765 				if (entry.dtStamp().isValid()) {
       
   766 					TCalTime resetCreationTime;
       
   767 					TTime nullTime = Time::NullTTime();
       
   768 					resetCreationTime.SetTimeLocalL(nullTime);
       
   769 					calEntry->SetDTStampL(resetCreationTime);
       
   770 				}
       
   771 
       
   772 				// Check if the favourite property is changed and update the
       
   773 				// same.
       
   774 				if (entry.favourite() != storedEntry.favourite()) {
       
   775 					calEntry->SetFavouriteL(entry.favourite());
       
   776 				}
       
   777 
       
   778 				// Update the entry using the CCalEntryView.
       
   779 				RPointerArray<CCalEntry> entryArray;
       
   780 				CleanupResetAndDestroyPushL(entryArray);
       
   781 				entryArray.AppendL(calEntry);
       
   782 				iCalEntryView->UpdateL(entryArray, success);
       
   783 
       
   784 				// Cleanup.
       
   785 				CleanupStack::PopAndDestroy( &entryArray );
       
   786 		)
       
   787 	} else {
       
   788 		TRAP(
       
   789 				iError,
       
   790 
       
   791 				// Get the entry corresponding to the id.
       
   792 				AgendaEntry storedEntry = fetchById(entry.id());
       
   793 				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
       
   794 
       
   795 				// Update the attendees.
       
   796 				if (!entry.isNull()
       
   797 						&& (entry.d->m_attendees != storedEntry.attendees())) {
       
   798 
       
   799 					RPointerArray<CCalAttendee>& attendeesArray =
       
   800 							calEntry->AttendeesL();
       
   801 					int iterator = 0;
       
   802 					while (attendeesArray.Count() > iterator) {
       
   803 						calEntry->DeleteAttendeeL(iterator);
       
   804 						iterator++;
       
   805 					}
       
   806 
       
   807 					addAttendeesToEntry(entry.d->m_attendees, *calEntry);
       
   808 				}
       
   809 
       
   810 				// Update the categories.
       
   811 				if (entry.d->m_categories != storedEntry.categories()) {
       
   812 
       
   813 					RPointerArray<CCalCategory> categories =
       
   814 							calEntry->CategoryListL();
       
   815 					int iterator = 0;
       
   816 					while (categories.Count() > iterator) {
       
   817 						calEntry->DeleteCategoryL(iterator);
       
   818 						iterator++;
       
   819 					}
       
   820 
       
   821 					addCategoriesToEntry(entry.d->m_categories, *calEntry);
       
   822 				}
       
   823 
       
   824 				// Update the alarm.
       
   825 				if (entry.alarm() != storedEntry.alarm()) {
       
   826 					setAlarmToEntry(entry.alarm(), *calEntry);
       
   827 				}
       
   828 
       
   829 				// Update the description.
       
   830 				if ((storedEntry.description() != entry.description()
       
   831 						&& !entry.description().isNull()) || entry.description().isNull() ) {
       
   832 					calEntry->SetDescriptionL(
       
   833 							TPtrC(reinterpret_cast<const TUint16 *> (
       
   834 									entry.description().utf16())));
       
   835 				}
       
   836 
       
   837 				// Update the location.
       
   838 				if (storedEntry.location() != entry.location()
       
   839 						&& !entry.location().isNull()) {
       
   840 					calEntry->SetLocationL(
       
   841 							TPtrC(reinterpret_cast<const TUint16 *> (
       
   842 									entry.location().utf16())));
       
   843 				}
       
   844 
       
   845 				// Update the priority.
       
   846 				if (storedEntry.priority() != entry.priority()
       
   847 						&& -1 != entry.priority()) {
       
   848 					calEntry->SetPriorityL(entry.priority());
       
   849 				}
       
   850 
       
   851 				// Update the summary.
       
   852 				if (storedEntry.summary() != entry.summary()
       
   853 						&& !entry.summary().isNull()) {
       
   854 					calEntry->SetSummaryL(
       
   855 							TPtrC(reinterpret_cast<const TUint16 *> (
       
   856 									entry.summary().utf16())));
       
   857 				}
       
   858 
       
   859 				// Update the method.
       
   860 				if (storedEntry.method() != entry.method() &&
       
   861 						AgendaEntry::MethodUnknown != entry.method()) {
       
   862 					calEntry->SetMethodL(
       
   863 							static_cast<CCalEntry::TMethod> (entry.method()));
       
   864 				}
       
   865 
       
   866 				// Update the time.
       
   867 				if (storedEntry.startTime() != entry.startTime()
       
   868 						|| storedEntry.endTime() != entry.endTime()) {
       
   869 
       
   870 					QDateTime startDateTime = entry.startTime();
       
   871 					QDate startDate = startDateTime.date();
       
   872 					QTime startTime = startDateTime.time();
       
   873 
       
   874 					TDateTime startCalendarDateTime(
       
   875 							startDate.year(),
       
   876 							static_cast<TMonth> (startDate.month() - 1),
       
   877 							startDate.day() - 1,
       
   878 							startTime.hour(),
       
   879 							startTime.minute(),
       
   880 							0,
       
   881 							0);
       
   882 
       
   883 					TTime startCalTime(startCalendarDateTime);
       
   884 					TCalTime calTime;
       
   885 					calTime.SetTimeLocalL(startCalTime);
       
   886 					QDateTime endDateTime = entry.endTime();
       
   887 					QDate endDate = endDateTime.date();
       
   888 					QTime endTime = endDateTime.time();
       
   889 
       
   890 					TDateTime endCalendarDateTime(
       
   891 							endDate.year(),
       
   892 							static_cast<TMonth>(endDate.month() - 1),
       
   893 							endDate.day() - 1,
       
   894 							endTime.hour(),
       
   895 							endTime.minute(),
       
   896 							0,
       
   897 							0);
       
   898 
       
   899 					TTime endCalTime(endCalendarDateTime);
       
   900 					TCalTime calTime2;
       
   901 					calTime2.SetTimeLocalL(endCalTime);
       
   902 
       
   903 					calEntry->SetStartAndEndTimeL(calTime, calTime2);
       
   904 				}
       
   905 
       
   906 				// Update the repeat rule
       
   907 				if (storedEntry.repeatRule() != entry.repeatRule()) {
       
   908 
       
   909 					calEntry->ClearRepeatingPropertiesL();
       
   910 
       
   911 					if(TCalRRule::EInvalid != entry.repeatRule().type()) {
       
   912 						AgendaRepeatRule agendaRepeatRule = entry.repeatRule();
       
   913 						TCalRRule repeatRule = 
       
   914 							createTCalRRuleFromAgendaRRule(agendaRepeatRule);
       
   915 						calEntry->SetRRuleL(repeatRule);
       
   916 					}
       
   917 				}
       
   918 				
       
   919 				// Check if the favourite property is changed and update the
       
   920 				// same.
       
   921 				if (entry.favourite() != storedEntry.favourite()) {
       
   922 					calEntry->SetFavouriteL(entry.favourite());
       
   923 				}
       
   924 				calEntry->SetLastModifiedDateL();
       
   925 				
       
   926 				// Save the geo value if any
       
   927 				AgendaGeoValue entryGeoValue = entry.geoValue();
       
   928 				if (!entryGeoValue.isNull() && (entryGeoValue != storedEntry.geoValue())) {
       
   929 					CCalGeoValue* geoValue = CCalGeoValue::NewL();
       
   930 					double latitude;
       
   931 					double longitude;
       
   932 					entryGeoValue.getLatLong(latitude, longitude);
       
   933 					
       
   934 					// set the values to symbian geo value
       
   935 					geoValue->SetLatLongL(latitude, longitude);
       
   936 					
       
   937 					// set it to CCalentry
       
   938 					calEntry->SetGeoValueL(*geoValue);
       
   939 					delete geoValue;
       
   940 				} else if (entryGeoValue.isNull()) {
       
   941                     // Clear the geo values if any
       
   942                     calEntry->ClearGeoValueL();
       
   943 				}
       
   944 								
       
   945 				// Update the entry using the calen entry view.
       
   946 				RPointerArray<CCalEntry> entryArray;
       
   947 				CleanupResetAndDestroyPushL(entryArray);
       
   948 				entryArray.AppendL(calEntry);
       
   949 				if (!isChild) {
       
   950 					iCalEntryView->UpdateL(entryArray, success);
       
   951 				} else {
       
   952 					iCalEntryView->StoreL(entryArray, success);
       
   953 				}
       
   954 				// Cleanup.
       
   955 				CleanupStack::PopAndDestroy( &entryArray );
       
   956 		)
       
   957 	}
       
   958 
       
   959 	// Emit the signal to notify the clients.
       
   960 	if (0 < success) {
       
   961 		emit q->entryUpdated(entry.id());
       
   962 	}
       
   963 	return (success != 0);
       
   964 }
       
   965 
       
   966 bool AgendaUtilPrivate::storeRepeatingEntry(const AgendaEntry& entry,
       
   967                                             bool copyToChildren)
       
   968 {
       
   969 	// First prepare the session with agenda server.
       
   970 	if (!mInstanceViewCreated) {
       
   971 		// Something went wrong.
       
   972 		return false;
       
   973 	}
       
   974 
       
   975 	if (entry.isNull()) {
       
   976 		// Invalid entry.
       
   977 		return false;
       
   978 	}
       
   979 
       
   980 	int success = 0;
       
   981 	
       
   982 	// Get the entry corresponding to the id.
       
   983 	AgendaEntry storedEntry = fetchById(entry.id());
       
   984 	CCalEntry* instance = iCalEntryView->FetchL(entry.id());
       
   985 	CleanupStack::PushL(instance);
       
   986 	
       
   987 	CCalEntry* calEntry;
       
   988 	if (instance) {
       
   989 		// Get all the entries with same global Uid.
       
   990 		RPointerArray<CCalEntry> entries;
       
   991 		CleanupResetAndDestroyPushL(entries);
       
   992 		iCalEntryView->FetchL(instance->UidL(), entries);
       
   993 		calEntry = entries[0];
       
   994 		entries.Remove(0);
       
   995 		CleanupStack::PopAndDestroy(&entries);
       
   996 	} else {
       
   997 		CleanupStack::PopAndDestroy(instance);
       
   998 		return false;
       
   999 	}
       
  1000 	CleanupStack::PopAndDestroy(instance);
       
  1001 	CleanupStack::PushL(calEntry);
       
  1002 	
       
  1003 	// This entry is repeating. Does it have EXDATEs which could be due to children?
       
  1004 	RArray<TCalTime> exceptionDates;
       
  1005 	CleanupClosePushL( exceptionDates );
       
  1006 	calEntry->GetExceptionDatesL( exceptionDates );
       
  1007 	TInt exceptionCount = exceptionDates.Count();
       
  1008 	CleanupStack::PopAndDestroy( &exceptionDates );
       
  1009 
       
  1010 	if (exceptionCount == 0) {
       
  1011 		// No exception dates so do a StoreL().
       
  1012 		// We have no exceptions, so there are no children to re-store
       
  1013 		// Same logic as above applies, we call StoreL rather than check to 
       
  1014 		// see if we could have called UpdateL
       
  1015 		success = updateEntry(entry, true);
       
  1016 		CleanupStack::PopAndDestroy( calEntry );
       
  1017 		return success;
       
  1018 	} 
       
  1019 
       
  1020 	//Is this a child entry?
       
  1021 	if (calEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime()) {
       
  1022 		success = updateEntry(entry, true);
       
  1023 		CleanupStack::PopAndDestroy( calEntry );
       
  1024 		return success;
       
  1025 	}
       
  1026 
       
  1027 	// Entry is not a child, but does it have any children?
       
  1028 	// Fetch array of entries associated with this UID.
       
  1029 	RPointerArray<CCalEntry> oldEntries;
       
  1030 	CleanupResetAndDestroyPushL(oldEntries);
       
  1031 	iCalEntryView->FetchL(calEntry->UidL(), oldEntries);
       
  1032 	bool hasChildren = oldEntries.Count() > 0;
       
  1033 	
       
  1034 	// Before we proceed further update calEntry with the latest modifications
       
  1035 	// Update only those fields that are required to copy to the children
       
  1036 	// refer to enum DifferenceFlag to know what fields need to be updated
       
  1037 	
       
  1038 	// set the summary
       
  1039 	calEntry->SetSummaryL(TPtrC(reinterpret_cast<const TUint16 *> (
       
  1040 										entry.summary().utf16())));
       
  1041 	
       
  1042 	// set the locaiton
       
  1043 	calEntry->SetLocationL(TPtrC(reinterpret_cast<const TUint16 *> (
       
  1044 										entry.location().utf16())));
       
  1045 	
       
  1046 	// Save the geo value if any
       
  1047 	AgendaGeoValue entryGeoValue = entry.geoValue();
       
  1048 	if (!entryGeoValue.isNull()) {
       
  1049 		CCalGeoValue* geoValue = CCalGeoValue::NewL();
       
  1050 		double latitude;
       
  1051 		double longitude;
       
  1052 		entryGeoValue.getLatLong(latitude, longitude);
       
  1053 		
       
  1054 		// set the values to symbian geo value
       
  1055 		geoValue->SetLatLongL(latitude, longitude);
       
  1056 		
       
  1057 		// set it to CCalentry
       
  1058 		calEntry->SetGeoValueL(*geoValue);
       
  1059 		delete geoValue;
       
  1060 	} else {
       
  1061         // Clear the geo values
       
  1062         calEntry->ClearGeoValueL();
       
  1063 	}
       
  1064 	
       
  1065 	// set the description
       
  1066 	calEntry->SetDescriptionL(TPtrC(reinterpret_cast<const TUint16 *> (
       
  1067 										entry.description().utf16())));
       
  1068 	
       
  1069 	// set the instance start and end dates to this
       
  1070 	TCalTime originalStartCalTime = calEntry->StartTimeL();
       
  1071 	TDateTime origStartDateTime = originalStartCalTime.TimeLocalL().DateTime();
       
  1072 	
       
  1073 	QDate date = entry.startTime().date();
       
  1074 	QTime time =entry.startTime().time();
       
  1075 	origStartDateTime.Set(date.year(),
       
  1076 					 static_cast<TMonth> (date.month() - 1),
       
  1077 					 date.day() - 1,
       
  1078 					 time.hour(),
       
  1079 					 time.minute(),time.second(), 0);
       
  1080 	TTime originalStartTime(origStartDateTime);
       
  1081 	originalStartCalTime.SetTimeLocalL(originalStartTime);
       
  1082 	
       
  1083 	TCalTime originalEndCalTime = calEntry->EndTimeL();
       
  1084 	TDateTime origEndDateTime = originalEndCalTime.TimeLocalL().DateTime();
       
  1085 	date = entry.endTime().date();
       
  1086 	time = entry.endTime().time();
       
  1087 	origEndDateTime.Set(date.year(),
       
  1088 					 static_cast<TMonth> (date.month() - 1),
       
  1089 					 date.day() - 1,
       
  1090 					 time.hour(),
       
  1091 					 time.minute(),time.second(), 0);
       
  1092 	TTime originalEndTime(origEndDateTime);
       
  1093 	originalEndCalTime.SetTimeLocalL(originalEndTime);
       
  1094 	
       
  1095 	calEntry->SetStartAndEndTimeL(originalStartCalTime, originalEndCalTime);
       
  1096 	
       
  1097 	// Set the repeat rules
       
  1098 	calEntry->ClearRepeatingPropertiesL();
       
  1099 
       
  1100 	if (TCalRRule::EInvalid != entry.repeatRule().type()) {
       
  1101 		AgendaRepeatRule agendaRepeatRule = entry.repeatRule();
       
  1102 		TCalRRule repeatRule = 
       
  1103 				createTCalRRuleFromAgendaRRule(agendaRepeatRule);
       
  1104 		calEntry->SetRRuleL(repeatRule);
       
  1105 
       
  1106 	}
       
  1107 	
       
  1108 	bool hasTimeOrDateCanged = (oldEntries[0]->StartTimeL().TimeUtcL() != 
       
  1109 			calEntry->StartTimeL().TimeUtcL() ||
       
  1110 			oldEntries[0]->EndTimeL().TimeUtcL() != calEntry->EndTimeL().TimeUtcL());
       
  1111 	if (oldEntries.Count() == 0) {
       
  1112 		//This is a new repeating entry, with exceptions
       
  1113 		//This must have come from an external application, as the 
       
  1114 		//calendar UI does not allow creation of this type of entry
       
  1115 		success = updateEntry(entry);
       
  1116 	} // Have the RRule or time fields changed 
       
  1117 	else if (copyToChildren || hasTimeOrDateCanged  
       
  1118 		|| haveRepeatPropertiesChanged(*oldEntries[0], *calEntry)) {
       
  1119 		if (hasChildren && copyToChildren)
       
  1120 			{
       
  1121 			copyChildrenExceptionData( *calEntry, oldEntries );
       
  1122 			}
       
  1123 		success = updateEntry(entry, false);
       
  1124 		
       
  1125 		if(hasChildren)
       
  1126 			{
       
  1127 			storeEachChildEntry( *calEntry, oldEntries, !copyToChildren );
       
  1128 			}
       
  1129 	}
       
  1130 	else
       
  1131 		{
       
  1132 		success = this->updateEntry(entry);
       
  1133 		}
       
  1134 	CleanupStack::PopAndDestroy( &oldEntries );
       
  1135 	CleanupStack::PopAndDestroy( calEntry );
       
  1136 
       
  1137 	return success;    
       
  1138 }
       
  1139 
       
  1140 bool AgendaUtilPrivate::createException(const AgendaEntry& entry, 
       
  1141 										QDateTime instanceOriginalDateTime)
       
  1142 { 
       
  1143 	// First prepare the session with agenda server.
       
  1144 	if (!mInstanceViewCreated) {
       
  1145 		// Something went wrong.
       
  1146 		return false;
       
  1147 	}
       
  1148 
       
  1149 	if (entry.isNull()) {
       
  1150 		// Invalid entry.
       
  1151 		return false;
       
  1152 	}
       
  1153 
       
  1154 	int success = 0;
       
  1155 	TCalLocalUid localUid = 0;
       
  1156 	if (AgendaEntry::TypeNote == entry.type()) {
       
  1157 		TRAP(
       
  1158 				iError,
       
  1159 
       
  1160 				// Get the entry corresponding to the id.
       
  1161 				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
       
  1162 				CleanupStack::PushL(calEntry);
       
  1163 				// We are creating an exception, hence get the global Uid
       
  1164 				HBufC8* guid = calEntry->UidL().AllocLC();
       
  1165 				// create new (child) entry
       
  1166 				// Use original instance time for recurrenceID as this entry hasn't got one.
       
  1167 				TCalTime originalCalTime;
       
  1168 				TDateTime originalDateTime(instanceOriginalDateTime.date().year(),
       
  1169 							TMonth(instanceOriginalDateTime.date().month() - 1),
       
  1170 							instanceOriginalDateTime.date().day() -1, 0, 0, 0, 0);
       
  1171 				TTime originalDateTimeTTime(originalDateTime);
       
  1172 				originalCalTime.SetTimeLocalL(originalDateTimeTTime);
       
  1173 				// create the new child now
       
  1174 				CCalEntry* newEntry = CCalEntry::NewL( calEntry->EntryTypeL(), 
       
  1175 													   guid,
       
  1176 													   calEntry->MethodL(),
       
  1177 													   calEntry->SequenceNumberL(),
       
  1178 													   originalCalTime,
       
  1179 													   CalCommon::EThisOnly );
       
  1180 				
       
  1181 				CleanupStack::Pop(guid);
       
  1182 				CleanupStack::PopAndDestroy(calEntry);
       
  1183 
       
  1184 				// Update the description.
       
  1185 				if (!entry.description().isNull()) {
       
  1186 					newEntry->SetDescriptionL(
       
  1187 							TPtrC(reinterpret_cast<const TUint16 *> (
       
  1188 									entry.description().utf16())));
       
  1189 				}
       
  1190 
       
  1191 				// Update the method.
       
  1192 				if (AgendaEntry::MethodUnknown != entry.method()) {
       
  1193 					newEntry->SetMethodL(
       
  1194 							static_cast<CCalEntry::TMethod> (entry.method()));
       
  1195 				}
       
  1196 
       
  1197 				// Update the last modification time.
       
  1198 				if (entry.lastModifiedDateTime().isValid()) {
       
  1199 					QDateTime dateTime = entry.lastModifiedDateTime();
       
  1200 					QDate lastDate = dateTime.date();
       
  1201 					QTime lastTime = dateTime.time();
       
  1202 
       
  1203 					TDateTime lastModDateTime(
       
  1204 							lastDate.year(),
       
  1205 							static_cast<TMonth> (lastDate.month() - 1),
       
  1206 							lastDate.day() - 1, lastTime.hour(),
       
  1207 							lastTime.minute(), 0, 0);
       
  1208 
       
  1209 					TTime lastModTime(lastModDateTime);
       
  1210 					TCalTime lastModCalTime;
       
  1211 					lastModCalTime.SetTimeLocalL(lastModTime);
       
  1212 					newEntry->SetLastModifiedDateL(lastModCalTime);
       
  1213 				}
       
  1214 
       
  1215 				newEntry->SetFavouriteL(entry.favourite());
       
  1216 
       
  1217 				// Update the entry using the CCalEntryView.
       
  1218 				RPointerArray<CCalEntry> entryArray;
       
  1219 				CleanupResetAndDestroyPushL(entryArray);
       
  1220 				entryArray.AppendL(newEntry);
       
  1221 				iCalEntryView->StoreL(entryArray, success);
       
  1222 
       
  1223 				localUid = newEntry->LocalUidL();
       
  1224 				// Cleanup.
       
  1225 				CleanupStack::PopAndDestroy(&entryArray);
       
  1226 		)
       
  1227 	} else {
       
  1228 		TRAP(
       
  1229 				iError,	
       
  1230 				
       
  1231 				CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
       
  1232 				CleanupStack::PushL(calEntry);
       
  1233 				// We are creating an exception, hence get the global Uid
       
  1234 				HBufC8* guid = calEntry->UidL().AllocLC();
       
  1235 				// create new (child) entry
       
  1236 				// Use original instance time for recurrenceID as this entry hasn't got one.
       
  1237 				TCalTime originalCalTime;
       
  1238 				TDateTime originalDateTime(instanceOriginalDateTime.date().year(),
       
  1239 							TMonth(instanceOriginalDateTime.date().month() - 1),
       
  1240 							instanceOriginalDateTime.date().day() -1, 0, 0, 0, 0);
       
  1241 				TTime originalDateTimeTTime(originalDateTime);
       
  1242 				originalCalTime.SetTimeLocalL(originalDateTimeTTime);
       
  1243 				// create the new child now
       
  1244 				CCalEntry* newEntry = CCalEntry::NewL( calEntry->EntryTypeL(), 
       
  1245 													   guid,
       
  1246 													   calEntry->MethodL(),
       
  1247 													   calEntry->SequenceNumberL(),
       
  1248 													   originalCalTime,
       
  1249 													   CalCommon::EThisOnly );
       
  1250 				
       
  1251 				CleanupStack::Pop(guid);
       
  1252 				CleanupStack::PopAndDestroy(calEntry);
       
  1253 				// Store the attendees.
       
  1254 				if (!entry.isNull()) {
       
  1255 					addAttendeesToEntry(entry.d->m_attendees, *newEntry);
       
  1256 					addCategoriesToEntry(entry.d->m_categories, *newEntry);
       
  1257 				}
       
  1258 
       
  1259 				// Store the alarm.
       
  1260 				if (!entry.alarm().isNull()) {
       
  1261 					setAlarmToEntry(entry.alarm(), *newEntry);
       
  1262 				}
       
  1263 
       
  1264 				// Store the description.
       
  1265 				if (!entry.description().isNull()) {
       
  1266 					newEntry->SetDescriptionL(
       
  1267 							TPtrC(reinterpret_cast<const TUint16 *> (
       
  1268 									entry.description().utf16())));
       
  1269 				}
       
  1270 
       
  1271 				// Store the location.
       
  1272 				if (!entry.location().isNull()) {
       
  1273 					newEntry->SetLocationL(
       
  1274 							TPtrC(reinterpret_cast<const TUint16 *> (
       
  1275 									entry.location().utf16())));
       
  1276 				}
       
  1277 
       
  1278 				// Store the priority.
       
  1279 				if ( -1 != entry.priority()) {
       
  1280 					newEntry->SetPriorityL(entry.priority());
       
  1281 				}
       
  1282 
       
  1283 				// Store the summary.
       
  1284 				if (!entry.summary().isNull()) {
       
  1285 					newEntry->SetSummaryL(
       
  1286 							TPtrC(reinterpret_cast<const TUint16 *> (
       
  1287 									entry.summary().utf16())));
       
  1288 				}
       
  1289 
       
  1290 				// Update the method.
       
  1291 				if (AgendaEntry::MethodUnknown != entry.method()) {
       
  1292 					newEntry->SetMethodL(
       
  1293 							static_cast<CCalEntry::TMethod> (entry.method()));
       
  1294 				}
       
  1295 
       
  1296 				// Store the time.
       
  1297 				QDateTime startDateTime = entry.startTime();
       
  1298 				QDate startDate = startDateTime.date();
       
  1299 				QTime startTime = startDateTime.time();
       
  1300 
       
  1301 				TDateTime startCalendarDateTime(
       
  1302 						startDate.year(),
       
  1303 						static_cast<TMonth> (startDate.month() - 1),
       
  1304 						startDate.day() - 1,
       
  1305 						startTime.hour(),
       
  1306 						startTime.minute(),
       
  1307 						0,
       
  1308 						0);
       
  1309 
       
  1310 				TTime startCalTime(startCalendarDateTime);
       
  1311 				TCalTime calTime;
       
  1312 				calTime.SetTimeLocalL(startCalTime);
       
  1313 				QDateTime endDateTime = entry.endTime();
       
  1314 				QDate endDate = endDateTime.date();
       
  1315 				QTime endTime = endDateTime.time();
       
  1316 
       
  1317 				TDateTime endCalendarDateTime(
       
  1318 						endDate.year(),
       
  1319 						static_cast<TMonth>(endDate.month() - 1),
       
  1320 						endDate.day() - 1,
       
  1321 						endTime.hour(),
       
  1322 						endTime.minute(),
       
  1323 						0,
       
  1324 						0);
       
  1325 
       
  1326 				TTime endCalTime(endCalendarDateTime);
       
  1327 				TCalTime calTime2;
       
  1328 				calTime2.SetTimeLocalL(endCalTime);
       
  1329 
       
  1330 				newEntry->SetStartAndEndTimeL(calTime, calTime2);
       
  1331 				
       
  1332 				// Save the geo value if any
       
  1333 				AgendaGeoValue entryGeoValue = entry.geoValue();
       
  1334 				if (!entryGeoValue.isNull()) {
       
  1335 					CCalGeoValue* geoValue = CCalGeoValue::NewL();
       
  1336 					double latitude;
       
  1337 					double longitude;
       
  1338 					entryGeoValue.getLatLong(latitude, longitude);
       
  1339 					
       
  1340 					// set the values to symbian geo value
       
  1341 					geoValue->SetLatLongL(latitude, longitude);
       
  1342 					
       
  1343 					// set it to CCalentry
       
  1344 					newEntry->SetGeoValueL(*geoValue);
       
  1345 					delete geoValue;
       
  1346 				}
       
  1347 				
       
  1348 				// No need to update the repeat rule as it is an exception
       
  1349 
       
  1350 				// Store the favourite
       
  1351 				newEntry->SetFavouriteL(entry.favourite());
       
  1352 				
       
  1353 				// reset local UID
       
  1354 				newEntry->SetLocalUidL( TCalLocalUid( 0 ) );
       
  1355 				
       
  1356 				// clear repeat rule properties
       
  1357 				newEntry->ClearRepeatingPropertiesL();
       
  1358 				// Update the entry using the calen entry view.
       
  1359 				RPointerArray<CCalEntry> entryArray;
       
  1360 				CleanupResetAndDestroyPushL(entryArray);
       
  1361 				entryArray.AppendL(newEntry);
       
  1362 				iCalEntryView->StoreL(entryArray, success);
       
  1363 				
       
  1364 				localUid = newEntry->LocalUidL();
       
  1365 				// Cleanup.
       
  1366 				CleanupStack::PopAndDestroy(&entryArray);
       
  1367 		)
       
  1368 	}
       
  1369 
       
  1370 	// Emit the signal to notify the clients.
       
  1371 	if (0 < success) {
       
  1372 		emit q->entryUpdated(localUid);
       
  1373 	}
       
  1374 	return (success != 0);	
       
  1375 }
   637 }
  1376 
   638 
  1377 /*!
   639 /*!
  1378 	Fetches an AgendaEntry, given the id.
   640 	Fetches an AgendaEntry, given the id.
  1379 
   641 
  1638 				if (time <= startDateForInstanceSearch.TimeLocalL()) {
   900 				if (time <= startDateForInstanceSearch.TimeLocalL()) {
  1639 					continue;
   901 					continue;
  1640 				}
   902 				}
  1641 			}
   903 			}
  1642         // Mark the required dates frm start date to end date
   904         // Mark the required dates frm start date to end date
  1643         TTimeIntervalDays days ;
       
  1644         int numOfDays = 0;
   905         int numOfDays = 0;
  1645         //check if the start date of the entry is before the start day of the grid
   906         //check if the start date of the entry is before the start day of the grid
  1646         if(startDate < rangeStart.date()){
   907         if(startDate < rangeStart.date()){
  1647             if(endDate<=rangeEnd.date()){
   908             if(endDate<=rangeEnd.date()){
  1648                 //if the end date of entry is lying in the grid ,
   909                 //if the end date of entry is lying in the grid ,
  1649                 //then mark the entry from start day of the grid to the end date of the entry
   910                 //then mark the entry from start day of the grid to the end date of the entry
  1650                 days = endCalTime.TimeLocalL().DaysFrom(startDateForInstanceSearch.TimeLocalL());
   911                 numOfDays = rangeStart.date().daysTo(endDate);
  1651                 numOfDays = days.Int();
       
  1652             }
   912             }
  1653             else{
   913             else{
  1654                 //if end date of the entry is greater then the last date of grid, 
   914                 //if end date of the entry is greater then the last date of grid, 
  1655                 //then mark all the date of the grid with the entry 
   915                 //then mark all the date of the grid with the entry 
  1656                 days = endDateForInstanceSearch.TimeLocalL().DaysFrom(startDateForInstanceSearch.TimeLocalL()) ;
   916                numOfDays = rangeStart.daysTo(rangeEnd);
  1657                 numOfDays = days.Int();
       
  1658             }
   917             }
  1659             // Check if the event is all-day
   918             // Check if the event is all-day
  1660             if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
   919             if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
  1661                 // no need to consider the date on which it ends
   920                 // no need to consider the date on which it ends
  1662                 // reduce days count by 1
   921                 // reduce days count by 1
  1675         //if the start date of the entry is lying inside the grid
   934         //if the start date of the entry is lying inside the grid
  1676         else{
   935         else{
  1677             if(endDate<=rangeEnd.date()){
   936             if(endDate<=rangeEnd.date()){
  1678                 //if the end date of entry is lying in the grid ,
   937                 //if the end date of entry is lying in the grid ,
  1679                 //then mark the entry from start date of the entry to the end date of the entry
   938                 //then mark the entry from start date of the entry to the end date of the entry
  1680                 days = endCalTime.TimeLocalL().DaysFrom(startCalTime.TimeLocalL()) ;
   939                 numOfDays = startDate.daysTo(endDate);
  1681                 numOfDays = days.Int();
       
  1682             }
   940             }
  1683             else{
   941             else{
  1684                 //if end date of the entry is greater then the last date of grid, 
   942                 //if end date of the entry is greater then the last date of grid, 
  1685                 //then mark all the date from start date of the entry to the end date of the grid 
   943                 //then mark all the date from start date of the entry to the end date of the grid 
  1686                 days = endDateForInstanceSearch.TimeLocalL().DaysFrom(startCalTime.TimeLocalL()) ;
   944                 numOfDays = startDate.daysTo(rangeEnd.date()); 
  1687                 numOfDays = days.Int();
       
  1688             }
   945             }
  1689             // Check if the event is all-day
   946             // Check if the event is all-day
  1690             if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
   947             if (instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
  1691                 // no need to consider the date on which it ends
   948                 // no need to consider the date on which it ends
  1692                 // reduce days count by 1
   949                 // reduce days count by 1
  1786         for (int i(0); i < instanceList.Count(); i++) {
  1043         for (int i(0); i < instanceList.Count(); i++) {
  1787             if ((endsAtStartOfDay(instanceList[i], time)) &&
  1044             if ((endsAtStartOfDay(instanceList[i], time)) &&
  1788                     instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
  1045                     instanceList[i]->Entry().EntryTypeL() == CCalEntry::EEvent) {
  1789                 // Previous day all-day event has been found, we are not supposed to
  1046                 // Previous day all-day event has been found, we are not supposed to
  1790                 // show it on current day, hence remove it from the instance list
  1047                 // show it on current day, hence remove it from the instance list
       
  1048                 CCalInstance *instance = instanceList[i];
  1791                 instanceList.Remove(i);
  1049                 instanceList.Remove(i);
       
  1050                 delete instance;
  1792                 i--;
  1051                 i--;
  1793             }
  1052             }
  1794         }
  1053         }
  1795         
  1054         
  1796         // Sort the list
  1055         // Sort the list
  2020 			}
  1279 			}
  2021 	)
  1280 	)
  2022 
  1281 
  2023 	// Return the parent entry.
  1282 	// Return the parent entry.
  2024 	return parentEntry;
  1283 	return parentEntry;
  2025 }
       
  2026 
       
  2027 /*!
       
  2028 	Clears the repeating properties of the entry. This means
       
  2029 	It will delete all the instances and stores a single entry
       
  2030 	which is non repeating
       
  2031 
       
  2032 	\param entry The entry for which repeating properties to be cleared
       
  2033 	\return None
       
  2034  */
       
  2035 void AgendaUtilPrivate::clearRepeatingProperties(AgendaEntry& entry)
       
  2036 {
       
  2037 	// Fetch the parent entry 
       
  2038 	// Get the CalEntry equivalent of the entry.
       
  2039 	CCalEntry* calEntry = iCalEntryView->FetchL(entry.id());
       
  2040 
       
  2041 	if (calEntry) {
       
  2042 		// Get all the entries with same global Uid.
       
  2043 		RPointerArray<CCalEntry> entries;
       
  2044 		CleanupResetAndDestroyPushL(entries);
       
  2045 		iCalEntryView->FetchL(calEntry->UidL(), entries);
       
  2046 		entries[0]->ClearRepeatingPropertiesL();
       
  2047 		CleanupStack::PopAndDestroy(&entries);
       
  2048 	}
       
  2049 }
  1284 }
  2050 
  1285 
  2051 /*!
  1286 /*!
  2052 	Returns the start and end times of previous occurence of a particular
  1287 	Returns the start and end times of previous occurence of a particular
  2053 	instance
  1288 	instance
  2458  */
  1693  */
  2459 bool AgendaUtilPrivate::areNoEntriesInCalendar()
  1694 bool AgendaUtilPrivate::areNoEntriesInCalendar()
  2460 {
  1695 {
  2461 	// First prepare the session with the agenda server.
  1696 	// First prepare the session with the agenda server.
  2462 	if (!mInstanceViewCreated) {
  1697 	if (!mInstanceViewCreated) {
  2463 		return false;
  1698         // database is not ready, so, return that there are no entries
       
  1699 		return true;
  2464 	}
  1700 	}
  2465 	
  1701 	
  2466 	bool isEmpty;
  1702 	bool isEmpty;
  2467 	// Query for the entries for entire range
  1703 	// Query for the entries for entire range
  2468 	RPointerArray<CCalInstance> instanceList;
  1704 	RPointerArray<CCalInstance> instanceList;
  2667 			QTime(
  1903 			QTime(
  2668 					calEndDateTime.Hour(), calEndDateTime.Minute(), 0, 0));
  1904 					calEndDateTime.Hour(), calEndDateTime.Minute(), 0, 0));
  2669 	entry.setStartAndEndTime(startDateTime, endDateTime);
  1905 	entry.setStartAndEndTime(startDateTime, endDateTime);
  2670 
  1906 
  2671 	// Attendees.
  1907 	// Attendees.
  2672 	RPointerArray<CCalAttendee>& calAttendees = calEntry.AttendeesL();
  1908 	RPointerArray<CCalAttendee> calAttendees = calEntry.AttendeesL();
  2673 
  1909 
  2674 	for (int i = 0; i < calAttendees.Count(); i++) {
  1910 	for (int i = 0; i < calAttendees.Count(); i++) {
  2675 		AgendaAttendee attendee;
  1911 		AgendaAttendee attendee;
  2676 		// Address.
  1912 		// Address.
  2677 		TPtrC calAddress = calAttendees[i]->Address();
  1913 		TPtrC calAddress = calAttendees[i]->Address();
  2696 						calAttendees[i]->StatusL()));
  1932 						calAttendees[i]->StatusL()));
  2697 		entry.addAttendee(attendee);
  1933 		entry.addAttendee(attendee);
  2698 	}
  1934 	}
  2699 
  1935 
  2700 	// Categories.
  1936 	// Categories.
  2701 	const RPointerArray<CCalCategory>& calCategories = calEntry.CategoryListL();
  1937 	const RPointerArray<CCalCategory> calCategories = calEntry.CategoryListL();
  2702 
  1938 
  2703 	for (int i = 0; i < calCategories.Count(); i++) {
  1939 	for (int i = 0; i < calCategories.Count(); i++) {
  2704 		AgendaCategory category;
  1940 		AgendaCategory category;
  2705 		CCalCategory::TCalCategoryType categoryType =
  1941 		CCalCategory::TCalCategoryType categoryType =
  2706 				calCategories[i]->Category();
  1942 				calCategories[i]->Category();
  2841 		delete geoValue;
  2077 		delete geoValue;
  2842 	}
  2078 	}
  2843 	
  2079 	
  2844 	// Return the entry.
  2080 	// Return the entry.
  2845 	return entry;
  2081 	return entry;
       
  2082 }
       
  2083 
       
  2084 /*!
       
  2085 	Copy all the data to CCalEntry from a given AgendaEntry.
       
  2086 	\param agendaEntry Reference to a AgendaEntry.
       
  2087 	\param calEntry Reference to a CCalEntry.
       
  2088  */
       
  2089 void AgendaUtilPrivate::createCCalEntryFromAgendaEntry(AgendaEntry &agendaEntry, CCalEntry &calEntry)
       
  2090 {
       
  2091 	if (agendaEntry.isNull()) {
       
  2092 			// Invalid entry.
       
  2093 			return;
       
  2094 		}
       
  2095 	
       
  2096 	TRAP(
       
  2097 			iError,
       
  2098 			// Add description to the agendaEntry.
       
  2099 			TPtrC
       
  2100 					description(
       
  2101 								reinterpret_cast<const TUint16*> (agendaEntry.description().utf16()));
       
  2102 			calEntry.SetDescriptionL(description);
       
  2103 			
       
  2104 			if(AgendaEntry::MethodUnknown != agendaEntry.method()) {
       
  2105 								calEntry.SetMethodL(
       
  2106 									static_cast<CCalEntry::TMethod> (agendaEntry.method()));
       
  2107 			}
       
  2108 	
       
  2109 			// Set the favourite property.
       
  2110 			calEntry.SetFavouriteL(agendaEntry.favourite());
       
  2111 			
       
  2112 			
       
  2113 			if (AgendaEntry::TypeNote == agendaEntry.type()) {
       
  2114 				// Set the last modification time.
       
  2115 				TCalTime calTime;
       
  2116 				QDateTime dateTime = agendaEntry.lastModifiedDateTime();
       
  2117 				TDateTime tempDateTime(dateTime.date().year(),
       
  2118 						static_cast<TMonth> (dateTime.date().month() - 1),
       
  2119 						dateTime.date().day() - 1, dateTime.time().hour(),
       
  2120 						dateTime.time().minute(), 0, 0);
       
  2121 				TTime tempTime(tempDateTime);
       
  2122 				calTime.SetTimeLocalL(tempTime);
       
  2123 				calEntry.SetLastModifiedDateL(calTime);
       
  2124 				
       
  2125 				// Set the dtstamp time.It is used to set the creation time.
       
  2126 				TCalTime creationCalTime;
       
  2127 				QDateTime dtStamp = agendaEntry.dtStamp();
       
  2128 				TDateTime
       
  2129 				creationDateTime(dtStamp.date().year(),
       
  2130 						static_cast<TMonth> (dtStamp.date().month() - 1),
       
  2131 						dtStamp.date().day() - 1, dtStamp.time().hour(),
       
  2132 						dtStamp.time().minute(), 0, 0);
       
  2133 				TTime creationTTime(creationDateTime);
       
  2134 				creationCalTime.SetTimeLocalL(creationTTime);
       
  2135 				calEntry.SetDTStampL(creationCalTime);
       
  2136 			} else {
       
  2137 	
       
  2138 			// Add the summary.
       
  2139 			TPtrC
       
  2140 					summary(
       
  2141 							reinterpret_cast<const TUint16*> (agendaEntry.summary().utf16()));
       
  2142 			calEntry.SetSummaryL(summary);
       
  2143 	
       
  2144 			// Set the agendaEntry Start/End Date and time.
       
  2145 			QDate date = agendaEntry.startTime().date();
       
  2146 			QTime time = agendaEntry.startTime().time();
       
  2147 	
       
  2148 			TDateTime startDateTime(date.year(), static_cast<TMonth> (date.month()
       
  2149 					- 1), date.day() - 1, time.hour(), time.minute(), 0, 0);
       
  2150 			TTime entryStartTime(startDateTime);
       
  2151 			TCalTime calStartTime;
       
  2152 
       
  2153 			date = agendaEntry.endTime().date();
       
  2154 			time = agendaEntry.endTime().time();
       
  2155 	
       
  2156 			TDateTime endDateTime(date.year(), static_cast<TMonth> (date.month()
       
  2157 					- 1), date.day() - 1, time.hour(), time.minute(), 0, 0);
       
  2158 			TTime entryEndTime(endDateTime);
       
  2159 			TCalTime calEndTime;
       
  2160 			
       
  2161 			// Use floating time for the nontimed entries.
       
  2162 			if(agendaEntry.isTimedEntry()) {
       
  2163 			    calStartTime.SetTimeLocalL(entryStartTime);
       
  2164 			    calEndTime.SetTimeLocalL(entryEndTime);    
       
  2165 			}else {
       
  2166 			    calStartTime.SetTimeLocalFloatingL(entryStartTime);
       
  2167 			    calEndTime.SetTimeLocalFloatingL(entryEndTime);
       
  2168 			}
       
  2169 			calEntry.SetStartAndEndTimeL(calStartTime, calEndTime);
       
  2170 	
       
  2171 			// Add attendees to the agendaEntry.
       
  2172 			addAttendeesToEntry(agendaEntry.d->m_attendees, calEntry);
       
  2173 	
       
  2174 			// Add categories to the agendaEntry.
       
  2175 			addCategoriesToEntry(agendaEntry.d->m_categories, calEntry);
       
  2176 	
       
  2177 			// Add Alarm to the agendaEntry.
       
  2178 			AgendaAlarm alarm = agendaEntry.alarm();
       
  2179 			setAlarmToEntry(alarm, calEntry);
       
  2180 	
       
  2181 			// Set the priority.
       
  2182 			int priority = agendaEntry.priority();
       
  2183 			if (agendaEntry.priority() != -1) {
       
  2184 				calEntry.SetPriorityL(priority);
       
  2185 			}
       
  2186 	
       
  2187 			// Set the location.
       
  2188 			TPtrC
       
  2189 					location(
       
  2190 							 reinterpret_cast<const TUint16*> (agendaEntry.location().utf16()));
       
  2191 			calEntry.SetLocationL(location);
       
  2192 	
       
  2193 			// Set the repeat type if applicable.
       
  2194 			if (AgendaRepeatRule::InvalidRule != agendaEntry.repeatRule().type()) {
       
  2195 				AgendaRepeatRule agendaRepeatRule = agendaEntry.repeatRule();
       
  2196 				TCalRRule repeatRule =
       
  2197 						createTCalRRuleFromAgendaRRule(agendaRepeatRule, agendaEntry.isTimedEntry());
       
  2198 				calEntry.SetRRuleL(repeatRule);
       
  2199 			}
       
  2200 	
       
  2201 			// Save the status of the agendaEntry.
       
  2202 			calEntry.SetStatusL((CCalEntry::TStatus) agendaEntry.status());
       
  2203 	
       
  2204 			// Save the geo value if any
       
  2205 			AgendaGeoValue entryGeoValue = agendaEntry.geoValue();
       
  2206 			if (!entryGeoValue.isNull()) {
       
  2207 				CCalGeoValue* geoValue = CCalGeoValue::NewL();
       
  2208 				double latitude;
       
  2209 				double longitude;
       
  2210 				entryGeoValue.getLatLong(latitude, longitude);
       
  2211 	
       
  2212 				// set the values to symbian geo value
       
  2213 				geoValue->SetLatLongL(latitude, longitude);
       
  2214 	
       
  2215 				// set it to CCalentry
       
  2216 				calEntry.SetGeoValueL(*geoValue);
       
  2217 				delete geoValue;
       
  2218 			} else {
       
  2219 				calEntry.ClearGeoValueL();
       
  2220 			}
       
  2221 		}
       
  2222 	)
       
  2223 
  2846 }
  2224 }
  2847 
  2225 
  2848 bool AgendaUtilPrivate::addAttendeesToEntry(
  2226 bool AgendaUtilPrivate::addAttendeesToEntry(
  2849 		const QList<AgendaAttendee>& attendees, CCalEntry& entry)
  2227 		const QList<AgendaAttendee>& attendees, CCalEntry& entry)
  2850 {
  2228 {
  3508   
  2886   
  3509     CleanupStack::PopAndDestroy( &allInstances );  
  2887     CleanupStack::PopAndDestroy( &allInstances );  
  3510     return nextTime;
  2888     return nextTime;
  3511 }
  2889 }
  3512 
  2890 
  3513 bool AgendaUtilPrivate::haveRepeatPropertiesChanged(const CCalEntry& newEntry, 
       
  3514 	                                  const CCalEntry& oldEntry)
       
  3515 {
       
  3516 	//Have the RRules Changed?
       
  3517 	TCalRRule newEntryRule;
       
  3518 	newEntry.GetRRuleL(newEntryRule);
       
  3519 
       
  3520 	TCalRRule oldEntryRule;
       
  3521 	oldEntry.GetRRuleL(oldEntryRule);
       
  3522 
       
  3523 	if ((newEntryRule.Type() != oldEntryRule.Type()) ||
       
  3524 	(newEntryRule.DtStart().TimeUtcL() != oldEntryRule.DtStart().TimeUtcL()) ||
       
  3525 	(newEntryRule.Until().TimeUtcL() != oldEntryRule.Until().TimeUtcL()) ||
       
  3526 	(newEntryRule.Count() != oldEntryRule.Count()))
       
  3527 		{
       
  3528 		return ETrue;
       
  3529 		}
       
  3530 
       
  3531 	// Did the RDates change?
       
  3532 	TBool rDatesChanged = EFalse;
       
  3533 	RArray<TCalTime> newRDates;
       
  3534 	RArray<TCalTime> oldRDates;
       
  3535 	CleanupClosePushL(newRDates);
       
  3536 	CleanupClosePushL(oldRDates);
       
  3537 	newEntry.GetRDatesL(newRDates);
       
  3538 	oldEntry.GetRDatesL(oldRDates);
       
  3539 
       
  3540 	if (newRDates.Count() != oldRDates.Count())
       
  3541 		{
       
  3542 		rDatesChanged = ETrue;
       
  3543 		}
       
  3544 	else
       
  3545 		{
       
  3546 		for (TInt x = 0; x < newRDates.Count(); ++x)
       
  3547 			{
       
  3548 			if (newRDates[x].TimeUtcL() != oldRDates[x].TimeUtcL())
       
  3549 				{
       
  3550 				rDatesChanged = ETrue;
       
  3551 				break;
       
  3552 				}
       
  3553 			}
       
  3554 		}
       
  3555 
       
  3556 	CleanupStack::PopAndDestroy(&oldRDates);
       
  3557 	CleanupStack::PopAndDestroy(&newRDates);
       
  3558 
       
  3559 	return rDatesChanged;
       
  3560 }
       
  3561 
       
  3562 void AgendaUtilPrivate::copyChildrenExceptionData( CCalEntry& editedEntry,
       
  3563 								RPointerArray<CCalEntry>& oldEntries )
       
  3564 {
       
  3565 	// For each oldChild..., 0th index will be parent
       
  3566 	for (int i=1; i<oldEntries.Count(); ++i) {
       
  3567 		// For each field...
       
  3568 		for(DifferenceFlag j=(DifferenceFlag)1; j<EntryDifferenceCount; j=(DifferenceFlag)(j<<1))
       
  3569 			{
       
  3570 			// Where oldChild field == oldParent Field
       
  3571 			// and newParent field != oldParent Field...
       
  3572 			if( isFieldSame(*oldEntries[i], *oldEntries[0], j ) &&
       
  3573 				!isFieldSame(editedEntry,  *oldEntries[0], j ) )
       
  3574 				{
       
  3575 				// ...copy newParent field to oldChild.
       
  3576 				copyField(editedEntry, *oldEntries[i], j);
       
  3577 				}
       
  3578 			}
       
  3579 	}	
       
  3580 }
       
  3581 
       
  3582 bool AgendaUtilPrivate::isFieldSame(CCalEntry& entryOne,
       
  3583 									CCalEntry& entryTwo,
       
  3584 									DifferenceFlag flag)
       
  3585 {
       
  3586 	switch( flag ) {
       
  3587 		case EntryDifferentStartTimeAndEndTime: {
       
  3588 			TTime zero(TInt64(0));
       
  3589 			TTime entryOneStartTime = entryOne.StartTimeL().TimeUtcL();
       
  3590 			TTime beginningOfDay = zero + entryOneStartTime.DaysFrom(zero);
       
  3591 			TTimeIntervalMinutes startTimeOne;
       
  3592 			entryOneStartTime.MinutesFrom(beginningOfDay, startTimeOne);
       
  3593 			TTime entryTwoStartTime = entryTwo.StartTimeL().TimeUtcL();
       
  3594 			beginningOfDay = zero + entryTwoStartTime.DaysFrom(zero);
       
  3595 			TTimeIntervalMinutes startTimeTwo;
       
  3596 			entryTwoStartTime.MinutesFrom(beginningOfDay, startTimeTwo);
       
  3597 			TTime entryOneEndTime = entryOne.EndTimeL().TimeUtcL();
       
  3598 			beginningOfDay = zero + entryOneEndTime.DaysFrom(zero);
       
  3599 			TTimeIntervalMinutes endTimeOne;
       
  3600 			entryOneEndTime.MinutesFrom(beginningOfDay, endTimeOne);
       
  3601 			TTime entryTwoEndTime = entryTwo.EndTimeL().TimeUtcL();
       
  3602 			beginningOfDay = zero + entryTwoEndTime.DaysFrom(zero);
       
  3603 			TTimeIntervalMinutes endTimeTwo;
       
  3604 			entryTwoEndTime.MinutesFrom(beginningOfDay, endTimeTwo);
       
  3605 			return      ( startTimeOne.Int()
       
  3606 						== startTimeTwo.Int() )
       
  3607 					&&  ( endTimeOne.Int() 
       
  3608 						== endTimeTwo.Int() );
       
  3609 		}
       
  3610 		case EntryDifferentSummary:
       
  3611 			return entryOne.SummaryL() == entryTwo.SummaryL();
       
  3612 		case EntryDifferentDescription:
       
  3613 			return entryOne.DescriptionL() == entryTwo.DescriptionL();
       
  3614 		case EntryDifferentLocation:
       
  3615 			return entryOne.LocationL() == entryTwo.LocationL();
       
  3616 		default:
       
  3617 			break;
       
  3618 	}
       
  3619 	return EFalse; // Never hit.
       
  3620 }
       
  3621 
       
  3622 void AgendaUtilPrivate::copyField( const CCalEntry& src,
       
  3623                                     CCalEntry& dst,
       
  3624                                     DifferenceFlag field )
       
  3625 {
       
  3626 	switch( field ) {
       
  3627 		case EntryDifferentStartTimeAndEndTime:
       
  3628 			{
       
  3629 			// START TIME
       
  3630 			// Keep aDst's start date, but copy the start time (h/m/s) from aSrc to aDst.
       
  3631 			TTime zero(TInt64(0));
       
  3632 			TTime srcStartTime = src.StartTimeL().TimeUtcL();
       
  3633 			TTime srcStartDay = zero + src.StartTimeL().TimeUtcL().DaysFrom(zero);
       
  3634 			TTime dstStartDay = zero + dst.StartTimeL().TimeUtcL().DaysFrom(zero);
       
  3635 			TTimeIntervalMinutes dstStartTimeOfDay;
       
  3636 			srcStartTime.MinutesFrom(srcStartDay, dstStartTimeOfDay);
       
  3637 	
       
  3638 			TCalTime startTime;
       
  3639 			startTime.SetTimeUtcL( dstStartDay + (TTimeIntervalMinutes)dstStartTimeOfDay );
       
  3640 	
       
  3641 	
       
  3642 			TTimeIntervalMinutes duration;
       
  3643 			src.EndTimeL().TimeUtcL().MinutesFrom(src.StartTimeL().TimeUtcL(), duration);
       
  3644 	
       
  3645 			// END TIME
       
  3646 			// Calculate the duration of aSrc, and make aDst endtime equal aDst startTime
       
  3647 			// + duration.  This will allow for events spanning multiple days.
       
  3648 			TCalTime endTime;
       
  3649 			endTime.SetTimeUtcL(startTime.TimeUtcL() + duration);
       
  3650 	
       
  3651 			dst.SetStartAndEndTimeL(startTime, endTime);
       
  3652 	
       
  3653 			break;
       
  3654 			}
       
  3655 		case EntryDifferentSummary:
       
  3656 			dst.SetSummaryL(src.SummaryL());
       
  3657 			break;
       
  3658 		case EntryDifferentDescription:
       
  3659 			dst.SetDescriptionL(src.DescriptionL());
       
  3660 			break;
       
  3661 		case EntryDifferentLocation:
       
  3662 		{
       
  3663 			dst.SetLocationL(src.LocationL());
       
  3664 			CCalGeoValue* geoValue = src.GeoValueL();
       
  3665 			if (geoValue) {
       
  3666 				dst.SetGeoValueL(*geoValue);
       
  3667 				delete geoValue;
       
  3668 			}
       
  3669 			break;
       
  3670 		}
       
  3671 		default:
       
  3672 			break;
       
  3673 	}
       
  3674 }
       
  3675 
       
  3676 void AgendaUtilPrivate::storeEachChildEntry(CCalEntry &entry,
       
  3677                                               RPointerArray<CCalEntry> &oldEntries,
       
  3678                                               bool resetLocalUid)
       
  3679     {
       
  3680     
       
  3681     // Start from 1 as we don't want to copy the old parent entry.
       
  3682     for(int i=1; i<oldEntries.Count(); ++i)
       
  3683         {
       
  3684         if (resetLocalUid)
       
  3685             {
       
  3686             // Reset the local UID of the exception.  When we store the exception, it will
       
  3687             // be added as a new entry rather than an update.
       
  3688             oldEntries[i]->SetLocalUidL( TCalLocalUid( 0 ) );
       
  3689             }
       
  3690 
       
  3691         // The RecurrenceId of child (exception) entries should never be a null time by definition.
       
  3692         // The code below will attempt to generate a RecurrenceId from the start time of the
       
  3693         // exception if no RecurrenceId is found.  This should never actually happen, and
       
  3694         // will not work if the start time/start date is changed.  The if case below should remain
       
  3695         // until the Symbian defect fix for NULL RecurrenceIds is verified.
       
  3696 
       
  3697         if(oldEntries[i]->RecurrenceIdL().TimeUtcL() == Time::NullTTime())
       
  3698             {
       
  3699             // This is being hit, but shouldn't be. Hence we create a new Recurrence ID.
       
  3700             // Without doing this, the SingleStoreL below fails with Agenda Model -35: No agenda server.
       
  3701             TCalTime recId = generateRecurrenceIdFromEntry( entry, oldEntries[i]->StartTimeL() );
       
  3702             CCalEntry *exception = CCalEntry::NewL( oldEntries[i]->EntryTypeL(),
       
  3703                                                 entry.UidL().AllocL(),
       
  3704                                                 oldEntries[i]->MethodL(),
       
  3705                                                 oldEntries[i]->SequenceNumberL(),
       
  3706                                                 recId,
       
  3707                                                 oldEntries[i]->RecurrenceRangeL() );
       
  3708             exception->CopyFromL(*oldEntries[i]);
       
  3709             exception->SetLastModifiedDateL();
       
  3710             TInt successCount=0;
       
  3711 			RPointerArray<CCalEntry> entries;
       
  3712 			CleanupResetAndDestroyPushL(entries);
       
  3713 			entries.Append( exception );
       
  3714 			iCalEntryView->StoreL( entries, successCount );
       
  3715 			CleanupStack::PopAndDestroy( &entries );
       
  3716             }
       
  3717         else
       
  3718             {
       
  3719             // If the start time of the series has been changed, the call below will
       
  3720             // leave with -1, and the child entries will be lost.  To prevent this
       
  3721             // we need to regenerate a new recurrence id for each child, create a copy
       
  3722             // of the child with the new recurrence id, and store that instead.
       
  3723             // Fixing this may cause issues with sync though, as some servers delete the
       
  3724             // children when changing the start time of the series anyway.
       
  3725         	oldEntries[i]->SetLastModifiedDateL();
       
  3726 			TInt successCount=0;
       
  3727 			RPointerArray<CCalEntry> entries;
       
  3728 			CleanupClosePushL(entries);
       
  3729 			entries.Append( oldEntries[i] );
       
  3730 			iCalEntryView->StoreL( entries, successCount );
       
  3731 			CleanupStack::Pop( &entries );
       
  3732             }
       
  3733         }
       
  3734     }
       
  3735 
       
  3736 TCalTime AgendaUtilPrivate::generateRecurrenceIdFromEntry( CCalEntry& entry, 
  2891 TCalTime AgendaUtilPrivate::generateRecurrenceIdFromEntry( CCalEntry& entry, 
  3737 														TCalTime instanceDate )
  2892 														TCalTime instanceDate )
  3738 {    
  2893 {    
  3739     TDateTime theTime = entry.StartTimeL().TimeUtcL().DateTime();
  2894     TDateTime theTime = entry.StartTimeL().TimeUtcL().DateTime();
  3740     TDateTime theDate = instanceDate.TimeUtcL().DateTime();
  2895     TDateTime theDate = instanceDate.TimeUtcL().DateTime();
  3814 	return agendaRepeatRule;
  2969 	return agendaRepeatRule;
  3815 
  2970 
  3816 }
  2971 }
  3817 
  2972 
  3818 TCalRRule AgendaUtilPrivate::createTCalRRuleFromAgendaRRule(
  2973 TCalRRule AgendaUtilPrivate::createTCalRRuleFromAgendaRRule(
  3819 												AgendaRepeatRule &agendaRRule)
  2974 												AgendaRepeatRule &agendaRRule, bool isNonFloating )
  3820 {
  2975 {
  3821 	TCalRRule
  2976 	TCalRRule
  3822 	        repeatRule(
  2977 	        repeatRule(
  3823 	                   static_cast<TCalRRule::TType> (agendaRRule.type()));
  2978 	                   static_cast<TCalRRule::TType> (agendaRRule.type()));
  3824 	QDateTime ruleStartDateTime = agendaRRule.repeatRuleStart();
  2979 	QDateTime ruleStartDateTime = agendaRRule.repeatRuleStart();
  3828 	                 ruleStartDateTime.time().hour(),
  2983 	                 ruleStartDateTime.time().hour(),
  3829 	                 ruleStartDateTime.time().minute(),
  2984 	                 ruleStartDateTime.time().minute(),
  3830 	                 0, 
  2985 	                 0, 
  3831 	                 0);
  2986 	                 0);
  3832 	
  2987 	
  3833 	TCalTime ruleStartCalTime;
       
  3834 	ruleStartCalTime.SetTimeLocalL(TTime(ruleStartCalendarDateTime));
       
  3835 	repeatRule.SetDtStart(ruleStartCalTime);
       
  3836 	repeatRule.SetInterval(agendaRRule.interval());
       
  3837 	QDateTime repeatUntilDate = agendaRRule.until();
  2988 	QDateTime repeatUntilDate = agendaRRule.until();
  3838 	TDateTime repeatTill(repeatUntilDate.date().year(), 
  2989 	TDateTime repeatTill(repeatUntilDate.date().year(), 
  3839 	                   static_cast<TMonth> (repeatUntilDate.date().month() - 1),
  2990 	                   static_cast<TMonth> (repeatUntilDate.date().month() - 1),
  3840 	                   repeatUntilDate.date().day() - 1, 
  2991 	                   repeatUntilDate.date().day() - 1, 
  3841 	                   repeatUntilDate.time().hour(), 
  2992 	                   repeatUntilDate.time().hour(), 
  3842 	                   repeatUntilDate.time().minute(), 
  2993 	                   repeatUntilDate.time().minute(), 
  3843 	                   0, 
  2994 	                   0, 
  3844 	                   0);
  2995 	                   0);
  3845 
  2996 	
       
  2997 	TCalTime ruleStartCalTime;
  3846 	TCalTime ruleRepeatTillTime;
  2998 	TCalTime ruleRepeatTillTime;
  3847 	ruleRepeatTillTime.SetTimeLocalL(TTime(repeatTill));
  2999 	if(isNonFloating) {
       
  3000 	    // Use Fixed time for timed entries.
       
  3001 	    ruleStartCalTime.SetTimeLocalL(TTime(ruleStartCalendarDateTime));
       
  3002 	    ruleRepeatTillTime.SetTimeLocalL(TTime(repeatTill));
       
  3003 	}else {
       
  3004 	    // Use Floating time for Non timed entries
       
  3005 	    ruleStartCalTime.SetTimeLocalFloatingL(TTime(ruleStartCalendarDateTime));
       
  3006 	    ruleRepeatTillTime.SetTimeLocalFloatingL(TTime(repeatTill));
       
  3007 	}
       
  3008 	repeatRule.SetDtStart(ruleStartCalTime);
       
  3009 	repeatRule.SetInterval(agendaRRule.interval());
  3848 	repeatRule.SetUntil(ruleRepeatTillTime);
  3010 	repeatRule.SetUntil(ruleRepeatTillTime);
  3849 
  3011 
  3850 	QList<AgendaRepeatRule::Day> qDays = agendaRRule.byDay();
  3012 	QList<AgendaRepeatRule::Day> qDays = agendaRRule.byDay();
  3851 	RArray<TDay> days;
  3013 	RArray<TDay> days;
  3852 	for (int i = 0; i < qDays.count(); i++) {
  3014 	for (int i = 0; i < qDays.count(); i++) {