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