187 |
199 |
188 emit q->entriesChanged(ids); |
200 emit q->entriesChanged(ids); |
189 } |
201 } |
190 |
202 |
191 /*! |
203 /*! |
192 Adds a new entry with the calendar database. |
204 To store the new entry or update the entry in the Calendar db. |
193 |
205 |
194 \param entry Reference to a new AgendaEntry to be added. |
206 \param entry The entry to be added/updated |
195 \return ulong The local uid of the entry added in the db. |
207 \param range The recurrence range of entry |
196 */ |
208 \return ulong The local uid of the entry added/updated in the db. |
197 ulong AgendaUtilPrivate::addEntry(const AgendaEntry& entry) |
209 */ |
|
210 ulong AgendaUtilPrivate::store(AgendaEntry &entry, AgendaUtil::RecurrenceRange range) |
198 { |
211 { |
199 // Will be filled with the lUID of the new entry created. |
212 // Will be filled with the lUID of the new entry created. |
200 TCalLocalUid localUid = 0; |
213 TCalLocalUid localUid = 0; |
201 int success = 0; |
|
202 |
214 |
203 // 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. |
204 if (!mInstanceViewCreated) { |
216 if (!mInstanceViewCreated) { |
205 // Something went wrong |
217 // Something went wrong |
206 return localUid; |
218 return localUid; |
207 } |
219 } |
208 |
220 CCalEntry *calEntry = 0; |
209 // Get the global uid. |
221 |
210 CCalenInterimUtils2* calenInterimUtils2 = CCalenInterimUtils2::NewL(); |
222 TRAP( |
211 HBufC8* globalUid = calenInterimUtils2->GlobalUidL(); |
223 iError, |
212 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) { |
213 TRAP( |
388 TRAP( |
214 iError, |
389 iError, |
215 |
390 |
216 RPointerArray<CCalEntry> entryArray; |
391 RPointerArray<CCalEntry> entryArray; |
217 CleanupResetAndDestroyPushL(entryArray); |
392 CleanupClosePushL(entryArray); |
218 CleanupStack::PushL(globalUid); |
|
219 |
393 |
220 // Construct a CCalEntry object and start filling the details. |
394 // Construct a CCalEntry object and start filling the details. |
221 CCalEntry* newEntry = 0; |
395 CCalEntry* newEntry = 0; |
222 newEntry = CCalEntry::NewL( |
396 newEntry = CCalEntry::NewL( |
223 static_cast<CCalEntry::TType>(entry.type()), |
397 static_cast<CCalEntry::TType>(type), |
224 globalUid, |
398 globalUid, |
225 static_cast<CCalEntry::TMethod>(entry.method()), |
399 static_cast<CCalEntry::TMethod>(entry.method()), |
226 0); |
400 0); |
227 |
|
228 CleanupStack::Pop(globalUid); |
|
229 |
401 |
230 // Add description. |
402 // Add description. |
231 TPtrC description(reinterpret_cast<const TUint16*>( |
403 TPtrC description(reinterpret_cast<const TUint16*>( |
232 entry.description().utf16())); |
404 entry.description().utf16())); |
233 newEntry->SetDescriptionL(description); |
405 newEntry->SetDescriptionL(description); |
234 |
406 |
235 // Set the favourite property. |
407 // Set the favourite property. |
236 newEntry->SetFavouriteL(entry.favourite()); |
408 newEntry->SetFavouriteL(entry.favourite()); |
237 |
|
238 // Set the last modification time. |
|
239 TCalTime calTime; |
|
240 QDateTime dateTime = entry.lastModifiedDateTime(); |
|
241 TDateTime tempDateTime( |
|
242 dateTime.date().year(), |
|
243 static_cast<TMonth>(dateTime.date().month() - 1), |
|
244 dateTime.date().day() - 1, dateTime.time().hour(), |
|
245 dateTime.time().minute(), 0, 0); |
|
246 TTime tempTime(tempDateTime); |
|
247 calTime.SetTimeLocalL(tempTime); |
|
248 newEntry->SetLastModifiedDateL(calTime); |
|
249 |
|
250 // Set the dtstamp time.It is used to set the cretaion time. |
|
251 TCalTime creationCalTime; |
|
252 QDateTime dtStamp = entry.dtStamp(); |
|
253 TDateTime creationDateTime( |
|
254 dtStamp.date().year(), |
|
255 static_cast<TMonth>(dtStamp.date().month() - 1), |
|
256 dtStamp.date().day() - 1, dtStamp.time().hour(), |
|
257 dtStamp.time().minute(), 0, 0); |
|
258 TTime creationTTime(creationDateTime); |
|
259 creationCalTime.SetTimeLocalL(creationTTime); |
|
260 newEntry->SetDTStampL(creationCalTime); |
|
261 |
409 |
262 // Finally set the entry to the database using the entry view. |
410 // Finally set the entry to the database using the entry view. |
263 entryArray.AppendL(newEntry); |
411 entryArray.AppendL(newEntry); |
264 iCalEntryView->StoreL(entryArray, success); |
412 iCalEntryView->StoreL(entryArray, success); |
265 localUid = newEntry->LocalUidL(); |
413 localUid = newEntry->LocalUidL(); |
372 |
529 |
373 // set it to CCalentry |
530 // set it to CCalentry |
374 newEntry->SetGeoValueL(*geoValue); |
531 newEntry->SetGeoValueL(*geoValue); |
375 delete geoValue; |
532 delete geoValue; |
376 } |
533 } |
377 |
|
378 // Finally set the entry to the database using the entry view. |
|
379 entryArray.AppendL(newEntry); |
|
380 iCalEntryView->StoreL(entryArray, success); |
|
381 localUid = newEntry->LocalUidL(); |
|
382 |
|
383 // Cleanup. |
|
384 CleanupStack::PopAndDestroy(&entryArray); |
|
385 ) |
|
386 } |
|
387 |
|
388 delete calenInterimUtils2; |
|
389 |
|
390 // Emit signal upon successful creation of entry. |
|
391 if (0 < localUid && 1 == success) { |
|
392 emit q->entryAdded(localUid); |
|
393 } |
|
394 return localUid; |
|
395 } |
|
396 |
|
397 /*! |
|
398 Clones the `entry' passed in the argument and saves it as type `type'. |
|
399 |
|
400 \param entry Entry which should be used for cloning. |
|
401 \param type The new type of the entry. |
|
402 \return ulong The local UID of the new entry. |
|
403 |
|
404 \sa deleteEntry() |
|
405 */ |
|
406 ulong AgendaUtilPrivate::cloneEntry( |
|
407 const AgendaEntry &entry, AgendaEntry::Type type) |
|
408 { |
|
409 // First prepare the session with agenda server. |
|
410 if (!mInstanceViewCreated) { |
|
411 // Something went wrong. |
|
412 return 0; |
|
413 } |
|
414 |
|
415 if (entry.isNull() |
|
416 || type == AgendaEntry::TypeUnknown) { |
|
417 return 0; |
|
418 } |
|
419 |
|
420 // Will be filled with the lUID of the new entry created. |
|
421 TCalLocalUid localUid = 0; |
|
422 int success = 0; |
|
423 CCalEntry *originalEntry = 0; |
|
424 HBufC8* globalUid = 0; |
|
425 |
|
426 // Get the stored entry first. |
|
427 TRAP( |
|
428 iError, |
|
429 |
|
430 originalEntry = iCalEntryView->FetchL(entry.id()); |
|
431 ) |
|
432 |
|
433 if (!originalEntry) { |
|
434 return 0; |
|
435 } |
|
436 |
|
437 // Now save the GUID of the saved entry. |
|
438 TRAP( |
|
439 iError, |
|
440 globalUid = originalEntry->UidL().AllocL(); |
|
441 ) |
|
442 |
|
443 delete originalEntry; |
|
444 |
|
445 // Now start cloning and create a new entry. |
|
446 if (AgendaEntry::TypeNote == type) { |
|
447 TRAP( |
|
448 iError, |
|
449 |
|
450 RPointerArray<CCalEntry> entryArray; |
|
451 CleanupClosePushL(entryArray); |
|
452 |
|
453 // Construct a CCalEntry object and start filling the details. |
|
454 CCalEntry* newEntry = 0; |
|
455 newEntry = CCalEntry::NewL( |
|
456 static_cast<CCalEntry::TType>(type), |
|
457 globalUid, |
|
458 static_cast<CCalEntry::TMethod>(entry.method()), |
|
459 0); |
|
460 |
|
461 // Add description. |
|
462 TPtrC description(reinterpret_cast<const TUint16*>( |
|
463 entry.description().utf16())); |
|
464 newEntry->SetDescriptionL(description); |
|
465 |
|
466 // Set the favourite property. |
|
467 newEntry->SetFavouriteL(entry.favourite()); |
|
468 |
|
469 // Finally set the entry to the database using the entry view. |
|
470 entryArray.AppendL(newEntry); |
|
471 iCalEntryView->StoreL(entryArray, success); |
|
472 localUid = newEntry->LocalUidL(); |
|
473 |
|
474 // Cleanup. |
|
475 CleanupStack::PopAndDestroy(&entryArray); |
|
476 ) |
|
477 } else { |
|
478 TRAP( |
|
479 iError, |
|
480 |
|
481 RPointerArray<CCalEntry> entryArray; |
|
482 CleanupClosePushL(entryArray); |
|
483 |
|
484 // Construct a CCalEntry object and start filling the details. |
|
485 CCalEntry* newEntry = 0; |
|
486 newEntry = CCalEntry::NewL( |
|
487 static_cast<CCalEntry::TType>(type), |
|
488 globalUid, |
|
489 static_cast<CCalEntry::TMethod>(entry.method()), |
|
490 0); |
|
491 |
|
492 // Add the summary. |
|
493 if (!entry.summary().isNull()) { |
|
494 TPtrC summary(reinterpret_cast<const TUint16*>( |
|
495 entry.summary().utf16())); |
|
496 newEntry->SetSummaryL(summary); |
|
497 } |
|
498 |
|
499 // Set the entry Start/End Date and time. |
|
500 QDate date = entry.startTime().date(); |
|
501 QTime time = entry.startTime().time(); |
|
502 |
|
503 TDateTime startDateTime( |
|
504 date.year(), static_cast<TMonth>(date.month() - 1), |
|
505 date.day() - 1, time.hour(), time.minute(), 0, 0); |
|
506 TTime entryStartTime(startDateTime); |
|
507 TCalTime calStartTime; |
|
508 calStartTime.SetTimeLocalL(entryStartTime); |
|
509 |
|
510 date = entry.endTime().date(); |
|
511 time = entry.endTime().time(); |
|
512 |
|
513 TDateTime endDateTime( |
|
514 date.year(), static_cast<TMonth>(date.month() - 1), |
|
515 date.day() - 1, time.hour(), time.minute(), 0, 0); |
|
516 TTime entryEndTime(endDateTime); |
|
517 TCalTime calEndTime; |
|
518 calEndTime.SetTimeLocalL(entryEndTime); |
|
519 newEntry->SetStartAndEndTimeL(calStartTime, calEndTime); |
|
520 |
|
521 // Add attendees to the entry. |
|
522 addAttendeesToEntry(entry.d->m_attendees, *newEntry); |
|
523 |
|
524 // Add categories to the entry. |
|
525 addCategoriesToEntry(entry.d->m_categories, *newEntry); |
|
526 |
|
527 // Add description to the entry. |
|
528 TPtrC description(reinterpret_cast<const TUint16*>( |
|
529 entry.description().utf16())); |
|
530 newEntry->SetDescriptionL(description); |
|
531 |
|
532 // Set the favourite property. |
|
533 newEntry->SetFavouriteL(entry.favourite()); |
|
534 |
|
535 // Add Alarm to the entry. |
|
536 AgendaAlarm alarm = entry.alarm(); |
|
537 if (!alarm.isNull()) { |
|
538 setAlarmToEntry(alarm, *newEntry); |
|
539 } |
|
540 |
|
541 // Set the priority. |
|
542 int priority = entry.priority(); |
|
543 if (entry.priority() != -1) { |
|
544 newEntry->SetPriorityL(priority); |
|
545 } |
|
546 |
|
547 // Set the location. |
|
548 if (!entry.location().isNull()) { |
|
549 TPtrC location(reinterpret_cast<const TUint16*>( |
|
550 entry.location().utf16())); |
|
551 newEntry->SetLocationL(location); |
|
552 } |
|
553 |
|
554 // Set the repeat type if applicable. |
|
555 if (AgendaRepeatRule::InvalidRule |
|
556 != entry.repeatRule().type()) { |
|
557 AgendaRepeatRule agendaRepeatRule = entry.repeatRule(); |
|
558 TCalRRule repeatRule = |
|
559 createTCalRRuleFromAgendaRRule(agendaRepeatRule); |
|
560 newEntry->SetRRuleL(repeatRule); |
|
561 } |
|
562 |
|
563 // Save the status of the entry. |
|
564 newEntry->SetStatusL((CCalEntry::TStatus) entry.status()); |
|
565 newEntry->SetLastModifiedDateL(); |
|
566 |
|
567 // Save the geo value if any |
|
568 AgendaGeoValue entryGeoValue = entry.geoValue(); |
|
569 if (!entryGeoValue.isNull()) { |
|
570 CCalGeoValue* geoValue = CCalGeoValue::NewL(); |
|
571 double latitude; |
|
572 double longitude; |
|
573 entryGeoValue.getLatLong(latitude, longitude); |
|
574 |
|
575 // set the values to symbian geo value |
|
576 geoValue->SetLatLongL(latitude, longitude); |
|
577 |
|
578 // set it to CCalentry |
|
579 newEntry->SetGeoValueL(*geoValue); |
|
580 delete geoValue; |
|
581 } |
|
582 |
534 |
583 // Finally set the entry to the database using the entry view. |
535 // Finally set the entry to the database using the entry view. |
584 entryArray.AppendL(newEntry); |
536 entryArray.AppendL(newEntry); |
585 iCalEntryView->StoreL(entryArray, success); |
537 iCalEntryView->StoreL(entryArray, success); |
586 localUid = newEntry->LocalUidL(); |
538 localUid = newEntry->LocalUidL(); |
680 } |
632 } |
681 ) |
633 ) |
682 |
634 |
683 // Emit the signal to notify the deletion of entry. |
635 // Emit the signal to notify the deletion of entry. |
684 emit q->entryDeleted(entry.id()); |
636 emit q->entryDeleted(entry.id()); |
685 } |
|
686 |
|
687 /*! |
|
688 Updates a given entry in the calendar database. |
|
689 |
|
690 \param entry The entry to be updated. |
|
691 \return bool true if updation was successful, false otherwise. |
|
692 */ |
|
693 bool AgendaUtilPrivate::updateEntry(const AgendaEntry& entry, bool isChild) |
|
694 { |
|
695 // First prepare the session with agenda server. |
|
696 if (!mInstanceViewCreated) { |
|
697 // Something went wrong. |
|
698 return false; |
|
699 } |
|
700 |
|
701 if (entry.isNull()) { |
|
702 // Invalid entry. |
|
703 return false; |
|
704 } |
|
705 |
|
706 int success = 0; |
|
707 |
|
708 if (AgendaEntry::TypeNote == entry.type()) { |
|
709 TRAP( |
|
710 iError, |
|
711 |
|
712 // Get the entry corresponding to the id. |
|
713 AgendaEntry storedEntry = fetchById(entry.id()); |
|
714 CCalEntry* calEntry = iCalEntryView->FetchL(entry.id()); |
|
715 |
|
716 // Update the description. |
|
717 if (storedEntry.description() != entry.description() |
|
718 && !entry.description().isNull()) { |
|
719 calEntry->SetDescriptionL( |
|
720 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
721 entry.description().utf16()))); |
|
722 } |
|
723 |
|
724 // Update the method. |
|
725 if (storedEntry.method() != entry.method() && |
|
726 AgendaEntry::MethodUnknown != entry.method()) { |
|
727 calEntry->SetMethodL( |
|
728 static_cast<CCalEntry::TMethod> (entry.method())); |
|
729 } |
|
730 |
|
731 // Update the last modification time. |
|
732 if (entry.lastModifiedDateTime().isValid()) { |
|
733 if (entry.lastModifiedDateTime() != |
|
734 storedEntry.lastModifiedDateTime()) { |
|
735 QDateTime dateTime = entry.lastModifiedDateTime(); |
|
736 QDate lastDate = dateTime.date(); |
|
737 QTime lastTime = dateTime.time(); |
|
738 |
|
739 TDateTime lastModDateTime( |
|
740 lastDate.year(), |
|
741 static_cast<TMonth> (lastDate.month() - 1), |
|
742 lastDate.day() - 1, lastTime.hour(), |
|
743 lastTime.minute(), 0, 0); |
|
744 |
|
745 TTime lastModTime(lastModDateTime); |
|
746 TCalTime lastModCalTime; |
|
747 lastModCalTime.SetTimeLocalL(lastModTime); |
|
748 calEntry->SetLastModifiedDateL(lastModCalTime); |
|
749 } |
|
750 } |
|
751 |
|
752 // Update the DTStamp time as the entry is modified. |
|
753 if (entry.dtStamp().isValid()) { |
|
754 TCalTime resetCreationTime; |
|
755 TTime nullTime = Time::NullTTime(); |
|
756 resetCreationTime.SetTimeLocalL(nullTime); |
|
757 calEntry->SetDTStampL(resetCreationTime); |
|
758 } |
|
759 |
|
760 // Check if the favourite property is changed and update the |
|
761 // same. |
|
762 if (entry.favourite() != storedEntry.favourite()) { |
|
763 calEntry->SetFavouriteL(entry.favourite()); |
|
764 } |
|
765 |
|
766 // Update the entry using the CCalEntryView. |
|
767 RPointerArray<CCalEntry> entryArray; |
|
768 CleanupResetAndDestroyPushL(entryArray); |
|
769 entryArray.AppendL(calEntry); |
|
770 iCalEntryView->UpdateL(entryArray, success); |
|
771 |
|
772 // Cleanup. |
|
773 CleanupStack::PopAndDestroy( &entryArray ); |
|
774 ) |
|
775 } else { |
|
776 TRAP( |
|
777 iError, |
|
778 |
|
779 // Get the entry corresponding to the id. |
|
780 AgendaEntry storedEntry = fetchById(entry.id()); |
|
781 CCalEntry* calEntry = iCalEntryView->FetchL(entry.id()); |
|
782 |
|
783 // Update the attendees. |
|
784 if (!entry.isNull() |
|
785 && (entry.d->m_attendees != storedEntry.attendees())) { |
|
786 |
|
787 RPointerArray<CCalAttendee>& attendeesArray = |
|
788 calEntry->AttendeesL(); |
|
789 int iterator = 0; |
|
790 while (attendeesArray.Count() > iterator) { |
|
791 calEntry->DeleteAttendeeL(iterator); |
|
792 iterator++; |
|
793 } |
|
794 |
|
795 addAttendeesToEntry(entry.d->m_attendees, *calEntry); |
|
796 } |
|
797 |
|
798 // Update the categories. |
|
799 if (entry.d->m_categories != storedEntry.categories()) { |
|
800 |
|
801 RPointerArray<CCalCategory> categories = |
|
802 calEntry->CategoryListL(); |
|
803 int iterator = 0; |
|
804 while (categories.Count() > iterator) { |
|
805 calEntry->DeleteCategoryL(iterator); |
|
806 iterator++; |
|
807 } |
|
808 |
|
809 addCategoriesToEntry(entry.d->m_categories, *calEntry); |
|
810 } |
|
811 |
|
812 // Update the alarm. |
|
813 if (entry.alarm() != storedEntry.alarm()) { |
|
814 setAlarmToEntry(entry.alarm(), *calEntry); |
|
815 } |
|
816 |
|
817 // Update the description. |
|
818 if ((storedEntry.description() != entry.description() |
|
819 && !entry.description().isNull()) || entry.description().isNull() ) { |
|
820 calEntry->SetDescriptionL( |
|
821 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
822 entry.description().utf16()))); |
|
823 } |
|
824 |
|
825 // Update the location. |
|
826 if (storedEntry.location() != entry.location() |
|
827 && !entry.location().isNull()) { |
|
828 calEntry->SetLocationL( |
|
829 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
830 entry.location().utf16()))); |
|
831 } |
|
832 |
|
833 // Update the priority. |
|
834 if (storedEntry.priority() != entry.priority() |
|
835 && -1 != entry.priority()) { |
|
836 calEntry->SetPriorityL(entry.priority()); |
|
837 } |
|
838 |
|
839 // Update the summary. |
|
840 if (storedEntry.summary() != entry.summary() |
|
841 && !entry.summary().isNull()) { |
|
842 calEntry->SetSummaryL( |
|
843 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
844 entry.summary().utf16()))); |
|
845 } |
|
846 |
|
847 // Update the method. |
|
848 if (storedEntry.method() != entry.method() && |
|
849 AgendaEntry::MethodUnknown != entry.method()) { |
|
850 calEntry->SetMethodL( |
|
851 static_cast<CCalEntry::TMethod> (entry.method())); |
|
852 } |
|
853 |
|
854 // Update the time. |
|
855 if (storedEntry.startTime() != entry.startTime() |
|
856 || storedEntry.endTime() != entry.endTime()) { |
|
857 |
|
858 QDateTime startDateTime = entry.startTime(); |
|
859 QDate startDate = startDateTime.date(); |
|
860 QTime startTime = startDateTime.time(); |
|
861 |
|
862 TDateTime startCalendarDateTime( |
|
863 startDate.year(), |
|
864 static_cast<TMonth> (startDate.month() - 1), |
|
865 startDate.day() - 1, |
|
866 startTime.hour(), |
|
867 startTime.minute(), |
|
868 0, |
|
869 0); |
|
870 |
|
871 TTime startCalTime(startCalendarDateTime); |
|
872 TCalTime calTime; |
|
873 calTime.SetTimeLocalL(startCalTime); |
|
874 QDateTime endDateTime = entry.endTime(); |
|
875 QDate endDate = endDateTime.date(); |
|
876 QTime endTime = endDateTime.time(); |
|
877 |
|
878 TDateTime endCalendarDateTime( |
|
879 endDate.year(), |
|
880 static_cast<TMonth>(endDate.month() - 1), |
|
881 endDate.day() - 1, |
|
882 endTime.hour(), |
|
883 endTime.minute(), |
|
884 0, |
|
885 0); |
|
886 |
|
887 TTime endCalTime(endCalendarDateTime); |
|
888 TCalTime calTime2; |
|
889 calTime2.SetTimeLocalL(endCalTime); |
|
890 |
|
891 calEntry->SetStartAndEndTimeL(calTime, calTime2); |
|
892 } |
|
893 |
|
894 // Update the repeat rule |
|
895 if (storedEntry.repeatRule() != entry.repeatRule()) { |
|
896 |
|
897 calEntry->ClearRepeatingPropertiesL(); |
|
898 |
|
899 if(TCalRRule::EInvalid != entry.repeatRule().type()) { |
|
900 AgendaRepeatRule agendaRepeatRule = entry.repeatRule(); |
|
901 TCalRRule repeatRule = |
|
902 createTCalRRuleFromAgendaRRule(agendaRepeatRule); |
|
903 calEntry->SetRRuleL(repeatRule); |
|
904 } |
|
905 } |
|
906 |
|
907 // Check if the favourite property is changed and update the |
|
908 // same. |
|
909 if (entry.favourite() != storedEntry.favourite()) { |
|
910 calEntry->SetFavouriteL(entry.favourite()); |
|
911 } |
|
912 calEntry->SetLastModifiedDateL(); |
|
913 |
|
914 // Save the geo value if any |
|
915 AgendaGeoValue entryGeoValue = entry.geoValue(); |
|
916 if (!entryGeoValue.isNull() && (entryGeoValue != storedEntry.geoValue())) { |
|
917 CCalGeoValue* geoValue = CCalGeoValue::NewL(); |
|
918 double latitude; |
|
919 double longitude; |
|
920 entryGeoValue.getLatLong(latitude, longitude); |
|
921 |
|
922 // set the values to symbian geo value |
|
923 geoValue->SetLatLongL(latitude, longitude); |
|
924 |
|
925 // set it to CCalentry |
|
926 calEntry->SetGeoValueL(*geoValue); |
|
927 delete geoValue; |
|
928 } else if (entryGeoValue.isNull()) { |
|
929 // Clear the geo values if any |
|
930 calEntry->ClearGeoValueL(); |
|
931 } |
|
932 |
|
933 // Update the entry using the calen entry view. |
|
934 RPointerArray<CCalEntry> entryArray; |
|
935 CleanupResetAndDestroyPushL(entryArray); |
|
936 entryArray.AppendL(calEntry); |
|
937 if (!isChild) { |
|
938 iCalEntryView->UpdateL(entryArray, success); |
|
939 } else { |
|
940 iCalEntryView->StoreL(entryArray, success); |
|
941 } |
|
942 // Cleanup. |
|
943 CleanupStack::PopAndDestroy( &entryArray ); |
|
944 ) |
|
945 } |
|
946 |
|
947 // Emit the signal to notify the clients. |
|
948 if (0 < success) { |
|
949 emit q->entryUpdated(entry.id()); |
|
950 } |
|
951 return (success != 0); |
|
952 } |
|
953 |
|
954 bool AgendaUtilPrivate::storeRepeatingEntry(const AgendaEntry& entry, |
|
955 bool copyToChildren) |
|
956 { |
|
957 // First prepare the session with agenda server. |
|
958 if (!mInstanceViewCreated) { |
|
959 // Something went wrong. |
|
960 return false; |
|
961 } |
|
962 |
|
963 if (entry.isNull()) { |
|
964 // Invalid entry. |
|
965 return false; |
|
966 } |
|
967 |
|
968 int success = 0; |
|
969 |
|
970 // Get the entry corresponding to the id. |
|
971 AgendaEntry storedEntry = fetchById(entry.id()); |
|
972 CCalEntry* instance = iCalEntryView->FetchL(entry.id()); |
|
973 CleanupStack::PushL(instance); |
|
974 |
|
975 CCalEntry* calEntry; |
|
976 if (instance) { |
|
977 // Get all the entries with same global Uid. |
|
978 RPointerArray<CCalEntry> entries; |
|
979 CleanupResetAndDestroyPushL(entries); |
|
980 iCalEntryView->FetchL(instance->UidL(), entries); |
|
981 calEntry = entries[0]; |
|
982 entries.Remove(0); |
|
983 CleanupStack::PopAndDestroy(&entries); |
|
984 } else { |
|
985 CleanupStack::PopAndDestroy(instance); |
|
986 return false; |
|
987 } |
|
988 CleanupStack::PopAndDestroy(instance); |
|
989 CleanupStack::PushL(calEntry); |
|
990 |
|
991 // This entry is repeating. Does it have EXDATEs which could be due to children? |
|
992 RArray<TCalTime> exceptionDates; |
|
993 CleanupClosePushL( exceptionDates ); |
|
994 calEntry->GetExceptionDatesL( exceptionDates ); |
|
995 TInt exceptionCount = exceptionDates.Count(); |
|
996 CleanupStack::PopAndDestroy( &exceptionDates ); |
|
997 |
|
998 if (exceptionCount == 0) { |
|
999 // No exception dates so do a StoreL(). |
|
1000 // We have no exceptions, so there are no children to re-store |
|
1001 // Same logic as above applies, we call StoreL rather than check to |
|
1002 // see if we could have called UpdateL |
|
1003 success = updateEntry(entry, true); |
|
1004 CleanupStack::PopAndDestroy( calEntry ); |
|
1005 return success; |
|
1006 } |
|
1007 |
|
1008 //Is this a child entry? |
|
1009 if (calEntry->RecurrenceIdL().TimeUtcL() != Time::NullTTime()) { |
|
1010 success = updateEntry(entry, true); |
|
1011 CleanupStack::PopAndDestroy( calEntry ); |
|
1012 return success; |
|
1013 } |
|
1014 |
|
1015 // Entry is not a child, but does it have any children? |
|
1016 // Fetch array of entries associated with this UID. |
|
1017 RPointerArray<CCalEntry> oldEntries; |
|
1018 CleanupResetAndDestroyPushL(oldEntries); |
|
1019 iCalEntryView->FetchL(calEntry->UidL(), oldEntries); |
|
1020 bool hasChildren = oldEntries.Count() > 0; |
|
1021 |
|
1022 // Before we proceed further update calEntry with the latest modifications |
|
1023 // Update only those fields that are required to copy to the children |
|
1024 // refer to enum DifferenceFlag to know what fields need to be updated |
|
1025 |
|
1026 // set the summary |
|
1027 calEntry->SetSummaryL(TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1028 entry.summary().utf16()))); |
|
1029 |
|
1030 // set the locaiton |
|
1031 calEntry->SetLocationL(TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1032 entry.location().utf16()))); |
|
1033 |
|
1034 // Save the geo value if any |
|
1035 AgendaGeoValue entryGeoValue = entry.geoValue(); |
|
1036 if (!entryGeoValue.isNull()) { |
|
1037 CCalGeoValue* geoValue = CCalGeoValue::NewL(); |
|
1038 double latitude; |
|
1039 double longitude; |
|
1040 entryGeoValue.getLatLong(latitude, longitude); |
|
1041 |
|
1042 // set the values to symbian geo value |
|
1043 geoValue->SetLatLongL(latitude, longitude); |
|
1044 |
|
1045 // set it to CCalentry |
|
1046 calEntry->SetGeoValueL(*geoValue); |
|
1047 delete geoValue; |
|
1048 } else { |
|
1049 // Clear the geo values |
|
1050 calEntry->ClearGeoValueL(); |
|
1051 } |
|
1052 |
|
1053 // set the description |
|
1054 calEntry->SetDescriptionL(TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1055 entry.description().utf16()))); |
|
1056 |
|
1057 // set the instance start and end dates to this |
|
1058 TCalTime originalStartCalTime = calEntry->StartTimeL(); |
|
1059 TDateTime origStartDateTime = originalStartCalTime.TimeLocalL().DateTime(); |
|
1060 |
|
1061 QDate date = entry.startTime().date(); |
|
1062 QTime time =entry.startTime().time(); |
|
1063 origStartDateTime.Set(date.year(), |
|
1064 static_cast<TMonth> (date.month() - 1), |
|
1065 date.day() - 1, |
|
1066 time.hour(), |
|
1067 time.minute(),time.second(), 0); |
|
1068 TTime originalStartTime(origStartDateTime); |
|
1069 originalStartCalTime.SetTimeLocalL(originalStartTime); |
|
1070 |
|
1071 TCalTime originalEndCalTime = calEntry->EndTimeL(); |
|
1072 TDateTime origEndDateTime = originalEndCalTime.TimeLocalL().DateTime(); |
|
1073 date = entry.endTime().date(); |
|
1074 time = entry.endTime().time(); |
|
1075 origEndDateTime.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 originalEndTime(origEndDateTime); |
|
1081 originalEndCalTime.SetTimeLocalL(originalEndTime); |
|
1082 |
|
1083 calEntry->SetStartAndEndTimeL(originalStartCalTime, originalEndCalTime); |
|
1084 |
|
1085 // Set the repeat rules |
|
1086 calEntry->ClearRepeatingPropertiesL(); |
|
1087 |
|
1088 if (TCalRRule::EInvalid != entry.repeatRule().type()) { |
|
1089 AgendaRepeatRule agendaRepeatRule = entry.repeatRule(); |
|
1090 TCalRRule repeatRule = |
|
1091 createTCalRRuleFromAgendaRRule(agendaRepeatRule); |
|
1092 calEntry->SetRRuleL(repeatRule); |
|
1093 |
|
1094 } |
|
1095 |
|
1096 bool hasTimeOrDateCanged = (oldEntries[0]->StartTimeL().TimeUtcL() != |
|
1097 calEntry->StartTimeL().TimeUtcL() || |
|
1098 oldEntries[0]->EndTimeL().TimeUtcL() != calEntry->EndTimeL().TimeUtcL()); |
|
1099 if (oldEntries.Count() == 0) { |
|
1100 //This is a new repeating entry, with exceptions |
|
1101 //This must have come from an external application, as the |
|
1102 //calendar UI does not allow creation of this type of entry |
|
1103 success = updateEntry(entry); |
|
1104 } // Have the RRule or time fields changed |
|
1105 else if (copyToChildren || hasTimeOrDateCanged |
|
1106 || haveRepeatPropertiesChanged(*oldEntries[0], *calEntry)) { |
|
1107 if (hasChildren && copyToChildren) |
|
1108 { |
|
1109 copyChildrenExceptionData( *calEntry, oldEntries ); |
|
1110 } |
|
1111 success = updateEntry(entry, false); |
|
1112 |
|
1113 if(hasChildren) |
|
1114 { |
|
1115 storeEachChildEntry( *calEntry, oldEntries, !copyToChildren ); |
|
1116 } |
|
1117 } |
|
1118 else |
|
1119 { |
|
1120 success = this->updateEntry(entry); |
|
1121 } |
|
1122 CleanupStack::PopAndDestroy( &oldEntries ); |
|
1123 CleanupStack::PopAndDestroy( calEntry ); |
|
1124 |
|
1125 return success; |
|
1126 } |
|
1127 |
|
1128 bool AgendaUtilPrivate::createException(const AgendaEntry& entry, |
|
1129 QDateTime instanceOriginalDateTime) |
|
1130 { |
|
1131 // First prepare the session with agenda server. |
|
1132 if (!mInstanceViewCreated) { |
|
1133 // Something went wrong. |
|
1134 return false; |
|
1135 } |
|
1136 |
|
1137 if (entry.isNull()) { |
|
1138 // Invalid entry. |
|
1139 return false; |
|
1140 } |
|
1141 |
|
1142 int success = 0; |
|
1143 TCalLocalUid localUid = 0; |
|
1144 if (AgendaEntry::TypeNote == entry.type()) { |
|
1145 TRAP( |
|
1146 iError, |
|
1147 |
|
1148 // Get the entry corresponding to the id. |
|
1149 CCalEntry* calEntry = iCalEntryView->FetchL(entry.id()); |
|
1150 CleanupStack::PushL(calEntry); |
|
1151 // We are creating an exception, hence get the global Uid |
|
1152 HBufC8* guid = calEntry->UidL().AllocLC(); |
|
1153 // create new (child) entry |
|
1154 // Use original instance time for recurrenceID as this entry hasn't got one. |
|
1155 TCalTime originalCalTime; |
|
1156 TDateTime originalDateTime(instanceOriginalDateTime.date().year(), |
|
1157 TMonth(instanceOriginalDateTime.date().month() - 1), |
|
1158 instanceOriginalDateTime.date().day() -1, 0, 0, 0, 0); |
|
1159 TTime originalDateTimeTTime(originalDateTime); |
|
1160 originalCalTime.SetTimeLocalL(originalDateTimeTTime); |
|
1161 // create the new child now |
|
1162 CCalEntry* newEntry = CCalEntry::NewL( calEntry->EntryTypeL(), |
|
1163 guid, |
|
1164 calEntry->MethodL(), |
|
1165 calEntry->SequenceNumberL(), |
|
1166 originalCalTime, |
|
1167 CalCommon::EThisOnly ); |
|
1168 |
|
1169 CleanupStack::Pop(guid); |
|
1170 CleanupStack::PopAndDestroy(calEntry); |
|
1171 |
|
1172 // Update the description. |
|
1173 if (!entry.description().isNull()) { |
|
1174 newEntry->SetDescriptionL( |
|
1175 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1176 entry.description().utf16()))); |
|
1177 } |
|
1178 |
|
1179 // Update the method. |
|
1180 if (AgendaEntry::MethodUnknown != entry.method()) { |
|
1181 newEntry->SetMethodL( |
|
1182 static_cast<CCalEntry::TMethod> (entry.method())); |
|
1183 } |
|
1184 |
|
1185 // Update the last modification time. |
|
1186 if (entry.lastModifiedDateTime().isValid()) { |
|
1187 QDateTime dateTime = entry.lastModifiedDateTime(); |
|
1188 QDate lastDate = dateTime.date(); |
|
1189 QTime lastTime = dateTime.time(); |
|
1190 |
|
1191 TDateTime lastModDateTime( |
|
1192 lastDate.year(), |
|
1193 static_cast<TMonth> (lastDate.month() - 1), |
|
1194 lastDate.day() - 1, lastTime.hour(), |
|
1195 lastTime.minute(), 0, 0); |
|
1196 |
|
1197 TTime lastModTime(lastModDateTime); |
|
1198 TCalTime lastModCalTime; |
|
1199 lastModCalTime.SetTimeLocalL(lastModTime); |
|
1200 newEntry->SetLastModifiedDateL(lastModCalTime); |
|
1201 } |
|
1202 |
|
1203 newEntry->SetFavouriteL(entry.favourite()); |
|
1204 |
|
1205 // Update the entry using the CCalEntryView. |
|
1206 RPointerArray<CCalEntry> entryArray; |
|
1207 CleanupResetAndDestroyPushL(entryArray); |
|
1208 entryArray.AppendL(newEntry); |
|
1209 iCalEntryView->StoreL(entryArray, success); |
|
1210 |
|
1211 localUid = newEntry->LocalUidL(); |
|
1212 // Cleanup. |
|
1213 CleanupStack::PopAndDestroy(&entryArray); |
|
1214 ) |
|
1215 } else { |
|
1216 TRAP( |
|
1217 iError, |
|
1218 |
|
1219 CCalEntry* calEntry = iCalEntryView->FetchL(entry.id()); |
|
1220 CleanupStack::PushL(calEntry); |
|
1221 // We are creating an exception, hence get the global Uid |
|
1222 HBufC8* guid = calEntry->UidL().AllocLC(); |
|
1223 // create new (child) entry |
|
1224 // Use original instance time for recurrenceID as this entry hasn't got one. |
|
1225 TCalTime originalCalTime; |
|
1226 TDateTime originalDateTime(instanceOriginalDateTime.date().year(), |
|
1227 TMonth(instanceOriginalDateTime.date().month() - 1), |
|
1228 instanceOriginalDateTime.date().day() -1, 0, 0, 0, 0); |
|
1229 TTime originalDateTimeTTime(originalDateTime); |
|
1230 originalCalTime.SetTimeLocalL(originalDateTimeTTime); |
|
1231 // create the new child now |
|
1232 CCalEntry* newEntry = CCalEntry::NewL( calEntry->EntryTypeL(), |
|
1233 guid, |
|
1234 calEntry->MethodL(), |
|
1235 calEntry->SequenceNumberL(), |
|
1236 originalCalTime, |
|
1237 CalCommon::EThisOnly ); |
|
1238 |
|
1239 CleanupStack::Pop(guid); |
|
1240 CleanupStack::PopAndDestroy(calEntry); |
|
1241 // Store the attendees. |
|
1242 if (!entry.isNull()) { |
|
1243 addAttendeesToEntry(entry.d->m_attendees, *newEntry); |
|
1244 addCategoriesToEntry(entry.d->m_categories, *newEntry); |
|
1245 } |
|
1246 |
|
1247 // Store the alarm. |
|
1248 if (!entry.alarm().isNull()) { |
|
1249 setAlarmToEntry(entry.alarm(), *newEntry); |
|
1250 } |
|
1251 |
|
1252 // Store the description. |
|
1253 if (!entry.description().isNull()) { |
|
1254 newEntry->SetDescriptionL( |
|
1255 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1256 entry.description().utf16()))); |
|
1257 } |
|
1258 |
|
1259 // Store the location. |
|
1260 if (!entry.location().isNull()) { |
|
1261 newEntry->SetLocationL( |
|
1262 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1263 entry.location().utf16()))); |
|
1264 } |
|
1265 |
|
1266 // Store the priority. |
|
1267 if ( -1 != entry.priority()) { |
|
1268 newEntry->SetPriorityL(entry.priority()); |
|
1269 } |
|
1270 |
|
1271 // Store the summary. |
|
1272 if (!entry.summary().isNull()) { |
|
1273 newEntry->SetSummaryL( |
|
1274 TPtrC(reinterpret_cast<const TUint16 *> ( |
|
1275 entry.summary().utf16()))); |
|
1276 } |
|
1277 |
|
1278 // Update the method. |
|
1279 if (AgendaEntry::MethodUnknown != entry.method()) { |
|
1280 newEntry->SetMethodL( |
|
1281 static_cast<CCalEntry::TMethod> (entry.method())); |
|
1282 } |
|
1283 |
|
1284 // Store the time. |
|
1285 QDateTime startDateTime = entry.startTime(); |
|
1286 QDate startDate = startDateTime.date(); |
|
1287 QTime startTime = startDateTime.time(); |
|
1288 |
|
1289 TDateTime startCalendarDateTime( |
|
1290 startDate.year(), |
|
1291 static_cast<TMonth> (startDate.month() - 1), |
|
1292 startDate.day() - 1, |
|
1293 startTime.hour(), |
|
1294 startTime.minute(), |
|
1295 0, |
|
1296 0); |
|
1297 |
|
1298 TTime startCalTime(startCalendarDateTime); |
|
1299 TCalTime calTime; |
|
1300 calTime.SetTimeLocalL(startCalTime); |
|
1301 QDateTime endDateTime = entry.endTime(); |
|
1302 QDate endDate = endDateTime.date(); |
|
1303 QTime endTime = endDateTime.time(); |
|
1304 |
|
1305 TDateTime endCalendarDateTime( |
|
1306 endDate.year(), |
|
1307 static_cast<TMonth>(endDate.month() - 1), |
|
1308 endDate.day() - 1, |
|
1309 endTime.hour(), |
|
1310 endTime.minute(), |
|
1311 0, |
|
1312 0); |
|
1313 |
|
1314 TTime endCalTime(endCalendarDateTime); |
|
1315 TCalTime calTime2; |
|
1316 calTime2.SetTimeLocalL(endCalTime); |
|
1317 |
|
1318 newEntry->SetStartAndEndTimeL(calTime, calTime2); |
|
1319 |
|
1320 // Save the geo value if any |
|
1321 AgendaGeoValue entryGeoValue = entry.geoValue(); |
|
1322 if (!entryGeoValue.isNull()) { |
|
1323 CCalGeoValue* geoValue = CCalGeoValue::NewL(); |
|
1324 double latitude; |
|
1325 double longitude; |
|
1326 entryGeoValue.getLatLong(latitude, longitude); |
|
1327 |
|
1328 // set the values to symbian geo value |
|
1329 geoValue->SetLatLongL(latitude, longitude); |
|
1330 |
|
1331 // set it to CCalentry |
|
1332 newEntry->SetGeoValueL(*geoValue); |
|
1333 delete geoValue; |
|
1334 } |
|
1335 |
|
1336 // No need to update the repeat rule as it is an exception |
|
1337 |
|
1338 // Store the favourite |
|
1339 newEntry->SetFavouriteL(entry.favourite()); |
|
1340 |
|
1341 // reset local UID |
|
1342 newEntry->SetLocalUidL( TCalLocalUid( 0 ) ); |
|
1343 |
|
1344 // clear repeat rule properties |
|
1345 newEntry->ClearRepeatingPropertiesL(); |
|
1346 // Update the entry using the calen entry view. |
|
1347 RPointerArray<CCalEntry> entryArray; |
|
1348 CleanupResetAndDestroyPushL(entryArray); |
|
1349 entryArray.AppendL(newEntry); |
|
1350 iCalEntryView->StoreL(entryArray, success); |
|
1351 |
|
1352 localUid = newEntry->LocalUidL(); |
|
1353 // Cleanup. |
|
1354 CleanupStack::PopAndDestroy(&entryArray); |
|
1355 ) |
|
1356 } |
|
1357 |
|
1358 // Emit the signal to notify the clients. |
|
1359 if (0 < success) { |
|
1360 emit q->entryUpdated(localUid); |
|
1361 } |
|
1362 return (success != 0); |
|
1363 } |
637 } |
1364 |
638 |
1365 /*! |
639 /*! |
1366 Fetches an AgendaEntry, given the id. |
640 Fetches an AgendaEntry, given the id. |
1367 |
641 |
2829 delete geoValue; |
2089 delete geoValue; |
2830 } |
2090 } |
2831 |
2091 |
2832 // Return the entry. |
2092 // Return the entry. |
2833 return entry; |
2093 return entry; |
|
2094 } |
|
2095 |
|
2096 /*! |
|
2097 Copy all the data to CCalEntry from a given AgendaEntry. |
|
2098 \param agendaEntry Reference to a AgendaEntry. |
|
2099 \param calEntry Reference to a CCalEntry. |
|
2100 */ |
|
2101 void AgendaUtilPrivate::createCCalEntryFromAgendaEntry(AgendaEntry &agendaEntry, CCalEntry &calEntry) |
|
2102 { |
|
2103 if (agendaEntry.isNull()) { |
|
2104 // Invalid entry. |
|
2105 return; |
|
2106 } |
|
2107 |
|
2108 TRAP( |
|
2109 iError, |
|
2110 // Add description to the agendaEntry. |
|
2111 TPtrC |
|
2112 description( |
|
2113 reinterpret_cast<const TUint16*> (agendaEntry.description().utf16())); |
|
2114 calEntry.SetDescriptionL(description); |
|
2115 |
|
2116 if(AgendaEntry::MethodUnknown != agendaEntry.method()) { |
|
2117 calEntry.SetMethodL( |
|
2118 static_cast<CCalEntry::TMethod> (agendaEntry.method())); |
|
2119 } |
|
2120 |
|
2121 // Set the favourite property. |
|
2122 calEntry.SetFavouriteL(agendaEntry.favourite()); |
|
2123 |
|
2124 |
|
2125 if (AgendaEntry::TypeNote == agendaEntry.type()) { |
|
2126 // Set the last modification time. |
|
2127 TCalTime calTime; |
|
2128 QDateTime dateTime = agendaEntry.lastModifiedDateTime(); |
|
2129 TDateTime tempDateTime(dateTime.date().year(), |
|
2130 static_cast<TMonth> (dateTime.date().month() - 1), |
|
2131 dateTime.date().day() - 1, dateTime.time().hour(), |
|
2132 dateTime.time().minute(), 0, 0); |
|
2133 TTime tempTime(tempDateTime); |
|
2134 calTime.SetTimeLocalL(tempTime); |
|
2135 calEntry.SetLastModifiedDateL(calTime); |
|
2136 |
|
2137 // Set the dtstamp time.It is used to set the creation time. |
|
2138 TCalTime creationCalTime; |
|
2139 QDateTime dtStamp = agendaEntry.dtStamp(); |
|
2140 TDateTime |
|
2141 creationDateTime(dtStamp.date().year(), |
|
2142 static_cast<TMonth> (dtStamp.date().month() - 1), |
|
2143 dtStamp.date().day() - 1, dtStamp.time().hour(), |
|
2144 dtStamp.time().minute(), 0, 0); |
|
2145 TTime creationTTime(creationDateTime); |
|
2146 creationCalTime.SetTimeLocalL(creationTTime); |
|
2147 calEntry.SetDTStampL(creationCalTime); |
|
2148 } else { |
|
2149 |
|
2150 // Add the summary. |
|
2151 TPtrC |
|
2152 summary( |
|
2153 reinterpret_cast<const TUint16*> (agendaEntry.summary().utf16())); |
|
2154 calEntry.SetSummaryL(summary); |
|
2155 |
|
2156 // Set the agendaEntry Start/End Date and time. |
|
2157 QDate date = agendaEntry.startTime().date(); |
|
2158 QTime time = agendaEntry.startTime().time(); |
|
2159 |
|
2160 TDateTime startDateTime(date.year(), static_cast<TMonth> (date.month() |
|
2161 - 1), date.day() - 1, time.hour(), time.minute(), 0, 0); |
|
2162 TTime entryStartTime(startDateTime); |
|
2163 TCalTime calStartTime; |
|
2164 |
|
2165 date = agendaEntry.endTime().date(); |
|
2166 time = agendaEntry.endTime().time(); |
|
2167 |
|
2168 TDateTime endDateTime(date.year(), static_cast<TMonth> (date.month() |
|
2169 - 1), date.day() - 1, time.hour(), time.minute(), 0, 0); |
|
2170 TTime entryEndTime(endDateTime); |
|
2171 TCalTime calEndTime; |
|
2172 |
|
2173 // Use floating time for the nontimed entries. |
|
2174 if(agendaEntry.isTimedEntry()) { |
|
2175 calStartTime.SetTimeLocalL(entryStartTime); |
|
2176 calEndTime.SetTimeLocalL(entryEndTime); |
|
2177 }else { |
|
2178 calStartTime.SetTimeLocalFloatingL(entryStartTime); |
|
2179 calEndTime.SetTimeLocalFloatingL(entryEndTime); |
|
2180 } |
|
2181 calEntry.SetStartAndEndTimeL(calStartTime, calEndTime); |
|
2182 |
|
2183 // Add attendees to the agendaEntry. |
|
2184 addAttendeesToEntry(agendaEntry.d->m_attendees, calEntry); |
|
2185 |
|
2186 // Add categories to the agendaEntry. |
|
2187 addCategoriesToEntry(agendaEntry.d->m_categories, calEntry); |
|
2188 |
|
2189 // Add Alarm to the agendaEntry. |
|
2190 AgendaAlarm alarm = agendaEntry.alarm(); |
|
2191 setAlarmToEntry(alarm, calEntry); |
|
2192 |
|
2193 // Set the priority. |
|
2194 int priority = agendaEntry.priority(); |
|
2195 if (agendaEntry.priority() != -1) { |
|
2196 calEntry.SetPriorityL(priority); |
|
2197 } |
|
2198 |
|
2199 // Set the location. |
|
2200 TPtrC |
|
2201 location( |
|
2202 reinterpret_cast<const TUint16*> (agendaEntry.location().utf16())); |
|
2203 calEntry.SetLocationL(location); |
|
2204 |
|
2205 // Set the repeat type if applicable. |
|
2206 if (AgendaRepeatRule::InvalidRule != agendaEntry.repeatRule().type()) { |
|
2207 AgendaRepeatRule agendaRepeatRule = agendaEntry.repeatRule(); |
|
2208 TCalRRule repeatRule = |
|
2209 createTCalRRuleFromAgendaRRule(agendaRepeatRule, agendaEntry.isTimedEntry()); |
|
2210 calEntry.SetRRuleL(repeatRule); |
|
2211 } |
|
2212 |
|
2213 // Save the status of the agendaEntry. |
|
2214 calEntry.SetStatusL((CCalEntry::TStatus) agendaEntry.status()); |
|
2215 |
|
2216 // Save the geo value if any |
|
2217 AgendaGeoValue entryGeoValue = agendaEntry.geoValue(); |
|
2218 if (!entryGeoValue.isNull()) { |
|
2219 CCalGeoValue* geoValue = CCalGeoValue::NewL(); |
|
2220 double latitude; |
|
2221 double longitude; |
|
2222 entryGeoValue.getLatLong(latitude, longitude); |
|
2223 |
|
2224 // set the values to symbian geo value |
|
2225 geoValue->SetLatLongL(latitude, longitude); |
|
2226 |
|
2227 // set it to CCalentry |
|
2228 calEntry.SetGeoValueL(*geoValue); |
|
2229 delete geoValue; |
|
2230 } else { |
|
2231 calEntry.ClearGeoValueL(); |
|
2232 } |
|
2233 } |
|
2234 ) |
|
2235 |
2834 } |
2236 } |
2835 |
2237 |
2836 bool AgendaUtilPrivate::addAttendeesToEntry( |
2238 bool AgendaUtilPrivate::addAttendeesToEntry( |
2837 const QList<AgendaAttendee>& attendees, CCalEntry& entry) |
2239 const QList<AgendaAttendee>& attendees, CCalEntry& entry) |
2838 { |
2240 { |
3496 |
2904 |
3497 CleanupStack::PopAndDestroy( &allInstances ); |
2905 CleanupStack::PopAndDestroy( &allInstances ); |
3498 return nextTime; |
2906 return nextTime; |
3499 } |
2907 } |
3500 |
2908 |
3501 bool AgendaUtilPrivate::haveRepeatPropertiesChanged(const CCalEntry& newEntry, |
|
3502 const CCalEntry& oldEntry) |
|
3503 { |
|
3504 //Have the RRules Changed? |
|
3505 TCalRRule newEntryRule; |
|
3506 newEntry.GetRRuleL(newEntryRule); |
|
3507 |
|
3508 TCalRRule oldEntryRule; |
|
3509 oldEntry.GetRRuleL(oldEntryRule); |
|
3510 |
|
3511 if ((newEntryRule.Type() != oldEntryRule.Type()) || |
|
3512 (newEntryRule.DtStart().TimeUtcL() != oldEntryRule.DtStart().TimeUtcL()) || |
|
3513 (newEntryRule.Until().TimeUtcL() != oldEntryRule.Until().TimeUtcL()) || |
|
3514 (newEntryRule.Count() != oldEntryRule.Count())) |
|
3515 { |
|
3516 return ETrue; |
|
3517 } |
|
3518 |
|
3519 // Did the RDates change? |
|
3520 TBool rDatesChanged = EFalse; |
|
3521 RArray<TCalTime> newRDates; |
|
3522 RArray<TCalTime> oldRDates; |
|
3523 CleanupClosePushL(newRDates); |
|
3524 CleanupClosePushL(oldRDates); |
|
3525 newEntry.GetRDatesL(newRDates); |
|
3526 oldEntry.GetRDatesL(oldRDates); |
|
3527 |
|
3528 if (newRDates.Count() != oldRDates.Count()) |
|
3529 { |
|
3530 rDatesChanged = ETrue; |
|
3531 } |
|
3532 else |
|
3533 { |
|
3534 for (TInt x = 0; x < newRDates.Count(); ++x) |
|
3535 { |
|
3536 if (newRDates[x].TimeUtcL() != oldRDates[x].TimeUtcL()) |
|
3537 { |
|
3538 rDatesChanged = ETrue; |
|
3539 break; |
|
3540 } |
|
3541 } |
|
3542 } |
|
3543 |
|
3544 CleanupStack::PopAndDestroy(&oldRDates); |
|
3545 CleanupStack::PopAndDestroy(&newRDates); |
|
3546 |
|
3547 return rDatesChanged; |
|
3548 } |
|
3549 |
|
3550 void AgendaUtilPrivate::copyChildrenExceptionData( CCalEntry& editedEntry, |
|
3551 RPointerArray<CCalEntry>& oldEntries ) |
|
3552 { |
|
3553 // For each oldChild..., 0th index will be parent |
|
3554 for (int i=1; i<oldEntries.Count(); ++i) { |
|
3555 // For each field... |
|
3556 for(DifferenceFlag j=(DifferenceFlag)1; j<EntryDifferenceCount; j=(DifferenceFlag)(j<<1)) |
|
3557 { |
|
3558 // Where oldChild field == oldParent Field |
|
3559 // and newParent field != oldParent Field... |
|
3560 if( isFieldSame(*oldEntries[i], *oldEntries[0], j ) && |
|
3561 !isFieldSame(editedEntry, *oldEntries[0], j ) ) |
|
3562 { |
|
3563 // ...copy newParent field to oldChild. |
|
3564 copyField(editedEntry, *oldEntries[i], j); |
|
3565 } |
|
3566 } |
|
3567 } |
|
3568 } |
|
3569 |
|
3570 bool AgendaUtilPrivate::isFieldSame(CCalEntry& entryOne, |
|
3571 CCalEntry& entryTwo, |
|
3572 DifferenceFlag flag) |
|
3573 { |
|
3574 switch( flag ) { |
|
3575 case EntryDifferentStartTimeAndEndTime: { |
|
3576 TTime zero(TInt64(0)); |
|
3577 TTime entryOneStartTime = entryOne.StartTimeL().TimeUtcL(); |
|
3578 TTime beginningOfDay = zero + entryOneStartTime.DaysFrom(zero); |
|
3579 TTimeIntervalMinutes startTimeOne; |
|
3580 entryOneStartTime.MinutesFrom(beginningOfDay, startTimeOne); |
|
3581 TTime entryTwoStartTime = entryTwo.StartTimeL().TimeUtcL(); |
|
3582 beginningOfDay = zero + entryTwoStartTime.DaysFrom(zero); |
|
3583 TTimeIntervalMinutes startTimeTwo; |
|
3584 entryTwoStartTime.MinutesFrom(beginningOfDay, startTimeTwo); |
|
3585 TTime entryOneEndTime = entryOne.EndTimeL().TimeUtcL(); |
|
3586 beginningOfDay = zero + entryOneEndTime.DaysFrom(zero); |
|
3587 TTimeIntervalMinutes endTimeOne; |
|
3588 entryOneEndTime.MinutesFrom(beginningOfDay, endTimeOne); |
|
3589 TTime entryTwoEndTime = entryTwo.EndTimeL().TimeUtcL(); |
|
3590 beginningOfDay = zero + entryTwoEndTime.DaysFrom(zero); |
|
3591 TTimeIntervalMinutes endTimeTwo; |
|
3592 entryTwoEndTime.MinutesFrom(beginningOfDay, endTimeTwo); |
|
3593 return ( startTimeOne.Int() |
|
3594 == startTimeTwo.Int() ) |
|
3595 && ( endTimeOne.Int() |
|
3596 == endTimeTwo.Int() ); |
|
3597 } |
|
3598 case EntryDifferentSummary: |
|
3599 return entryOne.SummaryL() == entryTwo.SummaryL(); |
|
3600 case EntryDifferentDescription: |
|
3601 return entryOne.DescriptionL() == entryTwo.DescriptionL(); |
|
3602 case EntryDifferentLocation: |
|
3603 return entryOne.LocationL() == entryTwo.LocationL(); |
|
3604 default: |
|
3605 break; |
|
3606 } |
|
3607 return EFalse; // Never hit. |
|
3608 } |
|
3609 |
|
3610 void AgendaUtilPrivate::copyField( const CCalEntry& src, |
|
3611 CCalEntry& dst, |
|
3612 DifferenceFlag field ) |
|
3613 { |
|
3614 switch( field ) { |
|
3615 case EntryDifferentStartTimeAndEndTime: |
|
3616 { |
|
3617 // START TIME |
|
3618 // Keep aDst's start date, but copy the start time (h/m/s) from aSrc to aDst. |
|
3619 TTime zero(TInt64(0)); |
|
3620 TTime srcStartTime = src.StartTimeL().TimeUtcL(); |
|
3621 TTime srcStartDay = zero + src.StartTimeL().TimeUtcL().DaysFrom(zero); |
|
3622 TTime dstStartDay = zero + dst.StartTimeL().TimeUtcL().DaysFrom(zero); |
|
3623 TTimeIntervalMinutes dstStartTimeOfDay; |
|
3624 srcStartTime.MinutesFrom(srcStartDay, dstStartTimeOfDay); |
|
3625 |
|
3626 TCalTime startTime; |
|
3627 startTime.SetTimeUtcL( dstStartDay + (TTimeIntervalMinutes)dstStartTimeOfDay ); |
|
3628 |
|
3629 |
|
3630 TTimeIntervalMinutes duration; |
|
3631 src.EndTimeL().TimeUtcL().MinutesFrom(src.StartTimeL().TimeUtcL(), duration); |
|
3632 |
|
3633 // END TIME |
|
3634 // Calculate the duration of aSrc, and make aDst endtime equal aDst startTime |
|
3635 // + duration. This will allow for events spanning multiple days. |
|
3636 TCalTime endTime; |
|
3637 endTime.SetTimeUtcL(startTime.TimeUtcL() + duration); |
|
3638 |
|
3639 dst.SetStartAndEndTimeL(startTime, endTime); |
|
3640 |
|
3641 break; |
|
3642 } |
|
3643 case EntryDifferentSummary: |
|
3644 dst.SetSummaryL(src.SummaryL()); |
|
3645 break; |
|
3646 case EntryDifferentDescription: |
|
3647 dst.SetDescriptionL(src.DescriptionL()); |
|
3648 break; |
|
3649 case EntryDifferentLocation: |
|
3650 { |
|
3651 dst.SetLocationL(src.LocationL()); |
|
3652 CCalGeoValue* geoValue = src.GeoValueL(); |
|
3653 if (geoValue) { |
|
3654 dst.SetGeoValueL(*geoValue); |
|
3655 delete geoValue; |
|
3656 } |
|
3657 break; |
|
3658 } |
|
3659 default: |
|
3660 break; |
|
3661 } |
|
3662 } |
|
3663 |
|
3664 void AgendaUtilPrivate::storeEachChildEntry(CCalEntry &entry, |
|
3665 RPointerArray<CCalEntry> &oldEntries, |
|
3666 bool resetLocalUid) |
|
3667 { |
|
3668 |
|
3669 // Start from 1 as we don't want to copy the old parent entry. |
|
3670 for(int i=1; i<oldEntries.Count(); ++i) |
|
3671 { |
|
3672 if (resetLocalUid) |
|
3673 { |
|
3674 // Reset the local UID of the exception. When we store the exception, it will |
|
3675 // be added as a new entry rather than an update. |
|
3676 oldEntries[i]->SetLocalUidL( TCalLocalUid( 0 ) ); |
|
3677 } |
|
3678 |
|
3679 // The RecurrenceId of child (exception) entries should never be a null time by definition. |
|
3680 // The code below will attempt to generate a RecurrenceId from the start time of the |
|
3681 // exception if no RecurrenceId is found. This should never actually happen, and |
|
3682 // will not work if the start time/start date is changed. The if case below should remain |
|
3683 // until the Symbian defect fix for NULL RecurrenceIds is verified. |
|
3684 |
|
3685 if(oldEntries[i]->RecurrenceIdL().TimeUtcL() == Time::NullTTime()) |
|
3686 { |
|
3687 // This is being hit, but shouldn't be. Hence we create a new Recurrence ID. |
|
3688 // Without doing this, the SingleStoreL below fails with Agenda Model -35: No agenda server. |
|
3689 TCalTime recId = generateRecurrenceIdFromEntry( entry, oldEntries[i]->StartTimeL() ); |
|
3690 CCalEntry *exception = CCalEntry::NewL( oldEntries[i]->EntryTypeL(), |
|
3691 entry.UidL().AllocL(), |
|
3692 oldEntries[i]->MethodL(), |
|
3693 oldEntries[i]->SequenceNumberL(), |
|
3694 recId, |
|
3695 oldEntries[i]->RecurrenceRangeL() ); |
|
3696 exception->CopyFromL(*oldEntries[i]); |
|
3697 exception->SetLastModifiedDateL(); |
|
3698 TInt successCount=0; |
|
3699 RPointerArray<CCalEntry> entries; |
|
3700 CleanupResetAndDestroyPushL(entries); |
|
3701 entries.Append( exception ); |
|
3702 iCalEntryView->StoreL( entries, successCount ); |
|
3703 CleanupStack::PopAndDestroy( &entries ); |
|
3704 } |
|
3705 else |
|
3706 { |
|
3707 // If the start time of the series has been changed, the call below will |
|
3708 // leave with -1, and the child entries will be lost. To prevent this |
|
3709 // we need to regenerate a new recurrence id for each child, create a copy |
|
3710 // of the child with the new recurrence id, and store that instead. |
|
3711 // Fixing this may cause issues with sync though, as some servers delete the |
|
3712 // children when changing the start time of the series anyway. |
|
3713 oldEntries[i]->SetLastModifiedDateL(); |
|
3714 TInt successCount=0; |
|
3715 RPointerArray<CCalEntry> entries; |
|
3716 CleanupClosePushL(entries); |
|
3717 entries.Append( oldEntries[i] ); |
|
3718 iCalEntryView->StoreL( entries, successCount ); |
|
3719 CleanupStack::Pop( &entries ); |
|
3720 } |
|
3721 } |
|
3722 } |
|
3723 |
|
3724 TCalTime AgendaUtilPrivate::generateRecurrenceIdFromEntry( CCalEntry& entry, |
2909 TCalTime AgendaUtilPrivate::generateRecurrenceIdFromEntry( CCalEntry& entry, |
3725 TCalTime instanceDate ) |
2910 TCalTime instanceDate ) |
3726 { |
2911 { |
3727 TDateTime theTime = entry.StartTimeL().TimeUtcL().DateTime(); |
2912 TDateTime theTime = entry.StartTimeL().TimeUtcL().DateTime(); |
3728 TDateTime theDate = instanceDate.TimeUtcL().DateTime(); |
2913 TDateTime theDate = instanceDate.TimeUtcL().DateTime(); |