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