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(); |
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 |
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(); |