|
1 /* |
|
2 * Copyright (c) 2002-2004 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: ?Description |
|
15 * |
|
16 */ |
|
17 |
|
18 // user includes |
|
19 #include "CalenEntryUpdater.h" |
|
20 #include "CleanupResetAndDestroy.h" |
|
21 #include "calenglobaldata.h" // CCalenGlobalData |
|
22 //debug |
|
23 #include "calendarui_debug.h" |
|
24 |
|
25 // system includes |
|
26 #include <calcommon.h> |
|
27 #include <CalenInterimUtils2.h> |
|
28 #include <calenagendautils.h> |
|
29 #include <calendateutils.h> |
|
30 #include <calentry.h> |
|
31 #include <calentryview.h> |
|
32 #include <calinstance.h> |
|
33 #include <calinstanceview.h> |
|
34 #include <calrrule.h> |
|
35 #include <vwsdef.h> |
|
36 #include <calencommands.hrh> // Calendar commands |
|
37 #include <calencontext.h> |
|
38 #include <caleninstanceid.h> // TCalenInstanceId |
|
39 #include <calenservices.h> |
|
40 #include <calenactionuiutils.h> |
|
41 |
|
42 // ----------------------------------------------------------------------------- |
|
43 // CCalenEntryUpdater::NewL() |
|
44 // Two-phased constructor. |
|
45 // (other items were commented in a header). |
|
46 // ----------------------------------------------------------------------------- |
|
47 // |
|
48 CCalenEntryUpdater* CCalenEntryUpdater::NewL( MCalenServices& aServices ,RArray<TInt>& aCollectionIds ) |
|
49 { |
|
50 TRACE_ENTRY_POINT; |
|
51 |
|
52 CCalenEntryUpdater* self = new (ELeave) CCalenEntryUpdater( aServices, aCollectionIds ); |
|
53 CleanupStack::PushL( self ); |
|
54 self->ConstructL(); |
|
55 CleanupStack::Pop( self ); |
|
56 |
|
57 TRACE_EXIT_POINT; |
|
58 return self; |
|
59 } |
|
60 |
|
61 // ----------------------------------------------------------------------------- |
|
62 // CCalenEntryUpdater::~CCalenEntryUpdater() |
|
63 // Destructor |
|
64 // (other items were commented in a header). |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 CCalenEntryUpdater::~CCalenEntryUpdater() |
|
68 { |
|
69 TRACE_ENTRY_POINT; |
|
70 TRACE_EXIT_POINT; |
|
71 } |
|
72 |
|
73 // ----------------------------------------------------------------------------- |
|
74 // CCalenEntryUpdater::CCalenEntryUpdater() |
|
75 // Constructor. |
|
76 // (other items were commented in a header). |
|
77 // ----------------------------------------------------------------------------- |
|
78 // |
|
79 CCalenEntryUpdater::CCalenEntryUpdater( MCalenServices& aServices , RArray<TInt>& aCollectionIds) |
|
80 : iServices( aServices ) , iCollectionIds(aCollectionIds) |
|
81 { |
|
82 TRACE_ENTRY_POINT; |
|
83 TRACE_EXIT_POINT; |
|
84 } |
|
85 |
|
86 // ----------------------------------------------------------------------------- |
|
87 // CCalenEntryUpdater::ConstructL() |
|
88 // Leaving construction. |
|
89 // (other items were commented in a header). |
|
90 // ----------------------------------------------------------------------------- |
|
91 // |
|
92 void CCalenEntryUpdater::ConstructL() |
|
93 { |
|
94 TRACE_ENTRY_POINT; |
|
95 TRACE_EXIT_POINT; |
|
96 } |
|
97 |
|
98 // ----------------------------------------------------------------------------- |
|
99 // CCalenEntryUpdater::DeleteEntryL() |
|
100 // Delete the given entry from agenda. |
|
101 // (other items were commented in a header). |
|
102 // ----------------------------------------------------------------------------- |
|
103 // |
|
104 void CCalenEntryUpdater::DeleteEntryL( CCalEntry& aEntry, TCalenInstanceId aInstanceId ) |
|
105 { |
|
106 TRACE_ENTRY_POINT; |
|
107 |
|
108 EntryViewL(aInstanceId.iColId).DeleteL( aEntry ); |
|
109 |
|
110 TRACE_EXIT_POINT; |
|
111 } |
|
112 |
|
113 // ----------------------------------------------------------------------------- |
|
114 // CCalenEntryUpdater::TryDeleteInstanceWithUiL() |
|
115 // Attempt to delete the entry, using CCalenCommonUI. Only delete the entry |
|
116 // using the repeat type defined in aRepeatType. |
|
117 // (other items were commented in a header). |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 void CCalenEntryUpdater::TryDeleteInstanceWithUiL( CCalEntry& aEntry, |
|
121 const TCalTime& aInstanceDate, |
|
122 CalCommon::TRecurrenceRange aRepeatType, |
|
123 MCalenServices& aServices ) |
|
124 { |
|
125 TRACE_ENTRY_POINT; |
|
126 DoTryDeleteInstanceWithUiL( aEntry, aInstanceDate, ETrue, aRepeatType, aServices ); |
|
127 TRACE_EXIT_POINT; |
|
128 } |
|
129 |
|
130 // ----------------------------------------------------------------------------- |
|
131 // CCalenEntryUpdater::TryDeleteInstanceWithUiL() |
|
132 // Attempt to delete the entry, using CCalenCommonUI to prompt the user whether to |
|
133 // delete the entire series or just the instance. |
|
134 // (other items were commented in a header). |
|
135 // ----------------------------------------------------------------------------- |
|
136 // |
|
137 void CCalenEntryUpdater::TryDeleteInstanceWithUiL( CCalEntry& aEntry, |
|
138 const TCalTime& aInstanceDate, |
|
139 MCalenServices& aServices ) |
|
140 { |
|
141 TRACE_ENTRY_POINT; |
|
142 |
|
143 DoTryDeleteInstanceWithUiL( aEntry, |
|
144 aInstanceDate, |
|
145 EFalse, |
|
146 CalCommon::EThisAndAll, |
|
147 aServices ); |
|
148 TRACE_EXIT_POINT; |
|
149 } |
|
150 |
|
151 // ----------------------------------------------------------------------------- |
|
152 // CCalenEntryUpdater::DoTryDeleteInstanceWithUiL() |
|
153 // If aHasRepeatType is ETrue, use aRepeatType to determine whether to delete the |
|
154 // entire series or just the instance. If aHasRepeatType is EFalse, aRepeatType is |
|
155 // ignored and the user is prompted to choose. |
|
156 // (other items were commented in a header). |
|
157 // ----------------------------------------------------------------------------- |
|
158 // |
|
159 void CCalenEntryUpdater::DoTryDeleteInstanceWithUiL( CCalEntry& /*aEntry*/, |
|
160 const TCalTime& /*aInstanceDate*/, |
|
161 TBool aHasRepeatType, |
|
162 CalCommon::TRecurrenceRange aRepeatType, |
|
163 MCalenServices& aServices ) |
|
164 { |
|
165 TRACE_ENTRY_POINT; |
|
166 |
|
167 if( aHasRepeatType ) |
|
168 { |
|
169 switch( aRepeatType ) |
|
170 { |
|
171 case CalCommon::EThisOnly: |
|
172 aServices.IssueCommandL( ECalenDeleteCurrentOccurrence ); |
|
173 break; |
|
174 case CalCommon::EThisAndAll: |
|
175 aServices.IssueCommandL( ECalenDeleteSeries ); |
|
176 break; |
|
177 default: |
|
178 ASSERT( 0 ); |
|
179 } |
|
180 } |
|
181 else |
|
182 { |
|
183 aServices.IssueCommandL( ECalenDeleteCurrentEntry ); |
|
184 } |
|
185 |
|
186 TRACE_EXIT_POINT; |
|
187 } |
|
188 |
|
189 // ----------------------------------------------------------------------------- |
|
190 // CCalenEntryUpdater::UpdateRDatesL() |
|
191 // Updates the RDates and Exception dates of the given entry. |
|
192 // (other items were commented in a header). |
|
193 // ----------------------------------------------------------------------------- |
|
194 // |
|
195 void CCalenEntryUpdater::UpdateRDatesL( CCalEntry& aEditedEntry, |
|
196 CCalEntry& aOrigEntry, |
|
197 const TCalTime& aOrigInstanceDate ) |
|
198 { |
|
199 TRACE_ENTRY_POINT; |
|
200 |
|
201 RArray<TCalTime> rdates; |
|
202 CleanupClosePushL( rdates ); |
|
203 aEditedEntry.GetRDatesL( rdates ); |
|
204 |
|
205 TBool hasRdates = rdates.Count() > 0; |
|
206 |
|
207 // If we've changed the RRule but we already have RDates, get rid of the RDates. |
|
208 if( hasRdates ) |
|
209 { |
|
210 TCalRRule editedRule; |
|
211 TBool editedHasRule = aEditedEntry.GetRRuleL( editedRule ) |
|
212 && editedRule.Type() != TCalRRule::EInvalid; |
|
213 |
|
214 TCalRRule origRule; |
|
215 TBool origHasRule = aOrigEntry.GetRRuleL( origRule ) |
|
216 && origRule.Type() != TCalRRule::EInvalid; |
|
217 |
|
218 TBool repeatRuleHasChanged = EFalse; |
|
219 if ( editedHasRule && origHasRule ) |
|
220 { |
|
221 repeatRuleHasChanged = TypeOrIntervalChangedL( editedRule, origRule ); |
|
222 } |
|
223 else |
|
224 { |
|
225 repeatRuleHasChanged = editedHasRule || origHasRule; |
|
226 } |
|
227 |
|
228 if( repeatRuleHasChanged && ! hasRdates ) |
|
229 { |
|
230 // Clear any RDates, Exception dates etc. |
|
231 aEditedEntry.ClearRepeatingPropertiesL(); |
|
232 aEditedEntry.SetRRuleL( editedRule ); |
|
233 } |
|
234 else |
|
235 { |
|
236 // If the start time of the entry has been modified, |
|
237 // and we have RDates, update the RDates to the new time. |
|
238 if( aEditedEntry.StartTimeL().TimeLocalL() != aOrigEntry.StartTimeL().TimeLocalL() ) |
|
239 { |
|
240 // The original time is that of the RDate which the user opened up, |
|
241 // not the start time of the entry. First iteration through the rates |
|
242 // is to get the time of day of the rdate on the instance day. |
|
243 |
|
244 TTimeIntervalMinutes origTime = -1; |
|
245 TTimeIntervalMinutes newTime = CalenDateUtils::TimeOfDay( aEditedEntry.StartTimeL().TimeLocalL() ); |
|
246 |
|
247 for( TInt i=0; i<rdates.Count(); ++i ) |
|
248 { |
|
249 if( CalenDateUtils::OnSameDay( aOrigInstanceDate.TimeLocalL(), rdates[i].TimeLocalL() ) ) |
|
250 { |
|
251 origTime = CalenDateUtils::TimeOfDay( rdates[i].TimeLocalL() ); |
|
252 } |
|
253 } |
|
254 |
|
255 // Alternatively, the entry opened up could have been the main parent entry. |
|
256 if( origTime.Int() == -1 ) |
|
257 { |
|
258 if( CalenDateUtils::OnSameDay( aOrigInstanceDate.TimeLocalL(), aOrigEntry.StartTimeL().TimeLocalL() ) ) |
|
259 { |
|
260 origTime = CalenDateUtils::TimeOfDay( aOrigEntry.StartTimeL().TimeLocalL() ); |
|
261 } |
|
262 } |
|
263 |
|
264 ASSERT( origTime.Int() != -1 ); |
|
265 |
|
266 RArray<TCalTime> exdates; |
|
267 CleanupClosePushL( exdates ); |
|
268 aOrigEntry.GetExceptionDatesL( exdates ); |
|
269 |
|
270 for( TInt i=0; i<rdates.Count(); ++i ) |
|
271 { |
|
272 TBool ignore = EFalse; |
|
273 |
|
274 for( TInt j=0; j<exdates.Count(); ++j ) |
|
275 { |
|
276 if( rdates[i].TimeUtcL() == exdates[j].TimeLocalL() ) |
|
277 { |
|
278 ignore = ETrue; |
|
279 break; |
|
280 } |
|
281 } |
|
282 |
|
283 if( !ignore && CalenDateUtils::TimeOfDay( rdates[ i ].TimeLocalL() ) == origTime ) |
|
284 { |
|
285 TTime beginningOfDay = CalenDateUtils::BeginningOfDay( rdates[ i ].TimeLocalL() ); |
|
286 |
|
287 |
|
288 // Use floating time for non-timed entries |
|
289 if ( !CalenAgendaUtils::IsTimedEntryL(aEditedEntry.EntryTypeL())) |
|
290 { |
|
291 rdates[ i ].SetTimeLocalFloatingL( beginningOfDay + newTime ); |
|
292 } |
|
293 else |
|
294 { |
|
295 rdates[ i ].SetTimeLocalL( beginningOfDay + newTime ); |
|
296 } |
|
297 } |
|
298 } |
|
299 |
|
300 aEditedEntry.SetRDatesL( rdates ); |
|
301 // SetExceptionDatesL doesn't remove any existing exception dates. |
|
302 // As as result we have to clear the repeating properties then repopulate |
|
303 // the entry's repeating properties by restoring the RRule, each child |
|
304 // entry, the RDates, and any unduplicated exception dates. |
|
305 aEditedEntry.SetExceptionDatesL( exdates ); |
|
306 CleanupStack::PopAndDestroy( &exdates ); |
|
307 } |
|
308 } |
|
309 } |
|
310 |
|
311 CleanupStack::PopAndDestroy(&rdates); |
|
312 |
|
313 TRACE_EXIT_POINT; |
|
314 } |
|
315 |
|
316 // ----------------------------------------------------------------------------- |
|
317 // CCalenEntryUpdater::TypeOrIntervalChangedL |
|
318 // Compares two rrules for differences |
|
319 // (other items were commented in a header). |
|
320 // ----------------------------------------------------------------------------- |
|
321 // |
|
322 TBool CCalenEntryUpdater::TypeOrIntervalChangedL( const TCalRRule& aEditedRule, |
|
323 const TCalRRule& aOrigRule ) const |
|
324 { |
|
325 TRACE_ENTRY_POINT; |
|
326 |
|
327 TBool repeatTypeChanged = aEditedRule.Type() != aOrigRule.Type(); |
|
328 TBool intervalChanged = aEditedRule.Interval() != aOrigRule.Interval(); |
|
329 |
|
330 TRACE_EXIT_POINT; |
|
331 return ( repeatTypeChanged || intervalChanged ); |
|
332 } |
|
333 |
|
334 // ----------------------------------------------------------------------------- |
|
335 // CCalenEntryUpdater::UpdateInstanceL() |
|
336 // Stores the given entry using CCalenInterimUtils2. |
|
337 // (other items were commented in a header). |
|
338 // ----------------------------------------------------------------------------- |
|
339 // |
|
340 void CCalenEntryUpdater::UpdateInstanceL( CCalEntry& aEditedEntry, |
|
341 CCalEntry& aOrigEntry, |
|
342 const TCalTime& aOrigInstanceDate, |
|
343 CalCommon::TRecurrenceRange aWhichInstances, |
|
344 const TCalTime& aNewInstanceStartDate, |
|
345 const TCalTime& aNewInstanceEndDate, |
|
346 const TDesC& aFileName ) |
|
347 { |
|
348 TRACE_ENTRY_POINT; |
|
349 |
|
350 TInt colId = iServices.SessionL(aFileName).CollectionIdL(); |
|
351 |
|
352 //Set the collection id here for temp instanceId and set it to context |
|
353 TCalenInstanceId instanceIdTemp = iServices.Context().InstanceId(); |
|
354 instanceIdTemp.iColId = colId; |
|
355 instanceIdTemp.iType = aEditedEntry.EntryTypeL(); |
|
356 |
|
357 if (aNewInstanceStartDate.TimeLocalL() != aOrigInstanceDate.TimeLocalL() |
|
358 || instanceIdTemp.iInstanceTime <= 0) |
|
359 { |
|
360 instanceIdTemp.iInstanceTime = aNewInstanceStartDate.TimeLocalL(); |
|
361 } |
|
362 iServices.Context().SetInstanceIdL(instanceIdTemp,iServices.Context().ViewId()); |
|
363 TBool isChild( aOrigEntry.RecurrenceIdL().TimeUtcL() != Time::NullTTime() ); |
|
364 |
|
365 if(isChild) |
|
366 { |
|
367 CCalenInterimUtils2::StoreL( EntryViewL(colId), aEditedEntry, ETrue ); |
|
368 } |
|
369 else if( aWhichInstances == CalCommon::EThisAndAll ) |
|
370 { |
|
371 UpdateRDatesL( aEditedEntry, aOrigEntry, aOrigInstanceDate ); |
|
372 CCalenInterimUtils2::StoreL( EntryViewL(colId), aEditedEntry, ETrue ); |
|
373 } |
|
374 else if( aWhichInstances == CalCommon::EThisOnly ) |
|
375 { |
|
376 // copy global UID from the original entry |
|
377 HBufC8* guid = aOrigEntry.UidL().AllocLC(); |
|
378 |
|
379 // create new (child) entry |
|
380 // Use original instance time for recurrenceID as this entry hasn't got one. |
|
381 CCalEntry* newEntry = CCalEntry::NewL( aOrigEntry.EntryTypeL(), |
|
382 guid, |
|
383 aOrigEntry.MethodL(), |
|
384 aOrigEntry.SequenceNumberL(), |
|
385 aOrigInstanceDate, |
|
386 aWhichInstances ); |
|
387 |
|
388 CleanupStack::Pop( guid ); // ownership transferred |
|
389 CleanupStack::PushL( newEntry ); |
|
390 |
|
391 // copy all the data from edited entry |
|
392 newEntry->CopyFromL( aEditedEntry ); |
|
393 |
|
394 // Workround for Symbian "features": |
|
395 // The summary is not automatically copied when it is very large. |
|
396 newEntry->SetSummaryL( aEditedEntry.SummaryL() ); |
|
397 // Calling SetStartAndEndTimeL on an entry with an RRule with TDays |
|
398 // completely ignores the date you pass in. |
|
399 if( ! CalenDateUtils::OnSameDay( aNewInstanceStartDate.TimeUtcL(), newEntry->StartTimeL().TimeUtcL() ) ) |
|
400 { |
|
401 TCalTime newStart, newEnd; |
|
402 TTime beginningOfDay = CalenDateUtils::BeginningOfDay( aNewInstanceStartDate.TimeUtcL() ); |
|
403 TTimeIntervalMinutes timeOfDay = CalenDateUtils::TimeOfDay( newEntry->StartTimeL().TimeUtcL() ); |
|
404 newStart.SetTimeUtcL( beginningOfDay + timeOfDay ); |
|
405 beginningOfDay = CalenDateUtils::BeginningOfDay( aNewInstanceEndDate.TimeUtcL() ); |
|
406 timeOfDay = CalenDateUtils::TimeOfDay( newEntry->EndTimeL().TimeUtcL() ); |
|
407 newEnd.SetTimeUtcL( beginningOfDay + timeOfDay ); |
|
408 newEntry->SetStartAndEndTimeL( newStart, newEnd ); |
|
409 } |
|
410 |
|
411 // reset local UID |
|
412 newEntry->SetLocalUidL( TCalLocalUid( 0 ) ); |
|
413 |
|
414 // clear repeat rule properties |
|
415 newEntry->ClearRepeatingPropertiesL(); |
|
416 |
|
417 // Set the geocoordinates |
|
418 CCalGeoValue* geoValue = aEditedEntry.GeoValueL(); |
|
419 if( geoValue ) |
|
420 { |
|
421 newEntry->SetGeoValueL( *geoValue ); |
|
422 delete geoValue; |
|
423 } |
|
424 |
|
425 CCalenInterimUtils2::StoreL( EntryViewL(colId), *newEntry, ETrue ); |
|
426 |
|
427 MCalenContext &context = iServices.Context(); |
|
428 TCalenInstanceId id = TCalenInstanceId::CreateL( *newEntry, aNewInstanceStartDate , colId ); |
|
429 context.SetFocusDateAndTimeAndInstanceL( aNewInstanceStartDate, id, context.ViewId() ); |
|
430 |
|
431 aEditedEntry.SetLocalUidL( newEntry->LocalUidL() ); |
|
432 |
|
433 CleanupStack::PopAndDestroy( newEntry ); |
|
434 } |
|
435 else |
|
436 { |
|
437 // not supported in UI level |
|
438 __ASSERT_ALWAYS( EFalse, User::Invariant() ); |
|
439 } |
|
440 |
|
441 TRACE_EXIT_POINT; |
|
442 } |
|
443 |
|
444 // ----------------------------------------------------------------------------- |
|
445 // CCalenEntryUpdater::FindInstanceL() |
|
446 // Returns the index into aInstances of the instance with the same UID as |
|
447 // aEntry, at the same date/time as aInstanceDate, or return KErrNotFound if |
|
448 // no match found. |
|
449 // (other items were commented in a header). |
|
450 // ----------------------------------------------------------------------------- |
|
451 // |
|
452 TInt CCalenEntryUpdater::FindInstanceL( CCalEntry& aEntry, |
|
453 const TCalTime& aInstanceDate, |
|
454 RPointerArray<CCalInstance>& aInstances) |
|
455 { |
|
456 TRACE_ENTRY_POINT; |
|
457 |
|
458 InstanceViewL().FindInstanceL( aInstances, |
|
459 CalCommon::EIncludeAll, |
|
460 CalCommon::TCalTimeRange(aInstanceDate, aInstanceDate) ); |
|
461 |
|
462 for( TInt i( 0 ); i < aInstances.Count(); i++ ) |
|
463 { |
|
464 if( aInstances[i]->Entry().UidL() == aEntry.UidL() ) |
|
465 { |
|
466 TRACE_EXIT_POINT; |
|
467 return i; |
|
468 } |
|
469 } |
|
470 |
|
471 TRACE_EXIT_POINT; |
|
472 return -1; |
|
473 } |
|
474 |
|
475 // ----------------------------------------------------------------------------- |
|
476 // CCalenEntryUpdater::EntryViewL() |
|
477 // Get CalEntryView from services |
|
478 // (other items were commented in a header). |
|
479 // ----------------------------------------------------------------------------- |
|
480 // |
|
481 CCalEntryView& CCalenEntryUpdater::EntryViewL(TInt ColId) |
|
482 { |
|
483 TRACE_ENTRY_POINT; |
|
484 |
|
485 CCalEntryView* entryView = iServices.EntryViewL(ColId); |
|
486 |
|
487 TRACE_EXIT_POINT; |
|
488 return *entryView; |
|
489 } |
|
490 |
|
491 // ----------------------------------------------------------------------------- |
|
492 // CCalenEntryUpdater::InstanceViewL() |
|
493 // Get CalInstanceView from services |
|
494 // (other items were commented in a header). |
|
495 // ----------------------------------------------------------------------------- |
|
496 // |
|
497 CCalInstanceView& CCalenEntryUpdater::InstanceViewL() |
|
498 { |
|
499 TRACE_ENTRY_POINT; |
|
500 |
|
501 CCalInstanceView* instanceView = iServices.InstanceViewL(iCollectionIds); |
|
502 |
|
503 TRACE_EXIT_POINT; |
|
504 return *instanceView; |
|
505 } |
|
506 |
|
507 // ----------------------------------------------------------------------------- |
|
508 // CCalenEntryUpdater::DeleteInstanceL() |
|
509 // Delete the given instance from agenda. |
|
510 // (other items were commented in a header). |
|
511 // ----------------------------------------------------------------------------- |
|
512 // |
|
513 void CCalenEntryUpdater::DeleteInstanceL( CCalEntry& /*aEntry*/, TCalenInstanceId aInstanceId ) |
|
514 { |
|
515 TRACE_ENTRY_POINT; |
|
516 |
|
517 CCalInstance* instance = CalenActionUiUtils::FindPossibleInstanceL( aInstanceId, InstanceViewL() ); |
|
518 if( instance ) |
|
519 { |
|
520 CleanupStack::PushL( instance ); |
|
521 InstanceViewL().DeleteL(instance , CalCommon::EThisOnly); |
|
522 CleanupStack::Pop( instance ); |
|
523 } |
|
524 |
|
525 TRACE_EXIT_POINT; |
|
526 } |
|
527 // End of File |