|
1 /* |
|
2 * Copyright (c) 2010 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: This file implements class CEmailMessageSearchAsync |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <emailclientapi.hrh> |
|
19 #include "emailmessagesearch.h" |
|
20 #include "emailmessage.h" |
|
21 |
|
22 /** |
|
23 * Global semaphore name. Semaphore blocks parallel service access. |
|
24 */ |
|
25 _LIT( KGlobalSemaphoreToPreventParallelCall, "12mymessaging.nokia.com34" ); |
|
26 |
|
27 // ======== MEMBER FUNCTIONS ======== |
|
28 |
|
29 // --------------------------------------------------------------------------- |
|
30 // CEmailMessageSearchAsync::NewL |
|
31 // --------------------------------------------------------------------------- |
|
32 CEmailMessageSearchAsync* CEmailMessageSearchAsync::NewL( |
|
33 CPluginData& aPluginData, |
|
34 const TMailboxId& aMailboxId ) |
|
35 { |
|
36 CEmailMessageSearchAsync* self = |
|
37 new ( ELeave ) CEmailMessageSearchAsync( aPluginData, aMailboxId ); |
|
38 CleanupStack::PushL( self ); |
|
39 self->ConstructL(); |
|
40 CleanupStack::Pop( self ); |
|
41 return self; |
|
42 } |
|
43 |
|
44 // --------------------------------------------------------------------------- |
|
45 // |
|
46 // --------------------------------------------------------------------------- |
|
47 void CEmailMessageSearchAsync::ConstructL() |
|
48 { |
|
49 iPlugin = iPluginData.ClaimInstanceL(); |
|
50 // Open existing semaphore, or create a new one |
|
51 if ( KErrNone != iGate.OpenGlobal( KGlobalSemaphoreToPreventParallelCall, EOwnerProcess ) ) |
|
52 { |
|
53 User::LeaveIfError( |
|
54 iGate.CreateGlobal( KGlobalSemaphoreToPreventParallelCall, 1, EOwnerProcess ) ); |
|
55 } |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // |
|
60 // ----------------------------------------------------------------------------- |
|
61 CEmailMessageSearchAsync::CEmailMessageSearchAsync( |
|
62 CPluginData& aPluginData, |
|
63 const TMailboxId& aMailboxId ) |
|
64 : iPluginData( aPluginData ), iMailboxId( aMailboxId.iId ), |
|
65 iCriteria(), iObserver( NULL ), iRemote( EFalse ) |
|
66 { |
|
67 } |
|
68 |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 // ----------------------------------------------------------------------------- |
|
72 CEmailMessageSearchAsync::~CEmailMessageSearchAsync() |
|
73 { |
|
74 iSearchStrings.Close(); |
|
75 iPluginData.ReleaseInstance(); |
|
76 iGate.Close(); |
|
77 } |
|
78 |
|
79 // ----------------------------------------------------------------------------- |
|
80 // |
|
81 // ----------------------------------------------------------------------------- |
|
82 TEmailTypeId CEmailMessageSearchAsync::InterfaceId() const |
|
83 { |
|
84 return KEmailIFUidSearch; |
|
85 } |
|
86 |
|
87 // ----------------------------------------------------------------------------- |
|
88 // |
|
89 // ----------------------------------------------------------------------------- |
|
90 void CEmailMessageSearchAsync::Release() |
|
91 { |
|
92 if (KErrNone != iGate.Wait(1)) |
|
93 { |
|
94 this->Cancel(); |
|
95 } |
|
96 delete this; |
|
97 } |
|
98 |
|
99 // ----------------------------------------------------------------------------- |
|
100 // Sets sort order for search results. |
|
101 // Leaves KErrNotReady if search is ongoing. |
|
102 // ----------------------------------------------------------------------------- |
|
103 void CEmailMessageSearchAsync::SetSortCriteriaL( const TEmailSortCriteria& aCriteria ) |
|
104 { |
|
105 IsSearchGoingOnL(); |
|
106 |
|
107 switch (aCriteria.iField) |
|
108 { |
|
109 case TEmailSortCriteria::EDontCare: |
|
110 iCriteria.iField = EFSMailDontCare; |
|
111 break; |
|
112 |
|
113 case TEmailSortCriteria::EByDate: |
|
114 iCriteria.iField = EFSMailSortByDate; |
|
115 break; |
|
116 |
|
117 case TEmailSortCriteria::EBySender: |
|
118 iCriteria.iField = EFSMailSortBySender; |
|
119 break; |
|
120 |
|
121 case TEmailSortCriteria::EByRecipient: |
|
122 iCriteria.iField = EFSMailSortByRecipient; |
|
123 break; |
|
124 |
|
125 case TEmailSortCriteria::EBySubject: |
|
126 iCriteria.iField = EFSMailSortBySubject; |
|
127 break; |
|
128 |
|
129 case TEmailSortCriteria::EByPriority: |
|
130 iCriteria.iField = EFSMailSortByPriority; |
|
131 break; |
|
132 |
|
133 case TEmailSortCriteria::EByFlagStatus: |
|
134 iCriteria.iField = EFSMailSortByFlagStatus; |
|
135 break; |
|
136 |
|
137 case TEmailSortCriteria::EByUnread: |
|
138 iCriteria.iField = EFSMailSortByUnread; |
|
139 break; |
|
140 |
|
141 case TEmailSortCriteria::EBySize: |
|
142 iCriteria.iField = EFSMailSortBySize; |
|
143 break; |
|
144 |
|
145 case TEmailSortCriteria::EByAttachment: |
|
146 iCriteria.iField = EFSMailSortByAttachment; |
|
147 break; |
|
148 |
|
149 default: |
|
150 User::Leave( KErrNotSupported ); |
|
151 break; |
|
152 |
|
153 } |
|
154 if (aCriteria.iAscending) |
|
155 { |
|
156 iCriteria.iOrder = EFSMailAscending; |
|
157 } |
|
158 else |
|
159 { |
|
160 iCriteria.iOrder = EFSMailDescending; |
|
161 } |
|
162 // Release gate |
|
163 iGate.Signal(); |
|
164 } |
|
165 |
|
166 // ----------------------------------------------------------------------------- |
|
167 // Adds a search key. Leaves KErrNotReady if search is ongoing. |
|
168 // ----------------------------------------------------------------------------- |
|
169 void CEmailMessageSearchAsync::AddSearchKeyL( const TDesC& aSearchKey ) |
|
170 { |
|
171 IsSearchGoingOnL(); |
|
172 |
|
173 iSearchStrings.AppendL(&aSearchKey); |
|
174 // Release gate |
|
175 iGate.Signal(); |
|
176 } |
|
177 |
|
178 /// ----------------------------------------------------------------------------- |
|
179 // Enables/disables search from remote email server. |
|
180 // Leaves KErrNotReady if search is ongoing. |
|
181 // ----------------------------------------------------------------------------- |
|
182 void CEmailMessageSearchAsync::SetRemoteSearchL( TBool aRemote ) |
|
183 { |
|
184 IsSearchGoingOnL(); |
|
185 |
|
186 iRemote = aRemote; |
|
187 // Release gate |
|
188 iGate.Signal(); |
|
189 // Currently plugins do not support this function |
|
190 User::Leave( KErrNotSupported ); |
|
191 } |
|
192 |
|
193 // ----------------------------------------------------------------------------- |
|
194 // Indicates whether remote search is enabled. |
|
195 // ----------------------------------------------------------------------------- |
|
196 TBool CEmailMessageSearchAsync::IsRemoteSearch() const |
|
197 { |
|
198 // Currently plugins do not support this function |
|
199 return EFalse; |
|
200 } |
|
201 |
|
202 // ----------------------------------------------------------------------------- |
|
203 // Starts search, all methods affecting search attribures leave |
|
204 // KErrNotReady while search is ongoing. |
|
205 // @param aObserver called when results are available. |
|
206 // |
|
207 void CEmailMessageSearchAsync::StartSearchL( MEmailSearchObserver& aObserver ) |
|
208 { |
|
209 IsSearchGoingOnL(); |
|
210 |
|
211 iObserver = &aObserver; |
|
212 const TFSMailMsgId fsMailboxId( iPluginData.Uid(), iMailboxId.iId ); |
|
213 RArray <TFSMailMsgId> folderIds; |
|
214 |
|
215 /** Search API */ |
|
216 |
|
217 /** |
|
218 * Asyncronous call for starting search for given string. Only one search can be |
|
219 * performed at a time. |
|
220 * |
|
221 * |
|
222 * This function will search for message's containing the given search string. |
|
223 * The search will be performed on the all message fields: To, Cc, Bcc, subject, body. |
|
224 * The search client will be notified of each found message, |
|
225 * and upon completion of the search. Only one search can be performed at a time. |
|
226 * |
|
227 * To change the sort order in the search result, use the same search string in the |
|
228 * but change the aSortCriteria parameter. The store "caches" the search |
|
229 * results generated by the same search string. |
|
230 * |
|
231 * The function will leave with KErrInUse if a search is already in progress. |
|
232 * |
|
233 * /note Only works if the store is in an authenticated state, |
|
234 * otherwise this function leaves with KErrNotReady |
|
235 * |
|
236 * @paran aMailBoxId id of the mailbox where messages are to be searched |
|
237 * @param aFolderIds list of folders where messages are to be searched |
|
238 * global or folder specific search depends on the size of array is 0 or not. |
|
239 * @param aSearchStrings text strings that will be searched from different message fields. |
|
240 * @param aSortCriteria sort criteria for the results |
|
241 * @param aSearchObserver client observer that will be notified about search status. |
|
242 * |
|
243 */ |
|
244 iPlugin->SearchL( fsMailboxId, |
|
245 folderIds, |
|
246 iSearchStrings, |
|
247 iCriteria, |
|
248 *this ); |
|
249 // Gate is kept closed as search is asynchronous. Gate will be reopen after search is completed, i.e. |
|
250 // CEmailMessageSearchAsync::SearchCompleted. |
|
251 } |
|
252 |
|
253 // ----------------------------------------------------------------------------- |
|
254 // Cancels search. |
|
255 // ----------------------------------------------------------------------------- |
|
256 void CEmailMessageSearchAsync::Cancel() |
|
257 { |
|
258 if (KErrNone != iGate.Wait(1)) |
|
259 { |
|
260 |
|
261 /** |
|
262 * Cancels current search. Does nothing if there is not any search. |
|
263 * The search client will not be called back after this function is called. |
|
264 * |
|
265 */ |
|
266 const TFSMailMsgId fsMailboxId( iPluginData.Uid(), iMailboxId.iId ); |
|
267 iPlugin->CancelSearch( fsMailboxId ); |
|
268 } |
|
269 else |
|
270 { |
|
271 // Release gate |
|
272 iGate.Signal(); |
|
273 } |
|
274 } |
|
275 |
|
276 // ----------------------------------------------------------------------------- |
|
277 // * @return search status: |
|
278 // * < 0 : Search has failed |
|
279 // * KRequestPending : search is ongoing. note that status may be |
|
280 // * KRequestPending after HandleResultL callback because results |
|
281 // * may be given in chunks of results. Size of chunk depends on |
|
282 // * implementation and may vary. |
|
283 // * KErrNone : initial state, or search has finished |
|
284 // ----------------------------------------------------------------------------- |
|
285 TInt CEmailMessageSearchAsync::Status() const |
|
286 { |
|
287 if (KErrNone != iGate.Wait(1)) |
|
288 { |
|
289 // Search is going on |
|
290 return KRequestPending; |
|
291 } |
|
292 else |
|
293 { |
|
294 // Release gate |
|
295 iGate.Signal(); |
|
296 } |
|
297 |
|
298 return KErrNone; |
|
299 } |
|
300 |
|
301 // ----------------------------------------------------------------------------- |
|
302 // Resets all search attribures. Cancels search if ongoing. |
|
303 // ----------------------------------------------------------------------------- |
|
304 void CEmailMessageSearchAsync::Reset() |
|
305 { |
|
306 if ( KErrNone != iGate.Wait( 1 ) ) |
|
307 { |
|
308 this->Cancel(); |
|
309 } |
|
310 |
|
311 iCriteria = TFSMailSortCriteria(); |
|
312 iSearchStrings.Reset(); |
|
313 |
|
314 // Release gate |
|
315 iGate.Signal(); |
|
316 |
|
317 }; |
|
318 |
|
319 // ----------------------------------------------------------------------------- |
|
320 // Notifies the email search API client that a match has been found |
|
321 // |
|
322 // @param aMatchMessage contains a pointer to the matched message. |
|
323 // Ownership is transfered to the observer. |
|
324 // ----------------------------------------------------------------------------- |
|
325 void CEmailMessageSearchAsync::MatchFoundL( CFSMailMessage* aMatchMessage ) |
|
326 { |
|
327 User::LeaveIfNull( iObserver ); |
|
328 CEmailMessage *result = CEmailMessage::NewL(iPluginData, aMatchMessage, EClientOwns ); |
|
329 iObserver->HandleResultL( result ); |
|
330 } |
|
331 |
|
332 // ----------------------------------------------------------------------------- |
|
333 // Notifies the email search API client that the search has completed |
|
334 // ----------------------------------------------------------------------------- |
|
335 void CEmailMessageSearchAsync::SearchCompletedL() |
|
336 { |
|
337 User::LeaveIfNull( iObserver ); |
|
338 iObserver->SearchCompletedL(); |
|
339 // Search is now complete, release gate. |
|
340 iGate.Signal(); |
|
341 } |
|
342 |
|
343 // ----------------------------------------------------------------------------- |
|
344 // Asks client if search engine should change search priority |
|
345 // ----------------------------------------------------------------------------- |
|
346 void CEmailMessageSearchAsync::ClientRequiredSearchPriority(TInt* /*apRequiredSearchPriority*/) |
|
347 { |
|
348 } |
|
349 |
|
350 // ----------------------------------------------------------------------------- |
|
351 // Function leaves if search is going on. Otherwise it doesn't do anything. |
|
352 // ----------------------------------------------------------------------------- |
|
353 void CEmailMessageSearchAsync::IsSearchGoingOnL() const |
|
354 { |
|
355 if ( KErrNone != iGate.Wait( 1 ) ) |
|
356 { |
|
357 // Leave now, search is going on |
|
358 User::Leave( KErrNotReady ); |
|
359 } |
|
360 } |
|
361 |
|
362 // End of file |