|
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 /** |
|
17 @file |
|
18 @internalComponent |
|
19 @released |
|
20 */ |
|
21 |
|
22 #include <cntviewbase.h> |
|
23 #include <cntitem.h> |
|
24 #include "cntviewprivate.h" |
|
25 #include <cntviewsortplugin.h> |
|
26 #include "persistencelayer.h" |
|
27 #include "cviewcontactmanager.h" |
|
28 #include "CNTSTD.H" |
|
29 #include <phbksync.h> |
|
30 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS |
|
31 #include <cntviewsortpluginbase.h> |
|
32 #endif |
|
33 //uncomment to test |
|
34 //#define __PROFILE_SORT__ |
|
35 |
|
36 //uncomment for commonly required debug printing |
|
37 //#define __VERBOSE_DEBUG__ |
|
38 |
|
39 //Define the patchable constants for the number of CViewContacts to read into memory |
|
40 //before merging them into a larger sorted list (via a heap sort).This is actually used |
|
41 //in cviewcontactmanager.cpp but must be defined here so that the compiler can not |
|
42 //perform any "constant folding" with the value |
|
43 EXPORT_C extern const TInt KNumberOfContactsToReadPerMerge = 500; |
|
44 |
|
45 extern void DebugLogNotification(const TDesC& aMethod, const TContactDbObserverEvent &aEvent); |
|
46 |
|
47 |
|
48 // |
|
49 // CContactLocalView. |
|
50 // |
|
51 CContactLocalView::CContactLocalView(const CContactDatabase& aDb,TContactViewPreferences aContactTypes, MLplPersistenceLayerFactory* aFactory) |
|
52 : CContactViewBase(aDb), |
|
53 iFactory(aFactory), |
|
54 iContacts(), |
|
55 iUnSortedContacts(), |
|
56 iViewPreferences(aContactTypes) |
|
57 { |
|
58 } |
|
59 |
|
60 |
|
61 /** |
|
62 Protected C++ constructor. |
|
63 |
|
64 Called by NewL(). |
|
65 |
|
66 @param aDb The underlying database that contains the contact items. |
|
67 @param aContactTypes Specifies which types of contact items should be included |
|
68 in the view and the behaviour for items that do not have content in any of |
|
69 the fields specified in the sort order. |
|
70 */ |
|
71 EXPORT_C CContactLocalView::CContactLocalView(const CContactDatabase& aDb,TContactViewPreferences aContactTypes) |
|
72 : CContactViewBase(aDb), |
|
73 iContacts(), |
|
74 iUnSortedContacts(), |
|
75 iViewPreferences(aContactTypes) |
|
76 { |
|
77 } |
|
78 |
|
79 |
|
80 /** |
|
81 Destructor. |
|
82 |
|
83 Deletes all resources owned by the object, and removes itself as the contact |
|
84 database observer. |
|
85 */ |
|
86 EXPORT_C CContactLocalView::~CContactLocalView() |
|
87 { |
|
88 #ifdef CONTACTS_API_PROFILING |
|
89 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewDestructor); |
|
90 #endif |
|
91 delete iTextDef; |
|
92 iContacts.ResetAndDestroy(); |
|
93 iUnSortedContacts.ResetAndDestroy(); |
|
94 iOutstandingEvents.Close(); |
|
95 iSortOrder.Close(); |
|
96 |
|
97 if (&iDb != NULL) |
|
98 { |
|
99 const_cast<CContactDatabase&>(iDb).RemoveObserver(*this); |
|
100 } |
|
101 |
|
102 delete iAsyncSorter; //Add this though we don't use it in local view any more |
|
103 delete iViewCntMgr; |
|
104 } |
|
105 |
|
106 |
|
107 /** |
|
108 Allocates and constructs the local view object. |
|
109 |
|
110 The view is sorted according to the sort order and view preferences specified, |
|
111 using a low priority idle time active object. The specified view observer |
|
112 is notified when the view is sorted and ready for use. |
|
113 |
|
114 @param aObserver An observer that receives notifications when this view is |
|
115 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
116 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady |
|
117 @param aDb The underlying database that contains the contact items. The view |
|
118 observes the database, so that it handles change events sent from the database. |
|
119 @param aSortOrder Specifies the fields to use to sort the items in the view. |
|
120 @param aContactTypes Specifies which types of contact items should be included |
|
121 in the view and the behaviour for items that do not have content in any of |
|
122 the fields specified in the sort order. |
|
123 @return The newly constructed local view object. |
|
124 */ |
|
125 EXPORT_C CContactLocalView* CContactLocalView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb, |
|
126 const RContactViewSortOrder& aSortOrder,TContactViewPreferences aContactTypes) |
|
127 { |
|
128 #ifdef CONTACTS_API_PROFILING |
|
129 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiNewL, aSortOrder, aContactTypes); |
|
130 #endif |
|
131 CContactLocalView* self = new(ELeave) CContactLocalView(aDb, aContactTypes); |
|
132 CleanupStack::PushL(self); |
|
133 self->ConstructL(aObserver, aSortOrder); |
|
134 CleanupStack::Pop(self); |
|
135 return self; |
|
136 } |
|
137 |
|
138 |
|
139 /** |
|
140 Protected second phase constructor. |
|
141 |
|
142 The view is sorted according to the sort order and view preferences specified, |
|
143 using a low priority idle time active object. The specified view observer |
|
144 is notified when the view is sorted and ready for use. |
|
145 |
|
146 Called by NewL(). |
|
147 |
|
148 @param aObserver An observer that receives notifications when this view is |
|
149 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
150 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady. |
|
151 @param aSortOrder Specifies the fields to use to sort the items in the view. |
|
152 */ |
|
153 EXPORT_C void CContactLocalView::ConstructL(MContactViewObserver& aObserver, const RContactViewSortOrder& aSortOrder) |
|
154 { |
|
155 // call new ConstructL |
|
156 ConstructL(aObserver, aSortOrder, EFalse, KNullDesC8); |
|
157 } |
|
158 |
|
159 |
|
160 /** |
|
161 Allocates and constructs the local view object. |
|
162 |
|
163 The view is sorted according to the sort order and view preferences specified, |
|
164 using a low priority idle time active object. The specified view observer |
|
165 is notified when the view is sorted and ready for use. |
|
166 |
|
167 @param aObserver An observer that receives notifications when this view is |
|
168 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
169 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady |
|
170 @param aDb The underlying database that contains the contact items. The view |
|
171 observes the database, so that it handles change events sent from the database. |
|
172 @param aSortOrder Specifies the fields to use to sort the items in the view. |
|
173 @param aContactTypes Specifies which types of contact items should be included |
|
174 in the view and the behaviour for items that do not have content in any of |
|
175 the fields specified in the sort order. |
|
176 @param aSortPluginName Specifies a plug-in that will be used to compare view contacts |
|
177 when the the view is sorted. This name is used by ECOM to select the plugin, and is matched |
|
178 with the "default_data" of all ECOM plugins that support the required interface. |
|
179 @return The newly constructed local view object. |
|
180 */ |
|
181 EXPORT_C CContactLocalView* CContactLocalView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb, const RContactViewSortOrder& aSortOrder, TContactViewPreferences aContactTypes, const TDesC8& aSortPluginName) |
|
182 { |
|
183 #ifdef CONTACTS_API_PROFILING |
|
184 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiNewL, aSortOrder, aContactTypes, aSortPluginName); |
|
185 #endif |
|
186 CContactLocalView* self = new(ELeave) CContactLocalView(aDb, aContactTypes); |
|
187 CleanupStack::PushL(self); |
|
188 self->ConstructL(aObserver, aSortOrder, ETrue, aSortPluginName); |
|
189 CleanupStack::Pop(self); |
|
190 return self; |
|
191 } |
|
192 |
|
193 |
|
194 /** |
|
195 CContactLocalView contructor, used in the server |
|
196 @internalTechnology |
|
197 */ |
|
198 EXPORT_C CContactLocalView* CContactLocalView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,const RContactViewSortOrder& aSortOrder,TContactViewPreferences aContactTypes, MLplPersistenceLayerFactory* aFactory, const TDesC8& aSortPluginName) |
|
199 { |
|
200 CContactLocalView* self = new (ELeave) CContactLocalView(aDb, aContactTypes, aFactory); |
|
201 CleanupStack::PushL(self); |
|
202 self->ConstructL(aObserver, aSortOrder, ETrue, aSortPluginName); |
|
203 CleanupStack::Pop(self); |
|
204 return self; |
|
205 } |
|
206 |
|
207 |
|
208 /** |
|
209 Protected second phase constructor. |
|
210 |
|
211 The view is sorted according to the sort order and view preferences specified, |
|
212 using a low priority idle time active object. The specified view observer |
|
213 is notified when the view is sorted and ready for use. |
|
214 |
|
215 Called by NewL(). |
|
216 |
|
217 @param aObserver An observer that receives notifications when this view is |
|
218 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
219 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady. |
|
220 @param aSortOrder Specifies the fields to use to sort the items in the view. |
|
221 @param aUseNamedPlugin A flag indicates whether the aSortPluginName parameter is valid. |
|
222 @param aSortPluginName Specifies a plug-in that will be used to compare view contacts |
|
223 when the the view is sorted. This name is used by ECOM to select the plugin, and is matched |
|
224 with the "default_data" of all ECOM plugins that support the required interface. |
|
225 */ |
|
226 void CContactLocalView::ConstructL(MContactViewObserver& aObserver,const RContactViewSortOrder& aSortOrder, TBool aUseNamedPlugin, const TDesC8& aSortPluginName) |
|
227 { |
|
228 CContactViewBase::ConstructL(); |
|
229 if(iFactory == NULL) |
|
230 { |
|
231 iFactory = const_cast<CContactDatabase&>(iDb).FactoryL(); |
|
232 } |
|
233 |
|
234 OpenL(aObserver); |
|
235 if (aUseNamedPlugin) |
|
236 { |
|
237 // find and load Sort plug-in |
|
238 if (aSortPluginName.Length()) |
|
239 { |
|
240 TUid sortPluginUid = FindSortPluginImplL (aSortPluginName); |
|
241 LoadViewSortPluginL(sortPluginUid, iViewPreferences); |
|
242 } |
|
243 } |
|
244 else |
|
245 { |
|
246 // find and load default Sort plug-in (if any) |
|
247 TUid sortPluginUid = FindDefaultViewSortPluginImplL(); |
|
248 if (sortPluginUid != KNullUid) |
|
249 { |
|
250 LoadViewSortPluginL(sortPluginUid, iViewPreferences); |
|
251 } |
|
252 } |
|
253 |
|
254 //Initialise sort order and textdef. |
|
255 SetSortOrderL(aSortOrder); |
|
256 |
|
257 //Create view contact manager to handle sorting |
|
258 iViewCntMgr = CViewContactManager::NewL(*this, *iFactory, *iTextDef, iViewPreferences, SortPluginImpl()); |
|
259 |
|
260 if (&iDb != NULL) |
|
261 { |
|
262 const_cast<CContactDatabase&>(iDb).AddObserverL(*this); |
|
263 } |
|
264 |
|
265 //Doing the sort. |
|
266 SortL(); |
|
267 } |
|
268 |
|
269 |
|
270 /** |
|
271 Gets the sort order, as set during construction. |
|
272 |
|
273 @return The sort order. |
|
274 */ |
|
275 EXPORT_C const RContactViewSortOrder& CContactLocalView::SortOrder() const |
|
276 { |
|
277 #ifdef CONTACTS_API_PROFILING |
|
278 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiSortOrder); |
|
279 #endif |
|
280 return iSortOrder; |
|
281 } |
|
282 |
|
283 |
|
284 /** |
|
285 Returns the ID of the contact item at a specified index into the view. |
|
286 |
|
287 @param aIndex An index into the view. |
|
288 @leave KErrNotFound The index is out of bounds. |
|
289 @return The ID of the contact item at the specified index. |
|
290 @leave KErrNotReady The view is not ready for use. |
|
291 */ |
|
292 TContactItemId CContactLocalView::AtL(TInt aIndex) const |
|
293 { |
|
294 #ifdef CONTACTS_API_PROFILING |
|
295 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiAtL, aIndex); |
|
296 #endif |
|
297 return iViewCntMgr->AtL(aIndex); |
|
298 } |
|
299 |
|
300 |
|
301 /** |
|
302 Returns the contact item at a specified index into the view. |
|
303 |
|
304 @param aIndex An index into the view. |
|
305 @leave KErrNotFound The index is out of bounds. |
|
306 @leave KErrNotReady The view is not ready for use. |
|
307 @return The reference to the copy of contact item at the specified index. |
|
308 */ |
|
309 const CViewContact& CContactLocalView::ContactAtL(TInt aIndex) const |
|
310 { |
|
311 #ifdef CONTACTS_API_PROFILING |
|
312 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiContactAtL, aIndex); |
|
313 #endif |
|
314 // state cannot be EInitializing or ENotReady |
|
315 if( iState != EReady ) |
|
316 { |
|
317 User::Leave(KErrNotReady); |
|
318 } |
|
319 |
|
320 return iViewCntMgr->ContactAtL(aIndex); |
|
321 } |
|
322 |
|
323 |
|
324 /** |
|
325 Gets the total number of contact items in the view. |
|
326 |
|
327 @return The number of contact items in the view. This includes both sorted |
|
328 and unsorted items. |
|
329 @leave KErrNotReady The view is not ready for use. |
|
330 */ |
|
331 TInt CContactLocalView::CountL() const |
|
332 { |
|
333 #ifdef CONTACTS_API_PROFILING |
|
334 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiCountL); |
|
335 #endif |
|
336 // state cannot be EInitializing or ENotReady |
|
337 if( iState != EReady ) |
|
338 { |
|
339 User::Leave(KErrNotReady); |
|
340 } |
|
341 |
|
342 return iViewCntMgr->Count(); |
|
343 } |
|
344 |
|
345 |
|
346 /** |
|
347 Searches for a contact item in the view with the specified ID. |
|
348 |
|
349 @param aId The ID of the contact item to search for. |
|
350 @return If found, the index into the view of the matching item. Otherwise, |
|
351 KErrNotFound. |
|
352 @leave KErrNotReady The view is not ready for use. |
|
353 */ |
|
354 TInt CContactLocalView::FindL(TContactItemId aId) const |
|
355 { |
|
356 #ifdef CONTACTS_API_PROFILING |
|
357 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiFindL, aId); |
|
358 #endif |
|
359 // state cannot be EInitializing or ENotReady |
|
360 if( iState != EReady ) |
|
361 { |
|
362 User::Leave(KErrNotReady); |
|
363 } |
|
364 |
|
365 return iViewCntMgr->FindL(aId); |
|
366 } |
|
367 |
|
368 |
|
369 /** |
|
370 Gets a descriptor containing the contents of all fields specified in the view's |
|
371 sort order for an item in the view. |
|
372 |
|
373 The field separator is used to separate the contents of each field. It is |
|
374 not appended to the last field. |
|
375 |
|
376 @param aIndex The index of the contact item into the view. |
|
377 @param aSeparator The string to use to separate the fields. |
|
378 @return Pointer to the contact item descriptor. |
|
379 */ |
|
380 HBufC* CContactLocalView::AllFieldsLC(TInt aIndex,const TDesC& aSeparator) const |
|
381 { |
|
382 #ifdef CONTACTS_API_PROFILING |
|
383 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiAllFieldsLC, aIndex); |
|
384 #endif |
|
385 if( iState != EReady ) |
|
386 { |
|
387 User::Leave(KErrNotReady); |
|
388 } |
|
389 |
|
390 return iViewCntMgr->AllFieldsLC(aIndex, aSeparator); |
|
391 } |
|
392 |
|
393 |
|
394 /** |
|
395 Sorts the view using the specified sort order, using a low priority idle time |
|
396 active object. |
|
397 |
|
398 This function is called during view construction and on receipt of certain |
|
399 change events from the underlying database. |
|
400 |
|
401 @param aSortOrder Specifies the fields to use to sort the items in the view. |
|
402 */ |
|
403 EXPORT_C void CContactLocalView::SortL(const RContactViewSortOrder& aSortOrder) |
|
404 { |
|
405 #ifdef CONTACTS_API_PROFILING |
|
406 TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiSortL); |
|
407 #endif |
|
408 |
|
409 if (&iDb != NULL) |
|
410 { |
|
411 if (!iDb.DatabaseReadyL()) |
|
412 { |
|
413 User::Leave(KErrNotReady); |
|
414 } |
|
415 } |
|
416 |
|
417 //set new sort order which also updates iTextDef. |
|
418 SetSortOrderL(aSortOrder); |
|
419 |
|
420 // reset sort error |
|
421 iExtension->iError = KErrNone; |
|
422 iViewCntMgr->SortL(*iTextDef); |
|
423 } |
|
424 |
|
425 |
|
426 /** |
|
427 Set sort order used to sorting the view contacts. |
|
428 */ |
|
429 void CContactLocalView::SetSortOrderL(const RContactViewSortOrder& aSortOrder) |
|
430 { |
|
431 // copy new sort order |
|
432 iSortOrder.CopyL(aSortOrder); |
|
433 |
|
434 // New sort order for Sort Plugin |
|
435 CViewContactSortPlugin* sortPluginImpl = SortPluginImpl(); |
|
436 if (sortPluginImpl) |
|
437 { |
|
438 sortPluginImpl->SetSortOrderL(aSortOrder); |
|
439 } |
|
440 |
|
441 // Initialisation for each explicitly requested sort or initialise sort |
|
442 // Construct a text def to read out the required fields from the db. |
|
443 CContactTextDef* textDef=CContactTextDef::NewLC(); |
|
444 TInt sortOrderCount=iSortOrder.Count(); |
|
445 |
|
446 for (TInt sortIndex=0;sortIndex<sortOrderCount;sortIndex++) |
|
447 { |
|
448 textDef->AppendL(TContactTextDefItem(iSortOrder[sortIndex])); |
|
449 } |
|
450 CleanupStack::Pop(); // textDef. |
|
451 |
|
452 delete iTextDef; |
|
453 iTextDef=textDef; |
|
454 } |
|
455 |
|
456 |
|
457 /** |
|
458 Start sorting if database is ready |
|
459 */ |
|
460 void CContactLocalView::SortL() |
|
461 { |
|
462 // View can Sort only if database is 'ready'. |
|
463 if (&iDb != NULL) |
|
464 { |
|
465 if (!iDb.DatabaseReadyL()) |
|
466 { |
|
467 return; |
|
468 } |
|
469 } |
|
470 |
|
471 // reset sort error |
|
472 iExtension->iError = KErrNone; |
|
473 iViewCntMgr->SortL(); |
|
474 } |
|
475 |
|
476 |
|
477 /** |
|
478 Unleavable(safe) resorting |
|
479 */ |
|
480 void CContactLocalView::SafeResort() |
|
481 { |
|
482 TRAPD(sortError, SortL()); |
|
483 |
|
484 // notify any error |
|
485 if (sortError) |
|
486 { |
|
487 NotifySortError(sortError); |
|
488 } |
|
489 } |
|
490 |
|
491 |
|
492 /** |
|
493 Inserts a contact item into the view, maintaining the view's sort order. |
|
494 |
|
495 For the item to be inserted, it must exist in the underlying database, and |
|
496 it must be of the correct type according to the view preferences. |
|
497 |
|
498 This function is called when a contact item or group is added to or changed |
|
499 in the underlying database. |
|
500 |
|
501 @param aId The ID of a contact item that exists in the underlying database. |
|
502 @return The index at which the item was inserted into the view, or KErrNotFound |
|
503 if the contact item was not found in the underlying database, or it already |
|
504 exists in the view. |
|
505 */ |
|
506 EXPORT_C TInt CContactLocalView::InsertL(TContactItemId aId) |
|
507 { |
|
508 #if defined(__VERBOSE_DEBUG__) |
|
509 RDebug::Print(_L("[CNTMODEL] CContactLocalView{ViewPrefs = 0x%08X}::InsertL into view Contact Id %i\r\n"), |
|
510 iViewPreferences, aId); |
|
511 #endif |
|
512 |
|
513 TContactViewPreferences view = iViewPreferences; |
|
514 return iViewCntMgr->InsertL(aId, view); |
|
515 } |
|
516 |
|
517 |
|
518 /** |
|
519 Removes a contact item from the view. |
|
520 |
|
521 This function is called when a contact item or group is deleted from or changed |
|
522 in the underlying database. |
|
523 |
|
524 @param aId The ID of the contact item to remove from the view. |
|
525 @return The index of the removed item into the view's list of sorted or unsorted |
|
526 contact items, or KErrNotFound if the item was not found in the view. |
|
527 */ |
|
528 EXPORT_C TInt CContactLocalView::RemoveL(TContactItemId aId) |
|
529 { |
|
530 return iViewCntMgr->RemoveL(aId); |
|
531 } |
|
532 |
|
533 EXPORT_C void CContactLocalView::CContactLocalView_Reserved_1() |
|
534 { |
|
535 } |
|
536 |
|
537 EXPORT_C void CContactLocalView::CContactLocalView_Reserved_2() |
|
538 { |
|
539 } |
|
540 |
|
541 |
|
542 /** |
|
543 Database event handler. |
|
544 |
|
545 @param aEvent the database event. |
|
546 */ |
|
547 void CContactLocalView::HandleDatabaseEventL(TContactDbObserverEvent aEvent) |
|
548 { |
|
549 // handle Backup / Restore notifications before checking View State |
|
550 switch (aEvent.iType) |
|
551 { |
|
552 case EContactDbObserverEventBackupBeginning: |
|
553 case EContactDbObserverEventRestoreBeginning: |
|
554 #if defined(__VERBOSE_DEBUG__) |
|
555 RDebug::Print(_L("[CNTMODEL] CContactLocalView{ViewPrefs = 0x%08X}::HandleDatabaseEventL -> Backup/Restore Beginning, state = %i\r\n"), |
|
556 iViewPreferences, iState); |
|
557 #endif |
|
558 if (iState == EReady) |
|
559 { |
|
560 SetState(ENotReady); |
|
561 } |
|
562 else |
|
563 { |
|
564 // stop sorting |
|
565 iViewCntMgr->StopSortL(); |
|
566 } |
|
567 return; |
|
568 |
|
569 case EContactDbObserverEventBackupRestoreCompleted: |
|
570 #if defined(__VERBOSE_DEBUG__) |
|
571 RDebug::Print(_L("[CNTMODEL] CContactLocalView{ViewPrefs = 0x%08X}::HandleDatabaseEventL -> Backup/Restore Completed, state = %i, old sort error %i\r\n"), |
|
572 iViewPreferences, iState, iExtension->iError); |
|
573 #endif |
|
574 if (iState == ENotReady && iExtension->iError == KErrNone) |
|
575 { |
|
576 // view was ready before tables were closed |
|
577 SetState(EReady); |
|
578 } |
|
579 else // view was Initializing (sorting) before tables were closed |
|
580 { |
|
581 // re-read database and sort |
|
582 SafeResort(); |
|
583 } |
|
584 return; |
|
585 |
|
586 default: |
|
587 // other events dealt with below |
|
588 break; |
|
589 } |
|
590 |
|
591 |
|
592 if (iState!=EReady) |
|
593 { |
|
594 if (iViewCntMgr->IsICCSynchronised()) |
|
595 { |
|
596 /* |
|
597 * View events are only queued when the ICC has been synchronised. This prevents |
|
598 * duplicate contacts in an ICC view because add events are not queued until the |
|
599 * SIM is fully synchronised. |
|
600 * |
|
601 * See LUD-5EBHZF "ICC contacts view broadcasts add item events after view is |
|
602 * ready" for more detail. |
|
603 */ |
|
604 |
|
605 #if defined(__VERBOSE_DEBUG__) |
|
606 DebugLogNotification(_L("[CNTMODEL] . . . . . Queueing Database Event "), aEvent); |
|
607 #endif |
|
608 iOutstandingEvents.AppendL(aEvent); |
|
609 |
|
610 // The view state is set to ENotReady when a recovery takes place, and also when the tables |
|
611 // are closed, so set ready here. |
|
612 if (iState == ENotReady && (aEvent.iType |
|
613 == EContactDbObserverEventRecover || aEvent.iType |
|
614 == EContactDbObserverEventTablesOpened)) |
|
615 { |
|
616 SetState(EReady); |
|
617 } |
|
618 // view was Initializing (sorting) before recovery or compression started! |
|
619 if (iState == EInitializing && (aEvent.iType |
|
620 == EContactDbObserverEventRecover || aEvent.iType |
|
621 == EContactDbObserverEventCompress)) |
|
622 { |
|
623 // re-read database and sort |
|
624 SafeResort(); |
|
625 } |
|
626 |
|
627 } |
|
628 |
|
629 |
|
630 #if defined(__VERBOSE_DEBUG__) |
|
631 else |
|
632 { |
|
633 DebugLogNotification(_L("[CNTMODEL] . . . . . Discarding Database Event "), aEvent); |
|
634 } |
|
635 #endif |
|
636 } |
|
637 else |
|
638 { |
|
639 TContactViewEvent event; |
|
640 event.iInt = KErrNone; |
|
641 switch(aEvent.iType) |
|
642 { |
|
643 case EContactDbObserverEventGroupChanged: |
|
644 { |
|
645 //Groups are a special case the base view may not contain the group |
|
646 //but a sub view may be such a group and need to know its changed |
|
647 //Local views can contain groups so this case carries on to the next so no break; |
|
648 event.iEventType=TContactViewEvent::EGroupChanged; |
|
649 event.iContactId=aEvent.iContactId; |
|
650 NotifyObservers(event); |
|
651 } |
|
652 case EContactDbObserverEventContactChanged: |
|
653 case EContactDbObserverEventOwnCardChanged: |
|
654 {// Remove from old position, and notify. |
|
655 TRAPD(err,event.iInt=RemoveL(aEvent.iContactId)); |
|
656 |
|
657 if (err == KErrNone && event.iInt != KErrNotFound) |
|
658 { |
|
659 event.iEventType=TContactViewEvent::EItemRemoved; |
|
660 event.iContactId=aEvent.iContactId; |
|
661 NotifyObservers(event); |
|
662 } |
|
663 |
|
664 // Insert at new position, and notify. |
|
665 event.iInt=InsertL(aEvent.iContactId); |
|
666 if (event.iInt != KErrNotFound) |
|
667 { |
|
668 event.iEventType=TContactViewEvent::EItemAdded; |
|
669 event.iContactId=aEvent.iContactId; |
|
670 NotifyObservers(event); |
|
671 } |
|
672 break; |
|
673 } |
|
674 case EContactDbObserverEventContactAdded: |
|
675 case EContactDbObserverEventGroupAdded: |
|
676 #if defined(__VERBOSE_DEBUG__) |
|
677 DebugLogNotification(_L("[CNTMODEL] DatabaseEvent -> Contact/Group Added"), aEvent); |
|
678 #endif |
|
679 event.iInt=InsertL(aEvent.iContactId); |
|
680 if (event.iInt != KErrNotFound) |
|
681 { |
|
682 event.iEventType=TContactViewEvent::EItemAdded; |
|
683 event.iContactId=aEvent.iContactId; |
|
684 NotifyObservers(event); |
|
685 } |
|
686 break; |
|
687 case EContactDbObserverEventContactDeleted: |
|
688 if(aEvent.iContactId == KNullContactId) // KNullContactId indicates a bulk delete. |
|
689 { |
|
690 SetState(EInitializing); // Use initializing state to avoid ESortOrderChanged event being sent to observers. |
|
691 SafeResort(); |
|
692 } |
|
693 else |
|
694 { |
|
695 event.iInt=RemoveL(aEvent.iContactId); |
|
696 if (event.iInt != KErrNotFound) |
|
697 { |
|
698 event.iEventType=TContactViewEvent::EItemRemoved; |
|
699 event.iContactId=aEvent.iContactId; |
|
700 NotifyObservers(event); |
|
701 } |
|
702 } |
|
703 break; |
|
704 case EContactDbObserverEventGroupDeleted: |
|
705 case EContactDbObserverEventOwnCardDeleted: |
|
706 event.iInt=RemoveL(aEvent.iContactId); |
|
707 if (event.iInt != KErrNotFound) |
|
708 { |
|
709 event.iEventType=TContactViewEvent::EItemRemoved; |
|
710 event.iContactId=aEvent.iContactId; |
|
711 NotifyObservers(event); |
|
712 } |
|
713 break; |
|
714 case EContactDbObserverEventUnknownChanges: |
|
715 case EContactDbObserverEventCurrentDatabaseChanged: |
|
716 SetState(EInitializing); // Use initializing state to avoid ESortOrderChanged event being sent to observers. |
|
717 SafeResort(); |
|
718 break; |
|
719 case EContactDbObserverEventSortOrderChanged: // event is not currently used |
|
720 SetState(ENotReady); |
|
721 SafeResort(); |
|
722 break; |
|
723 case EContactDbObserverEventTablesClosed: |
|
724 if (iState == EReady) |
|
725 { |
|
726 SetState(ENotReady); |
|
727 } |
|
728 break; |
|
729 case EContactDbObserverEventTablesOpened: |
|
730 // re-read database and sort |
|
731 SafeResort(); |
|
732 break; |
|
733 |
|
734 case EContactDbObserverEventNull: |
|
735 case EContactDbObserverEventUnused: |
|
736 case EContactDbObserverEventRecover: |
|
737 case EContactDbObserverEventCompress: |
|
738 case EContactDbObserverEventRollback: |
|
739 case EContactDbObserverEventTemplateChanged: |
|
740 case EContactDbObserverEventTemplateDeleted: |
|
741 case EContactDbObserverEventTemplateAdded: |
|
742 case EContactDbObserverEventCurrentItemDeleted: |
|
743 case EContactDbObserverEventCurrentItemChanged: |
|
744 case EContactDbObserverEventPreferredTemplateChanged: |
|
745 case EContactDbObserverEventSpeedDialsChanged: |
|
746 case EContactDbObserverEventRestoreBadDatabase: |
|
747 break; |
|
748 |
|
749 // these events should not come here, but be dealt with at the top of HandleDatabaseEventL |
|
750 case EContactDbObserverEventBackupBeginning: |
|
751 case EContactDbObserverEventRestoreBeginning: |
|
752 case EContactDbObserverEventBackupRestoreCompleted: |
|
753 break; |
|
754 |
|
755 default: |
|
756 ASSERT(EFalse); |
|
757 } |
|
758 } |
|
759 } |
|
760 |
|
761 |
|
762 /** |
|
763 Called from view contact item manager to notify the sorting has finished. |
|
764 |
|
765 @param aSortErr error occurs in sorting or KErrNone if sorting completes without error. |
|
766 */ |
|
767 void CContactLocalView::SortComplete(TInt aSortErr) |
|
768 { |
|
769 if(aSortErr != KErrNone) |
|
770 { |
|
771 NotifySortError(aSortErr); |
|
772 return; |
|
773 } |
|
774 |
|
775 if (iState != EInitializing) |
|
776 { |
|
777 //The view has just been re-sorted, notifiy observers ESortOrderChanged |
|
778 iState = EReady; |
|
779 NotifyObservers(TContactViewEvent(TContactViewEvent::ESortOrderChanged)); |
|
780 HandleOutstandingEvents(); |
|
781 } |
|
782 else |
|
783 { |
|
784 // Sorted for the first time, notifiy ready |
|
785 SetState(EReady); |
|
786 } |
|
787 } |
|
788 |
|
789 |
|
790 /** |
|
791 Set database state |
|
792 |
|
793 @param aState database state to set. |
|
794 */ |
|
795 void CContactLocalView::SetState(TState aState) |
|
796 { |
|
797 switch (iState) |
|
798 { |
|
799 case EInitializing: |
|
800 case ENotReady: |
|
801 ASSERT(aState==EReady); |
|
802 iState=EReady; |
|
803 NotifyObservers(TContactViewEvent(TContactViewEvent::EReady)); |
|
804 HandleOutstandingEvents(); |
|
805 break; |
|
806 case EReady: |
|
807 ASSERT(aState==ENotReady || aState==EInitializing); |
|
808 // ensure sort error is reset |
|
809 iExtension->iError = KErrNone; |
|
810 iState=aState; |
|
811 NotifyObservers(TContactViewEvent(TContactViewEvent::EUnavailable)); |
|
812 break; |
|
813 default: |
|
814 ASSERT(EFalse); |
|
815 } |
|
816 } |
|
817 |
|
818 |
|
819 /** |
|
820 Handle a particular queued event |
|
821 */ |
|
822 void CContactLocalView::HandleOutstandingEventL() |
|
823 { |
|
824 TContactDbObserverEvent event = iOutstandingEvents[0]; |
|
825 iOutstandingEvents.Remove(0); |
|
826 HandleDatabaseEventL(event); |
|
827 } |
|
828 |
|
829 /** |
|
830 Handle queued events when view is ready - sorting completes |
|
831 */ |
|
832 void CContactLocalView::HandleOutstandingEvents() |
|
833 { |
|
834 while (iOutstandingEvents.Count() > 0) |
|
835 { |
|
836 // loop through as many events as possible in the one Trap harness |
|
837 TRAP_IGNORE(HandleOutstandingEventL()); |
|
838 // if HandleDatabaseEventL left we must remove the event |
|
839 } |
|
840 } |
|
841 |
|
842 /** |
|
843 Gets the view preferences, as set during construction. |
|
844 |
|
845 @return The view preferences. |
|
846 */ |
|
847 TContactViewPreferences CContactLocalView::ContactViewPreferences() |
|
848 { |
|
849 return iViewPreferences; |
|
850 } |
|
851 |
|
852 |
|
853 /** |
|
854 Gets the sort order, as set during construction. |
|
855 |
|
856 This function cannot leave. |
|
857 |
|
858 @return The sort order. |
|
859 */ |
|
860 const RContactViewSortOrder& CContactLocalView::SortOrderL() const |
|
861 { |
|
862 return iSortOrder; |
|
863 } |
|
864 |
|
865 |
|
866 /** |
|
867 Notify observers that view construction failed. |
|
868 The error is stored so that if another client tries to open the view |
|
869 they will receive the same error. |
|
870 |
|
871 @param aError Leave code from CIdleContactSorter::RunL |
|
872 */ |
|
873 void CContactLocalView::NotifySortError(TInt aError) |
|
874 { |
|
875 iExtension->iError = aError; |
|
876 NotifyObservers(TContactViewEvent(TContactViewEvent::ESortError, aError)); |
|
877 } |
|
878 |
|
879 |
|
880 /** |
|
881 This is a reserved virtual exported function that is used for BC proofing |
|
882 against present and future additions of new exported virtual functions. |
|
883 |
|
884 @return Any return values of the helper methods called from this function or NULL. |
|
885 */ |
|
886 EXPORT_C TAny* CContactLocalView::CContactViewBase_Reserved_1(TFunction aFunction,TAny* aParams) |
|
887 { |
|
888 return CContactViewBase::CContactViewBase_Reserved_1(aFunction,aParams); |
|
889 } |
|
890 |