|
1 /* |
|
2 * Copyright (c) 2005-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 /** |
|
20 @file |
|
21 @internalComponent |
|
22 @released |
|
23 */ |
|
24 |
|
25 |
|
26 #include "clplanalyserproxy.h" |
|
27 #include <cntitem.h> |
|
28 #include <cntfldst.h> |
|
29 |
|
30 /** |
|
31 CLplAnalyserProxy constructor. |
|
32 */ |
|
33 CLplAnalyserProxy::CLplAnalyserProxy(MIniFileManager& aIniManager, MContactDbObserverV2& aCntDbObserver, MLplPersistenceBroker& aBroker, MLplTransactionManager& aTranMan, MLplContactProperties& aProperties) |
|
34 : |
|
35 CLplGenericProxy(aBroker, aTranMan), |
|
36 iCntDbObserver(aCntDbObserver), |
|
37 iIniManager(aIniManager), |
|
38 iProperties(aProperties) |
|
39 { |
|
40 } |
|
41 |
|
42 |
|
43 /** |
|
44 Create a new Contact item. |
|
45 */ |
|
46 TContactItemId CLplAnalyserProxy::CreateL(CContactItem& aItem, TUint aSessionId) |
|
47 { |
|
48 #if defined(__PROFILE_DEBUG__) |
|
49 RDebug::Print(_L("[CNTMODEL] MTD: CLplAnalyserProxy::CreateL")); |
|
50 #endif |
|
51 |
|
52 // Delegate creation to generic proxy. |
|
53 TContactItemId cntId = CLplGenericProxy::CreateL(aItem, aSessionId); |
|
54 |
|
55 // Notify observer of the change. |
|
56 switch(aItem.Type().iUid) |
|
57 { |
|
58 case KUidContactCardTemplateValue: |
|
59 { |
|
60 NotifyObserverL(EContactDbObserverEventTemplateAdded, aItem.Id()); |
|
61 } |
|
62 break; |
|
63 case KUidContactGroupValue: |
|
64 { |
|
65 NotifyObserverL(EContactDbObserverEventGroupAdded, aItem.Id()); |
|
66 } |
|
67 break; |
|
68 case KUidContactCardValue: |
|
69 case KUidContactOwnCardValue: |
|
70 case KUidContactICCEntryValue: |
|
71 { |
|
72 NotifyObserverL(EContactDbObserverEventContactAdded, aItem.Id()); |
|
73 } |
|
74 break; |
|
75 default: |
|
76 break; |
|
77 }; |
|
78 |
|
79 return(cntId); |
|
80 } |
|
81 |
|
82 |
|
83 /** |
|
84 Update an existing Contact item (or parts of it as specified by the view |
|
85 definition). |
|
86 */ |
|
87 void CLplAnalyserProxy::UpdateL(CContactItem& aItem, TUint aSessionId, TBool aSpeeDailUpdate) |
|
88 { |
|
89 // Delegate update to generic proxy. |
|
90 CLplGenericProxy::UpdateL(aItem, aSessionId); |
|
91 |
|
92 // Notify observer of the change. |
|
93 switch(aItem.Type().iUid) |
|
94 { |
|
95 case KUidContactTemplateValue: |
|
96 case KUidContactCardTemplateValue: |
|
97 { |
|
98 NotifyObserverL(EContactDbObserverEventTemplateChanged, aItem.Id()); |
|
99 } |
|
100 break; |
|
101 case KUidContactOwnCardValue: |
|
102 { |
|
103 NotifyObserverL(EContactDbObserverEventOwnCardChanged, aItem.Id()); |
|
104 // If an item with a speed dial is updated then update the speed |
|
105 // dials. |
|
106 (void)CheckSpeedDialUpdatesL(aItem); |
|
107 } |
|
108 break; |
|
109 case KUidContactGroupValue: |
|
110 { |
|
111 // send basic group change event.. |
|
112 NotifyObserverL(EContactDbObserverEventGroupChanged, aItem.Id(), 0, |
|
113 EContactDbObserverEventV2Null, 0); |
|
114 |
|
115 // ... and extended group change event |
|
116 CContactGroup& groupItem = static_cast<CContactGroup&>(aItem); |
|
117 bool groupMemberListUpdated = false; |
|
118 if (groupItem.iAddedContactIds != NULL && groupItem.iAddedContactIds->Count() > 0) |
|
119 { |
|
120 //some contacts were added |
|
121 groupMemberListUpdated = true; |
|
122 for (int i = 0; i < groupItem.iAddedContactIds->Count(); i++) |
|
123 { |
|
124 NotifyObserverL(EContactDbObserverEventNull, aItem.Id(), 0, |
|
125 EContactDbObserverEventV2ContactAddedToGroup, groupItem.iAddedContactIds->operator[](i)); |
|
126 } |
|
127 } |
|
128 if (groupItem.iRemovedContactIds != NULL && groupItem.iRemovedContactIds->Count() > 0) |
|
129 { |
|
130 //some contacts were removed |
|
131 groupMemberListUpdated = true; |
|
132 for (int i = 0; i < groupItem.iRemovedContactIds->Count(); i++) |
|
133 { |
|
134 NotifyObserverL(EContactDbObserverEventNull, aItem.Id(), 0, |
|
135 EContactDbObserverEventV2ContactRemovedFromGroup, groupItem.iRemovedContactIds->operator[](i)); |
|
136 } |
|
137 } |
|
138 if (!groupMemberListUpdated) |
|
139 { |
|
140 NotifyObserverL(EContactDbObserverEventNull, aItem.Id(), 0, |
|
141 EContactDbObserverEventV2GroupChanged, 0); |
|
142 } |
|
143 } |
|
144 break; |
|
145 case KUidContactCardValue: |
|
146 case KUidContactICCEntryValue: |
|
147 { |
|
148 // If an item with a speed dial is updated then update the speed |
|
149 // dials. |
|
150 if (!CheckSpeedDialUpdatesL(aItem) || !aSpeeDailUpdate) |
|
151 { |
|
152 NotifyObserverL(EContactDbObserverEventContactChanged, aItem.Id()); |
|
153 } |
|
154 } |
|
155 break; |
|
156 default: |
|
157 break; |
|
158 }; |
|
159 } |
|
160 |
|
161 |
|
162 /** |
|
163 Delete a Contact item. |
|
164 */ |
|
165 CContactItem* CLplAnalyserProxy::DeleteLC(TContactItemId aItemId, TUint aSessionId, TCntSendEventAction aEventType) |
|
166 { |
|
167 // Delegate delete to generic proxy. |
|
168 CContactItem* item = CLplGenericProxy::DeleteLC(aItemId, aSessionId, aEventType); |
|
169 |
|
170 // Notify observer of the change. |
|
171 switch(item->Type().iUid) |
|
172 { |
|
173 case KUidContactCardTemplateValue: |
|
174 { |
|
175 NotifyObserverL(EContactDbObserverEventTemplateDeleted, item->Id()); |
|
176 // If the prefered template is deleted then do the appropriate |
|
177 // follow up actions. |
|
178 CheckPrefTemplateDeleteL(aItemId); |
|
179 } |
|
180 break; |
|
181 case KUidContactOwnCardValue: |
|
182 { |
|
183 if (aEventType == ESendEvent) |
|
184 { |
|
185 NotifyObserverL(EContactDbObserverEventOwnCardDeleted, item->Id()); |
|
186 } |
|
187 else if (aEventType == ESendUnknownChangesEvent) |
|
188 { |
|
189 NotifyObserverL(EContactDbObserverEventUnknownChanges, KNullContactId); |
|
190 } |
|
191 |
|
192 // If an item with a speed dial is deleted then update the speed |
|
193 // dials. |
|
194 CheckSpeedDialDeletesL(aItemId); |
|
195 // Resets the Own Card ID to be KNullContactId. |
|
196 iProperties.SetOwnCardIdL(KNullContactId); |
|
197 } |
|
198 break; |
|
199 case KUidContactGroupValue: |
|
200 { |
|
201 NotifyObserverL(EContactDbObserverEventGroupDeleted, item->Id()); |
|
202 } |
|
203 break; |
|
204 case KUidContactCardValue: |
|
205 case KUidContactICCEntryValue: |
|
206 { |
|
207 // If an item with a speed dial is deleted then update the speed |
|
208 // dials. |
|
209 (void)CheckSpeedDialDeletesL(aItemId); |
|
210 if (aEventType == ESendEvent) |
|
211 { |
|
212 NotifyObserverL(EContactDbObserverEventContactDeleted, item->Id()); |
|
213 } |
|
214 else if (aEventType == ESendUnknownChangesEvent) |
|
215 { |
|
216 NotifyObserverL(EContactDbObserverEventUnknownChanges, KNullContactId); |
|
217 } |
|
218 } |
|
219 break; |
|
220 default: |
|
221 break; |
|
222 }; |
|
223 |
|
224 // Check if we deleted the current item (managed by initialisation file |
|
225 // manager). |
|
226 iIniManager.DeleteNotifyL(aItemId); |
|
227 |
|
228 return(item); |
|
229 } |
|
230 |
|
231 |
|
232 /** |
|
233 Change the type of an existing Contact item. |
|
234 */ |
|
235 void CLplAnalyserProxy::ChangeTypeL(TContactItemId aItemId, TUid aNewType) |
|
236 { |
|
237 // Delegate type change to generic proxy. |
|
238 CLplGenericProxy::ChangeTypeL(aItemId, aNewType); |
|
239 |
|
240 // If a Contact item is changed to be the Own Card then we need to notify |
|
241 // observers of the change. |
|
242 if (aNewType.iUid == KUidContactOwnCardValue) |
|
243 { |
|
244 NotifyObserverL(EContactDbObserverEventOwnCardChanged, aItemId); |
|
245 } |
|
246 } |
|
247 |
|
248 |
|
249 /** |
|
250 Set the connection ID to be used when notifying observer of a database event |
|
251 (unless a specific connection ID is specified when calling NotifyObserverL()). |
|
252 */ |
|
253 void CLplAnalyserProxy::SetConnectionId(TInt aConnectionId) |
|
254 { |
|
255 iConnectionId = aConnectionId; |
|
256 } |
|
257 |
|
258 |
|
259 /** |
|
260 Notify observer of database event. |
|
261 */ |
|
262 void CLplAnalyserProxy::NotifyObserverL(const TContactDbObserverEventType aType, |
|
263 const TContactItemId aContactId, const TUint aConnectionId, |
|
264 const TContactDbObserverEventTypeV2 aTypeV2, const TContactItemId aAdditionalContactId) |
|
265 { |
|
266 #if defined(__PROFILE_DEBUG__) |
|
267 RDebug::Print(_L("[CNTMODEL] MTD: CLplAnalyserProxy::NotifyObserverL")); |
|
268 #endif |
|
269 |
|
270 TContactDbObserverEventV2 event; |
|
271 event.iType = aType; |
|
272 event.iContactId = aContactId; |
|
273 |
|
274 if(!aConnectionId) |
|
275 { |
|
276 event.iConnectionId = iConnectionId; |
|
277 } |
|
278 else |
|
279 { |
|
280 event.iConnectionId = aConnectionId; |
|
281 } |
|
282 |
|
283 event.iTypeV2 = aTypeV2; |
|
284 event.iAdditionalContactId = aAdditionalContactId; |
|
285 |
|
286 iCntDbObserver.HandleDatabaseEventV2L(event); |
|
287 |
|
288 // Reset connection ID. |
|
289 iConnectionId = 0; |
|
290 } |
|
291 |
|
292 |
|
293 TBool CLplAnalyserProxy::CheckSpeedDialUpdatesL(CContactItem& aItem) |
|
294 { |
|
295 TBool retValue = EFalse; |
|
296 |
|
297 // Check if the specified Contact ID is present in the speed dial array. |
|
298 // The method returns the number of occurances: if zero then this contact |
|
299 // is not in the speed dial table. |
|
300 CArrayFix<TInt>* speedDialIndices = iIniManager.SpeedDialIndicesForContactIdLC(aItem.Id()); |
|
301 |
|
302 // Because this contact has one or more speed dial entries we need to ensure |
|
303 // that the server-side speed dial array is kept up to date with any changes |
|
304 // by the client. |
|
305 for(TInt count = speedDialIndices->Count() -1 ; count>=0; --count) |
|
306 { |
|
307 // So there is at least one speed dial with the particular contact ID. |
|
308 // Fetch speed dial index from array returned by server. |
|
309 TInt speedDialIndex = speedDialIndices->At(count); |
|
310 // Fetch phone number associated with speed dial position. |
|
311 TUid fieldTypeUid = SpeedDialFieldUidFromSpeedDialPosition(speedDialIndex); |
|
312 TInt fieldPos = aItem.CardFields().Find(fieldTypeUid); |
|
313 |
|
314 // Check if the phone number field associated with the speed dial has |
|
315 // been updated. |
|
316 if (fieldPos >= KErrNone) |
|
317 { |
|
318 // Get the requested field (i.e. the field containing the number for |
|
319 // the speed dial). |
|
320 CContactItemField& speeddialField = aItem.CardFields()[fieldPos]; |
|
321 // Check if it is a text field otherwise leave. |
|
322 if (speeddialField.StorageType() != KStorageTypeText) |
|
323 { |
|
324 User::Leave(KErrUnknown); |
|
325 } |
|
326 // Fetch phone number associated with speed dial position. |
|
327 // Truncate it if its length is > KSpeedDialPhoneLength |
|
328 TInt numLen = Min(speeddialField.TextStorage()->Text().Length(), KSpeedDialPhoneLength ); |
|
329 TPtrC phoneNumber(speeddialField.TextStorage()->Text().Mid(0, numLen)); |
|
330 // Update the server with the value of this speed dial. |
|
331 iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, aItem.Id(), phoneNumber, iConnectionId, ETrue); |
|
332 retValue = ETrue; |
|
333 } |
|
334 else |
|
335 { |
|
336 // The phone number field associated with the speed dial has been |
|
337 // deleted. |
|
338 iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, KNullContactId, KNullDesC(), iConnectionId, ETrue); |
|
339 retValue = ETrue; |
|
340 } |
|
341 } |
|
342 |
|
343 CleanupStack::PopAndDestroy(speedDialIndices); |
|
344 |
|
345 return retValue; |
|
346 } |
|
347 |
|
348 |
|
349 TBool CLplAnalyserProxy::CheckSpeedDialDeletesL(TContactItemId aItemId) |
|
350 { |
|
351 TBool retValue = EFalse; |
|
352 // Check if the specified contact ID is present in the speed dial array. |
|
353 // The method returns the number of occurances: if zero then this contact |
|
354 // is not in the speed dial table. |
|
355 CArrayFix<TInt>* speedDialIndices = iIniManager.SpeedDialIndicesForContactIdLC(aItemId); |
|
356 |
|
357 // Because this contact has one or more speed dial entries we need to ensure |
|
358 // that the server-side speed dial array is kept up to date with any changes |
|
359 // by the client. |
|
360 for(TInt count = speedDialIndices->Count() -1 ; count>=0; --count) |
|
361 { |
|
362 // Fetch speed dial index. |
|
363 TInt speedDialIndex = speedDialIndices->At(count); |
|
364 // Update the speed dial. |
|
365 iIniManager.SetSpeedDialIdForPositionL(speedDialIndex, KNullContactId, KNullDesC(), iConnectionId, ETrue); |
|
366 retValue = ETrue; |
|
367 } |
|
368 |
|
369 CleanupStack::PopAndDestroy(speedDialIndices); |
|
370 |
|
371 return retValue; |
|
372 } |
|
373 |
|
374 |
|
375 void CLplAnalyserProxy::CheckPrefTemplateDeleteL(TContactItemId aItemId) |
|
376 { |
|
377 if (iProperties.CardTemplatePrefIdL() == aItemId) |
|
378 { |
|
379 // Make sure the Own Card ID is persisted and up to date. |
|
380 iProperties.SetCardTemplatePrefIdL(KNullContactId); |
|
381 // There was no notification in the old contacts model but there |
|
382 // probably should have been. |
|
383 NotifyObserverL(EContactDbObserverEventPreferredTemplateChanged, aItemId); |
|
384 } |
|
385 } |
|
386 |
|
387 |
|
388 /** |
|
389 Static utility method to map a speed dial index onto a field type UID. |
|
390 |
|
391 Note: this method is duplicated, should be refactored into shared code/library. |
|
392 */ |
|
393 TUid CLplAnalyserProxy::SpeedDialFieldUidFromSpeedDialPosition(TInt aSpeedDialPosition) |
|
394 { |
|
395 TUid fieldTypeUid = KNullUid; |
|
396 switch (aSpeedDialPosition) |
|
397 { |
|
398 case 1: |
|
399 fieldTypeUid = KUidSpeedDialOne; |
|
400 break; |
|
401 case 2: |
|
402 fieldTypeUid = KUidSpeedDialTwo; |
|
403 break; |
|
404 case 3: |
|
405 fieldTypeUid = KUidSpeedDialThree; |
|
406 break; |
|
407 case 4: |
|
408 fieldTypeUid = KUidSpeedDialFour; |
|
409 break; |
|
410 case 5: |
|
411 fieldTypeUid = KUidSpeedDialFive; |
|
412 break; |
|
413 case 6: |
|
414 fieldTypeUid = KUidSpeedDialSix; |
|
415 break; |
|
416 case 7: |
|
417 fieldTypeUid = KUidSpeedDialSeven; |
|
418 break; |
|
419 case 8: |
|
420 fieldTypeUid = KUidSpeedDialEight; |
|
421 break; |
|
422 case 9: |
|
423 fieldTypeUid = KUidSpeedDialNine; |
|
424 break; |
|
425 } |
|
426 return fieldTypeUid; |
|
427 } |
|
428 |
|
429 |
|
430 /** |
|
431 Rollback the current transation in the Persistence Layer. |
|
432 */ |
|
433 void CLplAnalyserProxy::RollbackCurrentTransactionL(TUint aSessionId) |
|
434 { |
|
435 // Delegate rollback to generic proxy. |
|
436 CLplGenericProxy::RollbackCurrentTransactionL(aSessionId); |
|
437 // Notify observer of the rollback. |
|
438 NotifyObserverL(EContactDbObserverEventRollback, 0); |
|
439 } |