|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: CalenEditorDataHandler implements all logic of checking and |
|
15 * validating editor data |
|
16 * |
|
17 */ |
|
18 |
|
19 // System includes |
|
20 #include <calendateutils.h> |
|
21 #include <calenagendautils.h> |
|
22 #include <calinstance.h> |
|
23 #include <calalarm.h> |
|
24 #include <calentry.h> |
|
25 #include <calrrule.h> |
|
26 #include <centralrepository.h> |
|
27 #include <calattachment.h> |
|
28 #include <eikenv.h> |
|
29 #include <CalenInterimUtils2.h> |
|
30 #include <calencontext.h> |
|
31 #include <caleninstanceid.h> // TCalenInstanceId |
|
32 #include <calenservices.h> |
|
33 |
|
34 // User includes |
|
35 #include "CalenEditorDataHandler.h" |
|
36 #include "CalendarPrivateCRKeys.h" |
|
37 #include "CalenDefaultEditors.hrh" |
|
38 #include "calenentryutil.h" |
|
39 #include "CleanupResetAndDestroy.h" |
|
40 #include "calenattachmentutils.h" |
|
41 #include "calenattachmentinfo.h" |
|
42 #include "calenattachmentmodel.h" |
|
43 #include "calenunifiededitor.h" |
|
44 #include "calendarui_debug.h" |
|
45 |
|
46 // Constants |
|
47 #define KNoOfDaysInWeek 7 |
|
48 |
|
49 // ======== LOCAL FUNCTIONS ======== |
|
50 |
|
51 // ----------------------------------------------------------------------------- |
|
52 // IsTimed |
|
53 // Returns ETrue if the entry is timed (i.e. an appointment or a |
|
54 // reminder), EFalse otherwise. |
|
55 // (other items were commented in a header). |
|
56 // ----------------------------------------------------------------------------- |
|
57 // |
|
58 static TBool IsTimed( CCalEntry::TType aEntryType ) |
|
59 { |
|
60 TRACE_ENTRY_POINT; |
|
61 |
|
62 TRACE_EXIT_POINT; |
|
63 return aEntryType == CCalEntry::EAppt || aEntryType == CCalEntry::EReminder; |
|
64 } |
|
65 |
|
66 // ----------------------------------------------------------------------------- |
|
67 // ForeverDate |
|
68 // Returns the date which Calendar presumes to be infinitely far in the future. |
|
69 // Used, for example, when setting a repeating meeting to repeat forever. |
|
70 // (other items were commented in a header). |
|
71 // ----------------------------------------------------------------------------- |
|
72 // |
|
73 static TTime ForeverDate() |
|
74 { |
|
75 TRACE_ENTRY_POINT; |
|
76 |
|
77 TTime forever = TTime( TDateTime( ECalenForeverYear, static_cast<TMonth>( ECalenForeverMonth ), |
|
78 ECalenForeverDay, 0, 0, 0, 0) ); |
|
79 |
|
80 TRACE_EXIT_POINT; |
|
81 return forever; |
|
82 } |
|
83 |
|
84 // ----------------------------------------------------------------------------- |
|
85 // IsForeverDate |
|
86 // Returns ETrue if the given date is considered by Calendar to be infinitely |
|
87 // far in the future. |
|
88 // (other items were commented in a header). |
|
89 // ----------------------------------------------------------------------------- |
|
90 // |
|
91 static TBool IsForeverDate( const TTime& aDate ) |
|
92 { |
|
93 TRACE_ENTRY_POINT; |
|
94 |
|
95 TRACE_EXIT_POINT; |
|
96 return CalenDateUtils::OnSameDay( aDate, ForeverDate() ); |
|
97 } |
|
98 |
|
99 // ======== MEMBER FUNCTIONS ======== |
|
100 |
|
101 // --------------------------------------------------------------------------- |
|
102 // CCalenEditorDataHandler::CCalenEditorDataHandler |
|
103 // Constructor. |
|
104 // (other items were commented in a header). |
|
105 // --------------------------------------------------------------------------- |
|
106 // |
|
107 CCalenEditorDataHandler::CCalenEditorDataHandler( |
|
108 CCalEntry& aEntry, |
|
109 const TCalTime& aInstanceDateTime, |
|
110 TBool aIsCreatingNew, |
|
111 TInt aMaxTextEditorLength, |
|
112 MCalenServices& aServices, |
|
113 RArray<TInt>& aCollectionIds) |
|
114 : iEntry( aEntry ), |
|
115 iInstanceDateTime( aInstanceDateTime ), |
|
116 iIsCreatingNew( aIsCreatingNew ), |
|
117 iMaxTextEditorLength( aMaxTextEditorLength ), |
|
118 iServices( aServices ) , iCalendarFieldEdited(EFalse) , iCollectionIds(aCollectionIds) |
|
119 { |
|
120 TRACE_ENTRY_POINT; |
|
121 TRACE_EXIT_POINT; |
|
122 } |
|
123 |
|
124 // --------------------------------------------------------------------------- |
|
125 // CCalenEditorDataHandler::ConstructL |
|
126 // Two phase construction. |
|
127 // (other items were commented in a header). |
|
128 // --------------------------------------------------------------------------- |
|
129 // |
|
130 void CCalenEditorDataHandler::ConstructL() |
|
131 { |
|
132 TRACE_ENTRY_POINT; |
|
133 |
|
134 iEntryType = iEntry.EntryTypeL(); |
|
135 iRecurrenceId = iEntry.RecurrenceIdL(); |
|
136 |
|
137 iOriginal = CCalenEntryUtil::NewL( iEntry, iInstanceDateTime ); |
|
138 iEdited = CCalenEntryUtil::NewL( iEntry, iInstanceDateTime ); |
|
139 if ( IsCreatingNew() ) |
|
140 { |
|
141 SetDefaultNewValuesL( *iOriginal ); // modify iOriginal also |
|
142 SetDefaultNewValuesL( *iEdited ); |
|
143 } |
|
144 else |
|
145 { |
|
146 iInstanceId = iServices.Context().InstanceId(); |
|
147 } |
|
148 |
|
149 |
|
150 TRACE_EXIT_POINT; |
|
151 } |
|
152 |
|
153 // --------------------------------------------------------------------------- |
|
154 // CCalenEditorDataHandler::NewL |
|
155 // Two-phased constructor. |
|
156 // (other items were commented in a header). |
|
157 // --------------------------------------------------------------------------- |
|
158 // |
|
159 CCalenEditorDataHandler* CCalenEditorDataHandler::NewL( |
|
160 CCalEntry& aEntry, |
|
161 const TCalTime& aInstanceDateTime, |
|
162 TBool aIsCreatingNew, |
|
163 TInt aMaxTextEditorLength, |
|
164 MCalenServices& aServices, |
|
165 RArray<TInt>& aCollectionIds) |
|
166 { |
|
167 TRACE_ENTRY_POINT; |
|
168 |
|
169 CCalenEditorDataHandler* self = new( ELeave ) CCalenEditorDataHandler( |
|
170 aEntry, aInstanceDateTime, aIsCreatingNew, aMaxTextEditorLength, aServices,aCollectionIds ); |
|
171 CleanupStack::PushL( self ); |
|
172 self->ConstructL(); |
|
173 CleanupStack::Pop( self ); |
|
174 |
|
175 TRACE_EXIT_POINT; |
|
176 return self; |
|
177 } |
|
178 |
|
179 // --------------------------------------------------------------------------- |
|
180 // CCalenEditorDataHandler::~CCalenEditorDataHandler |
|
181 // Destructor. |
|
182 // (other items were commented in a header). |
|
183 // --------------------------------------------------------------------------- |
|
184 // |
|
185 CCalenEditorDataHandler::~CCalenEditorDataHandler() |
|
186 { |
|
187 TRACE_ENTRY_POINT; |
|
188 |
|
189 delete iOriginal; |
|
190 delete iEdited; |
|
191 |
|
192 TRACE_EXIT_POINT; |
|
193 } |
|
194 |
|
195 // --------------------------------------------------------------------------- |
|
196 // CCalenEditorDataHandler::Edited |
|
197 // Returns the CCalenEditorDataHandler used to represent the entry the |
|
198 // user is currently editing. |
|
199 // (other items were commented in a header). |
|
200 // --------------------------------------------------------------------------- |
|
201 // |
|
202 CCalenEntryUtil& CCalenEditorDataHandler::Edited() |
|
203 { |
|
204 TRACE_ENTRY_POINT; |
|
205 |
|
206 TRACE_EXIT_POINT; |
|
207 return *iEdited; |
|
208 } |
|
209 |
|
210 // --------------------------------------------------------------------------- |
|
211 // CCalenEditorDataHandler::Original |
|
212 // Returns the CCalenEditorDataHandler used to represent the entry the |
|
213 // user originally opened. |
|
214 // (other items were commented in a header). |
|
215 // --------------------------------------------------------------------------- |
|
216 // |
|
217 const CCalenEntryUtil& CCalenEditorDataHandler::Original() const |
|
218 { |
|
219 TRACE_ENTRY_POINT; |
|
220 |
|
221 TRACE_EXIT_POINT; |
|
222 return *iOriginal; |
|
223 } |
|
224 |
|
225 // --------------------------------------------------------------------------- |
|
226 // CCalenEditorDataHandler::Entry |
|
227 // Returns the entry this object is wrapping round. |
|
228 // (other items were commented in a header). |
|
229 // --------------------------------------------------------------------------- |
|
230 // |
|
231 CCalEntry& CCalenEditorDataHandler::Entry() |
|
232 { |
|
233 TRACE_ENTRY_POINT; |
|
234 |
|
235 TRACE_EXIT_POINT; |
|
236 return iEntry; |
|
237 } |
|
238 |
|
239 // --------------------------------------------------------------------------- |
|
240 // CCalenEditorDataHandler::InstanceDateTime |
|
241 // Returns the instance date/time. |
|
242 // (other items were commented in a header). |
|
243 // --------------------------------------------------------------------------- |
|
244 // |
|
245 const TCalTime& CCalenEditorDataHandler::InstanceDateTime() const |
|
246 { |
|
247 TRACE_ENTRY_POINT; |
|
248 |
|
249 TRACE_EXIT_POINT; |
|
250 return iInstanceDateTime; |
|
251 } |
|
252 |
|
253 |
|
254 // --------------------------------------------------------------------------- |
|
255 // CCalenEditorDataHandler::ShouldSaveOrDeleteOrDoNothingL |
|
256 // Works out whether the entry should be deleted, saved, |
|
257 // or whether no action should be taken. |
|
258 // (other items were commented in a header). |
|
259 // --------------------------------------------------------------------------- |
|
260 // |
|
261 CCalenEditorDataHandler::TAction CCalenEditorDataHandler::ShouldSaveOrDeleteOrDoNothingL() |
|
262 { |
|
263 TRACE_ENTRY_POINT; |
|
264 |
|
265 if ( !IsEditedL() ) |
|
266 { |
|
267 // Not edited at all OR |
|
268 // Only added space characters to text fields but not |
|
269 // edited the non-text fields |
|
270 // no need to save the note |
|
271 TRACE_EXIT_POINT; |
|
272 return CCalenEditorDataHandler::EActionNothing; |
|
273 } |
|
274 |
|
275 // *************** THE NOTE IS EDITED ******************** |
|
276 if(IsCreatingNew()) |
|
277 { |
|
278 // ************* EDITED NEW NOTE ********* |
|
279 |
|
280 // Subject && Location && Description are text fields |
|
281 // If text fields as a whole is not empty, we can save the note |
|
282 // If text fields as a whole IS empty, we can STILL save the note |
|
283 // since we edited "non-text" fields |
|
284 if ( !NonTextFieldsEditedL() && AreTextFieldsEmptyL() ) |
|
285 { |
|
286 TRACE_EXIT_POINT; |
|
287 return CCalenEditorDataHandler::EActionNothing; |
|
288 } |
|
289 else |
|
290 { |
|
291 TRACE_EXIT_POINT; |
|
292 return CCalenEditorDataHandler::EActionSave; |
|
293 } |
|
294 } |
|
295 |
|
296 // **************** EDITED OLD NOTE ********** |
|
297 |
|
298 if(AreTextFieldsClearedL() && !NonTextFieldsEditedL()) // subject && location && description |
|
299 { |
|
300 // ***** OLD NOTE + TEXT FIELDS EMPTIED + NON-TEXT FIELDS NOT EDITED |
|
301 // Even if user may have edited non-text fields, |
|
302 // delete the note |
|
303 TRACE_EXIT_POINT; |
|
304 return CCalenEditorDataHandler::EActionDelete; |
|
305 } |
|
306 |
|
307 // ****** OLD NOTE WITH TEXT FIELDS ********** |
|
308 // Save the note, since the text fields contain something |
|
309 TRACE_EXIT_POINT; |
|
310 return CCalenEditorDataHandler::EActionSave; |
|
311 } |
|
312 |
|
313 // --------------------------------------------------------------------------- |
|
314 // CCalenEditorDataHandler::NonTextFieldsEdited |
|
315 // Returns ETrue if any of the non-text fields (e.g. time fields) of the entry |
|
316 // have been edited, EFalse otherwise. |
|
317 // (other items were commented in a header). |
|
318 // --------------------------------------------------------------------------- |
|
319 // |
|
320 TBool CCalenEditorDataHandler::NonTextFieldsEditedL() |
|
321 { |
|
322 TRACE_ENTRY_POINT; |
|
323 |
|
324 TRACE_EXIT_POINT; |
|
325 |
|
326 return ( IsStartDateTimeEdited() || |
|
327 IsEndDateTimeEdited() || |
|
328 IsAlarmEditedL() || |
|
329 IsRepeatRuleEdited() || |
|
330 IsPriorityEdited() || |
|
331 IsCalendarEditedL() || |
|
332 IsAttachmentExists() || |
|
333 IsEventTypeEdited() || |
|
334 AllDayFieldEdited() ); |
|
335 } |
|
336 |
|
337 // --------------------------------------------------------------------------- |
|
338 // CCalenEditorDataHandler::TextFieldsEdited |
|
339 // Returns ETrue if any of the text fields (e.g. summary) of the entry |
|
340 // have been edited, EFalse otherwise. |
|
341 // (other items were commented in a header). |
|
342 // --------------------------------------------------------------------------- |
|
343 // |
|
344 TBool CCalenEditorDataHandler::TextFieldsEdited() |
|
345 { |
|
346 TRACE_ENTRY_POINT; |
|
347 |
|
348 TRACE_EXIT_POINT; |
|
349 |
|
350 return ( IsSummaryEdited() || IsLocationEdited() || IsDescriptionEdited() |
|
351 || IsAttachmentExists() ); |
|
352 } |
|
353 |
|
354 // --------------------------------------------------------------------------- |
|
355 // CCalenEditorDataHandler::IsEditedL |
|
356 // Returns ETrue if the entry has been modified, EFalse otherwise. |
|
357 // (other items were commented in a header). |
|
358 // --------------------------------------------------------------------------- |
|
359 // |
|
360 TBool CCalenEditorDataHandler::IsEditedL() |
|
361 { |
|
362 TRACE_ENTRY_POINT; |
|
363 |
|
364 TRACE_EXIT_POINT; |
|
365 |
|
366 return ( TextFieldsEdited() || NonTextFieldsEditedL() ); |
|
367 } |
|
368 |
|
369 // --------------------------------------------------------------------------- |
|
370 // CCalenEditorDataHandler::WriteChangesToEntryL |
|
371 // Read the data from the form and set it to the entry. |
|
372 // (other items were commented in a header). |
|
373 // --------------------------------------------------------------------------- |
|
374 // |
|
375 void CCalenEditorDataHandler::WriteChangesToEntryL( CalCommon::TRecurrenceRange aRepeatTarget ) |
|
376 { |
|
377 TRACE_ENTRY_POINT; |
|
378 |
|
379 // This is only place where we can read data from CCalEntry. |
|
380 // E.g. when we calculate alarm offset, we need to read start time from |
|
381 // entry, not anymore from CCalenEntryUtil. |
|
382 TBool isNew = IsCreatingNew(); |
|
383 |
|
384 WriteStartAndEndTimesToEntryL( aRepeatTarget ); |
|
385 |
|
386 if ( isNew || IsSummaryEdited() ) |
|
387 { |
|
388 TPtrC summary = Edited().Summary(); |
|
389 // If text is considered empty, always store as KNullDesC |
|
390 if ( CalenAgendaUtils::IsEmptyText( summary ) ) |
|
391 { |
|
392 summary.Set( KNullDesC ); |
|
393 } |
|
394 iEntry.SetSummaryL( summary ); |
|
395 } |
|
396 |
|
397 if ( isNew || IsLocationEdited() ) |
|
398 { |
|
399 TPtrC location = Edited().Location(); |
|
400 // If text is considered empty, always store as KNullDesC |
|
401 if ( CalenAgendaUtils::IsEmptyText( location ) ) |
|
402 { |
|
403 location.Set(KNullDesC); |
|
404 } |
|
405 iEntry.SetLocationL( location ); |
|
406 } |
|
407 |
|
408 if ( isNew || IsDescriptionEdited() ) |
|
409 { |
|
410 iEntry.SetDescriptionL( Edited().Description() ); |
|
411 } |
|
412 |
|
413 // Repeat rule has to be modified in both cases |
|
414 if ( isNew || IsStartDateTimeEdited() || IsRepeatRuleEdited() ) |
|
415 { |
|
416 |
|
417 if ( aRepeatTarget == CalCommon::EThisOnly) |
|
418 { |
|
419 iEntry.ClearRepeatingPropertiesL(); |
|
420 } |
|
421 else if ( Edited().IsRepeating() ) |
|
422 { |
|
423 // If we're an RDate (with repeat type ERepeatOther), don't try to set an RRule, |
|
424 // but don't clear the repeat properties either. |
|
425 if( Edited().RepeatType() != ERepeatOther ) |
|
426 { |
|
427 TCalRRule rrule; |
|
428 |
|
429 CalculateRepeatRuleL( Edited().StartDateTime(), |
|
430 Edited().RepeatType(), |
|
431 Edited().RepeatUntilDateTime(), |
|
432 rrule ); |
|
433 |
|
434 iEntry.SetRRuleL( rrule ); |
|
435 |
|
436 // As there should not be any rdates, remove any that are |
|
437 // still present |
|
438 RArray<TCalTime> emptyList; |
|
439 CleanupClosePushL( emptyList ); |
|
440 iEntry.SetRDatesL( emptyList ); |
|
441 CleanupStack::PopAndDestroy(); // emptyList |
|
442 } |
|
443 else |
|
444 { |
|
445 // The repeat type is ERepeatOther, therefore as |
|
446 // it is impossible to create an entry of type |
|
447 // ERepeat other using the editor either the repeat until |
|
448 // date or the start date must have been changed |
|
449 |
|
450 // The start date/time has changed, in order for the |
|
451 // series to maintain its pattern, any rDates and if |
|
452 // present rRule are moved by the same offset |
|
453 // The repeat type is ERepeatOther, so check if we have any rdates |
|
454 RArray<TCalTime> rDateList; |
|
455 CleanupClosePushL( rDateList ); |
|
456 iEntry.GetRDatesL( rDateList ); |
|
457 TInt count = rDateList.Count(); |
|
458 |
|
459 if ( count == 0 ) |
|
460 { |
|
461 // There are no rdates so the new until and start date can be applied |
|
462 // directly. |
|
463 TCalRRule rrule; |
|
464 |
|
465 CalculateRepeatRuleL( Edited().StartDateTime(), |
|
466 Edited().RepeatType(), |
|
467 Edited().RepeatUntilDateTime(), |
|
468 rrule ); |
|
469 |
|
470 iEntry.SetRRuleL( rrule ); |
|
471 } |
|
472 else |
|
473 { |
|
474 // There are rDates which need to be checked. |
|
475 if ( IsStartDateTimeEdited() ) |
|
476 { |
|
477 // Need to shift any rdates |
|
478 TTime editedStart = iEdited->StartDateTime(); |
|
479 TTime origStart = iOriginal->StartDateTime(); |
|
480 TTimeIntervalMicroSeconds offSet = editedStart.MicroSecondsFrom( origStart ); |
|
481 for ( TInt index = 0; index < count; index++ ) |
|
482 { |
|
483 TCalTime& rDateTime = rDateList[ index ]; |
|
484 TTime shiftedTime = rDateTime.TimeUtcL(); |
|
485 TDateTime before = shiftedTime.DateTime(); |
|
486 shiftedTime += offSet; |
|
487 TDateTime after = shiftedTime.DateTime(); |
|
488 rDateTime.SetTimeUtcL( shiftedTime ); |
|
489 } |
|
490 } |
|
491 |
|
492 // Check and fix the rDates and rRules match the |
|
493 // repeat until date and time. |
|
494 TTime untilTime = Edited().RepeatUntilDateTime(); |
|
495 |
|
496 // Remove any rdates that are after the the repeat until date |
|
497 TInt count = rDateList.Count(); |
|
498 if ( count > 0 ) |
|
499 { |
|
500 TInt index = count - 1; |
|
501 do |
|
502 { |
|
503 TTime lastRDate = CalenDateUtils::BeginningOfDay( rDateList[ index ].TimeLocalL() ); |
|
504 TDateTime before = lastRDate.DateTime(); |
|
505 if ( lastRDate > untilTime ) |
|
506 { |
|
507 rDateList.Remove( index-- ); |
|
508 } |
|
509 else |
|
510 { |
|
511 index = KErrNotFound; |
|
512 } |
|
513 } while ( index != KErrNotFound ); |
|
514 } |
|
515 |
|
516 // Need to check if the end date of the |
|
517 // rrule needs adjusting if it exists. |
|
518 TCalRRule rRule; |
|
519 if ( iEntry.GetRRuleL( rRule ) ) |
|
520 { |
|
521 count = rDateList.Count(); |
|
522 if ( count > 0 ) |
|
523 { |
|
524 // There still exists some rdates, so only need to trim |
|
525 // the rrule if it exists |
|
526 TTime lastRDate = CalenDateUtils::BeginningOfDay( rDateList[ count - 1 ].TimeLocalL() ); |
|
527 const TTime& origUntilDate = Original().RepeatUntilDateTime(); |
|
528 TTime startDT = rRule.DtStart().TimeLocalL(); |
|
529 |
|
530 if ( lastRDate <= origUntilDate && startDT > lastRDate ) |
|
531 { |
|
532 if ( startDT < untilTime) |
|
533 { |
|
534 if( origUntilDate != untilTime) |
|
535 { |
|
536 ApplyUntilDateToRRuleL( rRule, untilTime); |
|
537 iEntry.SetRRuleL( rRule ); |
|
538 } |
|
539 } |
|
540 else |
|
541 { |
|
542 // The repeat start is after the until date |
|
543 // so remove any repeat information. |
|
544 iEntry.ClearRepeatingPropertiesL(); |
|
545 |
|
546 // If the entry date has been moved past the until |
|
547 // date, need to swap the an rDate for the entry. |
|
548 TTime startTime = iEntry.StartTimeL().TimeLocalL(); |
|
549 |
|
550 if ( startTime > untilTime ) |
|
551 { |
|
552 // Find the duration of the entry |
|
553 TTime endTime = iEntry.EndTimeL().TimeLocalL(); |
|
554 TTimeIntervalMinutes duration; |
|
555 //startTime.MinutesFrom( endTime, duration );// for bug: CMCA-745CZ4 |
|
556 endTime.MinutesFrom( startTime, duration ); |
|
557 |
|
558 // Choose the first rDate as the new start time |
|
559 TCalTime newStartTime = rDateList[ 0 ]; |
|
560 endTime = newStartTime.TimeLocalL() + duration; |
|
561 |
|
562 // FIXME. |
|
563 // If there is only one rDate left, the agenda model |
|
564 // will crash if it is deleted. |
|
565 if ( count != 0 ) |
|
566 { |
|
567 rDateList.Remove( 0 ); |
|
568 } |
|
569 |
|
570 TCalTime newEndTime; |
|
571 if ( UseFloatingTimeL() ) |
|
572 { |
|
573 newEndTime.SetTimeLocalFloatingL( endTime ); |
|
574 } |
|
575 else |
|
576 { |
|
577 newEndTime.SetTimeLocalL( endTime ); |
|
578 } |
|
579 |
|
580 iEntry.SetStartAndEndTimeL( newStartTime, newEndTime ); |
|
581 } |
|
582 } |
|
583 } |
|
584 } |
|
585 } |
|
586 |
|
587 iEntry.SetRDatesL( rDateList ); |
|
588 } |
|
589 |
|
590 CleanupStack::PopAndDestroy(); // rDateList |
|
591 } |
|
592 } |
|
593 else |
|
594 { |
|
595 iEntry.ClearRepeatingPropertiesL(); |
|
596 |
|
597 // FIXME As the entry is supposedly not repeating |
|
598 // any rDates should be removed. Unforunately this |
|
599 // is not possible at the moment because removing the |
|
600 // rdates will cause the agenda model to panic |
|
601 // |
|
602 // RArray<TCalTime> emptyList; |
|
603 // CleanupClosePushL( emptyList ); |
|
604 // iEntry.SetRDatesL( emptyList ); |
|
605 // CleanupStack::PopAndDestroy(); // emptyList |
|
606 } |
|
607 } |
|
608 |
|
609 if ( isNew || IsAlarmEditedL() && ( iEntry.StatusL() != CCalEntry::ETodoCompleted ) ) |
|
610 { |
|
611 if ( Edited().IsAlarmActivated() ) |
|
612 { |
|
613 CCalAlarm* alarm = iEntry.AlarmL(); |
|
614 if ( ! alarm ) |
|
615 { |
|
616 alarm = CCalAlarm::NewL(); |
|
617 } |
|
618 CleanupStack::PushL( alarm ); |
|
619 |
|
620 TTime startTime; |
|
621 // ToDos don't have start time! |
|
622 // If we have undated todo with alarm that was taken care earlier |
|
623 if (iEntry.EntryTypeL()==CCalEntry::ETodo) |
|
624 { |
|
625 startTime = iEntry.EndTimeL().TimeLocalL(); |
|
626 } |
|
627 |
|
628 // if this is not todo we use starttime normal way |
|
629 else |
|
630 { |
|
631 startTime = iEntry.StartTimeL().TimeLocalL(); |
|
632 } |
|
633 TCalRRule ignore; |
|
634 TBool isRepeating = iEntry.GetRRuleL( ignore ); |
|
635 |
|
636 // If edit alarm of repeating entry, we have to nudge start |
|
637 // time to instance date |
|
638 if ( isRepeating && aRepeatTarget == CalCommon::EThisAndAll ) |
|
639 { |
|
640 // nudge to instance date; |
|
641 TTime instanceDate = iInstanceDateTime.TimeLocalL(); |
|
642 if ( IsStartDateTimeEdited() ) |
|
643 { |
|
644 instanceDate = Edited().EventDateTime(); |
|
645 } |
|
646 |
|
647 TDateTime insDt = instanceDate.DateTime(); |
|
648 TDateTime startDt = startTime.DateTime(); |
|
649 // Don't use individual setters (SetMonth, SetDay ...), because |
|
650 // they break if month doesn't contain old date |
|
651 // or date to be set. |
|
652 startDt.Set( insDt.Year(), insDt.Month(), insDt.Day(), |
|
653 startDt.Hour(), startDt.Minute(), |
|
654 startDt.Second(), startDt.MicroSecond() ); |
|
655 startTime = TTime( startDt ); |
|
656 } |
|
657 |
|
658 TTime alarmTime = Edited().AlarmDateTime(); |
|
659 |
|
660 TTimeIntervalMinutes offset; |
|
661 startTime.MinutesFrom( alarmTime, offset ); |
|
662 alarm->SetTimeOffset( offset ); |
|
663 |
|
664 iEntry.SetAlarmL( alarm ); |
|
665 CleanupStack::PopAndDestroy( alarm ); |
|
666 } |
|
667 else |
|
668 { |
|
669 iEntry.SetAlarmL( NULL ); |
|
670 } |
|
671 } |
|
672 |
|
673 if ( isNew || IsPriorityEdited() ) |
|
674 { |
|
675 // map priority here |
|
676 TUint priority = 0; |
|
677 switch ( Edited().Priority() ) |
|
678 { |
|
679 case CCalenEntryUtil::ETodoPriorityHigh: |
|
680 priority = 1; |
|
681 break; |
|
682 case CCalenEntryUtil::ETodoPriorityNormal: |
|
683 priority = 2; |
|
684 break; |
|
685 case CCalenEntryUtil::ETodoPriorityLow: |
|
686 priority = 3; |
|
687 break; |
|
688 default: |
|
689 ASSERT( EFalse ); |
|
690 break; |
|
691 } |
|
692 iEntry.SetPriorityL( priority ); |
|
693 } |
|
694 |
|
695 if ( isNew ) |
|
696 { |
|
697 CCalEntry::TReplicationStatus status = CCalEntry::EOpen; |
|
698 switch ( Edited().SynchType() ) |
|
699 { |
|
700 case CCalenEntryUtil::ESynchPrivate: |
|
701 status = CCalEntry::EPrivate; |
|
702 break; |
|
703 case CCalenEntryUtil::ESynchPublic: |
|
704 status = CCalEntry::EOpen; |
|
705 break; |
|
706 case CCalenEntryUtil::ESynchNoSync: |
|
707 status = CCalEntry::ERestricted; |
|
708 break; |
|
709 default: |
|
710 ASSERT( EFalse ); |
|
711 break; |
|
712 } |
|
713 iEntry.SetReplicationStatusL( status ); |
|
714 } |
|
715 |
|
716 /** |
|
717 * S60 settings for new entries |
|
718 */ |
|
719 if ( IsCreatingNew() ) |
|
720 { |
|
721 if ( Edited().EntryType() == CCalEntry::EAnniv ) |
|
722 { |
|
723 TCalRRule rrule( TCalRRule::EYearly ); |
|
724 rrule.SetDtStart( iEntry.StartTimeL() ); |
|
725 rrule.SetInterval( 1 ); |
|
726 rrule.SetCount( 0 ); |
|
727 iEntry.SetRRuleL( rrule ); |
|
728 } |
|
729 } |
|
730 |
|
731 // check for attachments |
|
732 if( isNew || IsAttachmentExists() ) |
|
733 { |
|
734 // TODO: Uncomment this when enabling attachment support |
|
735 AddAttachementsToEntryL(); |
|
736 } |
|
737 TRACE_EXIT_POINT; |
|
738 } |
|
739 |
|
740 // ----------------------------------------------------------------------------- |
|
741 // CCalenEditorDataHandler::ApplyUntilDateToRRuleL |
|
742 // Applies an new until date to a rrule |
|
743 // (other items were commented in a header). |
|
744 // ----------------------------------------------------------------------------- |
|
745 // |
|
746 void CCalenEditorDataHandler::ApplyUntilDateToRRuleL( TCalRRule& aRRule, const TTime& aRepeatUntil ) const |
|
747 { |
|
748 TRACE_ENTRY_POINT; |
|
749 // note repeat is set to forever. |
|
750 if ( ! CalenDateUtils::IsValidDay( aRepeatUntil ) || IsForeverDate( aRepeatUntil ) ) |
|
751 { |
|
752 // Set repeat to forever: |
|
753 aRRule.SetCount( 0 ); |
|
754 } |
|
755 else |
|
756 { |
|
757 // Change repeatuntil so that hours, minutes, ... are same as in start date |
|
758 TDateTime dtUntil = aRepeatUntil.DateTime(); |
|
759 TDateTime dtStart= iEntry.StartTimeL().TimeLocalL().DateTime(); |
|
760 |
|
761 dtUntil.Set( dtUntil.Year(), dtUntil.Month(), dtUntil.Day(), |
|
762 dtStart.Hour(), dtStart.Minute(), dtStart.Second(), dtStart.MicroSecond() ); |
|
763 |
|
764 TCalTime calRepeatUntil; |
|
765 if ( UseFloatingTimeL() ) |
|
766 { |
|
767 calRepeatUntil.SetTimeLocalFloatingL( TTime( dtUntil ) ); |
|
768 } |
|
769 else |
|
770 { |
|
771 calRepeatUntil.SetTimeLocalL( TTime( dtUntil ) ); |
|
772 } |
|
773 aRRule.SetUntil( calRepeatUntil ); |
|
774 } |
|
775 TRACE_EXIT_POINT; |
|
776 } |
|
777 // ----------------------------------------------------------------------------- |
|
778 // CCalenEditorDataHandler::DurationGreaterThanRepeatIntervalError |
|
779 // Returns ETrue if the duration of instances of the meeting is greater than |
|
780 // the repeat period of the series, EFalse otherwise. |
|
781 // (other items were commented in a header). |
|
782 // ----------------------------------------------------------------------------- |
|
783 // |
|
784 TBool CCalenEditorDataHandler::DurationGreaterThanRepeatIntervalError() |
|
785 { |
|
786 TRACE_ENTRY_POINT; |
|
787 TBool isError = EFalse; |
|
788 switch( Edited().RepeatType() ) |
|
789 { |
|
790 case ERepeatDaily: |
|
791 case ERepeatWorkdays: |
|
792 { |
|
793 TTimeIntervalDays durDays = Edited().EndDateTime().DaysFrom( Edited().StartDateTime() ); |
|
794 isError = durDays >= TTimeIntervalDays(1); |
|
795 break; |
|
796 } |
|
797 case ERepeatWeekly: |
|
798 { |
|
799 TTimeIntervalDays durDays = Edited().EndDateTime().DaysFrom( Edited().StartDateTime() ); |
|
800 isError = durDays >= TTimeIntervalDays(7); |
|
801 break; |
|
802 } |
|
803 case ERepeatBiWeekly: |
|
804 { |
|
805 TTimeIntervalDays durDays = Edited().EndDateTime().DaysFrom( Edited().StartDateTime() ); |
|
806 isError = durDays >= TTimeIntervalDays(14); |
|
807 break; |
|
808 } |
|
809 case ERepeatMonthly: |
|
810 { |
|
811 TTimeIntervalMonths durMonths = Edited().EndDateTime().MonthsFrom( Edited().StartDateTime() ); |
|
812 isError = durMonths >= TTimeIntervalMonths(1); |
|
813 break; |
|
814 } |
|
815 case ERepeatYearly: |
|
816 { |
|
817 TTimeIntervalYears durYears = Edited().EndDateTime().YearsFrom( Edited().StartDateTime() ); |
|
818 isError = durYears >= TTimeIntervalYears(1); |
|
819 break; |
|
820 } |
|
821 case ERepeatOther: |
|
822 { |
|
823 isError = EFalse; |
|
824 break; |
|
825 } |
|
826 default: |
|
827 // Not repeating, no error |
|
828 isError = EFalse; |
|
829 break; |
|
830 } |
|
831 TRACE_EXIT_POINT; |
|
832 return isError; |
|
833 } |
|
834 |
|
835 // ----------------------------------------------------------------------------- |
|
836 // CCalenEditorDataHandler::CheckErrorsForThisAndAllL |
|
837 // Check for errors in the form. This function should only be called when the |
|
838 // user has decided they want to edit "This and all" from a prompt, or when the |
|
839 // entry is not repeating. |
|
840 // (other items were commented in a header). |
|
841 // ----------------------------------------------------------------------------- |
|
842 // |
|
843 CCalenEditorDataHandler::TError CCalenEditorDataHandler::CheckErrorsForThisAndAllL() |
|
844 { |
|
845 TRACE_ENTRY_POINT; |
|
846 |
|
847 // From UI spec: |
|
848 // 5 checks is specified, only one not needed in this phase is 2.1 |
|
849 |
|
850 const TTime start = Edited().StartDateTime(); |
|
851 const TTime end = Edited().EndDateTime(); |
|
852 |
|
853 // 1) Check that entry doesn't end earlier than it starts |
|
854 if ( end < start ) |
|
855 { |
|
856 TRACE_EXIT_POINT; |
|
857 return CCalenEditorDataHandler::EFormErrStopTimeEarlierThanStartTime; |
|
858 } |
|
859 |
|
860 // 2) Repeating entry checks: |
|
861 if ( Edited().IsRepeating() ) |
|
862 { |
|
863 // 2.1) Check that repeat until date is a) later than start date (for new notes) |
|
864 // b) not before start date (for existing notes) |
|
865 TTime repeatUntilDay = CalenDateUtils::BeginningOfDay( |
|
866 Edited().RepeatUntilDateTime() ); |
|
867 |
|
868 TTime repeatStartDay; |
|
869 |
|
870 // if new note or old note isnt repeating |
|
871 // edited.repeatUntil date must be greater than edited.start date |
|
872 // else |
|
873 // if IsRepeatRuleEdited or IsStartDateTimeEdited |
|
874 // //(either one above will make a new rule in which edited.startdate is the start date) |
|
875 // edited.repeatUntil must be greater than edited.start date |
|
876 // else |
|
877 // edited.repeatUntil must be greater than start date on disk |
|
878 |
|
879 TCalRRule rrule; |
|
880 if( IsCreatingNew() || |
|
881 !Entry().GetRRuleL(rrule) || |
|
882 IsRepeatRuleEdited() || |
|
883 IsStartDateTimeEdited() ) |
|
884 { |
|
885 // We don't have an rrule so we can't get the rrule start date, |
|
886 // or user has edited a field that will cause new start date to be used in the new rule. |
|
887 // Use the edited entry's start date. |
|
888 repeatStartDay = CalenDateUtils::BeginningOfDay( start ); |
|
889 } |
|
890 else |
|
891 { |
|
892 // original rrule is valid and new rule will not be created |
|
893 repeatStartDay = CalenDateUtils::BeginningOfDay( rrule.DtStart().TimeLocalL() ); |
|
894 } |
|
895 |
|
896 if ( repeatUntilDay <= repeatStartDay ) |
|
897 { |
|
898 TRACE_EXIT_POINT; |
|
899 return CCalenEditorDataHandler::EFormErrRepeatUntilEarlierThanNote; |
|
900 } |
|
901 |
|
902 if( DurationGreaterThanRepeatIntervalError() ) |
|
903 { |
|
904 TRACE_EXIT_POINT; |
|
905 return CCalenEditorDataHandler::EFormErrDurationGreaterThanRepeatInterval; |
|
906 } |
|
907 // 3) Alarm field checks: |
|
908 TRACE_EXIT_POINT; |
|
909 return CheckAlarmFieldsForErrorsL(ETrue); // user editing the series |
|
910 } |
|
911 |
|
912 // 3) Alarm field checks: |
|
913 TRACE_EXIT_POINT; |
|
914 return CheckAlarmFieldsForErrorsL(); // user editing the series |
|
915 } |
|
916 |
|
917 // ----------------------------------------------------------------------------- |
|
918 // CCalenEditorDataHandler::CheckErrorsForThisOnlyL |
|
919 // Check for errors in the form. This function should only be called when the |
|
920 // user has decided they want to edit "This only" from a prompt, or when the |
|
921 // entry is an exception. |
|
922 // (other items were commented in a header). |
|
923 // ----------------------------------------------------------------------------- |
|
924 // |
|
925 CCalenEditorDataHandler::TError CCalenEditorDataHandler::CheckErrorsForThisOnlyL( CCalEntry& /*aParentEntry*/, |
|
926 CCalInstanceView& /*aInstanceView*/ ) |
|
927 { |
|
928 TRACE_ENTRY_POINT; |
|
929 |
|
930 const TTime start = Edited().StartDateTime(); |
|
931 const TTime end = Edited().EndDateTime(); |
|
932 |
|
933 // Check that entry doesn't end earlier than it starts |
|
934 if ( end < start ) |
|
935 { |
|
936 TRACE_EXIT_POINT; |
|
937 return CCalenEditorDataHandler::EFormErrStopTimeEarlierThanStartTime; |
|
938 } |
|
939 |
|
940 TError error = CheckForOutOfSequenceL(); |
|
941 |
|
942 if( error != EFormErrNone ) |
|
943 { |
|
944 return error; |
|
945 } |
|
946 |
|
947 // Alarm field checks: |
|
948 TRACE_EXIT_POINT; |
|
949 return CheckAlarmFieldsForErrorsL(); // user creating/editing an exception |
|
950 } |
|
951 |
|
952 // ----------------------------------------------------------------------------- |
|
953 // CCalenEditorDataHandler::CheckForOutOfSequenceL |
|
954 // Checks to see if the instance is being moved out of sequence, relative to |
|
955 // the rest of the series. |
|
956 // (other items were commented in a header). |
|
957 // ----------------------------------------------------------------------------- |
|
958 // |
|
959 CCalenEditorDataHandler::TError CCalenEditorDataHandler::CheckForOutOfSequenceL() |
|
960 { |
|
961 TRACE_ENTRY_POINT; |
|
962 // Only perform the checks when we change the start or end time of the meeting. |
|
963 if( !IsStartDateTimeEdited() && !IsEndDateTimeEdited() ) |
|
964 { |
|
965 TRACE_EXIT_POINT; |
|
966 return EFormErrNone; |
|
967 } |
|
968 |
|
969 TCalTime prevStart, prevEnd; |
|
970 |
|
971 GetPreviousInstanceTimeL( prevStart, prevEnd ); |
|
972 |
|
973 if( prevStart.TimeLocalL() != Time::NullTTime() ) |
|
974 { |
|
975 // Does the exception end on/after prevEnd? |
|
976 if( Edited().StartDateTime() < prevEnd.TimeLocalL() ) |
|
977 { |
|
978 // Does the exception start after prevStart? |
|
979 if( Edited().StartDateTime() > prevStart.TimeLocalL() ) |
|
980 { |
|
981 TRACE_EXIT_POINT; |
|
982 return EFormErrOverlapsExistingInstance; |
|
983 } |
|
984 else |
|
985 { |
|
986 // Does the exception finish after prevStart? |
|
987 if( Edited().EndDateTime() > prevStart.TimeLocalL() ) |
|
988 { |
|
989 TRACE_EXIT_POINT; |
|
990 return EFormErrOverlapsExistingInstance; |
|
991 } |
|
992 else |
|
993 { |
|
994 TRACE_EXIT_POINT; |
|
995 return EFormErrOutOfSequence; |
|
996 } |
|
997 } |
|
998 } |
|
999 |
|
1000 // Does the exception start on the same day as prevStart? |
|
1001 if( CalenDateUtils::OnSameDay( Edited().StartDateTime(), prevStart.TimeLocalL() ) ) |
|
1002 { |
|
1003 TRACE_EXIT_POINT; |
|
1004 return EFormErrInstanceAlreadyExistsOnThisDay; |
|
1005 } |
|
1006 } |
|
1007 |
|
1008 TCalTime nextStart, nextEnd; |
|
1009 |
|
1010 GetNextInstanceTimeL( nextStart, nextEnd ); |
|
1011 |
|
1012 if( nextStart.TimeLocalL() != Time::NullTTime() ) |
|
1013 { |
|
1014 // Does the exception finish on/before nextStart? |
|
1015 if( Edited().EndDateTime() > nextStart.TimeLocalL() ) |
|
1016 { |
|
1017 // Does the exception finish before nextFinish? |
|
1018 if( Edited().EndDateTime() < nextEnd.TimeLocalL() ) |
|
1019 { |
|
1020 TRACE_EXIT_POINT; |
|
1021 return EFormErrOverlapsExistingInstance; |
|
1022 } |
|
1023 else |
|
1024 { |
|
1025 // Does the exception start before nextFinish? |
|
1026 if( Edited().StartDateTime() < nextEnd.TimeLocalL() ) |
|
1027 { |
|
1028 TRACE_EXIT_POINT; |
|
1029 return EFormErrOverlapsExistingInstance; |
|
1030 } |
|
1031 else |
|
1032 { |
|
1033 TRACE_EXIT_POINT; |
|
1034 return EFormErrOutOfSequence; |
|
1035 } |
|
1036 } |
|
1037 } |
|
1038 |
|
1039 // Does the exception start on the same day as nextStart? |
|
1040 if( CalenDateUtils::OnSameDay( Edited().StartDateTime(), nextStart.TimeLocalL() ) ) |
|
1041 { |
|
1042 TRACE_EXIT_POINT; |
|
1043 return EFormErrInstanceAlreadyExistsOnThisDay; |
|
1044 } |
|
1045 } |
|
1046 |
|
1047 // Does the series have any rdates |
|
1048 RArray<TCalTime> rDateArray; |
|
1049 CleanupClosePushL( rDateArray ); |
|
1050 Entry().GetRDatesL( rDateArray ); |
|
1051 TInt rDateCount = rDateArray.Count(); |
|
1052 |
|
1053 if ( rDateCount > 0 ) |
|
1054 { |
|
1055 // If the series has rdates, check that the exception |
|
1056 // does not overlap or start on the same day |
|
1057 const TTime& startDateTime = Edited().StartDateTime(); |
|
1058 const TTime& endDateTime = Edited().EndDateTime(); |
|
1059 TTimeIntervalMinutes duration; |
|
1060 startDateTime.MinutesFrom( endDateTime, duration ); |
|
1061 |
|
1062 for ( TInt index = 0; index < rDateCount; index++ ) |
|
1063 { |
|
1064 const TTime& rDate = rDateArray[ index ].TimeLocalL(); |
|
1065 |
|
1066 if ( !CalenDateUtils::OnSameDay( Original().StartDateTime(), rDate ) ) |
|
1067 { |
|
1068 // Does the exception start or end on the same day as a rdate. |
|
1069 if ( CalenDateUtils::OnSameDay( startDateTime, rDate ) ) |
|
1070 { |
|
1071 CleanupStack::PopAndDestroy(); // rDateArray |
|
1072 TRACE_EXIT_POINT; |
|
1073 return EFormErrInstanceAlreadyExistsOnThisDay; |
|
1074 } |
|
1075 |
|
1076 // Does the exception overlap an rdate? |
|
1077 TTime rDateEnd = rDate + duration; |
|
1078 if ( endDateTime > rDateEnd && startDateTime < rDate ) |
|
1079 { |
|
1080 CleanupStack::PopAndDestroy(); // rDateArray |
|
1081 TRACE_EXIT_POINT; |
|
1082 return EFormErrOverlapsExistingInstance; |
|
1083 } |
|
1084 } |
|
1085 } |
|
1086 } |
|
1087 |
|
1088 CleanupStack::PopAndDestroy(); // rDateArray |
|
1089 TRACE_EXIT_POINT; |
|
1090 return EFormErrNone; |
|
1091 } |
|
1092 |
|
1093 // ----------------------------------------------------------------------------- |
|
1094 // CCalenEditorDataHandler::GetPreviousInstanceTimeL |
|
1095 // Gets the start and end times of the previous instance. Sets both to a null |
|
1096 // time if there is no instance before the current one |
|
1097 // (other items were commented in a header). |
|
1098 // ----------------------------------------------------------------------------- |
|
1099 // |
|
1100 void CCalenEditorDataHandler::GetPreviousInstanceTimeL( TCalTime& aPreviousStartTime, |
|
1101 TCalTime& aPreviousEndTime ) |
|
1102 { |
|
1103 TRACE_ENTRY_POINT; |
|
1104 |
|
1105 aPreviousStartTime.SetTimeLocalL( Time::NullTTime() ); |
|
1106 aPreviousEndTime.SetTimeLocalL( Time::NullTTime() ); |
|
1107 |
|
1108 RPointerArray<CCalEntry> entries; |
|
1109 CleanupResetAndDestroyPushL(entries); |
|
1110 |
|
1111 EntryViewL().FetchL( Entry().UidL(), entries ); |
|
1112 |
|
1113 TCalTime currentInstanceDate = Entry().RecurrenceIdL(); |
|
1114 if( currentInstanceDate.TimeUtcL() == Time::NullTTime() ) |
|
1115 { |
|
1116 // We must be creating a new exception. Calculate the recurrence id. |
|
1117 TTimeIntervalMinutes timeOfDay = CalenDateUtils::TimeOfDay( entries[0]->StartTimeL().TimeLocalL() ); |
|
1118 TTime beginningOfDay = CalenDateUtils::BeginningOfDay( InstanceDateTime().TimeLocalL() ); |
|
1119 currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay ); |
|
1120 } |
|
1121 |
|
1122 TCalRRule rrule; |
|
1123 if( entries[0]->GetRRuleL(rrule) ) |
|
1124 { |
|
1125 TCalenRepeatIndex repeatIndex = CalenNoteDataUtil::RepeatIndexL( *entries[0] ); |
|
1126 TBool keepLooking = ETrue; |
|
1127 RArray<TCalTime> exdates; |
|
1128 CleanupClosePushL( exdates ); |
|
1129 entries[0]->GetExceptionDatesL(exdates); |
|
1130 |
|
1131 // Needed for case ERepeatOther |
|
1132 TCalRRule::TType type( rrule.Type() ); |
|
1133 TInt repeatInterval( rrule.Interval() ); |
|
1134 TCalTime start, end; |
|
1135 TTime previousInstanceTime = Time::NullTTime(); |
|
1136 |
|
1137 while( keepLooking ) |
|
1138 { |
|
1139 // Subtract the repeat interval of the parent. |
|
1140 switch( repeatIndex ) |
|
1141 { |
|
1142 case ERepeatDaily: |
|
1143 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(1) ); |
|
1144 break; |
|
1145 case ERepeatWeekly: |
|
1146 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7) ); |
|
1147 break; |
|
1148 case ERepeatBiWeekly: |
|
1149 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(14) ); |
|
1150 break; |
|
1151 case ERepeatMonthly: |
|
1152 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalMonths(1) ); |
|
1153 break; |
|
1154 case ERepeatYearly: |
|
1155 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalYears(1) ); |
|
1156 break; |
|
1157 case ERepeatWorkdays: |
|
1158 currentInstanceDate.SetTimeLocalL(currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7) ); |
|
1159 case ERepeatOther: |
|
1160 /* This case includes repeating events like: 3 days every week, 3rd weekday of everymonth |
|
1161 that does not fall in any cases above but still have repeating rule*/ |
|
1162 |
|
1163 // Check if the current entry being edited is child entry |
|
1164 // If yes, then put back the child entry time to currentInstanceDate |
|
1165 if(Entry().RecurrenceIdL().TimeUtcL() != Time::NullTTime() ) |
|
1166 { |
|
1167 TTimeIntervalMinutes timeOfDay = CalenDateUtils::TimeOfDay( Entry().StartTimeL().TimeLocalL() ); |
|
1168 TTime beginningOfDay = CalenDateUtils::BeginningOfDay( InstanceDateTime().TimeLocalL() ); |
|
1169 currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay ); |
|
1170 } |
|
1171 |
|
1172 switch( type ) |
|
1173 { |
|
1174 case TCalRRule::EDaily: |
|
1175 start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(1 * repeatInterval)); |
|
1176 break; |
|
1177 case TCalRRule::EWeekly: |
|
1178 start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalDays(7 * repeatInterval)); |
|
1179 break; |
|
1180 case TCalRRule::EMonthly: |
|
1181 // Add 7 days of buffer to cover the cases were gap b/w two instances of the event |
|
1182 // can go beuong 30 days. Ex: Every third wednesday of every month |
|
1183 start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalMonths(repeatInterval)-TTimeIntervalDays(7 * repeatInterval)); |
|
1184 break; |
|
1185 case TCalRRule::EYearly: |
|
1186 // Add 7 days of buffer to cover the cases were gap b/w two instances of the event |
|
1187 // can go beuong 365 days. Ex: Every third wednesday of September of every year |
|
1188 start.SetTimeLocalL( currentInstanceDate.TimeLocalL()-TTimeIntervalYears(repeatInterval)-TTimeIntervalDays(7 * repeatInterval)); |
|
1189 break; |
|
1190 } |
|
1191 |
|
1192 end.SetTimeLocalL(CalenDateUtils::BeginningOfDay(currentInstanceDate.TimeLocalL())); |
|
1193 previousInstanceTime = GetPreviousInstanceForRepeatOtherL(*entries[0], CalCommon::TCalTimeRange( start, end)); |
|
1194 currentInstanceDate.SetTimeLocalL( previousInstanceTime); |
|
1195 break; |
|
1196 default: |
|
1197 case ERepeatNotRepeated: |
|
1198 keepLooking = EFalse; |
|
1199 break; |
|
1200 } |
|
1201 |
|
1202 // Is currentInstanceDate before parent dt start? |
|
1203 if( currentInstanceDate.TimeLocalL() < entries[0]->StartTimeL().TimeLocalL() ) |
|
1204 { |
|
1205 // There are no instances before the exception |
|
1206 keepLooking = EFalse; |
|
1207 } |
|
1208 else |
|
1209 { |
|
1210 // Is there an exdate on currentInstanceDate? |
|
1211 TBool isExdateOnDay = EFalse; |
|
1212 for(TInt i=0; i<exdates.Count(); ++i) |
|
1213 { |
|
1214 if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() ) |
|
1215 { |
|
1216 isExdateOnDay = ETrue; |
|
1217 // There is an exdate - is there a child associated with the exdate? |
|
1218 for(TInt j=1; j<entries.Count(); ++j) |
|
1219 { |
|
1220 if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() ) |
|
1221 { |
|
1222 // This child is the previous instance. |
|
1223 aPreviousStartTime = entries[j]->StartTimeL(); |
|
1224 aPreviousEndTime = entries[j]->EndTimeL(); |
|
1225 keepLooking = EFalse; |
|
1226 } |
|
1227 } |
|
1228 break; |
|
1229 } |
|
1230 } |
|
1231 |
|
1232 if( !isExdateOnDay ) |
|
1233 { |
|
1234 // The instance exists and hasn't been deleted or made into an exception. |
|
1235 // Use information from the parent to set the start/end times. |
|
1236 aPreviousStartTime = currentInstanceDate; |
|
1237 |
|
1238 TTimeIntervalMinutes duration; |
|
1239 TTime start = entries[0]->StartTimeL().TimeLocalL(); |
|
1240 TTime end = entries[0]->EndTimeL().TimeLocalL(); |
|
1241 end.MinutesFrom( start, duration ); |
|
1242 aPreviousEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration ); |
|
1243 keepLooking = EFalse; |
|
1244 } |
|
1245 } |
|
1246 } |
|
1247 CleanupStack::PopAndDestroy( &exdates ); |
|
1248 } |
|
1249 |
|
1250 CleanupStack::PopAndDestroy(&entries); |
|
1251 |
|
1252 TRACE_EXIT_POINT; |
|
1253 } |
|
1254 |
|
1255 // ----------------------------------------------------------------------------- |
|
1256 // CCalenEditorDataHandler::GetNextInstanceTimeL |
|
1257 // Gets the start and end times of the next instance. Sets both to a null |
|
1258 // time if there is no instance after the current one. |
|
1259 // (other items were commented in a header). |
|
1260 // ----------------------------------------------------------------------------- |
|
1261 // |
|
1262 void CCalenEditorDataHandler::GetNextInstanceTimeL( TCalTime& aNextStartTime, |
|
1263 TCalTime& aNextEndTime ) |
|
1264 { |
|
1265 TRACE_ENTRY_POINT; |
|
1266 |
|
1267 aNextStartTime.SetTimeLocalL( Time::NullTTime() ); |
|
1268 aNextEndTime.SetTimeLocalL( Time::NullTTime() ); |
|
1269 |
|
1270 RPointerArray<CCalEntry> entries; |
|
1271 CleanupResetAndDestroyPushL(entries); |
|
1272 |
|
1273 EntryViewL().FetchL( Entry().UidL(), entries ); |
|
1274 |
|
1275 TCalTime currentInstanceDate = Entry().RecurrenceIdL(); |
|
1276 if( currentInstanceDate.TimeUtcL() == Time::NullTTime() ) |
|
1277 { |
|
1278 // We must be creating a new exception. Calculate the recurrence id. |
|
1279 TTimeIntervalMinutes timeOfDay = CalenDateUtils::TimeOfDay( entries[0]->StartTimeL().TimeLocalL() ); |
|
1280 TTime beginningOfDay = CalenDateUtils::BeginningOfDay( InstanceDateTime().TimeLocalL() ); |
|
1281 currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay ); |
|
1282 } |
|
1283 |
|
1284 TCalRRule rrule; |
|
1285 if( entries[0]->GetRRuleL(rrule) ) |
|
1286 { |
|
1287 TCalenRepeatIndex repeatIndex = CalenNoteDataUtil::RepeatIndexL( *entries[0] ); |
|
1288 TBool keepLooking = ETrue; |
|
1289 RArray<TCalTime> exdates; |
|
1290 CleanupClosePushL( exdates ); |
|
1291 entries[0]->GetExceptionDatesL(exdates); |
|
1292 |
|
1293 // Needed for case ERepeatOther |
|
1294 TCalRRule::TType type( rrule.Type() ); |
|
1295 TInt repeatInterval( rrule.Interval() ); |
|
1296 TCalTime start, end; |
|
1297 TTime nextInstanceTime = Time::NullTTime(); |
|
1298 |
|
1299 while( keepLooking ) |
|
1300 { |
|
1301 // Subtract the repeat interval of the parent. |
|
1302 switch( repeatIndex ) |
|
1303 { |
|
1304 case ERepeatDaily: |
|
1305 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1) ); |
|
1306 break; |
|
1307 case ERepeatWeekly: |
|
1308 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7) ); |
|
1309 break; |
|
1310 case ERepeatBiWeekly: |
|
1311 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(14) ); |
|
1312 break; |
|
1313 case ERepeatMonthly: |
|
1314 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalMonths(1) ); |
|
1315 break; |
|
1316 case ERepeatYearly: |
|
1317 currentInstanceDate.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalYears(1) ); |
|
1318 break; |
|
1319 case ERepeatWorkdays: |
|
1320 currentInstanceDate.SetTimeLocalL(currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7) ); |
|
1321 break; |
|
1322 case ERepeatOther: |
|
1323 { |
|
1324 /* This case includes repeating events like: 3 days every week, 3rd weekday of everymonth |
|
1325 that does not fall in any cases above but still have repeating rule*/ |
|
1326 |
|
1327 // Check if the current entry being edited is child entry |
|
1328 // If yes, then put back the child entry time to currentInstanceDate |
|
1329 if(Entry().RecurrenceIdL().TimeUtcL() != Time::NullTTime()) |
|
1330 { |
|
1331 TTimeIntervalMinutes timeOfDay = CalenDateUtils::TimeOfDay( Entry().StartTimeL().TimeLocalL() ); |
|
1332 TTime beginningOfDay = CalenDateUtils::BeginningOfDay( InstanceDateTime().TimeLocalL() ); |
|
1333 currentInstanceDate.SetTimeLocalL( beginningOfDay + timeOfDay ); |
|
1334 } |
|
1335 switch( type ) |
|
1336 { |
|
1337 case TCalRRule::EDaily: |
|
1338 end.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1 * repeatInterval)); |
|
1339 break; |
|
1340 case TCalRRule::EWeekly: |
|
1341 end.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalDays(7 * repeatInterval)); |
|
1342 break; |
|
1343 case TCalRRule::EMonthly: |
|
1344 // Add 7 days of buffer to cover the cases were gap b/w two instances of the event |
|
1345 // can go beuong 30 days. Ex: Every third wednesday of every month |
|
1346 end.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalMonths(repeatInterval)+TTimeIntervalDays(7 * repeatInterval)); |
|
1347 break; |
|
1348 case TCalRRule::EYearly: |
|
1349 // Add 7 days of buffer to cover the cases were gap b/w two instances of the event |
|
1350 // can go beuong 365 days. Ex: Every third wednesday of September of every year |
|
1351 end.SetTimeLocalL( currentInstanceDate.TimeLocalL()+TTimeIntervalYears(repeatInterval)+TTimeIntervalDays(7 * repeatInterval)); |
|
1352 break; |
|
1353 } |
|
1354 |
|
1355 start.SetTimeLocalL(CalenDateUtils::BeginningOfDay(currentInstanceDate.TimeLocalL()+TTimeIntervalDays(1))); |
|
1356 |
|
1357 nextInstanceTime = GetNextInstanceForRepeatOtherL(*entries[0], CalCommon::TCalTimeRange( start, end)); |
|
1358 currentInstanceDate.SetTimeLocalL( nextInstanceTime); |
|
1359 break; |
|
1360 } |
|
1361 case ERepeatNotRepeated: |
|
1362 keepLooking = EFalse; |
|
1363 break; |
|
1364 default: |
|
1365 break; |
|
1366 } |
|
1367 |
|
1368 // Is currentInstanceDate after parent dt end? |
|
1369 if( currentInstanceDate.TimeLocalL() > rrule.Until().TimeLocalL() ) |
|
1370 { |
|
1371 // There are no instances before the exception |
|
1372 keepLooking = EFalse; |
|
1373 } |
|
1374 else |
|
1375 { |
|
1376 // Is there an exdate on currentInstanceDate? |
|
1377 TBool isExdateOnDay = EFalse; |
|
1378 for(TInt i=0; i<exdates.Count(); ++i) |
|
1379 { |
|
1380 if( exdates[i].TimeLocalL() == currentInstanceDate.TimeLocalL() ) |
|
1381 { |
|
1382 isExdateOnDay = ETrue; |
|
1383 // There is an exdate - is there a child associated with the exdate? |
|
1384 for(TInt j=1; j<entries.Count(); ++j) |
|
1385 { |
|
1386 if( entries[j]->RecurrenceIdL().TimeLocalL() == currentInstanceDate.TimeLocalL() ) |
|
1387 { |
|
1388 // This child is the previous instance. |
|
1389 aNextStartTime = entries[j]->StartTimeL(); |
|
1390 aNextEndTime = entries[j]->EndTimeL(); |
|
1391 keepLooking = EFalse; |
|
1392 } |
|
1393 } |
|
1394 break; |
|
1395 } |
|
1396 } |
|
1397 |
|
1398 if( !isExdateOnDay ) |
|
1399 { |
|
1400 // The instance exists and hasn't been deleted or made into an exception. |
|
1401 // Use information from the parent to set the start/end times. |
|
1402 aNextStartTime = currentInstanceDate; |
|
1403 |
|
1404 TTimeIntervalMinutes duration; |
|
1405 TTime start = entries[0]->StartTimeL().TimeLocalL(); |
|
1406 TTime end = entries[0]->EndTimeL().TimeLocalL(); |
|
1407 end.MinutesFrom( start, duration ); |
|
1408 aNextEndTime.SetTimeLocalL( currentInstanceDate.TimeLocalL() + duration ); |
|
1409 keepLooking = EFalse; |
|
1410 } |
|
1411 } |
|
1412 } |
|
1413 CleanupStack::PopAndDestroy( &exdates ); |
|
1414 } |
|
1415 |
|
1416 CleanupStack::PopAndDestroy(&entries); |
|
1417 |
|
1418 TRACE_EXIT_POINT; |
|
1419 } |
|
1420 |
|
1421 // ----------------------------------------------------------------------------- |
|
1422 // CCalenEditorDataHandler::CheckAlarmFieldsForErrorsL |
|
1423 // Check the alarm fields for errors. Returns the error if found, or |
|
1424 // EFormErrNone if no error found. |
|
1425 // (other items were commented in a header). |
|
1426 // ----------------------------------------------------------------------------- |
|
1427 // |
|
1428 CCalenEditorDataHandler::TError CCalenEditorDataHandler::CheckAlarmFieldsForErrorsL(TBool aSeries) |
|
1429 { |
|
1430 TRACE_ENTRY_POINT; |
|
1431 |
|
1432 TError error = EFormErrNone; |
|
1433 // If alarm not active, no check |
|
1434 if ( Edited().IsAlarmActivated() ) |
|
1435 { |
|
1436 TTime alarm = Edited().AlarmDateTime(); |
|
1437 TTime startTime = Edited().StartDateTime(); |
|
1438 TTime now(Time::NullTTime()); |
|
1439 now.HomeTime(); |
|
1440 |
|
1441 if(IsAlarmInAcceptablePeriod(error, alarm, startTime)) |
|
1442 { |
|
1443 // ask form (not iEntry) if it is repeating |
|
1444 // if we launched an old exception, then form has no repeat field |
|
1445 // if creating a new exception, then form has repeat field |
|
1446 TBool EventIsInFuture = (IsTimedEntry() && (startTime > now)) || |
|
1447 (!IsTimedEntry() && (startTime.DaysFrom(now) >= TTimeIntervalDays(0))); |
|
1448 if( !aSeries && (alarm < now) && ( iEdited->EntryType()!=CCalEntry::EAnniv ) ) |
|
1449 { |
|
1450 // dont let non-repeating future entries have alarms in past |
|
1451 error = EFormErrAlarmTimePast; |
|
1452 } |
|
1453 /* otherwise, save alarm to past: |
|
1454 * new/old non-repeating & in past |
|
1455 * repeating new/old repeating in past/future |
|
1456 */ |
|
1457 } |
|
1458 } |
|
1459 |
|
1460 TRACE_EXIT_POINT; |
|
1461 return error; |
|
1462 } |
|
1463 |
|
1464 // ----------------------------------------------------------------------------- |
|
1465 // CCalenEditorDataHandler::IsAlarmInAcceptablePeriod |
|
1466 // Check alarm time validity |
|
1467 // (other items were commented in a header). |
|
1468 // ----------------------------------------------------------------------------- |
|
1469 // |
|
1470 TBool CCalenEditorDataHandler::IsAlarmInAcceptablePeriod(TError& aError, |
|
1471 const TTime& aAlarmTime, const TTime& aStartTime) const |
|
1472 { |
|
1473 TRACE_ENTRY_POINT; |
|
1474 |
|
1475 TTime upperLimit = IsTimedEntry() ? |
|
1476 aStartTime : |
|
1477 CalenDateUtils::BeginningOfDay(aStartTime) + TTimeIntervalDays(1); |
|
1478 TTime lowerLimit = aStartTime - TTimeIntervalDays(31); |
|
1479 TBool acceptable = ETrue; |
|
1480 if(aAlarmTime < lowerLimit) |
|
1481 { |
|
1482 acceptable = EFalse; |
|
1483 aError = EFormErrAlarmDateTooManyDaysBeforeNote; |
|
1484 } |
|
1485 else if(aAlarmTime > upperLimit) |
|
1486 { |
|
1487 acceptable = EFalse; |
|
1488 aError = EFormErrAlarmTimeLaterThanNote; |
|
1489 } |
|
1490 |
|
1491 TRACE_EXIT_POINT; |
|
1492 return acceptable; |
|
1493 } |
|
1494 |
|
1495 // ----------------------------------------------------------------------------- |
|
1496 // CCalenEditorDataHandler::ForceValidValuesL |
|
1497 // Force the form to use valid values. This function gets called when the user |
|
1498 // forces the application to exit, for example by pressing the off button. |
|
1499 // We attempt to save as much data as possible from the form. |
|
1500 // (other items were commented in a header). |
|
1501 // ----------------------------------------------------------------------------- |
|
1502 // |
|
1503 void CCalenEditorDataHandler::ForceValidValuesL( CalCommon::TRecurrenceRange aRepeatTarget ) |
|
1504 { |
|
1505 TRACE_ENTRY_POINT; |
|
1506 |
|
1507 // Checks and valid values are |
|
1508 // from S60 Calendar UI spec, chapter 4.6.4.1 Exiting Note Editor: |
|
1509 |
|
1510 // We modify values as we go, thus we can't pre-read fields. |
|
1511 // E.g. when start time is needed in check, it should be always read |
|
1512 // from model, because previous check might have modified it. |
|
1513 |
|
1514 // 2) if ends earlier than starts |
|
1515 if ( Edited().EndDateTime() < Edited().StartDateTime() ) |
|
1516 { |
|
1517 // a) (for new entry) set end time equal to start time |
|
1518 if ( IsCreatingNew() ) |
|
1519 { |
|
1520 Edited().SetEndDateTimeL( Edited().StartDateTime() ); |
|
1521 } |
|
1522 // b) (for existing entries) replace with original end time |
|
1523 else |
|
1524 { |
|
1525 Edited().SetEndDateTimeL( Original().EndDateTime() ); |
|
1526 // if still wrong, replace start time also |
|
1527 Edited().SetStartDateTimeL( Original().StartDateTime() ); |
|
1528 } |
|
1529 } // END end < start check |
|
1530 |
|
1531 // 1) Alarm validation |
|
1532 if ( Edited().IsAlarmActivated() ) |
|
1533 { |
|
1534 TTime now; |
|
1535 now.HomeTime(); |
|
1536 |
|
1537 // Note: all three checks are done for each alarm. |
|
1538 // Alarm time is read always again, because modifications are done after each check |
|
1539 |
|
1540 // 1.1) a) if alarm more than 31 days before start, alarm is set 31 days before start |
|
1541 // b) (for todos) - "" - before due date |
|
1542 TTime maxAlarmBeforeStart = Edited().StartDateTime() - TTimeIntervalDays( 31 ); |
|
1543 if ( Edited().AlarmDateTime() < maxAlarmBeforeStart ) |
|
1544 { |
|
1545 Edited().SetAlarmDateTimeL( maxAlarmBeforeStart ); |
|
1546 } |
|
1547 |
|
1548 // 1.2) a) (meetings) if alarm later than start, set it to default alarm time |
|
1549 // b) (for todos & annivs) - "" - later than due date |
|
1550 TTime atLatest = Edited().StartDateTime(); |
|
1551 if(!IsTimedEntry()) |
|
1552 { |
|
1553 atLatest += TTimeIntervalDays(1); |
|
1554 atLatest -= TTimeIntervalSeconds(1); |
|
1555 // at Latest for ToDo/Anniv would be DD @ 23:59:59 |
|
1556 } |
|
1557 if( Edited().AlarmDateTime() > atLatest ) |
|
1558 { |
|
1559 SetDefaultAlarmDateTimeL(); |
|
1560 } |
|
1561 |
|
1562 // 1.3) if alarm is set to passed time, |
|
1563 if ( Edited().AlarmDateTime() < now ) |
|
1564 { |
|
1565 // a) it is set off for |
|
1566 // - new/old NON-REPEATING entries |
|
1567 if (!Edited().IsRepeating() && Edited().EntryType() != CCalEntry::EAnniv ) |
|
1568 { |
|
1569 Edited().SetAlarmOffL(); |
|
1570 } |
|
1571 // b) (for existing entries) it is saved, unless it has failed 1.1 or 1.2 |
|
1572 else |
|
1573 { |
|
1574 // keep, if it is repeating entry, since repeating entries |
|
1575 // can have alarms in past |
|
1576 } |
|
1577 } |
|
1578 } // END alarm checks |
|
1579 |
|
1580 // 3) Repeat rule checks |
|
1581 if ( Edited().IsRepeating() ) |
|
1582 { |
|
1583 // if repeating note's repeat until date |
|
1584 // a) (for new entries) isn't one day later than start date |
|
1585 // b) (for existing entries) is before start date |
|
1586 // set it to one year later from start date |
|
1587 TTime repeatUntilDay = CalenDateUtils::BeginningOfDay( |
|
1588 Edited().RepeatUntilDateTime() ); |
|
1589 TTime startDay = CalenDateUtils::BeginningOfDay( Edited().StartDateTime() ); |
|
1590 if ( ( IsCreatingNew() && repeatUntilDay <= startDay) || |
|
1591 (! IsCreatingNew() && repeatUntilDay < startDay) ) |
|
1592 { |
|
1593 Edited().SetRepeatUntilDateTimeL( startDay + TTimeIntervalYears(1) ); |
|
1594 } |
|
1595 } |
|
1596 |
|
1597 // 4) if due date of todo is passed or invalid, save it with entered date |
|
1598 // no operation (this is just clarification in UI spec |
|
1599 |
|
1600 |
|
1601 // 5) Check for out of sequence for exceptions |
|
1602 // 6) Check for duration > rpt interval for series |
|
1603 |
|
1604 if( aRepeatTarget == CalCommon::EThisOnly ) |
|
1605 { |
|
1606 TError error = CheckForOutOfSequenceL(); |
|
1607 |
|
1608 if( error != EFormErrNone ) |
|
1609 { |
|
1610 // Revert start/end times |
|
1611 Edited().SetStartDateTimeL( Original().StartDateTime() ); |
|
1612 Edited().SetEndDateTimeL( Original().EndDateTime() ); |
|
1613 } |
|
1614 } |
|
1615 else if( aRepeatTarget == CalCommon::EThisAndAll ) |
|
1616 { |
|
1617 if( DurationGreaterThanRepeatIntervalError() ) |
|
1618 { |
|
1619 // Revert start/end times |
|
1620 Edited().SetStartDateTimeL( Original().StartDateTime() ); |
|
1621 Edited().SetEndDateTimeL( Original().EndDateTime() ); |
|
1622 } |
|
1623 } |
|
1624 |
|
1625 TRACE_EXIT_POINT; |
|
1626 } |
|
1627 |
|
1628 // ----------------------------------------------------------------------------- |
|
1629 // CCalenEditorDataHandler::IsOldEntry |
|
1630 // Returns ETrue if the entry was already created previously so that |
|
1631 // we are now editing it, returns EFalse otherwise. |
|
1632 // (other items were commented in a header). |
|
1633 // ----------------------------------------------------------------------------- |
|
1634 // |
|
1635 TBool CCalenEditorDataHandler::IsOldEntry() |
|
1636 { |
|
1637 TRACE_ENTRY_POINT; |
|
1638 |
|
1639 TRACE_EXIT_POINT; |
|
1640 return !IsCreatingNew(); |
|
1641 } |
|
1642 |
|
1643 // ----------------------------------------------------------------------------- |
|
1644 // CCalenEditorDataHandler::AreTextFieldsEmptyL |
|
1645 // Returns ETrue if summary && location && description text fields are all empty |
|
1646 // Returns EFalse otherwise. |
|
1647 // (other items were commented in a header). |
|
1648 // ----------------------------------------------------------------------------- |
|
1649 // |
|
1650 TBool CCalenEditorDataHandler::AreTextFieldsEmptyL() |
|
1651 { |
|
1652 TRACE_ENTRY_POINT; |
|
1653 |
|
1654 // We have to consider texts empty, if only summary is empty, in case |
|
1655 // location is not supported, because location can still exists in database. |
|
1656 TBool summaryAndDescriptionEmpty = CalenAgendaUtils::IsEmptyText( iEdited->Summary() ) && |
|
1657 CalenAgendaUtils::IsEmptyText( iEdited->Description() ); |
|
1658 |
|
1659 if(LocationEnabledInUiL()) |
|
1660 { |
|
1661 TRACE_EXIT_POINT; |
|
1662 return summaryAndDescriptionEmpty && CalenAgendaUtils::IsEmptyText( iEdited->Location() ); |
|
1663 } |
|
1664 |
|
1665 TRACE_EXIT_POINT; |
|
1666 |
|
1667 return summaryAndDescriptionEmpty; // and location is empty implicitly |
|
1668 } |
|
1669 |
|
1670 // ----------------------------------------------------------------------------- |
|
1671 // CCalenEditorDataHandler::AreTextFieldsClearedL |
|
1672 // Returns ETrue if the user cleared the text in the location and summary fields. |
|
1673 // (other items were commented in a header). |
|
1674 // ----------------------------------------------------------------------------- |
|
1675 // |
|
1676 TBool CCalenEditorDataHandler::AreTextFieldsClearedL() |
|
1677 { |
|
1678 TRACE_ENTRY_POINT; |
|
1679 |
|
1680 if ( CalenAgendaUtils::IsEmptyText( iEdited->Summary() ) && |
|
1681 CalenAgendaUtils::IsEmptyText( iEdited->Description() ) ) |
|
1682 { |
|
1683 if ( LocationEnabledInUiL() ) |
|
1684 { |
|
1685 if ( CalenAgendaUtils::IsEmptyText( iEdited->Location() ) ) |
|
1686 { |
|
1687 if ( IsSummaryEmptied() || IsDescriptionEmptied() || IsLocationEmptied() ) |
|
1688 { |
|
1689 TRACE_EXIT_POINT; |
|
1690 return ETrue; |
|
1691 } |
|
1692 } |
|
1693 } |
|
1694 |
|
1695 else if ( IsSummaryEmptied() || IsDescriptionEmptied() ) |
|
1696 { |
|
1697 TRACE_EXIT_POINT; |
|
1698 return ETrue; |
|
1699 } |
|
1700 } |
|
1701 |
|
1702 TRACE_EXIT_POINT; |
|
1703 |
|
1704 return EFalse; |
|
1705 } |
|
1706 |
|
1707 // ----------------------------------------------------------------------------- |
|
1708 // CCalenEditorDataHandler::IsDescriptionEmptied |
|
1709 // Returns ETrue, the description was not empty in original && is empty |
|
1710 // in the edited note |
|
1711 // Returns EFalse, otherwise |
|
1712 // (other items were commented in a header). |
|
1713 // ----------------------------------------------------------------------------- |
|
1714 TBool CCalenEditorDataHandler::IsDescriptionEmptied() |
|
1715 { |
|
1716 TRACE_ENTRY_POINT; |
|
1717 |
|
1718 if( !CalenAgendaUtils::IsEmptyText( iOriginal->Description() ) && |
|
1719 CalenAgendaUtils::IsEmptyText( iEdited->Description() ) ) |
|
1720 { |
|
1721 TRACE_EXIT_POINT; |
|
1722 return ETrue; |
|
1723 } |
|
1724 |
|
1725 TRACE_EXIT_POINT; |
|
1726 |
|
1727 return EFalse; |
|
1728 } |
|
1729 |
|
1730 // ----------------------------------------------------------------------------- |
|
1731 // CCalenEditorDataHandler::IsSummaryEmptied |
|
1732 // Returns ETrue, the summary was not empty in original && is empty |
|
1733 // in the edited note |
|
1734 // Returns EFalse, otherwise |
|
1735 // (other items were commented in a header). |
|
1736 // ----------------------------------------------------------------------------- |
|
1737 TBool CCalenEditorDataHandler::IsSummaryEmptied() |
|
1738 { |
|
1739 TRACE_ENTRY_POINT; |
|
1740 |
|
1741 if( !CalenAgendaUtils::IsEmptyText( iOriginal->Summary() ) && |
|
1742 CalenAgendaUtils::IsEmptyText( iEdited->Summary() ) ) |
|
1743 { |
|
1744 TRACE_EXIT_POINT; |
|
1745 return ETrue; |
|
1746 } |
|
1747 |
|
1748 TRACE_EXIT_POINT; |
|
1749 return EFalse; |
|
1750 } |
|
1751 |
|
1752 // ----------------------------------------------------------------------------- |
|
1753 // CCalenEditorDataHandler::IsLocationEmptied |
|
1754 // Returns ETrue, the summary was not empty in original && is empty |
|
1755 // in the edited note |
|
1756 // Returns EFalse, otherwise |
|
1757 // (other items were commented in a header). |
|
1758 // ----------------------------------------------------------------------------- |
|
1759 TBool CCalenEditorDataHandler::IsLocationEmptied() |
|
1760 { |
|
1761 TRACE_ENTRY_POINT; |
|
1762 |
|
1763 if( !CalenAgendaUtils::IsEmptyText( iOriginal->Location() ) && |
|
1764 CalenAgendaUtils::IsEmptyText( iEdited->Location() ) ) |
|
1765 { |
|
1766 TRACE_EXIT_POINT; |
|
1767 return ETrue; |
|
1768 } |
|
1769 |
|
1770 TRACE_EXIT_POINT; |
|
1771 return EFalse; |
|
1772 } |
|
1773 |
|
1774 // ----------------------------------------------------------------------------- |
|
1775 // CCalenEditorDataHandler::IsEntryTypeEdited |
|
1776 // Returns ETrue if the 'Entry Type' is edited, EFalse otherwise. |
|
1777 // (other items were commented in a header). |
|
1778 // ----------------------------------------------------------------------------- |
|
1779 // |
|
1780 TBool CCalenEditorDataHandler::IsEntryTypeEdited() |
|
1781 { |
|
1782 TRACE_ENTRY_POINT; |
|
1783 |
|
1784 TRACE_EXIT_POINT; |
|
1785 return iOriginal->EntryType() != iEdited->EntryType(); |
|
1786 } |
|
1787 |
|
1788 // ----------------------------------------------------------------------------- |
|
1789 // CCalenEditorDataHandler::IsStartDateTimeEdited |
|
1790 // Returns ETrue if the start date/time has been edited, EFalse otherwise. |
|
1791 // (other items were commented in a header). |
|
1792 // ----------------------------------------------------------------------------- |
|
1793 // |
|
1794 TBool CCalenEditorDataHandler::IsStartDateTimeEdited() |
|
1795 { |
|
1796 TRACE_ENTRY_POINT; |
|
1797 |
|
1798 TBool isEdited = EFalse; |
|
1799 |
|
1800 TTime orgTTime = iOriginal->StartDateTime(); |
|
1801 TTime editedTTime = iEdited->StartDateTime(); |
|
1802 |
|
1803 // Get TDateTime of Original & Edited entries. |
|
1804 TDateTime orgDT = orgTTime.DateTime(); |
|
1805 TDateTime editedDT = editedTTime.DateTime(); |
|
1806 |
|
1807 if( !IsTimedEntry() && IsCreatingNew() ) |
|
1808 { |
|
1809 // For non-timed event,on while creating new entry. |
|
1810 // check for only Date field change only. |
|
1811 if( orgDT.Day() != editedDT.Day() || |
|
1812 orgDT.Month() != editedDT.Month() || |
|
1813 orgDT.Year() != editedDT.Year() ) |
|
1814 { |
|
1815 isEdited = ETrue; |
|
1816 } |
|
1817 } |
|
1818 else |
|
1819 { |
|
1820 |
|
1821 // For timed entry, check for Entry Date/Time Changes |
|
1822 if( orgTTime != editedTTime ) |
|
1823 { |
|
1824 isEdited = ETrue; |
|
1825 } |
|
1826 } |
|
1827 |
|
1828 TRACE_EXIT_POINT; |
|
1829 return isEdited; |
|
1830 |
|
1831 //return iOriginal->StartDateTime() != iEdited->StartDateTime(); |
|
1832 |
|
1833 } |
|
1834 |
|
1835 // ----------------------------------------------------------------------------- |
|
1836 // CCalenEditorDataHandler::IsEndDateTimeEdited |
|
1837 // Returns ETrue if the end date/time has been edited, EFalse otherwise. |
|
1838 // (other items were commented in a header). |
|
1839 // ----------------------------------------------------------------------------- |
|
1840 // |
|
1841 TBool CCalenEditorDataHandler::IsEndDateTimeEdited() |
|
1842 { |
|
1843 TRACE_ENTRY_POINT; |
|
1844 TBool isEdited = EFalse; |
|
1845 |
|
1846 TTime orgTTime = iOriginal->EndDateTime(); |
|
1847 TTime editedTTime = iEdited->EndDateTime(); |
|
1848 |
|
1849 // Get TDateTime of Original & Edited entries. |
|
1850 TDateTime orgDT = orgTTime.DateTime(); |
|
1851 TDateTime editedDT = editedTTime.DateTime(); |
|
1852 |
|
1853 if( !IsTimedEntry() && IsCreatingNew() ) |
|
1854 { |
|
1855 |
|
1856 // For non-timed event, check for only Date field change. |
|
1857 // No need to check for Entry time change. |
|
1858 if( orgDT.Day() != editedDT.Day() || |
|
1859 orgDT.Month() != editedDT.Month() || |
|
1860 orgDT.Year() != editedDT.Year() ) |
|
1861 { |
|
1862 isEdited = ETrue; |
|
1863 } |
|
1864 } |
|
1865 else |
|
1866 { |
|
1867 // For timed entry, check for Entry Date/Time Changes |
|
1868 if( orgTTime != editedTTime ) |
|
1869 { |
|
1870 isEdited = ETrue; |
|
1871 } |
|
1872 } |
|
1873 |
|
1874 TRACE_EXIT_POINT; |
|
1875 return isEdited; |
|
1876 |
|
1877 //return iOriginal->EndDateTime() != iEdited->EndDateTime(); |
|
1878 } |
|
1879 |
|
1880 // ----------------------------------------------------------------------------- |
|
1881 // CCalenEditorDataHandler::IsDescriptionEdited |
|
1882 // Returns ETrue if the description has been modified, EFalse otherwise. |
|
1883 // (other items were commented in a header). |
|
1884 // ----------------------------------------------------------------------------- |
|
1885 // |
|
1886 TBool CCalenEditorDataHandler::IsDescriptionEdited() |
|
1887 { |
|
1888 TRACE_ENTRY_POINT; |
|
1889 |
|
1890 TRACE_EXIT_POINT; |
|
1891 return iOriginal->Description() != iEdited->Description(); |
|
1892 } |
|
1893 |
|
1894 // ----------------------------------------------------------------------------- |
|
1895 // CCalenEditorDataHandler::IsPriorityEdited |
|
1896 // Returns ETrue if the priotity has been modified, EFalse otherwise. |
|
1897 // (other items were commented in a header). |
|
1898 // ----------------------------------------------------------------------------- |
|
1899 // |
|
1900 TBool CCalenEditorDataHandler::IsPriorityEdited() |
|
1901 { |
|
1902 TRACE_ENTRY_POINT; |
|
1903 |
|
1904 TRACE_EXIT_POINT; |
|
1905 return iOriginal->Priority() != iEdited->Priority(); |
|
1906 } |
|
1907 |
|
1908 // ----------------------------------------------------------------------------- |
|
1909 // CCalenEditorDataHandler::IsCalendarEditedL |
|
1910 // Returns ETrue if the calendar filed has been edited, EFalse otherwise. |
|
1911 // (other items were commented in a header). |
|
1912 // ----------------------------------------------------------------------------- |
|
1913 // |
|
1914 TBool CCalenEditorDataHandler::IsCalendarEditedL() |
|
1915 { |
|
1916 TRACE_ENTRY_POINT; |
|
1917 |
|
1918 TRACE_EXIT_POINT; |
|
1919 return iCalendarFieldEdited; |
|
1920 } |
|
1921 |
|
1922 // ----------------------------------------------------------------------------- |
|
1923 // CCalenEditorDataHandler::IsSummaryEdited |
|
1924 // Returns ETrue if the summary has been edited, EFalse otherwise. |
|
1925 // (other items were commented in a header). |
|
1926 // ----------------------------------------------------------------------------- |
|
1927 // |
|
1928 TBool CCalenEditorDataHandler::IsSummaryEdited() |
|
1929 { |
|
1930 TRACE_ENTRY_POINT; |
|
1931 |
|
1932 // For summary and location, we compare only that part of text |
|
1933 // that fits to editor. If it's equal, then we don't go and unnecessarily |
|
1934 // truncate existing data. |
|
1935 TRACE_EXIT_POINT; |
|
1936 return ( iOriginal->Summary().Left( iMaxTextEditorLength ) |
|
1937 != iEdited->Summary().Left( iMaxTextEditorLength ) ); |
|
1938 } |
|
1939 |
|
1940 // ----------------------------------------------------------------------------- |
|
1941 // CCalenEditorDataHandler::IsLocationEdited |
|
1942 // Returns ETrue if the location has been edited, EFalse otherwise. |
|
1943 // (other items were commented in a header). |
|
1944 // ----------------------------------------------------------------------------- |
|
1945 // |
|
1946 TBool CCalenEditorDataHandler::IsLocationEdited() |
|
1947 { |
|
1948 TRACE_ENTRY_POINT; |
|
1949 |
|
1950 // For summary and location, we compare only that part of text |
|
1951 // that fits to editor. If it's equal, then we don't go and unnecessarily |
|
1952 // truncate existing data. |
|
1953 TRACE_EXIT_POINT; |
|
1954 return ( iOriginal->Location().Left( iMaxTextEditorLength ) |
|
1955 != iEdited->Location().Left( iMaxTextEditorLength ) ); |
|
1956 } |
|
1957 |
|
1958 // ----------------------------------------------------------------------------- |
|
1959 // CCalenEditorDataHandler::IsAlarmEditedL |
|
1960 // Returns ETrue if the alarm has been edited, EFalse otherwise. |
|
1961 // (other items were commented in a header). |
|
1962 // ----------------------------------------------------------------------------- |
|
1963 // |
|
1964 TBool CCalenEditorDataHandler::IsAlarmEditedL() |
|
1965 { |
|
1966 TRACE_ENTRY_POINT; |
|
1967 |
|
1968 if ( iOriginal->IsAlarmActivated() && iEdited->IsAlarmActivated() ) |
|
1969 { |
|
1970 // The alarm must be flagged as changed if the interval between the entry start |
|
1971 // and the alarm is different. (We can't just compare alarm times directly because |
|
1972 // the start date of the entry may have changed.) |
|
1973 TTimeIntervalMinutes origOffset, editedOffset; |
|
1974 |
|
1975 User::LeaveIfError( iOriginal->AlarmDateTime().MinutesFrom( iOriginal->StartDateTime(), origOffset ) ); |
|
1976 User::LeaveIfError( iEdited->AlarmDateTime().MinutesFrom( iEdited->StartDateTime(), editedOffset ) ); |
|
1977 |
|
1978 TBool alarmTimeChanged = origOffset != editedOffset; |
|
1979 |
|
1980 TRACE_EXIT_POINT; |
|
1981 return alarmTimeChanged; |
|
1982 } |
|
1983 else |
|
1984 { |
|
1985 TBool statusChanged = iOriginal->IsAlarmActivated() != iEdited->IsAlarmActivated(); |
|
1986 |
|
1987 TRACE_EXIT_POINT; |
|
1988 return statusChanged; |
|
1989 } |
|
1990 } |
|
1991 |
|
1992 // ----------------------------------------------------------------------------- |
|
1993 // CCalenEditorDataHandler::IsRepeatRuleEdited |
|
1994 // Returns ETrue if the repeat rule has been edited, EFalse otherwise. |
|
1995 // (other items were commented in a header). |
|
1996 // ----------------------------------------------------------------------------- |
|
1997 // |
|
1998 TBool CCalenEditorDataHandler::IsRepeatRuleEdited() |
|
1999 { |
|
2000 TRACE_ENTRY_POINT; |
|
2001 |
|
2002 if ( iOriginal->IsRepeating() && iEdited->IsRepeating() ) |
|
2003 { |
|
2004 TBool repeatTypeChanged = iOriginal->RepeatType() != iEdited->RepeatType(); |
|
2005 TBool untilDateChanged = iOriginal->RepeatUntilDateTime() != iEdited->RepeatUntilDateTime(); |
|
2006 |
|
2007 TRACE_EXIT_POINT; |
|
2008 return repeatTypeChanged || untilDateChanged; |
|
2009 } |
|
2010 else |
|
2011 { |
|
2012 TBool statusChanged = iOriginal->IsRepeating() != iEdited->IsRepeating(); |
|
2013 |
|
2014 TRACE_EXIT_POINT; |
|
2015 return statusChanged; |
|
2016 } |
|
2017 } |
|
2018 |
|
2019 // ----------------------------------------------------------------------------- |
|
2020 // CCalenEditorDataHandler::LocationEnabledInUiL |
|
2021 // Returns ETrue if the location is a valid field for this type of entry |
|
2022 // (i.e. meetings & reminders only), EFalse otherwise. |
|
2023 // (other items were commented in a header). |
|
2024 // ----------------------------------------------------------------------------- |
|
2025 // |
|
2026 TBool CCalenEditorDataHandler::LocationEnabledInUiL() |
|
2027 { |
|
2028 TRACE_ENTRY_POINT; |
|
2029 |
|
2030 // Location is enabled for timed entries (i.e. an appointment or a |
|
2031 // reminder) |
|
2032 TRACE_EXIT_POINT; |
|
2033 return IsTimedEntry(); |
|
2034 } |
|
2035 |
|
2036 // ----------------------------------------------------------------------------- |
|
2037 // CCalenEditorDataHandler::IsTimedEntry |
|
2038 // Returns ETrue if this is a timed entry, EFalse otherwise. |
|
2039 // (other items were commented in a header). |
|
2040 // ----------------------------------------------------------------------------- |
|
2041 // |
|
2042 TBool CCalenEditorDataHandler::IsTimedEntry() const |
|
2043 { |
|
2044 TRACE_ENTRY_POINT; |
|
2045 |
|
2046 TRACE_EXIT_POINT; |
|
2047 return IsTimed( iEdited->EntryType() ); |
|
2048 } |
|
2049 |
|
2050 // ----------------------------------------------------------------------------- |
|
2051 // CCalenEditorDataHandler::IsCreatingNew |
|
2052 // Returns ETrue if the user is creating a new entry, EFalse if the user is |
|
2053 // editing an existing entry. |
|
2054 // (other items were commented in a header). |
|
2055 // ----------------------------------------------------------------------------- |
|
2056 // |
|
2057 TBool CCalenEditorDataHandler::IsCreatingNew() const |
|
2058 { |
|
2059 TRACE_ENTRY_POINT; |
|
2060 |
|
2061 TRACE_EXIT_POINT; |
|
2062 return iIsCreatingNew; |
|
2063 } |
|
2064 |
|
2065 // ----------------------------------------------------------------------------- |
|
2066 // CCalenEditorDataHandler::IsStartDateChanged |
|
2067 // Returns ETrue if the start date of the entry has been changed, |
|
2068 // EFalse otherwise. Note that this function only checks the date, |
|
2069 // and not the time of day, of the entry. |
|
2070 // (other items were commented in a header). |
|
2071 // ----------------------------------------------------------------------------- |
|
2072 // |
|
2073 TBool CCalenEditorDataHandler::IsStartDateChanged() |
|
2074 { |
|
2075 TRACE_ENTRY_POINT; |
|
2076 |
|
2077 TRACE_EXIT_POINT; |
|
2078 return ! CalenDateUtils::OnSameDay( iOriginal->StartDateTime(), |
|
2079 iEdited->StartDateTime() ); |
|
2080 } |
|
2081 |
|
2082 // ----------------------------------------------------------------------------- |
|
2083 // CCalenEditorDataHandler::IsAttachmentExists |
|
2084 // Returns ETrue calendar entry is having attachments |
|
2085 // (other items were commented in a header). |
|
2086 // ----------------------------------------------------------------------------- |
|
2087 // |
|
2088 TBool CCalenEditorDataHandler::IsAttachmentExists() |
|
2089 { |
|
2090 TRACE_ENTRY_POINT; |
|
2091 TBool attachmentExits(EFalse); |
|
2092 |
|
2093 // TODO: Uncomment this when enabling attachment support |
|
2094 |
|
2095 if( (iOriginal->AttachmentCount() != iEdited->AttachmentCount()) |
|
2096 || iServices.GetAttachmentData()->NumberOfItems() ) |
|
2097 { |
|
2098 attachmentExits = ETrue; |
|
2099 } |
|
2100 |
|
2101 TRACE_EXIT_POINT; |
|
2102 return attachmentExits; |
|
2103 } |
|
2104 |
|
2105 // ----------------------------------------------------------------------------- |
|
2106 // CCalenEditorDataHandler::IsEventTypeEdited |
|
2107 // (other items were commented in a header). |
|
2108 // ----------------------------------------------------------------------------- |
|
2109 // |
|
2110 TBool CCalenEditorDataHandler::IsEventTypeEdited() |
|
2111 { |
|
2112 TRACE_ENTRY_POINT; |
|
2113 TBool fieldModified = EFalse; |
|
2114 |
|
2115 // Check EventType field is edited for already saved Entry |
|
2116 // For Newly created entry, ignore the EventTypeChange |
|
2117 if( (iOriginal->EntryType() != iEdited->EntryType()) && !IsCreatingNew() ) |
|
2118 { |
|
2119 fieldModified = ETrue; |
|
2120 } |
|
2121 |
|
2122 TRACE_EXIT_POINT; |
|
2123 return fieldModified; |
|
2124 } |
|
2125 |
|
2126 // ----------------------------------------------------------------------------- |
|
2127 // CCalenEditorDataHandler::AllDayFieldEdited |
|
2128 // Returns ETrue if `All day event' line has been modified. |
|
2129 // (other items were commented in a header). |
|
2130 // ----------------------------------------------------------------------------- |
|
2131 // |
|
2132 TBool CCalenEditorDataHandler::AllDayFieldEdited() |
|
2133 { |
|
2134 TRACE_ENTRY_POINT; |
|
2135 TBool fieldModified = EFalse; |
|
2136 |
|
2137 if( iOriginal->IsAllDayEvent() != iEdited->IsAllDayEvent() ) |
|
2138 { |
|
2139 fieldModified = ETrue; |
|
2140 } |
|
2141 |
|
2142 TRACE_EXIT_POINT; |
|
2143 return fieldModified; |
|
2144 } |
|
2145 |
|
2146 // ----------------------------------------------------------------------------- |
|
2147 // CCalenEditorDataHandler::SetDefaultAlarmDateTimeL |
|
2148 // Sets the alarm to the default value. This function is called after the user |
|
2149 // forces an exit, e.g. when pressing the power off button. |
|
2150 // (other items were commented in a header). |
|
2151 // ----------------------------------------------------------------------------- |
|
2152 // |
|
2153 void CCalenEditorDataHandler::SetDefaultAlarmDateTimeL() |
|
2154 { |
|
2155 TRACE_ENTRY_POINT; |
|
2156 |
|
2157 /** |
|
2158 * Default alarm time is UI spec logic. |
|
2159 * It is important that this is here, because there shouldn't be UI spec logic in CCalenEntryUtil, |
|
2160 * only in CCalenEditorDataHandler. |
|
2161 * |
|
2162 * It is still a bit odd, that other set methods are in CCalenEntryUtil but not here. |
|
2163 * Maybe I add wrapper set methods for edited data also in *Handler. |
|
2164 * e.g. void SetAlarmOffL() { Edited().SetAlarmOffL(); } |
|
2165 * |
|
2166 */ |
|
2167 TTime defaultAlarm; |
|
2168 |
|
2169 if ( IsTimedEntry() ) |
|
2170 { |
|
2171 TTimeIntervalMinutes defaultOffsetM( 15 ); // FIXME: should be read from central repository |
|
2172 defaultAlarm = Edited().StartDateTime() - defaultOffsetM; |
|
2173 } |
|
2174 else |
|
2175 { |
|
2176 TTimeIntervalHours defaultOffsetH( -8 ); |
|
2177 defaultAlarm = CalenDateUtils::BeginningOfDay( Edited().EventDateTime() ) - defaultOffsetH; |
|
2178 } |
|
2179 |
|
2180 Edited().SetAlarmOnL( defaultAlarm ); |
|
2181 |
|
2182 TRACE_EXIT_POINT; |
|
2183 } |
|
2184 |
|
2185 // ----------------------------------------------------------------------------- |
|
2186 // CCalenEditorDataHandler::CalculateRepeatRuleL |
|
2187 // Calculates the repeat rule for a given entry. |
|
2188 // (other items were commented in a header). |
|
2189 // ----------------------------------------------------------------------------- |
|
2190 // |
|
2191 void CCalenEditorDataHandler::CalculateRepeatRuleL( |
|
2192 const TTime& aStartDateTime, |
|
2193 TCalenRepeatIndex aNewRepeatType, |
|
2194 const TTime& aRepeatUntil, |
|
2195 TCalRRule& aRRule) |
|
2196 { |
|
2197 TRACE_ENTRY_POINT; |
|
2198 |
|
2199 // FIXME: This is copy-pasted from old implementation. |
|
2200 // This should be rewritten with care. |
|
2201 //If it ain't broke...? |
|
2202 TTime startDateTime = aStartDateTime; |
|
2203 TTime repeatUntil = aRepeatUntil; |
|
2204 |
|
2205 TCalRRule origRRule; |
|
2206 TBool hasOrigRRule = iEntry.GetRRuleL( origRRule ); |
|
2207 |
|
2208 TBool isStartDateSame = CalenDateUtils::OnSameDay( |
|
2209 Original().StartDateTime(), Edited().StartDateTime() ); |
|
2210 |
|
2211 // |
|
2212 // If repeat type is changed, repeat start date |
|
2213 // is replaced to the date of "Start date" field. |
|
2214 // |
|
2215 if ( hasOrigRRule && |
|
2216 isStartDateSame && |
|
2217 aNewRepeatType == Original().RepeatType() ) |
|
2218 { |
|
2219 aRRule = origRRule; // keep the original setting... |
|
2220 // until date changed? |
|
2221 } |
|
2222 else if (aNewRepeatType == ERepeatOther) |
|
2223 { |
|
2224 // prevRptDef is ALWAYS non-NULL in this block, |
|
2225 // because previous note's repeat ALWAYS exists. |
|
2226 aRRule = origRRule; |
|
2227 TCalTime repeatStart; |
|
2228 if ( UseFloatingTimeL() ) |
|
2229 { |
|
2230 repeatStart.SetTimeLocalFloatingL( startDateTime ); |
|
2231 } |
|
2232 else |
|
2233 { |
|
2234 repeatStart.SetTimeLocalL( startDateTime ); |
|
2235 } |
|
2236 aRRule.SetDtStart( repeatStart ); |
|
2237 } |
|
2238 else |
|
2239 { |
|
2240 TCalTime repeatSt; |
|
2241 if ( UseFloatingTimeL() ) |
|
2242 { |
|
2243 repeatSt.SetTimeLocalFloatingL( startDateTime ); |
|
2244 } |
|
2245 else |
|
2246 { |
|
2247 repeatSt.SetTimeLocalL( startDateTime ); |
|
2248 } |
|
2249 aRRule.SetDtStart( repeatSt ); |
|
2250 aRRule.SetInterval( 1 ); |
|
2251 |
|
2252 TInt interval(1); |
|
2253 |
|
2254 switch ( aNewRepeatType ) |
|
2255 { |
|
2256 case (ERepeatDaily): // Daily |
|
2257 { |
|
2258 aRRule.SetType( TCalRRule::EDaily ); |
|
2259 break; |
|
2260 } |
|
2261 case (ERepeatWeekly): // Weekly |
|
2262 { |
|
2263 if (hasOrigRRule && origRRule.Type() == TCalRRule::EDaily && |
|
2264 origRRule.Interval() == 7) |
|
2265 { |
|
2266 // If old note's repeat is every 7 days, |
|
2267 // set repeat to every 7 days to Agenda, NOT every week. |
|
2268 // |
|
2269 aRRule.SetType( TCalRRule::EDaily ); |
|
2270 interval = 7; |
|
2271 } |
|
2272 else |
|
2273 { |
|
2274 aRRule.SetType( TCalRRule::EWeekly ); |
|
2275 |
|
2276 RArray<TDay> dayArray; |
|
2277 CleanupClosePushL( dayArray ); |
|
2278 dayArray.Append( aRRule.DtStart().TimeLocalL().DayNoInWeek() ); |
|
2279 aRRule.SetByDay( dayArray ); |
|
2280 CleanupStack::PopAndDestroy( &dayArray ); |
|
2281 } |
|
2282 break; |
|
2283 } |
|
2284 case (ERepeatBiWeekly): // Bi-weekly |
|
2285 { |
|
2286 if ( hasOrigRRule && origRRule.Type() == TCalRRule::EDaily && |
|
2287 origRRule.Interval() == 14) |
|
2288 { |
|
2289 // If old note's repeat is every 14 days, |
|
2290 // set repeat to every 14 days to Agenda, NOT every 2 weeks. |
|
2291 // |
|
2292 aRRule.SetType( TCalRRule::EDaily ); |
|
2293 interval = 14; |
|
2294 } |
|
2295 else |
|
2296 { |
|
2297 aRRule.SetType( TCalRRule::EWeekly ); |
|
2298 interval = 2; |
|
2299 |
|
2300 RArray<TDay> dayArray; |
|
2301 CleanupClosePushL( dayArray ); |
|
2302 dayArray.Append( aRRule.DtStart().TimeLocalL().DayNoInWeek() ); |
|
2303 aRRule.SetByDay( dayArray ); |
|
2304 CleanupStack::PopAndDestroy( &dayArray ); |
|
2305 } |
|
2306 break; |
|
2307 } |
|
2308 case ERepeatWorkdays:// Weekly |
|
2309 { |
|
2310 TLocale iLocale; |
|
2311 TUint iWorkDays = iLocale.WorkDays(); |
|
2312 if (hasOrigRRule && origRRule.Type() == TCalRRule::EDaily |
|
2313 && origRRule.Interval() == 7) |
|
2314 { |
|
2315 // If old note's repeat is every 7 days, |
|
2316 // set repeat to every 7 days to Agenda, NOT every week. |
|
2317 // |
|
2318 aRRule.SetType(TCalRRule::EDaily); |
|
2319 interval = 7; |
|
2320 } |
|
2321 else |
|
2322 { |
|
2323 aRRule.SetType(TCalRRule::EWeekly); |
|
2324 RArray<TDay> dayArray; |
|
2325 CleanupClosePushL(dayArray); |
|
2326 TInt fixedNum = 1; |
|
2327 TInt ruleday = 0; |
|
2328 for (TInt i =0 ; i < KNoOfDaysInWeek ; i++) |
|
2329 { |
|
2330 ruleday = fixedNum << i; |
|
2331 if(iWorkDays & ruleday) |
|
2332 { |
|
2333 dayArray.Append((TDay)i); |
|
2334 aRRule.SetByDay(dayArray); |
|
2335 } |
|
2336 } |
|
2337 CleanupStack::PopAndDestroy(&dayArray); |
|
2338 } |
|
2339 break; |
|
2340 |
|
2341 } |
|
2342 case (ERepeatMonthly): |
|
2343 // Monthly By Position |
|
2344 { |
|
2345 aRRule.SetType( TCalRRule::EMonthly ); |
|
2346 |
|
2347 RArray<TInt> dateArray; |
|
2348 CleanupClosePushL( dateArray ); |
|
2349 dateArray.Append( aRRule.DtStart().TimeLocalL().DayNoInMonth() ); |
|
2350 aRRule.SetByMonthDay( dateArray ); |
|
2351 CleanupStack::PopAndDestroy( &dateArray ); |
|
2352 |
|
2353 break; |
|
2354 } |
|
2355 case (ERepeatYearly): // Yearly |
|
2356 { |
|
2357 // If old note's repeat is every 12 months, |
|
2358 // set repeat to every 12 months to Agenda, NOT every year. |
|
2359 // |
|
2360 if ( hasOrigRRule && origRRule.Type() == TCalRRule::EMonthly && |
|
2361 origRRule.Interval() == 12) |
|
2362 { |
|
2363 aRRule.SetType( TCalRRule::EMonthly ); |
|
2364 interval = 12; |
|
2365 } |
|
2366 else |
|
2367 { |
|
2368 aRRule.SetType( TCalRRule::EYearly ); |
|
2369 } |
|
2370 break; |
|
2371 } |
|
2372 default: // Repeat item is "Other" |
|
2373 { |
|
2374 interval = aRRule.Interval(); // To copy previous note's interval |
|
2375 break; |
|
2376 } |
|
2377 } |
|
2378 |
|
2379 aRRule.SetInterval( interval ); |
|
2380 } |
|
2381 |
|
2382 // If repeat until is max date of Calendar, |
|
2383 // note repeat is set to forever. |
|
2384 if ( ! CalenDateUtils::IsValidDay(repeatUntil) || IsForeverDate( repeatUntil ) ) |
|
2385 { |
|
2386 // Set repeat to forever: |
|
2387 aRRule.SetCount( 0 ); |
|
2388 } |
|
2389 else |
|
2390 { |
|
2391 // Change repeatuntil so that hours, minutes, ... are same as in start date |
|
2392 TDateTime dtUntil = repeatUntil.DateTime(); |
|
2393 TDateTime dtStart= iEntry.StartTimeL().TimeLocalL().DateTime(); |
|
2394 |
|
2395 dtUntil.Set( dtUntil.Year(), dtUntil.Month(), dtUntil.Day(), |
|
2396 dtStart.Hour(), dtStart.Minute(), dtStart.Second(), dtStart.MicroSecond()); |
|
2397 |
|
2398 TCalTime calRepeatUntil; |
|
2399 if ( UseFloatingTimeL() ) |
|
2400 { |
|
2401 calRepeatUntil.SetTimeLocalFloatingL( TTime( dtUntil ) ); |
|
2402 } |
|
2403 else |
|
2404 { |
|
2405 calRepeatUntil.SetTimeLocalL( TTime( dtUntil ) ); |
|
2406 } |
|
2407 aRRule.SetUntil( calRepeatUntil ); |
|
2408 } |
|
2409 |
|
2410 TRACE_EXIT_POINT; |
|
2411 } |
|
2412 |
|
2413 // ----------------------------------------------------------------------------- |
|
2414 // CCalenEditorDataHandler::SetDefaultNewValuesL |
|
2415 // Sets the default values when creating a new entry. |
|
2416 // (other items were commented in a header). |
|
2417 // ----------------------------------------------------------------------------- |
|
2418 // |
|
2419 void CCalenEditorDataHandler::SetDefaultNewValuesL(CCalenEntryUtil& aData) |
|
2420 { |
|
2421 TRACE_ENTRY_POINT; |
|
2422 |
|
2423 // FIXME: I don't know if this method should be needed or not. |
|
2424 // It's a bit unclear that if pass entry that is new, |
|
2425 // should we set default data in caller (application) or |
|
2426 // here. |
|
2427 // But to replicate old editor functionality, we set in editor |
|
2428 // side |
|
2429 |
|
2430 ASSERT( IsCreatingNew() ); |
|
2431 // start time and end time are taken from passed entry. |
|
2432 // They have to be initialized outside of editors |
|
2433 |
|
2434 // subject, location, description are by default empty |
|
2435 |
|
2436 // repeat rule is by default off |
|
2437 |
|
2438 // alarm is by default off |
|
2439 |
|
2440 // synch value |
|
2441 aData.SetSynchTypeL( CCalenEntryUtil::ESynchPrivate ); |
|
2442 |
|
2443 // priority |
|
2444 aData.SetPriorityL( CCalenEntryUtil::ETodoPriorityNormal ); |
|
2445 |
|
2446 TRACE_EXIT_POINT; |
|
2447 } |
|
2448 |
|
2449 // ----------------------------------------------------------------------------- |
|
2450 // CCalenEditorDataHandler::IsChildL |
|
2451 // Returns ETrue if the entry is a child, EFalse otherwise. |
|
2452 // (other items were commented in a header). |
|
2453 // ----------------------------------------------------------------------------- |
|
2454 // |
|
2455 TBool CCalenEditorDataHandler::IsChildL() const |
|
2456 { |
|
2457 TRACE_ENTRY_POINT; |
|
2458 |
|
2459 TRACE_EXIT_POINT; |
|
2460 return iRecurrenceId.TimeUtcL() != Time::NullTTime(); |
|
2461 } |
|
2462 |
|
2463 // ----------------------------------------------------------------------------- |
|
2464 // CCalenEditorDataHandler::UseFloatingTimeL |
|
2465 // Returns ETrue if the entry should use floating time, EFalse otherwise. |
|
2466 // (other items were commented in a header). |
|
2467 // ----------------------------------------------------------------------------- |
|
2468 // |
|
2469 TBool CCalenEditorDataHandler::UseFloatingTimeL() const |
|
2470 { |
|
2471 TRACE_ENTRY_POINT; |
|
2472 |
|
2473 // Use floating time based on type |
|
2474 // This way we ensure that entries _created_ with Calendar Editors |
|
2475 // are consistent regarding time mode. |
|
2476 // |
|
2477 TRACE_EXIT_POINT; |
|
2478 return (! IsTimedEntry()); // use floating time for non-timed entries |
|
2479 |
|
2480 } |
|
2481 |
|
2482 // ----------------------------------------------------------------------------- |
|
2483 // CCalenEditorDataHandler::WriteStartAndEndTimesToEntryL |
|
2484 // Writes the start and end times from the form to the CCalEntry. |
|
2485 // (other items were commented in a header). |
|
2486 // ----------------------------------------------------------------------------- |
|
2487 // |
|
2488 void CCalenEditorDataHandler::WriteStartAndEndTimesToEntryL( CalCommon::TRecurrenceRange aRepeatTarget ) |
|
2489 { |
|
2490 TRACE_ENTRY_POINT; |
|
2491 |
|
2492 const TBool unDatedTodo=(iEntry.EntryTypeL()==CCalEntry::ETodo) && (iEntry.EndTimeL().TimeLocalL()==Time::NullTTime()); |
|
2493 const TBool unDatedTodoWithAlarm=unDatedTodo && (Edited().IsAlarmActivated()); |
|
2494 |
|
2495 TBool shouldWriteBothTimes = |
|
2496 // For new entries |
|
2497 IsCreatingNew() || |
|
2498 // When creating exception entry (exception entry's time are read from editors) |
|
2499 ( aRepeatTarget != CalCommon::EThisAndAll ) || |
|
2500 // when repeating entry is modified to be non-repeating (entry's times are read from editors) |
|
2501 ( Original().IsRepeating() && ! Edited().IsRepeating() ); |
|
2502 |
|
2503 if ( shouldWriteBothTimes || IsStartDateTimeEdited() || IsEndDateTimeEdited() || unDatedTodoWithAlarm ) |
|
2504 { |
|
2505 |
|
2506 TCalTime entryStart; |
|
2507 TCalTime entryEnd; |
|
2508 |
|
2509 // 1) Initialize entryStart and entryEnd with original times. |
|
2510 // But for todos we need to be careful, because there might not be them originally |
|
2511 // In S60 UI, todos don't have starttime, so we use same for both start and end time. |
|
2512 if (iEntry.EntryTypeL()==CCalEntry::ETodo) |
|
2513 { |
|
2514 // if undated todo and it has alarm activated |
|
2515 if ((iEntry.EndTimeL().TimeLocalL()==Time::NullTTime()) && (Edited().IsAlarmActivated())) |
|
2516 { |
|
2517 entryStart.SetTimeLocalL(Edited().EventDateTime()); |
|
2518 entryEnd.SetTimeLocalL(Edited().EventDateTime()); |
|
2519 shouldWriteBothTimes=ETrue; // Ensures that times are written later |
|
2520 } |
|
2521 else |
|
2522 { |
|
2523 entryStart = iEntry.EndTimeL(); |
|
2524 entryEnd = iEntry.EndTimeL(); |
|
2525 } |
|
2526 } |
|
2527 else |
|
2528 { |
|
2529 entryStart = iEntry.StartTimeL(); |
|
2530 entryEnd = iEntry.EndTimeL(); |
|
2531 } |
|
2532 |
|
2533 // 2) Decide start time |
|
2534 if ( shouldWriteBothTimes || IsStartDateTimeEdited() ) |
|
2535 { |
|
2536 TTime newStart = Edited().StartDateTime(); |
|
2537 TDateTime newStartDT = newStart.DateTime(); |
|
2538 // Special case: |
|
2539 // In case c) only start time (hh:mm) of d) existing a) repeating b) series is edited, |
|
2540 // we need to preserve start date (dd.mm.yyy), because start date in editors |
|
2541 // is instance's start date. |
|
2542 // (Example of problematic cases that brings up, when UI represents |
|
2543 // two different concepts in same start date field) |
|
2544 // a) repeating b) series is edited c) only start time is edited d) existing |
|
2545 if ( Edited().IsRepeating() && aRepeatTarget == CalCommon::EThisAndAll && ! IsStartDateChanged() && ! IsCreatingNew() ) |
|
2546 { |
|
2547 TDateTime oldDt = iEntry.StartTimeL().TimeLocalL().DateTime(); |
|
2548 TDateTime editDt = newStart.DateTime(); |
|
2549 newStart = TTime( TDateTime( oldDt.Year(), oldDt.Month(), oldDt.Day(), |
|
2550 editDt.Hour(), editDt.Minute(), |
|
2551 oldDt.Second(), oldDt.MicroSecond() ) ); |
|
2552 } |
|
2553 else if ( ( Edited().RepeatType() == ERepeatOther ) && IsStartDateChanged() ) |
|
2554 { |
|
2555 // The start time might have been disguised because the entry |
|
2556 // consists of an rRule and rDates. The actual start time |
|
2557 // needs to be extracted |
|
2558 RArray<TCalTime> rDates; |
|
2559 CleanupClosePushL( rDates ); |
|
2560 |
|
2561 iEntry.GetRDatesL( rDates ); |
|
2562 if ( rDates.Count() > 0 ) |
|
2563 { |
|
2564 // As we have rDates, check to see if there is an |
|
2565 // rRule |
|
2566 TCalRRule rRule; |
|
2567 if ( iEntry.GetRRuleL( rRule ) ) |
|
2568 { |
|
2569 TTime firstRDate = rDates[ 0 ].TimeLocalL(); |
|
2570 TTime rRuleStart = iEntry.StartTimeL().TimeLocalL(); |
|
2571 TTime lastRDate = rDates[ rDates.Count() - 1 ].TimeLocalL(); |
|
2572 TTimeIntervalMinutes startDateShiftInterval = 0; |
|
2573 if ( firstRDate < rRuleStart ) |
|
2574 { |
|
2575 // The first rDate is before the start of the rRule |
|
2576 // So adjust the start date accordingly |
|
2577 |
|
2578 User::LeaveIfError( newStart.MinutesFrom( firstRDate, startDateShiftInterval ) ); |
|
2579 } |
|
2580 else |
|
2581 { |
|
2582 // The start of the rRule comes first |
|
2583 User::LeaveIfError( newStart.MinutesFrom( rRuleStart, startDateShiftInterval ) ); |
|
2584 } |
|
2585 |
|
2586 newStart = rRuleStart + startDateShiftInterval; |
|
2587 |
|
2588 TInt rRuleCount = rRule.Count(); |
|
2589 rRule.SetCount( rRuleCount ); |
|
2590 |
|
2591 TCalTime rRuleDT; |
|
2592 if ( UseFloatingTimeL() ) |
|
2593 { |
|
2594 rRuleDT.SetTimeLocalFloatingL( newStart ); |
|
2595 } |
|
2596 else |
|
2597 { |
|
2598 rRuleDT.SetTimeLocalL( newStart ); |
|
2599 } |
|
2600 |
|
2601 rRule.SetDtStart( rRuleDT ); |
|
2602 |
|
2603 // For rearranging the recurrence pattern for an |
|
2604 // entry having rdates |
|
2605 |
|
2606 TInt repeatType = rRule.Type(); |
|
2607 switch ( repeatType ) |
|
2608 { |
|
2609 case ( TCalRRule::EWeekly ): //For Weekly repeating event |
|
2610 { |
|
2611 RArray<TDay> dayArray; |
|
2612 CleanupClosePushL( dayArray ); |
|
2613 dayArray.Append( rRule.DtStart().TimeLocalL().DayNoInWeek() ); |
|
2614 rRule.SetByDay( dayArray ); |
|
2615 CleanupStack::PopAndDestroy( &dayArray ); |
|
2616 |
|
2617 // Adjust the RepeatUntil date |
|
2618 ApplyUntilDateToRRuleL( rRule, Edited().RepeatUntilDateTime() ); |
|
2619 break; |
|
2620 } |
|
2621 case ( TCalRRule::EMonthly ):// For Monthly repeating event |
|
2622 { |
|
2623 RArray<TInt> dateArray; |
|
2624 CleanupClosePushL( dateArray ); |
|
2625 dateArray.Append( rRule.DtStart().TimeLocalL().DayNoInMonth() ); |
|
2626 rRule.SetByMonthDay( dateArray ); |
|
2627 CleanupStack::PopAndDestroy( &dateArray ); |
|
2628 |
|
2629 // Adjust the RepeatUntil date |
|
2630 ApplyUntilDateToRRuleL( rRule, Edited().RepeatUntilDateTime() ); |
|
2631 break; |
|
2632 } |
|
2633 |
|
2634 case ( TCalRRule::EDaily ):// For Daily repeating event |
|
2635 { |
|
2636 TCalRRule curRule; |
|
2637 iEntry.GetRRuleL( curRule ); |
|
2638 |
|
2639 // Adjust the RepeatUntil date |
|
2640 if(lastRDate < curRule.Until().TimeLocalL() ) |
|
2641 { |
|
2642 ApplyUntilDateToRRuleL( rRule, Edited().RepeatUntilDateTime() ); |
|
2643 } |
|
2644 |
|
2645 |
|
2646 break; |
|
2647 } |
|
2648 default: |
|
2649 { |
|
2650 break; |
|
2651 } |
|
2652 } |
|
2653 |
|
2654 |
|
2655 iEntry.SetRRuleL( rRule ); |
|
2656 } |
|
2657 } |
|
2658 |
|
2659 CleanupStack::PopAndDestroy(); // rDates |
|
2660 } |
|
2661 |
|
2662 if ( UseFloatingTimeL() ) |
|
2663 { |
|
2664 entryStart.SetTimeLocalFloatingL( newStart ); |
|
2665 } |
|
2666 else |
|
2667 { |
|
2668 entryStart.SetTimeLocalL( newStart ); |
|
2669 } |
|
2670 } |
|
2671 |
|
2672 // 3) Decide end time |
|
2673 if ( shouldWriteBothTimes || IsEndDateTimeEdited() ) |
|
2674 { |
|
2675 TTime start = Edited().StartDateTime(); |
|
2676 TTime end = Edited().EndDateTime(); |
|
2677 |
|
2678 // For all-day events, we add 24 hours to end date |
|
2679 // to make it full day long |
|
2680 /*if ( iEntryType == CCalEntry::EEvent) |
|
2681 { |
|
2682 end += TTimeIntervalDays(1); |
|
2683 }*/ |
|
2684 |
|
2685 TTimeIntervalMinutes duration; |
|
2686 TInt err = end.MinutesFrom( start, duration ); |
|
2687 ASSERT( err == KErrNone ); |
|
2688 ASSERT( duration >= TTimeIntervalMinutes(0) ); |
|
2689 |
|
2690 if ( UseFloatingTimeL() ) |
|
2691 { |
|
2692 entryEnd.SetTimeLocalFloatingL( entryStart.TimeLocalL() + duration ); |
|
2693 } |
|
2694 else |
|
2695 { |
|
2696 entryEnd.SetTimeLocalL( entryStart.TimeLocalL() + duration ); |
|
2697 } |
|
2698 } |
|
2699 |
|
2700 // If EntryType is changed as Non-timed/Timed entry, along with StartTime(AND/OR)EndTime, |
|
2701 // Both Start/End time TimeMode should be changed accordingly. |
|
2702 if ( UseFloatingTimeL() ) |
|
2703 { |
|
2704 entryStart.SetTimeLocalFloatingL( entryStart.TimeLocalL() ); |
|
2705 entryEnd.SetTimeLocalFloatingL( entryEnd.TimeLocalL() ); |
|
2706 } |
|
2707 else |
|
2708 { |
|
2709 entryStart.SetTimeLocalL( entryStart.TimeLocalL() ); |
|
2710 entryEnd.SetTimeLocalL( entryEnd.TimeLocalL() ); |
|
2711 } |
|
2712 |
|
2713 // Write times to entry |
|
2714 iEntry.SetStartAndEndTimeL( entryStart, entryEnd ); |
|
2715 } |
|
2716 |
|
2717 TRACE_EXIT_POINT; |
|
2718 } |
|
2719 |
|
2720 //---------------------------------------------------------------------- |
|
2721 // CCalenEditorDataHandler::ResetOriginalDataL |
|
2722 // Reset original editor data |
|
2723 // (other items were commented in a header). |
|
2724 //---------------------------------------------------------------------- |
|
2725 void CCalenEditorDataHandler::ResetOriginalDataL() |
|
2726 { |
|
2727 TRACE_ENTRY_POINT; |
|
2728 |
|
2729 if(iOriginal) |
|
2730 { |
|
2731 delete iOriginal; |
|
2732 iOriginal=NULL; |
|
2733 } |
|
2734 iOriginal = CCalenEntryUtil::NewL( iEntry, iInstanceDateTime ); |
|
2735 |
|
2736 TRACE_EXIT_POINT; |
|
2737 } |
|
2738 |
|
2739 //---------------------------------------------------------------------- |
|
2740 // CCalenEditorDataHandler::EntryViewL |
|
2741 // Temp function to get to work |
|
2742 // (other items were commented in a header). |
|
2743 //---------------------------------------------------------------------- |
|
2744 CCalEntryView& CCalenEditorDataHandler::EntryViewL() |
|
2745 { |
|
2746 TRACE_ENTRY_POINT; |
|
2747 |
|
2748 CCalEntryView* entryView = iServices.EntryViewL(CurrentDbCollectionId()); |
|
2749 |
|
2750 TRACE_EXIT_POINT; |
|
2751 return *entryView; |
|
2752 } |
|
2753 |
|
2754 //---------------------------------------------------------------------- |
|
2755 // CCalenEditorDataHandler::InstanceViewL |
|
2756 // Temp function to get to work |
|
2757 // (other items were commented in a header). |
|
2758 //---------------------------------------------------------------------- |
|
2759 CCalInstanceView& CCalenEditorDataHandler::InstanceViewL() |
|
2760 { |
|
2761 TRACE_ENTRY_POINT; |
|
2762 |
|
2763 CCalInstanceView* instanceView = iServices.InstanceViewL(iCollectionIds); |
|
2764 |
|
2765 TRACE_EXIT_POINT; |
|
2766 return *instanceView; |
|
2767 } |
|
2768 |
|
2769 // ----------------------------------------------------------------------------- |
|
2770 // CCalenEditorDataHandler::GetPreviousInstanceForRepeatOtherL() |
|
2771 // Returns the time of the previous instance of a particular repeating entry |
|
2772 // (other items were commented in a header). |
|
2773 // ----------------------------------------------------------------------------- |
|
2774 // |
|
2775 TTime CCalenEditorDataHandler::GetPreviousInstanceForRepeatOtherL(CCalEntry& aEntry, const CalCommon::TCalTimeRange& timeRange) |
|
2776 { |
|
2777 RPointerArray<CCalInstance> allInstances; |
|
2778 CleanupResetAndDestroyPushL( allInstances ); |
|
2779 |
|
2780 TInt filter; |
|
2781 // Get the entry type to be filtered |
|
2782 switch(aEntry.EntryTypeL()) |
|
2783 { |
|
2784 case CCalEntry::EAppt: |
|
2785 filter = CalCommon::EIncludeAppts; |
|
2786 break; |
|
2787 case CCalEntry::ETodo: |
|
2788 filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos; |
|
2789 break; |
|
2790 case CCalEntry::EEvent: |
|
2791 filter = CalCommon::EIncludeEvents; |
|
2792 break; |
|
2793 case CCalEntry::EReminder: |
|
2794 filter = CalCommon::EIncludeReminder; |
|
2795 break; |
|
2796 case CCalEntry::EAnniv: |
|
2797 filter = CalCommon::EIncludeAnnivs; |
|
2798 break; |
|
2799 default: |
|
2800 filter = CalCommon::EIncludeAll; |
|
2801 break; |
|
2802 }; |
|
2803 |
|
2804 iServices.InstanceViewL()->FindInstanceL( allInstances, |
|
2805 (CalCommon::TCalViewFilterFlags)filter, |
|
2806 timeRange); |
|
2807 |
|
2808 TTime previousTime = Time::NullTTime(); |
|
2809 |
|
2810 for( TInt i = allInstances.Count() - 1; i >= 0; i-- ) |
|
2811 { |
|
2812 if( allInstances[i]->Entry().UidL() == aEntry.UidL() ) |
|
2813 { |
|
2814 TRACE_EXIT_POINT; |
|
2815 previousTime = allInstances[i]->Time().TimeLocalL(); |
|
2816 break; |
|
2817 } |
|
2818 } |
|
2819 |
|
2820 CleanupStack::PopAndDestroy( &allInstances ); |
|
2821 return previousTime; |
|
2822 } |
|
2823 |
|
2824 // ----------------------------------------------------------------------------- |
|
2825 // CCalenEditorDataHandler::GetNextInstanceForRepeatOtherL() |
|
2826 // Returns the time of the next instance of a particular repeating entry |
|
2827 // (other items were commented in a header). |
|
2828 // ----------------------------------------------------------------------------- |
|
2829 // |
|
2830 TTime CCalenEditorDataHandler::GetNextInstanceForRepeatOtherL( CCalEntry& aEntry, const CalCommon::TCalTimeRange& timeRange ) |
|
2831 { |
|
2832 RPointerArray<CCalInstance> allInstances; |
|
2833 CleanupResetAndDestroyPushL( allInstances ); |
|
2834 |
|
2835 TInt filter; |
|
2836 // Get the entry type to be filtered |
|
2837 switch( aEntry.EntryTypeL() ) |
|
2838 { |
|
2839 case CCalEntry::EAppt: |
|
2840 filter = CalCommon::EIncludeAppts; |
|
2841 break; |
|
2842 case CCalEntry::ETodo: |
|
2843 filter = CalCommon::EIncludeCompletedTodos | CalCommon::EIncludeIncompletedTodos; |
|
2844 break; |
|
2845 case CCalEntry::EEvent: |
|
2846 filter = CalCommon::EIncludeEvents; |
|
2847 break; |
|
2848 case CCalEntry::EReminder: |
|
2849 filter = CalCommon::EIncludeReminder; |
|
2850 break; |
|
2851 case CCalEntry::EAnniv: |
|
2852 filter = CalCommon::EIncludeAnnivs; |
|
2853 break; |
|
2854 default: |
|
2855 filter = CalCommon::EIncludeAll; |
|
2856 break; |
|
2857 }; |
|
2858 |
|
2859 iServices.InstanceViewL()->FindInstanceL( allInstances, |
|
2860 ( CalCommon::TCalViewFilterFlags )filter, |
|
2861 timeRange); |
|
2862 |
|
2863 TTime nextTime = Time::NullTTime(); |
|
2864 |
|
2865 TInt i( 0 ); |
|
2866 for( ; i < allInstances.Count(); i++ ) |
|
2867 { |
|
2868 if( allInstances[i]->Entry().UidL() == aEntry.UidL() ) |
|
2869 { |
|
2870 TRACE_EXIT_POINT; |
|
2871 nextTime = allInstances[i]->Time().TimeLocalL(); |
|
2872 break; |
|
2873 } |
|
2874 } |
|
2875 |
|
2876 CleanupStack::PopAndDestroy( &allInstances ); |
|
2877 return nextTime; |
|
2878 } |
|
2879 |
|
2880 // ----------------------------------------------------------------------------- |
|
2881 // CCalenEditorDataHandler::SetEntryType |
|
2882 // add attachments to the entry as ccalattachments |
|
2883 // ----------------------------------------------------------------------------- |
|
2884 // |
|
2885 void CCalenEditorDataHandler::SetEntryType( CCalEntry::TType aNewEntryType ) |
|
2886 { |
|
2887 iEntryType = aNewEntryType; |
|
2888 } |
|
2889 |
|
2890 // ----------------------------------------------------------------------------- |
|
2891 // CCalenEditorDataHandler::AddAttachementsToEntryL |
|
2892 // add attachments to the entry as ccalattachments |
|
2893 // ----------------------------------------------------------------------------- |
|
2894 // |
|
2895 void CCalenEditorDataHandler::AddAttachementsToEntryL() |
|
2896 { |
|
2897 TRACE_ENTRY_POINT; |
|
2898 |
|
2899 // Get the list of attachments from model and add them to entry |
|
2900 RPointerArray<CCalenAttachmentInfo> attachmentInfoList; |
|
2901 iServices.GetAttachmentData()->GetAttachmentListL( attachmentInfoList ); |
|
2902 TInt attachmentCount = iEntry.AttachmentCountL(); |
|
2903 TInt modelCount = attachmentInfoList.Count(); |
|
2904 |
|
2905 if( attachmentCount > 0 && modelCount == 0 ) |
|
2906 { |
|
2907 // This means that all the attachments in the entry have been deleted |
|
2908 // by the user. So remove all attchments from the entry |
|
2909 for( int index = 0 ; index < attachmentCount ; index++ ) |
|
2910 { |
|
2911 iEntry.DeleteAttachmentL( *iEntry.AttachmentL( 0 ) ); |
|
2912 } |
|
2913 |
|
2914 // No attachments need to be added at this point, we can simply return. |
|
2915 attachmentInfoList.Close(); |
|
2916 TRACE_EXIT_POINT; |
|
2917 return; |
|
2918 } |
|
2919 |
|
2920 // Delete all the attachmenst of the entry which are not present in the model |
|
2921 TInt currentIndex = 0; |
|
2922 for( TInt index=0; index < attachmentCount; index++ ) |
|
2923 { |
|
2924 CCalAttachment* attachment = iEntry.AttachmentL( currentIndex ); |
|
2925 TBool matchFound = EFalse; |
|
2926 for( int modelIndex = 0 ; modelIndex < modelCount ; modelIndex++ ) |
|
2927 { |
|
2928 CCalenAttachmentInfo* attachmentInfo = attachmentInfoList[ modelIndex ]; |
|
2929 if( attachmentInfo->StoreType() == |
|
2930 CCalenAttachmentInfo::ECalenAttachmentFetchedFromEntry ) |
|
2931 { |
|
2932 // We are only interested in those attachments which have been |
|
2933 // fetched from the entry because any newly added attachments |
|
2934 // will not yet be updated in the entry |
|
2935 RFile attachmentHandle; |
|
2936 CleanupClosePushL( attachmentHandle ); |
|
2937 attachment->FileAttachment()->FetchFileHandleL( attachmentHandle ); |
|
2938 |
|
2939 TFileName systemFileName; |
|
2940 attachmentHandle.FullName( systemFileName ); |
|
2941 |
|
2942 if( systemFileName == attachmentInfo->SystemFileName() ) |
|
2943 { |
|
2944 // There is an attachment in the model which matches the |
|
2945 // attachment in the entry. So do not delete it |
|
2946 matchFound = ETrue; |
|
2947 CleanupStack::PopAndDestroy( &attachmentHandle ); |
|
2948 break; |
|
2949 } |
|
2950 CleanupStack::PopAndDestroy( &attachmentHandle ); |
|
2951 } |
|
2952 } |
|
2953 if( !matchFound ) |
|
2954 { |
|
2955 // There is no matching attachment in the model. Delete it from entry |
|
2956 // This will compress the attachment array. Hence do not increment the currentIndex |
|
2957 iEntry.DeleteAttachmentL( *iEntry.AttachmentL( currentIndex ) ); |
|
2958 } |
|
2959 else |
|
2960 { |
|
2961 // Move to the next attachment |
|
2962 currentIndex++; |
|
2963 } |
|
2964 } |
|
2965 |
|
2966 // Now add the remaining newly added attachments to the entry |
|
2967 for( TInt index=0 ; index< modelCount ; index++ ) |
|
2968 { |
|
2969 CCalenAttachmentInfo* attachmentInfo = attachmentInfoList[ index ]; |
|
2970 if( attachmentInfo->StoreType() == CCalenAttachmentInfo::ECalenNewAttachment ) |
|
2971 { |
|
2972 TParsePtrC fileNameParser(attachmentInfo->FileName()); |
|
2973 RFile fileHandle; |
|
2974 CEikonEnv* eikonEnv = CEikonEnv::Static(); |
|
2975 RFs& fs = eikonEnv->FsSession(); |
|
2976 User::LeaveIfError(fs.ShareProtected()); |
|
2977 |
|
2978 TInt err = fileHandle.Open( fs, attachmentInfo->FileName(), EFileWrite ); |
|
2979 if( KErrNone != err ) |
|
2980 { |
|
2981 attachmentInfoList.Close(); |
|
2982 TRACE_EXIT_POINT; |
|
2983 return; |
|
2984 } |
|
2985 CleanupClosePushL(fileHandle); |
|
2986 |
|
2987 CCalAttachment* attachment = CCalAttachment::NewFileL(fileHandle); |
|
2988 CleanupStack::PopAndDestroy(&fileHandle); |
|
2989 |
|
2990 CleanupStack::PushL( attachment ); |
|
2991 // Sets the label for the attachment |
|
2992 attachment->SetLabelL( fileNameParser.NameAndExt() ); |
|
2993 // Sets mime type for the attachment |
|
2994 attachment->SetMimeTypeL( attachmentInfo->DataType().Des8() ); |
|
2995 attachment->SetAttribute(CCalAttachment::EExportInline); |
|
2996 iEntry.AddAttachmentL( *attachment ); |
|
2997 CleanupStack::Pop( attachment ); |
|
2998 } |
|
2999 } |
|
3000 attachmentInfoList.Close(); |
|
3001 |
|
3002 TRACE_EXIT_POINT; |
|
3003 } |
|
3004 |
|
3005 |
|
3006 // ----------------------------------------------------------------------------- |
|
3007 // CCalenEditorDataHandler::SetCalendarFieldEditedL |
|
3008 // Set if calendar is been edited or not with previous and current collection id |
|
3009 // ----------------------------------------------------------------------------- |
|
3010 // |
|
3011 void CCalenEditorDataHandler::SetCalendarFieldEditedL(TBool aEdited , |
|
3012 TCalCollectionId aPreviousDbColId, |
|
3013 TCalCollectionId aCurrentDbColId) |
|
3014 { |
|
3015 TRACE_ENTRY_POINT |
|
3016 iCalendarFieldEdited = aEdited; |
|
3017 iPreviousDbColId = aPreviousDbColId; |
|
3018 iCurrentDbColId = aCurrentDbColId; |
|
3019 TRACE_EXIT_POINT |
|
3020 } |
|
3021 |
|
3022 // ----------------------------------------------------------------------------- |
|
3023 // CCalenEditorDataHandler::PreviousDbCollectionId |
|
3024 // Get previous collection id |
|
3025 // ----------------------------------------------------------------------------- |
|
3026 // |
|
3027 TCalCollectionId CCalenEditorDataHandler::PreviousDbCollectionId() |
|
3028 { |
|
3029 TRACE_ENTRY_POINT |
|
3030 TRACE_EXIT_POINT |
|
3031 return iPreviousDbColId; |
|
3032 } |
|
3033 |
|
3034 // ----------------------------------------------------------------------------- |
|
3035 // CCalenEditorDataHandler::CurrentDbCollectionId |
|
3036 // Get current collection id |
|
3037 // ----------------------------------------------------------------------------- |
|
3038 // |
|
3039 TCalCollectionId CCalenEditorDataHandler::CurrentDbCollectionId() |
|
3040 { |
|
3041 TRACE_ENTRY_POINT |
|
3042 TRACE_EXIT_POINT |
|
3043 return iCurrentDbColId; |
|
3044 } |
|
3045 |
|
3046 // ----------------------------------------------------------------------------- |
|
3047 // CCalenEditorDataHandler::CalenInstanceId |
|
3048 // Returns the instance id. |
|
3049 // (other items were commented in a header). |
|
3050 // ----------------------------------------------------------------------------- |
|
3051 // |
|
3052 const TCalenInstanceId CCalenEditorDataHandler::CalenInstanceId() |
|
3053 { |
|
3054 TRACE_ENTRY_POINT; |
|
3055 |
|
3056 TRACE_EXIT_POINT; |
|
3057 |
|
3058 return iInstanceId; |
|
3059 } |
|
3060 |
|
3061 // End of file --Don't remove this. |