|
1 /* |
|
2 * Copyright (c) 2007 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: Predictive Contact Search Algorithm 1 helper class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDES |
|
20 |
|
21 #include "CPcsAlgorithm1.h" |
|
22 #include "CPcsAlgorithm1Helper.h" |
|
23 #include "CPcsAlgorithm1Utils.h" |
|
24 #include "CPcsDebug.h" |
|
25 #include "CPcsCache.h" |
|
26 #include "CPcsKeyMap.h" |
|
27 #include "CPsData.h" |
|
28 #include "CWords.h" |
|
29 #include "CPsQuery.h" |
|
30 #include "CPsQueryItem.h" |
|
31 #include "CPsDataPluginInterface.h" |
|
32 #include "CPcsPoolElement.h" |
|
33 |
|
34 // ============================== MEMBER FUNCTIONS ============================ |
|
35 |
|
36 // ---------------------------------------------------------------------------- |
|
37 // CPcsAlgorithm1Helper::NewL |
|
38 // Two Phase Construction |
|
39 // ---------------------------------------------------------------------------- |
|
40 CPcsAlgorithm1Helper* CPcsAlgorithm1Helper::NewL(CPcsAlgorithm1* aAlgorithm) |
|
41 { |
|
42 PRINT ( _L("Enter CPcsAlgorithm1Helper::NewL") ); |
|
43 |
|
44 CPcsAlgorithm1Helper* self = new ( ELeave ) CPcsAlgorithm1Helper(); |
|
45 CleanupStack::PushL( self ); |
|
46 self->ConstructL(aAlgorithm); |
|
47 CleanupStack::Pop( self ); |
|
48 |
|
49 PRINT ( _L("End CPcsAlgorithm1Helper::NewL") ); |
|
50 |
|
51 return self; |
|
52 } |
|
53 |
|
54 // ---------------------------------------------------------------------------- |
|
55 // CPcsAlgorithm1Helper::CPcsAlgorithm1Helper |
|
56 // Two Phase Construction |
|
57 // ---------------------------------------------------------------------------- |
|
58 CPcsAlgorithm1Helper::CPcsAlgorithm1Helper() |
|
59 { |
|
60 PRINT ( _L("Enter CPcsAlgorithm1Helper::CPcsAlgorithm1") ); |
|
61 PRINT ( _L("End CPcsAlgorithm1Helper::CPcsAlgorithm1") ); |
|
62 } |
|
63 |
|
64 // ---------------------------------------------------------------------------- |
|
65 // CPcsAlgorithm1Helper::ConstructL |
|
66 // Two Phase Construction |
|
67 // ---------------------------------------------------------------------------- |
|
68 void CPcsAlgorithm1Helper::ConstructL(CPcsAlgorithm1* aAlgorithm) |
|
69 { |
|
70 PRINT ( _L("Enter CPcsAlgorithm1Helper::ConstructL") ); |
|
71 |
|
72 iAlgorithm = aAlgorithm; |
|
73 iKeyMap = iAlgorithm->GetKeyMap(); |
|
74 |
|
75 PRINT ( _L("End CPcsAlgorithm1Helper::ConstructL") ); |
|
76 } |
|
77 |
|
78 // ---------------------------------------------------------------------------- |
|
79 // CPcsAlgorithm1Helper::CPcsAlgorithm1Helper |
|
80 // Destructor |
|
81 // ---------------------------------------------------------------------------- |
|
82 CPcsAlgorithm1Helper::~CPcsAlgorithm1Helper() |
|
83 { |
|
84 PRINT ( _L("Enter CPcsAlgorithm1Helper::~CPcsAlgorithm1Helper") ); |
|
85 iSearchResultsArr.ResetAndDestroy(); |
|
86 PRINT ( _L("End CPcsAlgorithm1Helper::~CPcsAlgorithm1Helper") ); |
|
87 } |
|
88 |
|
89 // ---------------------------------------------------------------------------- |
|
90 // CPcsAlgorithm1Helper::SearchSingleL |
|
91 // Search function for query in ITU-T mode, QWERTY mode, or Mixed (ITU-T and QWERTY) mode. |
|
92 // ---------------------------------------------------------------------------- |
|
93 void CPcsAlgorithm1Helper::SearchSingleL( const CPsSettings& aSettings, |
|
94 CPsQuery& aPsQuery, |
|
95 TBool aIsSearchInGroup, |
|
96 RArray<TInt>& aContactsInGroup, |
|
97 RPointerArray<CPsData>& aSearchResults, |
|
98 RPointerArray<CPsPattern>& aSearchSeqs ) |
|
99 { |
|
100 PRINT ( _L("Enter CPcsAlgorithm1Helper::SearchSingleL") ); |
|
101 |
|
102 __LATENCY_MARK ( _L("CPcsAlgorithm1Helper::SearchSingleL") ); |
|
103 |
|
104 // Create filtering helper for the required sort type |
|
105 TSortType sortType = aSettings.GetSortType(); |
|
106 CPcsAlgorithm1FilterHelper* filterHelper = CPcsAlgorithm1FilterHelper::NewL(sortType); |
|
107 CleanupStack::PushL( filterHelper ); |
|
108 |
|
109 // Search from cache based on first character |
|
110 const CPsQueryItem& firstCharItem = aPsQuery.GetItemAtL(0); |
|
111 TInt cachePoolId = iKeyMap->PoolIdForCharacter( firstCharItem.Character(), firstCharItem.Mode() ); |
|
112 |
|
113 // Reset the result set array for new search |
|
114 iSearchResultsArr.ResetAndDestroy(); |
|
115 |
|
116 // Get the data stores |
|
117 RPointerArray<TDesC> dataStores; |
|
118 CleanupResetAndDestroyPushL( dataStores ); |
|
119 aSettings.SearchUrisL(dataStores); |
|
120 |
|
121 // Get the required display fields from the client |
|
122 RArray<TInt> requiredDataFields; |
|
123 CleanupClosePushL( requiredDataFields ); |
|
124 aSettings.DisplayFieldsL(requiredDataFields); |
|
125 |
|
126 // Perform search for each required data store |
|
127 RPointerArray<CPcsPoolElement> elements; |
|
128 CleanupClosePushL( elements ); |
|
129 |
|
130 for ( TInt dsIndex = 0; |
|
131 dsIndex < dataStores.Count(); |
|
132 dsIndex++ ) |
|
133 { |
|
134 RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> (); |
|
135 CleanupStack::PushL( temp ); |
|
136 iSearchResultsArr.AppendL( temp ); |
|
137 CleanupStack::Pop( temp ); |
|
138 |
|
139 // Get the contents for this data store |
|
140 TInt arrayIndex = iAlgorithm->GetCacheIndex(*(dataStores[dsIndex])); |
|
141 if ( arrayIndex < 0 ) continue; |
|
142 CPcsCache* cache = iAlgorithm->GetCache(arrayIndex); |
|
143 cache->GetContactsForKeyL(cachePoolId, elements); |
|
144 |
|
145 // Get the supported data fields for this data store |
|
146 RArray<TInt> supportedDataFields; |
|
147 CleanupClosePushL( supportedDataFields ); |
|
148 cache->GetDataFields(supportedDataFields); |
|
149 |
|
150 // Get the filtered data fields for this data store |
|
151 TUint8 filteredDataMatch = CPcsAlgorithm1Utils::FilterDataFieldsL(requiredDataFields, |
|
152 supportedDataFields); |
|
153 |
|
154 // Perform filtering |
|
155 FilterResultsSingleL(filterHelper, |
|
156 elements, |
|
157 aPsQuery, |
|
158 filteredDataMatch, |
|
159 aIsSearchInGroup, |
|
160 aContactsInGroup); |
|
161 |
|
162 // If alphabetical sorting, get the results for this datastore |
|
163 if ( sortType == EAlphabetical ) |
|
164 { |
|
165 filterHelper->GetResults(*(iSearchResultsArr[dsIndex])); |
|
166 } |
|
167 |
|
168 elements.Reset(); |
|
169 CleanupStack::PopAndDestroy( &supportedDataFields ); // Close |
|
170 } |
|
171 |
|
172 CleanupStack::PopAndDestroy( &elements ); // Close |
|
173 CleanupStack::PopAndDestroy( &requiredDataFields ); // Close |
|
174 CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy |
|
175 |
|
176 // If alphabetical sorting, merge the result sets of all datastores |
|
177 if ( sortType == EAlphabetical ) |
|
178 { |
|
179 // Merge the result sets of individual datastores alphabetically |
|
180 CPcsAlgorithm1Utils::FormCompleteSearchResultsL(iSearchResultsArr, |
|
181 aSearchResults); |
|
182 } |
|
183 else |
|
184 { |
|
185 // Results are already sorted pattern based |
|
186 filterHelper->GetResults(aSearchResults); |
|
187 } |
|
188 |
|
189 // Get the sorted match sequence list |
|
190 filterHelper->GetPatternsL(aSearchSeqs); |
|
191 |
|
192 PRINT1 ( _L("CPcsAlgorithm1Helper::SearchSingleL: Number of search results = %d"), aSearchResults.Count() ); |
|
193 |
|
194 // Cleanup |
|
195 for ( TInt i = 0; i < iSearchResultsArr.Count(); i++ ) |
|
196 { |
|
197 iSearchResultsArr[i]->Reset(); |
|
198 } |
|
199 iSearchResultsArr.ResetAndDestroy(); |
|
200 |
|
201 CleanupStack::PopAndDestroy( filterHelper ); |
|
202 |
|
203 __LATENCY_MARKEND ( _L("CPcsAlgorithm1Helper::SearchSingleL") ); |
|
204 |
|
205 PRINT ( _L("End CPcsAlgorithm1Helper::SearchSingleL") ); |
|
206 } |
|
207 |
|
208 // ---------------------------------------------------------------------------- |
|
209 // CPcsAlgorithm1Helper::FilterResultsSingleL |
|
210 // Subset search function |
|
211 // ---------------------------------------------------------------------------- |
|
212 void CPcsAlgorithm1Helper::FilterResultsSingleL(CPcsAlgorithm1FilterHelper* aAlgorithmFilterHelper, |
|
213 RPointerArray<CPcsPoolElement>& aSearchSet, |
|
214 CPsQuery& aPsQuery, |
|
215 TUint8 aFilteredDataMatch, |
|
216 TBool aIsSearchInGroup, |
|
217 RArray<TInt>& aContactsInGroup) |
|
218 { |
|
219 PRINT ( _L("Enter CPcsAlgorithm1Helper::FilterResultsSingleL") ); |
|
220 |
|
221 __LATENCY_MARK ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL") ); |
|
222 |
|
223 // Convert the search query to char-and-key string |
|
224 TBuf<KPsQueryMaxLen> queryAsDes; |
|
225 iKeyMap->GetMixedKeyStringForQueryL( aPsQuery, queryAsDes ); |
|
226 |
|
227 PRINTQUERY ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL: "), aPsQuery ); |
|
228 |
|
229 PRINT1 ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL: char-and-key string for the query is \"%S\""), |
|
230 &queryAsDes ); |
|
231 |
|
232 // Parse thru each search set elements and filter the results |
|
233 for ( TInt index = 0; index < aSearchSet.Count(); index++ ) |
|
234 { |
|
235 CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*>(aSearchSet[index]); |
|
236 CPsData* psData = poolElement->GetPsData(); |
|
237 psData->ClearDataMatches(); |
|
238 |
|
239 // Skip this contact if performing group search and this contact doesn't |
|
240 // belong to the group |
|
241 if ( aIsSearchInGroup && aContactsInGroup.Find(psData->Id()) == KErrNotFound ) |
|
242 { |
|
243 continue; |
|
244 } |
|
245 |
|
246 RPointerArray<TDesC> tempMatchSeq; |
|
247 CleanupResetAndDestroyPushL( tempMatchSeq ); |
|
248 TBool isAdded = EFalse; |
|
249 |
|
250 // Parse thru each data and filter the results |
|
251 for ( TInt dataIndex = 0; dataIndex < psData->DataElementCount(); dataIndex++ ) |
|
252 { |
|
253 // Filter off data fields not required in search |
|
254 TUint8 bitIndex = 1 << dataIndex; |
|
255 |
|
256 TUint8 filter = bitIndex & aFilteredDataMatch; |
|
257 if ( filter == 0x0 ) |
|
258 { |
|
259 // Move to next data |
|
260 continue; |
|
261 } |
|
262 |
|
263 if ( poolElement->IsDataMatch(dataIndex) ) |
|
264 { |
|
265 TLex lex( *psData->Data(dataIndex) ); |
|
266 |
|
267 // First word |
|
268 TPtrC token = lex.NextToken(); |
|
269 |
|
270 // Search thru multiple words |
|
271 while ( token.Length() != 0 ) |
|
272 { |
|
273 // Convert the data to char-and-key string |
|
274 TBuf<KPsQueryMaxLen> dataWithKeys; |
|
275 iKeyMap->GetMixedKeyStringForDataL( aPsQuery, token, dataWithKeys ); |
|
276 |
|
277 if ( CPcsAlgorithm1Utils::MyCompareKeyAndString(dataWithKeys, queryAsDes, aPsQuery) ) |
|
278 { |
|
279 psData->SetDataMatch(dataIndex); |
|
280 isAdded = ETrue; |
|
281 |
|
282 // Extract matched character sequence |
|
283 TInt len = queryAsDes.Length(); |
|
284 TPtrC seq = token.Left(len); |
|
285 CPcsAlgorithm1Utils::AppendMatchToSeqL( tempMatchSeq, seq ); |
|
286 } |
|
287 // Next word |
|
288 token.Set(lex.NextToken()); |
|
289 } |
|
290 } |
|
291 } |
|
292 |
|
293 // Add the result |
|
294 if ( isAdded ) |
|
295 { |
|
296 aAlgorithmFilterHelper->AddL(psData,tempMatchSeq); |
|
297 } |
|
298 |
|
299 // Cleanup the match sequence array as |
|
300 // they are stored in pattern details structure |
|
301 CleanupStack::PopAndDestroy( &tempMatchSeq ); // ResetAndDestroy |
|
302 } |
|
303 |
|
304 __LATENCY_MARKEND ( _L("CPcsAlgorithm1Helper::FilterResultsSingleL") ); |
|
305 |
|
306 PRINT ( _L("End CPcsAlgorithm1Helper::FilterResultsSingleL") ); |
|
307 } |
|
308 |
|
309 // ---------------------------------------------------------------------------- |
|
310 // CPcsAlgorithm1Helper::SearchMatchSeqL |
|
311 // Funciton to search matching sequences in the input text |
|
312 // ---------------------------------------------------------------------------- |
|
313 void CPcsAlgorithm1Helper::SearchMatchSeqL(CPsQuery& aPsQuery, |
|
314 const TDesC& aData, |
|
315 RPointerArray<TDesC>& aMatchSet, |
|
316 RArray<TPsMatchLocation>& aMatchLocation ) |
|
317 { |
|
318 PRINT ( _L("Enter CPcsAlgorithm1Helper::SearchMatchSeqL") ); |
|
319 |
|
320 HBufC* queryAsDes = HBufC::NewLC(aPsQuery.Count()); |
|
321 TPtr queryAsDesPtr(queryAsDes->Des()); |
|
322 iKeyMap->GetMixedKeyStringForQueryL( aPsQuery, queryAsDesPtr ); |
|
323 |
|
324 // Convert the data into words |
|
325 TLex lex(aData); |
|
326 |
|
327 // First word |
|
328 TPtrC token = lex.NextToken(); |
|
329 |
|
330 TInt beg = lex.Offset() - token.Length(); // start index of match sequence |
|
331 |
|
332 // Search thru multiple words |
|
333 while ( token.Length() != 0 ) |
|
334 { |
|
335 HBufC* data = HBufC::NewLC(token.Length()); |
|
336 TPtr dataPtr(data->Des()); |
|
337 iKeyMap->GetMixedKeyStringForDataL( aPsQuery, token, dataPtr ); |
|
338 |
|
339 if ( CPcsAlgorithm1Utils::MyCompareKeyAndString(dataPtr, *queryAsDes, aPsQuery) ) |
|
340 { |
|
341 TInt len = queryAsDes->Length(); |
|
342 |
|
343 TPsMatchLocation tempLocation; |
|
344 |
|
345 // check for directionality of the text |
|
346 TBool found(EFalse); |
|
347 TBidiText::TDirectionality dir = TBidiText::TextDirectionality(token, &found); |
|
348 |
|
349 tempLocation.index = beg; |
|
350 tempLocation.length = len; |
|
351 tempLocation.direction = dir; |
|
352 |
|
353 // Add the match location to the data structure array |
|
354 aMatchLocation.Append(tempLocation); |
|
355 |
|
356 // Add the sequence to the match sequence |
|
357 TPtrC seq = token.Left(len); |
|
358 CPcsAlgorithm1Utils::AppendMatchToSeqL( aMatchSet, seq ); |
|
359 } |
|
360 |
|
361 // Next word |
|
362 token.Set(lex.NextToken()); |
|
363 beg = lex.Offset() - token.Length(); // start index of next word |
|
364 CleanupStack::PopAndDestroy(); //data |
|
365 } |
|
366 |
|
367 CleanupStack::PopAndDestroy( queryAsDes ); |
|
368 |
|
369 PRINT ( _L("End CPcsAlgorithm1Helper::SearchMatchSeqL") ); |
|
370 } |
|
371 |
|
372 // ---------------------------------------------------------------------------- |
|
373 // CPcsAlgorithm1Helper::SortSearchSeqsL() |
|
374 // |
|
375 // ---------------------------------------------------------------------------- |
|
376 void CPcsAlgorithm1Helper::SortSearchSeqsL(RPointerArray<TDesC>& aSearchSeqs) |
|
377 { |
|
378 // Sort the search seqs |
|
379 TLinearOrder<TDesC> rule( CPcsAlgorithm1Utils::CompareCollate ); |
|
380 aSearchSeqs.Sort(rule); |
|
381 } |
|
382 |
|
383 // End of file |