210 |
211 |
211 // ---------------------------------------------------------------------------- |
212 // ---------------------------------------------------------------------------- |
212 // CPcsAlgorithm1Utils::CompareDataBySortOrderL() |
213 // CPcsAlgorithm1Utils::CompareDataBySortOrderL() |
213 // TLinearOrder rule for comparison of data objects |
214 // TLinearOrder rule for comparison of data objects |
214 // ---------------------------------------------------------------------------- |
215 // ---------------------------------------------------------------------------- |
215 TInt CPcsAlgorithm1Utils::CompareDataBySortOrderL(const CPsData& aObject1, |
216 TInt CPcsAlgorithm1Utils::CompareDataBySortOrderL(const CPsData& aObject1, |
216 const CPsData& aObject2) |
217 const CPsData& aObject2) |
217 { |
218 { |
218 TInt compareRes(0); |
219 TInt compareRes = 0; |
219 |
220 |
220 if( CPsData::CompareById(aObject1, aObject2) ) |
221 if( CPsData::CompareById(aObject1, aObject2) ) |
221 { |
222 { |
222 return compareRes; |
223 return compareRes; |
223 } |
224 } |
224 |
225 |
225 // Fetch the cache list stored in TLS to recover the sort order |
226 // Fetch the cache list stored in TLS to recover the sort order |
226 typedef RPointerArray<CPcsCache> PTR; |
227 typedef RPointerArray<CPcsCache> PTR; |
227 PTR* pcsCache = static_cast<PTR*>(Dll::Tls()); |
228 PTR* pcsCache = static_cast<PTR*>(Dll::Tls()); |
228 User::LeaveIfNull(pcsCache); |
229 User::LeaveIfNull(pcsCache); |
229 |
230 |
230 CPcsCache* cache1 = (*pcsCache)[aObject1.UriId()]; |
231 CPcsCache* cache1 = (*pcsCache)[aObject1.UriId()]; |
231 CPcsCache* cache2 = (*pcsCache)[aObject2.UriId()]; |
232 CPcsCache* cache2 = (*pcsCache)[aObject2.UriId()]; |
232 RArray<TInt> indexOrder1; |
233 RArray<TInt> indexOrder1; |
233 RArray<TInt> indexOrder2; |
234 RArray<TInt> indexOrder2; |
234 |
235 |
235 // Get the index order based on sort order from the cache |
236 // Get the index order based on sort order from the cache |
236 cache1->GetIndexOrder(indexOrder1); |
237 cache1->GetIndexOrder(indexOrder1); |
237 CleanupClosePushL(indexOrder1); |
238 CleanupClosePushL(indexOrder1); |
238 cache2->GetIndexOrder(indexOrder2); |
239 cache2->GetIndexOrder(indexOrder2); |
239 CleanupClosePushL(indexOrder2); |
240 CleanupClosePushL(indexOrder2); |
240 |
241 |
241 TInt idx2 = 0; |
242 // Check if Sort Order is identical (it must be for same cache) |
242 for(TInt idx1 = 0; |
243 TBool sameIndexOrder = ETrue; |
243 idx1 < indexOrder1.Count() && idx2 < indexOrder2.Count() && compareRes == 0; |
244 if ( indexOrder1.Count() != indexOrder2.Count() ) |
244 idx1++) |
245 { |
245 { |
246 sameIndexOrder = EFalse; |
|
247 } |
|
248 else |
|
249 { |
|
250 for ( TInt i = 0; i < indexOrder1.Count(); i++ ) |
|
251 { |
|
252 if (indexOrder1[i] != indexOrder2[i]) |
|
253 { |
|
254 sameIndexOrder = EFalse; |
|
255 break; |
|
256 } |
|
257 } |
|
258 } |
|
259 |
|
260 // Sort Orders among different caches should be the same, anyway |
|
261 // if caches and SO are different we compare by cache URI index |
|
262 if (!sameIndexOrder) |
|
263 { |
|
264 compareRes = aObject1.UriId() - aObject2.UriId(); |
|
265 |
|
266 CleanupStack::PopAndDestroy(&indexOrder2); |
|
267 CleanupStack::PopAndDestroy(&indexOrder1); |
|
268 return compareRes; |
|
269 } |
|
270 |
|
271 // The comparison between contacts data is done for the sort order |
|
272 // fields skipping the ones that are empty |
|
273 TInt indexCount = indexOrder1.Count(); |
|
274 TInt idx1 = 0; |
|
275 TInt idx2 = 0; |
|
276 while ( compareRes == 0 && idx1 < indexCount && idx2 < indexCount ) |
|
277 { |
|
278 // Get contact field of 1st contact |
246 TInt object1Idx = indexOrder1[idx1]; |
279 TInt object1Idx = indexOrder1[idx1]; |
247 HBufC* strCompare1 = aObject1.Data(object1Idx)->Des().AllocLC(); |
280 HBufC* strCompare1 = aObject1.Data(object1Idx)->Des().AllocLC(); |
248 |
281 TPtr strCompare1Ptr( strCompare1->Des() ); |
249 if ( object1Idx < aObject1.DataElementCount() |
282 CPcsAlgorithm1Utils::MyTrim( strCompare1Ptr ); |
250 && aObject1.Data(object1Idx) |
283 |
251 && strCompare1->Length() ) |
284 // Get contact field of 2nd contact |
252 { |
285 TInt object2Idx = indexOrder2[idx2]; |
253 strCompare1->Des().TrimAll(); |
286 HBufC* strCompare2 = aObject2.Data(object2Idx)->Des().AllocLC(); |
254 |
287 TPtr strCompare2Ptr( strCompare2->Des() ); |
255 for(; idx2 < indexOrder2.Count(); idx2++) |
288 CPcsAlgorithm1Utils::MyTrim( strCompare2Ptr ); |
256 { |
289 |
257 TInt object2Idx = indexOrder2[idx2]; |
290 if ( strCompare1->Length() > 0 && strCompare2->Length() > 0 ) |
258 |
291 { |
259 HBufC* strCompare2 = aObject2.Data(object2Idx)->Des().AllocLC(); |
292 compareRes = CPcsAlgorithm1Utils::MyCompareC(*strCompare1, *strCompare2); |
260 |
293 idx1++; |
261 if( strCompare2->Length() ) |
294 idx2++; |
262 { |
295 } |
263 strCompare2->Des().TrimAll(); |
296 else // Increment only the index of the contact with empty field |
264 |
297 { |
265 compareRes = CPcsAlgorithm1Utils::MyCompareC(*strCompare1, *strCompare2); |
298 if ( strCompare1->Length() == 0 ) |
266 |
299 idx1++; |
267 CleanupStack::PopAndDestroy(strCompare2); |
300 if ( strCompare2->Length() == 0 ) |
268 |
301 idx2++; |
269 if( compareRes == 0 ) |
302 } |
270 { |
303 |
271 idx2++; |
304 CleanupStack::PopAndDestroy(strCompare2); |
272 } |
|
273 break; |
|
274 } |
|
275 CleanupStack::PopAndDestroy(strCompare2); |
|
276 } |
|
277 } |
|
278 CleanupStack::PopAndDestroy(strCompare1); |
305 CleanupStack::PopAndDestroy(strCompare1); |
279 } |
306 } |
280 |
307 |
281 CleanupStack::PopAndDestroy(&indexOrder2); |
308 // We do not return that contacts are equal by SO |
|
309 if ( compareRes == 0 ) |
|
310 { |
|
311 if ( idx1 != idx2 ) |
|
312 { |
|
313 // Compare by index position |
|
314 // If idx1 > idx2 and SO is "FN LN" it means for instance that: |
|
315 // Contact1=[FN:"", LN:"Smith"], idx1=2 |
|
316 // Contact2=[FN:"Smith", LN:"Donald"], idx2=1 |
|
317 // Therefore Contact1="Smith" is < than Contact2="Smith Donald" |
|
318 // and the return value of this method has to be < 0 (idx2-idx1) |
|
319 |
|
320 compareRes = idx2 - idx1; |
|
321 } |
|
322 else |
|
323 { |
|
324 // Compare by URI ID as 1st choice and Contact ID as 2nd choice |
|
325 |
|
326 compareRes == ( aObject1.UriId() != aObject2.UriId() ) ? |
|
327 aObject1.UriId() - aObject2.UriId() : aObject1.Id() - aObject2.Id(); |
|
328 } |
|
329 } |
|
330 |
|
331 CleanupStack::PopAndDestroy(&indexOrder2); |
282 CleanupStack::PopAndDestroy(&indexOrder1); |
332 CleanupStack::PopAndDestroy(&indexOrder1); |
283 |
333 |
284 return compareRes; |
334 return compareRes; |
285 } |
335 } |
286 |
336 |