|
1 // Copyright (c) 2001-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 #include <cntview.h> |
|
17 #include "CNTSTD.H" |
|
18 |
|
19 |
|
20 //#define CNTVIEW_API_PROFILING |
|
21 // To see the diferences between class versions check the in source documentation of TContactViewEvent |
|
22 const TUint KClassVersion1 = 1; |
|
23 const TUint KClassVersion2 = 2; |
|
24 |
|
25 // |
|
26 // CContactSubView. |
|
27 // |
|
28 |
|
29 CContactSubView::CContactSubView(const CContactDatabase& aDb,CContactViewBase& aView) |
|
30 : CContactViewBase(aDb),iView(aView), iClassVersion(KClassVersion1) |
|
31 { |
|
32 } |
|
33 |
|
34 CContactSubView::CContactSubView(const CContactDatabase& aDb,const CContactSubView& aView) |
|
35 : CContactViewBase(aDb),iView(aView.iView) |
|
36 { |
|
37 } |
|
38 |
|
39 CContactSubView::~CContactSubView() |
|
40 { |
|
41 iView.Close(*this); |
|
42 delete iRange; |
|
43 iRange=NULL; |
|
44 } |
|
45 |
|
46 EXPORT_C CContactSubView* CContactSubView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,CContactViewBase& aView,const TDesC& aBoundary) |
|
47 /** Allocates and constructs a new CContactSubView version 1 object, specifying the sub view's |
|
48 criteria. |
|
49 |
|
50 When adding/deleting contacts in the view, MContactViewObserver observer will receive |
|
51 TContactViewEvent events with iInt parameter set to KErrNone. |
|
52 |
|
53 @param aObserver An observer that receives notifications when this view is |
|
54 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
55 event when the view is ready. An attempt to use the view before this notification |
|
56 causes a panic. |
|
57 @param aDb The database containing the contact items. |
|
58 @param aView The underlying view. |
|
59 @param aBoundary A string containing the sub view criteria. Possible values |
|
60 are: <, >, <=, or >=, followed by a character. |
|
61 @return The newly constructed sub view object. */ |
|
62 { |
|
63 #ifdef CNTVIEW_API_PROFILING |
|
64 RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); |
|
65 #endif |
|
66 CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); |
|
67 CleanupStack::PushL(self); |
|
68 self->ConstructL(aObserver,aBoundary); |
|
69 CleanupStack::Pop(self); |
|
70 return self; |
|
71 } |
|
72 |
|
73 EXPORT_C CContactSubView* CContactSubView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,CContactViewBase& aView,const TDesC& aLowBoundary,const TDesC& aHighBoundary) |
|
74 /** Allocates and constructs a new CContactSubView version 1 object, specifying the sub view's |
|
75 upper and lower boundary criteria. |
|
76 |
|
77 When adding/deleting contacts in the view, MContactViewObserver observer will receive |
|
78 TContactViewEvent events with iInt parameter set to KErrNone. |
|
79 |
|
80 @param aObserver An observer that receives notifications when this view is |
|
81 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
82 event when the view is ready. An attempt to use the view before this notification |
|
83 causes a panic. |
|
84 @param aDb The database containing the contact items. |
|
85 @param aView The underlying view. |
|
86 @param aLowBoundary A string containing the sub view's lower boundary criteria. |
|
87 Possible values are: > or >=, followed by a character. |
|
88 @param aHighBoundary A string containing the sub view's upper boundary criteria. |
|
89 Possible values are: < or <=, followed by a character. |
|
90 @return The newly constructed sub view object. */ |
|
91 { |
|
92 #ifdef CNTVIEW_API_PROFILING |
|
93 RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); |
|
94 #endif |
|
95 CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); |
|
96 CleanupStack::PushL(self); |
|
97 self->ConstructL(aObserver,aLowBoundary,aHighBoundary); |
|
98 CleanupStack::Pop(self); |
|
99 return self; |
|
100 } |
|
101 |
|
102 EXPORT_C CContactSubView* CContactSubView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,const TDesC& aBoundary) |
|
103 /** Allocates and constructs a new CContactSubView version 2 object, specifying the sub view's |
|
104 criteria. |
|
105 |
|
106 When adding/deleting contacts in the view, MContactViewObserver observer will receive |
|
107 TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item |
|
108 |
|
109 @param aObserver An observer that receives notifications when this view is |
|
110 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
111 event when the view is ready. An attempt to use the view before this notification |
|
112 causes a panic. |
|
113 @param aDb The database containing the contact items. |
|
114 @param aView The underlying view. |
|
115 @param aBoundary A string containing the sub view criteria. Possible values |
|
116 are: <, >, <=, or >=, followed by a character. |
|
117 @return The newly constructed sub view object. */ |
|
118 { |
|
119 #ifdef CNTVIEW_API_PROFILING |
|
120 RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); |
|
121 #endif |
|
122 CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); |
|
123 CleanupStack::PushL(self); |
|
124 self->ConstructL(aObserver,aBoundary); |
|
125 self->iClassVersion = KClassVersion2; |
|
126 CleanupStack::Pop(self); |
|
127 return self; |
|
128 } |
|
129 |
|
130 EXPORT_C CContactSubView* CContactSubView::NewL(CContactViewBase& aView,const CContactDatabase& aDb,MContactViewObserver& aObserver,const TDesC& aLowBoundary,const TDesC& aHighBoundary) |
|
131 /** Allocates and constructs a new CContactSubView version 2 object, specifying the sub view's |
|
132 upper and lower boundary criteria. |
|
133 |
|
134 When adding/deleting contacts in the view, MContactViewObserver observer will receive |
|
135 TContactViewEvent events with iInt parameter set to index into the observed view of the added/deleted item |
|
136 |
|
137 @param aObserver An observer that receives notifications when this view is |
|
138 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady |
|
139 event when the view is ready. An attempt to use the view before this notification |
|
140 causes a panic. |
|
141 @param aDb The database containing the contact items. |
|
142 @param aView The underlying view. |
|
143 @param aLowBoundary A string containing the sub view's lower boundary criteria. |
|
144 Possible values are: > or >=, followed by a character. |
|
145 @param aHighBoundary A string containing the sub view's upper boundary criteria. |
|
146 Possible values are: < or <=, followed by a character. |
|
147 @return The newly constructed sub view object. */ |
|
148 { |
|
149 #ifdef CNTVIEW_API_PROFILING |
|
150 RDebug::Print(_L("[CNTMODEL] CContactSubView::NewL()\n")); |
|
151 #endif |
|
152 CContactSubView* self=new(ELeave) CContactSubView(aDb,aView); |
|
153 CleanupStack::PushL(self); |
|
154 self->ConstructL(aObserver,aLowBoundary,aHighBoundary); |
|
155 self->iClassVersion = KClassVersion2; |
|
156 CleanupStack::Pop(self); |
|
157 return self; |
|
158 } |
|
159 |
|
160 /** |
|
161 * This is a reserved virtual exported function that is used for BC proofing |
|
162 * against present and future additions of new exported virtual functions. |
|
163 @return Any return values of the helper methods called from this function or NULL. |
|
164 */ |
|
165 TAny* CContactSubView::CContactViewBase_Reserved_1(TFunction aFunction,TAny* aParams) |
|
166 { |
|
167 return CContactViewBase::CContactViewBase_Reserved_1(aFunction,aParams); |
|
168 } |
|
169 |
|
170 void CContactSubView::CommonConstructL(MContactViewObserver& aObserver) |
|
171 { |
|
172 CContactViewBase::ConstructL(); |
|
173 OpenL(aObserver); |
|
174 iView.OpenL(*this); |
|
175 } |
|
176 |
|
177 void CContactSubView::ConstructL(MContactViewObserver& aObserver,const TDesC& aBoundary) |
|
178 { |
|
179 CommonConstructL(aObserver); |
|
180 TBuf<KMaxBoundaryMatchLength+2> boundary(aBoundary); |
|
181 CContactViewRangeBase::TCriteria criteria(DecodeBoundary(boundary)); |
|
182 switch (criteria) |
|
183 { |
|
184 case CContactViewRangeBase::ELessThan: |
|
185 case CContactViewRangeBase::ELessThanOrEqualTo: |
|
186 iRange=NULL; |
|
187 iRange=CContactViewLowRange::NewL(iView,boundary,criteria); |
|
188 break; |
|
189 case CContactViewRangeBase::EGreaterThan: |
|
190 case CContactViewRangeBase::EGreaterThanOrEqualTo: |
|
191 iRange=NULL; |
|
192 iRange=CContactViewHighRange::NewL(iView,boundary,criteria); |
|
193 break; |
|
194 default: |
|
195 ASSERT(EFalse); |
|
196 } |
|
197 } |
|
198 |
|
199 void CContactSubView::ConstructL(MContactViewObserver& aObserver,const TDesC& aLowBoundary,const TDesC& aHighBoundary) |
|
200 { |
|
201 CommonConstructL(aObserver); |
|
202 TBuf<KMaxBoundaryMatchLength+2> lowBoundary(aLowBoundary); |
|
203 CContactViewRangeBase::TCriteria lowCriteria(DecodeBoundary(lowBoundary)); |
|
204 TBuf<KMaxBoundaryMatchLength+2> highBoundary(aHighBoundary); |
|
205 CContactViewRangeBase::TCriteria highCriteria(DecodeBoundary(highBoundary)); |
|
206 iRange=NULL; |
|
207 iRange=CContactViewRange::NewL(iView,lowBoundary,lowCriteria,highBoundary,highCriteria); |
|
208 } |
|
209 |
|
210 |
|
211 CContactViewRangeBase::TCriteria CContactSubView::DecodeBoundary(TDes& aBoundary) const |
|
212 { |
|
213 CContactViewRangeBase::TCriteria criteria(CContactViewRangeBase::ELessThan); |
|
214 |
|
215 switch (aBoundary[0]) |
|
216 { |
|
217 case '<': |
|
218 criteria=CContactViewRangeBase::ELessThan; |
|
219 break; |
|
220 case '>': |
|
221 criteria=CContactViewRangeBase::EGreaterThan; |
|
222 break; |
|
223 default: |
|
224 __ASSERT_DEBUG(EFalse,Panic(ECntPanicNoViewIndexMatchCriteria)); |
|
225 } |
|
226 |
|
227 aBoundary.Delete(0,1); // Delete first char. |
|
228 |
|
229 if (aBoundary[0]=='=') |
|
230 { |
|
231 switch (criteria) |
|
232 { |
|
233 case CContactViewRangeBase::ELessThan: |
|
234 criteria=CContactViewRangeBase::ELessThanOrEqualTo; |
|
235 break; |
|
236 case CContactViewRangeBase::EGreaterThan: |
|
237 criteria=CContactViewRangeBase::EGreaterThanOrEqualTo; |
|
238 break; |
|
239 } |
|
240 aBoundary.Delete(0,1); // Delete first char. |
|
241 } |
|
242 |
|
243 return criteria; |
|
244 } |
|
245 |
|
246 TContactItemId CContactSubView::AtL(TInt aIndex) const |
|
247 /** Gets the contact item ID at the specified index into the sub view. |
|
248 |
|
249 In release builds, zero is returned if the sub view's upper and lower boundaries |
|
250 have not been set, (in debug builds, a panic occurs). |
|
251 |
|
252 @param aIndex Index into the sub view of a contact item ID. |
|
253 @leave KErrNotFound aIndex is outside the bounds of the sub view's array. |
|
254 @return The contact item ID. */ |
|
255 { |
|
256 if (iRange->IndicesValid()) |
|
257 { |
|
258 if(!(iRange->LowIndex()+aIndex<=iRange->HighIndex())) |
|
259 { |
|
260 //Out of Bounds |
|
261 User::Leave(KErrNotFound); |
|
262 } |
|
263 return iView.AtL(MapToUnderlyingViewIndex(aIndex)); |
|
264 } |
|
265 __ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView)); |
|
266 return 0; |
|
267 } |
|
268 |
|
269 const CViewContact& CContactSubView::ContactAtL(TInt aIndex) const |
|
270 /** Gets the contact item at the specified index into the sub view. |
|
271 |
|
272 A NULL contact item is returned if the sub view's upper and lower boundaries |
|
273 have not been set (in debug builds, a panic occurs). |
|
274 |
|
275 @param aIndex Index into the sub view of the required item. |
|
276 @leave KErrNotFound aIndex is outside the bounds of the sub view's array. |
|
277 @return The contact item. */ |
|
278 { |
|
279 if (iRange->IndicesValid()) |
|
280 { |
|
281 if(!(iRange->LowIndex()+aIndex<=iRange->HighIndex())) |
|
282 { |
|
283 //Out of Bounds |
|
284 User::Leave(KErrNotFound); |
|
285 } |
|
286 return iView.ContactAtL(MapToUnderlyingViewIndex(aIndex)); |
|
287 } |
|
288 __ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView)); |
|
289 // the following code is never executed and is purely to stop the compiler warnings |
|
290 const CViewContact* nullContact=NULL; |
|
291 return *nullContact; |
|
292 } |
|
293 |
|
294 TInt CContactSubView::CountL() const |
|
295 /** Gets the number of contact item IDs in the sub view. |
|
296 |
|
297 Zero is returned if the sub view's upper and lower boundaries have not been |
|
298 set. |
|
299 |
|
300 @return The number of contact item IDs in the sub view. */ |
|
301 { |
|
302 if (iRange->IndicesValid()) |
|
303 { |
|
304 return iRange->HighIndex()-iRange->LowIndex()+1; |
|
305 } |
|
306 return 0; |
|
307 } |
|
308 |
|
309 TInt CContactSubView::FindL(TContactItemId aId) const |
|
310 /** Finds the index into the sub view of the specified contact item. |
|
311 |
|
312 @param aId The contact item ID to search for. |
|
313 @return The index of the first matching item in the sub view or KErrNotFound |
|
314 if the sub view's upper and lower boundaries have not been set or if the item |
|
315 is not in the sub view. */ |
|
316 { |
|
317 const TInt index=iView.FindL(aId); |
|
318 if (iRange->IndicesValid() && index>=iRange->LowIndex() && index<=iRange->HighIndex()) |
|
319 { |
|
320 return MapToSubViewIndex(index); |
|
321 } |
|
322 return KErrNotFound; |
|
323 } |
|
324 |
|
325 HBufC* CContactSubView::AllFieldsLC(TInt aIndex,const TDesC& aSeparator) const |
|
326 /** Returns a descriptor containing the contents of all fields for an item in the |
|
327 sub view. |
|
328 |
|
329 NULL is returned if the sub view's upper and lower boundaries have not been |
|
330 set (in debug builds, a panic occurs). |
|
331 |
|
332 @param aIndex The index into the sub view of the contact item. |
|
333 @param aSeparator The string to use to separate the fields. |
|
334 @return Pointer to the contact item descriptor. */ |
|
335 { |
|
336 if (iRange->IndicesValid()) |
|
337 { |
|
338 return iView.AllFieldsLC(MapToUnderlyingViewIndex(aIndex),aSeparator); |
|
339 } |
|
340 __ASSERT_DEBUG(EFalse,Panic(ECntPanicInvalidIndexForSubView)); |
|
341 return NULL; |
|
342 } |
|
343 |
|
344 const RContactViewSortOrder& CContactSubView::SortOrderL() const |
|
345 /** Gets the underlying view's sort order. |
|
346 |
|
347 @return The sort order. */ |
|
348 { |
|
349 return iView.SortOrderL(); |
|
350 } |
|
351 |
|
352 TContactViewPreferences CContactSubView::ContactViewPreferences() |
|
353 /** Gets the underlying view's view preferences. |
|
354 |
|
355 @return The view preferences. */ |
|
356 { |
|
357 return iView.ContactViewPreferences(); |
|
358 } |
|
359 |
|
360 #ifdef _DEBUG |
|
361 void CContactSubView::HandleContactViewEvent(const CContactViewBase& aView,const TContactViewEvent& aEvent) |
|
362 #else |
|
363 void CContactSubView::HandleContactViewEvent(const CContactViewBase& /*aView*/,const TContactViewEvent& aEvent) |
|
364 #endif |
|
365 { |
|
366 ASSERT(&aView==&iView); |
|
367 TBool notifyObservers=ETrue; |
|
368 TContactViewEvent event=aEvent; |
|
369 switch (event.iEventType) |
|
370 { |
|
371 case TContactViewEvent::EUnavailable: |
|
372 case TContactViewEvent::ESortError: |
|
373 case TContactViewEvent::EServerError: |
|
374 iState=ENotReady; |
|
375 break; |
|
376 case TContactViewEvent::EReady: |
|
377 case TContactViewEvent::ESortOrderChanged: |
|
378 { |
|
379 TRAPD(err,iRange->SetL()); |
|
380 if (err) |
|
381 { |
|
382 event.iEventType=TContactViewEvent::EIndexingError; |
|
383 event.iInt=err; |
|
384 } |
|
385 else |
|
386 { |
|
387 iState=EReady; |
|
388 } |
|
389 } |
|
390 break; |
|
391 case TContactViewEvent::EItemAdded: |
|
392 case TContactViewEvent::EItemRemoved: |
|
393 // notifyObservers=iRange->Update(event); |
|
394 TRAPD(err,iRange->SetL()); |
|
395 if (err) |
|
396 { |
|
397 event.iEventType=TContactViewEvent::EIndexingError; |
|
398 event.iInt=err; |
|
399 } |
|
400 else |
|
401 { |
|
402 //get the contact index within subview |
|
403 if(iClassVersion == KClassVersion2) |
|
404 { |
|
405 if(iRange->LowIndex() == KErrNotFound) |
|
406 { |
|
407 notifyObservers = EFalse; |
|
408 } |
|
409 else |
|
410 { |
|
411 event.iInt -= iRange->LowIndex(); |
|
412 } |
|
413 } |
|
414 else |
|
415 { |
|
416 event.iInt = KErrNone; |
|
417 } |
|
418 } |
|
419 break; |
|
420 case TContactViewEvent::EGroupChanged: |
|
421 break; |
|
422 default: |
|
423 ASSERT(EFalse); |
|
424 } |
|
425 |
|
426 if (notifyObservers) |
|
427 { |
|
428 NotifyObservers(event); |
|
429 } |
|
430 } |
|
431 |
|
432 TInt CContactSubView::MapToUnderlyingViewIndex(TInt aSubViewIndex) const |
|
433 { |
|
434 ASSERT(iRange->IndicesValid()); |
|
435 return aSubViewIndex+iRange->LowIndex(); |
|
436 } |
|
437 |
|
438 TInt CContactSubView::MapToSubViewIndex(TInt aUnderlyingViewIndex) const |
|
439 { |
|
440 ASSERT(iRange->IndicesValid()); |
|
441 return aUnderlyingViewIndex-iRange->LowIndex(); |
|
442 } |