39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 //system includes |
41 //system includes |
42 #include <e32base.h> |
42 #include <e32base.h> |
43 #include <s32mem.h> |
43 #include <s32mem.h> |
|
44 #include <cntitem.h> |
44 |
45 |
45 //user includes |
46 //user includes |
46 #include "cntsymbiandatabase.h" |
47 #include "cntsymbiandatabase.h" |
47 #include "cntsymbiantransformerror.h" |
48 #include "cntsymbiantransformerror.h" |
48 #include "qcontactchangeset.h" |
49 #include "qcontactchangeset.h" |
49 #include "qcontactmanagerengine.h" |
50 #include "qcontactmanagerengine.h" |
50 |
51 |
51 // Constant |
52 // Constant |
52 typedef QPair<QContactLocalId, QContactLocalId> QOwnCardPair; |
53 typedef QPair<QContactLocalId, QContactLocalId> QOwnCardPair; |
53 |
54 |
54 CntSymbianDatabase::CntSymbianDatabase(QContactManagerEngine *engine, QContactManager::Error& error) : |
55 CntSymbianDatabase::CntSymbianDatabase(QContactManagerEngine *engine, QContactManager::Error* error) : |
|
56 m_engine(engine), |
55 m_contactDatabase(0), |
57 m_contactDatabase(0), |
56 m_currentOwnCardId(0) |
58 m_currentOwnCardId(0) |
57 { |
59 { |
58 TRAPD(err, m_contactDatabase = CContactDatabase::OpenL()) |
60 TRAPD(err, initializeL()); |
59 |
61 CntSymbianTransformError::transformError(err, error); |
60 //Database not found, create it |
62 } |
61 if(err == KErrNotFound) |
63 |
62 { |
64 void CntSymbianDatabase::initializeL() |
63 TRAP(err, m_contactDatabase = CContactDatabase::CreateL()) |
65 { |
64 } |
66 User::LeaveIfNull(m_engine); |
65 |
67 |
66 //Database opened successfully |
68 TRAPD(err, m_contactDatabase = CContactDatabase::OpenL()); |
67 if (err == KErrNone) |
69 |
68 { |
70 // Database not found, create it |
|
71 if(err == KErrNotFound) { |
|
72 m_contactDatabase = CContactDatabase::CreateL(); |
|
73 } |
|
74 |
|
75 #ifndef SYMBIAN_BACKEND_USE_SQLITE |
69 // In pre 10.1 platforms the AddObserverL & RemoveObserver functions are not |
76 // In pre 10.1 platforms the AddObserverL & RemoveObserver functions are not |
70 // exported so we need to use CContactChangeNotifier. |
77 // exported so we need to use CContactChangeNotifier. |
71 #ifndef SYMBIAN_BACKEND_USE_SQLITE |
78 TRAP(err, m_contactChangeNotifier = CContactChangeNotifier::NewL(*m_contactDatabase, this)); |
72 TRAP(err, m_contactChangeNotifier = CContactChangeNotifier::NewL(*m_contactDatabase, this)); |
|
73 #else |
79 #else |
74 TRAP(err, m_contactDatabase->AddObserverL(*this)); |
80 TRAP(err, m_contactDatabase->AddObserverL(*this)); |
75 #endif |
81 #endif |
76 if (err == KErrNone) |
82 |
77 m_engine = engine; |
83 // Read current own card id (self contact id) |
78 |
84 TContactItemId myCard = m_contactDatabase->OwnCardId(); |
79 // Read current own card id (self contact id) |
85 if (myCard > 0) |
80 TContactItemId myCard = m_contactDatabase->OwnCardId(); |
86 m_currentOwnCardId = QContactLocalId(myCard); |
81 if (myCard > 0) |
87 |
82 m_currentOwnCardId = QContactLocalId(myCard); |
88 // Currently the group membership check is only used in pre-10.1 |
83 } |
89 // platforms. In 10.1 we need to check the performance penalty |
84 CntSymbianTransformError::transformError(err, error); |
90 // caused in the instantiation of QContactManager. If the |
|
91 // performance is too bad, then the MContactDbObserver API needs to |
|
92 // be changed in 10.1 so that we don't need the group membership |
|
93 // buffer in the engine level. In other words events like |
|
94 // EContactDbObserverEventGroupMembersAdded and |
|
95 // EContactDbObserverEventGroupMembersRemoved need to be added to |
|
96 // MContactDbObserver. |
|
97 #ifndef SYMBIAN_BACKEND_USE_SQLITE |
|
98 updateGroupMembershipsL(); |
|
99 #endif |
85 } |
100 } |
86 |
101 |
87 CntSymbianDatabase::~CntSymbianDatabase() |
102 CntSymbianDatabase::~CntSymbianDatabase() |
88 { |
103 { |
89 m_engine = NULL; |
104 m_engine = NULL; |
128 { |
143 { |
129 case EContactDbObserverEventContactAdded: |
144 case EContactDbObserverEventContactAdded: |
130 if(m_contactsEmitted.contains(id)) |
145 if(m_contactsEmitted.contains(id)) |
131 m_contactsEmitted.removeOne(id); |
146 m_contactsEmitted.removeOne(id); |
132 else |
147 else |
133 changeSet.addedContacts().insert(id); |
148 changeSet.insertAddedContact(id); |
134 break; |
149 break; |
135 case EContactDbObserverEventOwnCardDeleted: |
150 case EContactDbObserverEventOwnCardDeleted: |
|
151 m_currentOwnCardId = QContactLocalId(0); |
|
152 // ...and send contact deleted event |
136 case EContactDbObserverEventContactDeleted: |
153 case EContactDbObserverEventContactDeleted: |
137 if(m_contactsEmitted.contains(id)) |
154 if(m_contactsEmitted.contains(id)) |
138 m_contactsEmitted.removeOne(id); |
155 m_contactsEmitted.removeOne(id); |
139 else |
156 else |
140 changeSet.removedContacts().insert(id); |
157 changeSet.insertRemovedContact(id); |
141 break; |
158 break; |
142 case EContactDbObserverEventContactChanged: |
159 case EContactDbObserverEventContactChanged: |
143 if(m_contactsEmitted.contains(id)) |
160 if(m_contactsEmitted.contains(id)) |
144 m_contactsEmitted.removeOne(id); |
161 m_contactsEmitted.removeOne(id); |
145 else |
162 else |
146 changeSet.changedContacts().insert(id); |
163 changeSet.insertChangedContact(id); |
147 break; |
164 break; |
148 case EContactDbObserverEventGroupAdded: |
165 case EContactDbObserverEventGroupAdded: |
149 if(m_contactsEmitted.contains(id)) |
166 if(m_contactsEmitted.contains(id)) { |
150 m_contactsEmitted.removeOne(id); |
167 // adding a group triggers also a "changed" event. The work-around |
151 else |
168 // is to leave the id to m_contactsEmitted |
152 changeSet.addedRelationshipsContacts().insert(id); |
169 } else { |
|
170 changeSet.insertAddedContact(id); |
|
171 m_contactsEmitted.append(id); |
|
172 } |
153 break; |
173 break; |
154 case EContactDbObserverEventGroupDeleted: |
174 case EContactDbObserverEventGroupDeleted: |
155 if(m_contactsEmitted.contains(id)) |
175 if(m_contactsEmitted.contains(id)) |
156 m_contactsEmitted.removeOne(id); |
176 m_contactsEmitted.removeOne(id); |
157 else |
177 else |
158 changeSet.removedRelationshipsContacts().insert(id); |
178 changeSet.insertRemovedContact(id); |
159 break; |
179 break; |
160 case EContactDbObserverEventGroupChanged: |
180 case EContactDbObserverEventGroupChanged: |
161 if(m_contactsEmitted.contains(id)) |
181 if(m_contactsEmitted.contains(id)) |
162 m_contactsEmitted.removeOne(id); |
182 m_contactsEmitted.removeOne(id); |
163 else |
183 else { |
164 changeSet.changedContacts().insert(id); //group is a contact |
184 #ifndef SYMBIAN_BACKEND_USE_SQLITE |
|
185 // Contact DB observer API does not give information of contacts |
|
186 // possibly added to or removed from the group |
|
187 QSet<QContactLocalId> added; |
|
188 QSet<QContactLocalId> removed; |
|
189 TRAPD(err, updateGroupMembershipsL(id, added, removed)); |
|
190 if(err != KErrNone){ |
|
191 changeSet.setDataChanged(true); |
|
192 } else if(removed.count()) { |
|
193 // The group changed event was caused by removing contacts |
|
194 // from the group |
|
195 changeSet.insertRemovedRelationshipsContact(id); |
|
196 changeSet.insertRemovedRelationshipsContacts(removed.toList()); |
|
197 } else if(added.count()) { |
|
198 // The group changed event was caused by adding contacts |
|
199 // to the group |
|
200 changeSet.insertAddedRelationshipsContact(id); |
|
201 changeSet.insertAddedRelationshipsContacts(added.toList()); |
|
202 } else { |
|
203 // The group changed event was caused by modifying the group |
|
204 changeSet.insertChangedContact(id); |
|
205 } |
|
206 #else |
|
207 // Currently the group membership check is only used in pre-10.1 |
|
208 // platforms. In 10.1 we need to check the performance penalty |
|
209 // caused in the instantiation of QContactManager. If the |
|
210 // performance is too bad, then the MContactDbObserver API needs to |
|
211 // be changed in 10.1 so that we don't need the group membership |
|
212 // buffer in the engine level. In other words events like |
|
213 // EContactDbObserverEventGroupMembersAdded and |
|
214 // EContactDbObserverEventGroupMembersRemoved need to be added to |
|
215 // MContactDbObserver. |
|
216 changeSet.insertChangedContact(id); //group is a contact |
|
217 #endif |
|
218 } |
165 break; |
219 break; |
166 case EContactDbObserverEventOwnCardChanged: |
220 case EContactDbObserverEventOwnCardChanged: |
167 { |
221 if(m_contactsEmitted.contains(id)) |
|
222 m_contactsEmitted.removeOne(id); |
|
223 else { |
168 QOwnCardPair ownCard(m_currentOwnCardId, QContactLocalId(id)); |
224 QOwnCardPair ownCard(m_currentOwnCardId, QContactLocalId(id)); |
169 changeSet.oldAndNewSelfContactId() = ownCard; |
225 changeSet.setOldAndNewSelfContactId(ownCard); |
170 m_currentOwnCardId = QContactLocalId(id); |
226 m_currentOwnCardId = QContactLocalId(id); |
171 break; |
|
172 } |
227 } |
|
228 break; |
173 default: |
229 default: |
174 break; // ignore other events |
230 break; // ignore other events |
175 } |
231 } |
176 |
232 |
177 changeSet.emitSignals(m_engine); |
233 changeSet.emitSignals(m_engine); |
178 } |
234 } |
179 |
235 |
180 |
236 /* |
181 |
237 * Private implementation for updating the buffer containing the members of all |
182 |
238 * groups. |
183 |
239 */ |
184 |
240 void CntSymbianDatabase::updateGroupMembershipsL() |
|
241 { |
|
242 CContactIdArray *groupIds = m_contactDatabase->GetGroupIdListL(); |
|
243 for (TInt i(0); i < groupIds->Count(); ++i) { |
|
244 QContactLocalId id = (*groupIds)[i]; |
|
245 QSet<QContactLocalId> dummySet; |
|
246 updateGroupMembershipsL(id, dummySet, dummySet); |
|
247 } |
|
248 delete groupIds; |
|
249 } |
|
250 |
|
251 /* |
|
252 * Private implementation for updating the buffer containing the members of a |
|
253 * group. |
|
254 */ |
|
255 void CntSymbianDatabase::updateGroupMembershipsL( |
|
256 QContactLocalId groupId, |
|
257 QSet<QContactLocalId> &added, |
|
258 QSet<QContactLocalId> &removed) |
|
259 { |
|
260 QSet<QContactLocalId> groupMembersNew = groupMembersL(groupId); |
|
261 QSet<QContactLocalId> groupMembersOld = m_groupContents.value(groupId); |
|
262 |
|
263 if(groupMembersOld.count() < groupMembersNew.count()) { |
|
264 added = groupMembersNew - groupMembersOld; |
|
265 m_groupContents.remove(groupId); |
|
266 m_groupContents.insert(groupId, groupMembersNew); |
|
267 } else if(groupMembersOld.count() > groupMembersNew.count()) { |
|
268 removed = groupMembersOld - groupMembersNew; |
|
269 m_groupContents.remove(groupId); |
|
270 m_groupContents.insert(groupId, groupMembersNew); |
|
271 } |
|
272 } |
|
273 |
|
274 /* |
|
275 * Private implementation for fetching the members of a group. |
|
276 */ |
|
277 QSet<QContactLocalId> CntSymbianDatabase::groupMembersL(QContactLocalId groupId) |
|
278 { |
|
279 QSet<QContactLocalId> groupMembers; |
|
280 |
|
281 CContactItem *contactItem = m_contactDatabase->ReadContactLC(TContactItemId(groupId)); |
|
282 Q_ASSERT(contactItem && contactItem->Type() == KUidContactGroup); |
|
283 CContactGroup *group = static_cast<CContactGroup*>(contactItem); |
|
284 |
|
285 const CContactIdArray *idArray = group->ItemsContained(); |
|
286 |
|
287 //loop through all the contacts and add them to the list |
|
288 for (int i(0); i < idArray->Count(); i++) { |
|
289 groupMembers.insert((*idArray)[i]); |
|
290 } |
|
291 CleanupStack::PopAndDestroy(contactItem); |
|
292 |
|
293 return groupMembers; |
|
294 } |