|
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: This file implements class CFsComposerFetchLogic. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "emailtrace.h" |
|
20 #include "cfsmailclient.h" |
|
21 #include "cfsmailcommon.h" |
|
22 #include <FreestyleEmailUi.rsg> |
|
23 #include <StringLoader.h> |
|
24 |
|
25 #include "FreestyleEmailUiAppui.h" |
|
26 #include "FSComposerFetchLogic.h" |
|
27 #include "FreestyleEmailUiUtilities.h" |
|
28 #include "FSEmail.pan" |
|
29 |
|
30 // ----------------------------------------------------------------------------- |
|
31 // CFsComposerFetchLogic::NewL |
|
32 // ----------------------------------------------------------------------------- |
|
33 // |
|
34 CFsComposerFetchLogic* CFsComposerFetchLogic::NewL( CFSMailClient& aClient, |
|
35 TFSMailMsgId aMailBoxId, TFSMailMsgId aFolderId, TFSMailMsgId aMessageId, |
|
36 MComposerFetchLogicCallback& aObserver, CFreestyleEmailUiAppUi& aAppUi ) |
|
37 { |
|
38 FUNC_LOG; |
|
39 |
|
40 CFsComposerFetchLogic* self = new (ELeave) CFsComposerFetchLogic( aClient, aObserver, aAppUi ); |
|
41 CleanupStack::PushL( self ); |
|
42 self->ConstructL( aMailBoxId, aFolderId, aMessageId ); |
|
43 CleanupStack::Pop( self ); |
|
44 |
|
45 return self; |
|
46 } |
|
47 |
|
48 |
|
49 // ----------------------------------------------------------------------------- |
|
50 // CFsComposerFetchLogic::CFsComposerFetchLogic |
|
51 // ----------------------------------------------------------------------------- |
|
52 // |
|
53 CFsComposerFetchLogic::CFsComposerFetchLogic( CFSMailClient& aClient, |
|
54 MComposerFetchLogicCallback& aObserver, CFreestyleEmailUiAppUi& aAppUi ): |
|
55 iRunMode( EModeInvalid ), iState( EStateNotStarted ), iAppUi( aAppUi ), |
|
56 iClient( aClient ), iObserver( aObserver ),iFetchingCancelGoingOn(EFalse), |
|
57 iFetchingStructure(EFalse), iFetchingBody(EFalse),iRequestCompleted(EFalse) |
|
58 { |
|
59 FUNC_LOG; |
|
60 } |
|
61 |
|
62 |
|
63 // ----------------------------------------------------------------------------- |
|
64 // CFsComposerFetchLogic::~CFsComposerFetchLogic |
|
65 // ----------------------------------------------------------------------------- |
|
66 // |
|
67 CFsComposerFetchLogic::~CFsComposerFetchLogic() |
|
68 { |
|
69 FUNC_LOG; |
|
70 |
|
71 if ( iAppUi.DownloadInfoMediator() ) |
|
72 { |
|
73 iAppUi.DownloadInfoMediator()->StopObserving( this ); |
|
74 } |
|
75 |
|
76 iParts.Close(); |
|
77 |
|
78 delete iMessage; |
|
79 delete iFolder; |
|
80 delete iMailBox; |
|
81 |
|
82 } |
|
83 |
|
84 |
|
85 // ----------------------------------------------------------------------------- |
|
86 // CFsComposerFetchLogic::ConstructL |
|
87 // ----------------------------------------------------------------------------- |
|
88 // |
|
89 void CFsComposerFetchLogic::ConstructL( TFSMailMsgId aMailBoxId, |
|
90 TFSMailMsgId aFolderId, TFSMailMsgId aMessageId ) |
|
91 { |
|
92 FUNC_LOG; |
|
93 |
|
94 iMailBox = iClient.GetMailBoxByUidL( aMailBoxId ); |
|
95 iFolder = iClient.GetFolderByUidL( aMailBoxId, aFolderId ); |
|
96 iMessage = iClient.GetMessageByUidL( aMailBoxId, aFolderId, aMessageId, EFSMsgDataStructure ); |
|
97 |
|
98 } |
|
99 |
|
100 |
|
101 // ----------------------------------------------------------------------------- |
|
102 // CFsComposerFetchLogic::RunReplyLogicL |
|
103 // ----------------------------------------------------------------------------- |
|
104 // |
|
105 void CFsComposerFetchLogic::RunReplyLogicL() |
|
106 { |
|
107 FUNC_LOG; |
|
108 |
|
109 iRunMode = EModeReply; |
|
110 iState = EStateSmartReply; |
|
111 iError = KErrNone; |
|
112 RunStateL(); |
|
113 } |
|
114 |
|
115 |
|
116 // ----------------------------------------------------------------------------- |
|
117 // CFsComposerFetchLogic::RunForwardLogicL |
|
118 // ----------------------------------------------------------------------------- |
|
119 // |
|
120 void CFsComposerFetchLogic::RunForwardLogicL() |
|
121 { |
|
122 FUNC_LOG; |
|
123 |
|
124 iRunMode = EModeForward; |
|
125 iState = EStateSmartForward; |
|
126 iError = KErrNone; |
|
127 if ( iAppUi.DownloadInfoMediator() ) |
|
128 { |
|
129 iAppUi.DownloadInfoMediator()->AddObserver( this, iMessage->GetMessageId() ); |
|
130 } |
|
131 RunStateL(); |
|
132 |
|
133 } |
|
134 |
|
135 |
|
136 // ----------------------------------------------------------------------------- |
|
137 // CFsComposerFetchLogic::RequestResponseL |
|
138 // ----------------------------------------------------------------------------- |
|
139 // |
|
140 void CFsComposerFetchLogic::RequestResponseL( TFSProgress aEvent, TInt aRequestId ) |
|
141 { |
|
142 FUNC_LOG; |
|
143 |
|
144 // Ignore all responses when cancelling is in progress. |
|
145 if( iFetchingCancelGoingOn ) |
|
146 { |
|
147 return; |
|
148 } |
|
149 |
|
150 iError = aEvent.iError; |
|
151 |
|
152 if ( !iError ) |
|
153 { |
|
154 if ( TFsEmailUiUtility::IsCompleteOrCancelEvent( aEvent ) ) |
|
155 { |
|
156 if ( aEvent.iProgressStatus == TFSProgress::EFSStatus_RequestCancelled ) |
|
157 { |
|
158 iError = KErrCancel; |
|
159 } |
|
160 else |
|
161 { |
|
162 if ( iStructureRequestId == aRequestId ) |
|
163 { |
|
164 iState = EStateBody; |
|
165 } |
|
166 else if ( iBodyRequestId == aRequestId ) |
|
167 { |
|
168 iState = EStateAttachments; |
|
169 } |
|
170 else |
|
171 { |
|
172 __ASSERT_DEBUG( EFalse, Panic(EFSEmailUiUnexpectedValue) ); |
|
173 iError = KErrUnknown; |
|
174 } |
|
175 |
|
176 if ( !iError ) |
|
177 { |
|
178 TRAP( iError, RunStateL() ); |
|
179 } |
|
180 } |
|
181 } |
|
182 } |
|
183 |
|
184 if ( iError ) |
|
185 { |
|
186 // Show error note for connection errors. Notes for other errors |
|
187 // are shown in CNcsComposeView::DoeActivateL() |
|
188 if ( iError == KErrCouldNotConnect || |
|
189 iError == KErrConnectionTerminated ) |
|
190 { |
|
191 TFsEmailUiUtility::ShowErrorNoteL( |
|
192 R_FREESTYLE_EMAIL_ERROR_GENERAL_CONNECTION_ERROR, |
|
193 ETrue ); |
|
194 } |
|
195 Complete(); |
|
196 } |
|
197 |
|
198 } |
|
199 |
|
200 |
|
201 // ----------------------------------------------------------------------------- |
|
202 // CFsComposerFetchLogic::RequestResponseL |
|
203 // ----------------------------------------------------------------------------- |
|
204 // |
|
205 void CFsComposerFetchLogic::RequestResponseL( const TFSProgress& aEvent, const TPartData& aPart ) |
|
206 { |
|
207 FUNC_LOG; |
|
208 |
|
209 // Ignore all responses when cancelling is in progress. |
|
210 if ( !iFetchingCancelGoingOn ) |
|
211 { |
|
212 if ( !iError && aEvent.iError ) |
|
213 { |
|
214 // Cancel all fetching when first error occurs |
|
215 iError = aEvent.iError; |
|
216 CancelFetchings(); |
|
217 } |
|
218 else if ( TFsEmailUiUtility::IsCompleteOrCancelEvent( aEvent ) ) |
|
219 { |
|
220 // Remove the completed/failed download item |
|
221 for ( TInt i=0; i<iParts.Count(); i++ ) |
|
222 { |
|
223 if ( iParts[i] == aPart ) |
|
224 { |
|
225 iParts.Remove( i ); |
|
226 break; |
|
227 } |
|
228 } |
|
229 |
|
230 // If last part just got removed, then move on |
|
231 if ( !iParts.Count() ) |
|
232 { |
|
233 Complete(); |
|
234 } |
|
235 } |
|
236 } |
|
237 } |
|
238 |
|
239 // ----------------------------------------------------------------------------- |
|
240 // CFsComposerFetchLogic::RunState |
|
241 // ----------------------------------------------------------------------------- |
|
242 // |
|
243 void CFsComposerFetchLogic::RunStateL() |
|
244 { |
|
245 FUNC_LOG; |
|
246 |
|
247 TBool doNextState = EFalse; |
|
248 |
|
249 do |
|
250 { |
|
251 doNextState = EFalse; |
|
252 |
|
253 switch ( iState ) |
|
254 { |
|
255 case EStateSmartReply: |
|
256 { |
|
257 TBool supported = iMailBox->HasCapability( EFSMBoxCapaSmartReply ); |
|
258 TBool smartEdit = iMailBox->HasCapability( EFSMBoxCapaSmartEdit ); |
|
259 if ( supported && !smartEdit ) |
|
260 { |
|
261 Complete(); |
|
262 } |
|
263 else |
|
264 { |
|
265 iState = EStateStructure; |
|
266 doNextState = ETrue; |
|
267 } |
|
268 } |
|
269 break; |
|
270 |
|
271 case EStateSmartForward: |
|
272 { |
|
273 TBool supported = iMailBox->HasCapability( EFSMBoxCapaSmartForward ); |
|
274 TBool smartEdit = iMailBox->HasCapability( EFSMBoxCapaSmartEdit ); |
|
275 if ( supported && !smartEdit ) |
|
276 { |
|
277 Complete(); |
|
278 } |
|
279 else |
|
280 { |
|
281 iState = EStateStructure; |
|
282 doNextState = ETrue; |
|
283 } |
|
284 } |
|
285 break; |
|
286 |
|
287 case EStateStructure: |
|
288 { |
|
289 TBool hasStructure = TFsEmailUiUtility::IsMessageStructureKnown( *iMessage ); |
|
290 if ( hasStructure ) |
|
291 { |
|
292 iState = EStateBody; |
|
293 doNextState = ETrue; |
|
294 } |
|
295 else |
|
296 { |
|
297 RArray<TFSMailMsgId> ids; |
|
298 CleanupClosePushL( ids ); |
|
299 ids.AppendL( iMessage->GetMessageId() ); |
|
300 TRAP( iError, iStructureRequestId = iFolder->FetchMessagesL( ids, EFSMsgDataStructure, *this ) ); |
|
301 CleanupStack::PopAndDestroy( &ids ); |
|
302 if ( KErrNone == iError ) |
|
303 { |
|
304 // fetching started successfully |
|
305 iFetchingStructure = ETrue; |
|
306 } |
|
307 else |
|
308 { |
|
309 // error occurred |
|
310 Complete(); |
|
311 } |
|
312 } |
|
313 } |
|
314 break; |
|
315 |
|
316 case EStateBody: |
|
317 { |
|
318 CFSMailMessagePart* body = iMessage->PlainTextBodyPartL(); |
|
319 TBool fetched = EFalse; |
|
320 // Do we have plain text body part |
|
321 if ( !body ) |
|
322 { |
|
323 // No plain text body part so try to get HTML body part |
|
324 body = iMessage->HtmlBodyPartL(); |
|
325 } |
|
326 |
|
327 // Do we have any body part |
|
328 if ( body ) |
|
329 { |
|
330 fetched = TFsEmailUiUtility::IsMessagePartFullyFetched( *body ); |
|
331 } |
|
332 else |
|
333 { |
|
334 // If there is no body part, then it doens't need to be fetched |
|
335 // and we may move on. |
|
336 fetched = ETrue; |
|
337 } |
|
338 |
|
339 CleanupStack::PushL( body ); |
|
340 if ( fetched ) |
|
341 { |
|
342 // with Smart |
|
343 if ( EModeReply == iRunMode ) |
|
344 { |
|
345 Complete(); |
|
346 } |
|
347 else if ( EModeForward == iRunMode ) |
|
348 { |
|
349 TBool smartForward = iMailBox->HasCapability( EFSMBoxCapaSmartForward ); |
|
350 if ( smartForward ) |
|
351 { |
|
352 // do not download attachments if smartforward |
|
353 Complete(); |
|
354 } |
|
355 else |
|
356 { |
|
357 // if smartforward is not suppported fetch attachments |
|
358 iState = EStateAttachments; |
|
359 doNextState = ETrue; |
|
360 } |
|
361 // Smart Edit changes end |
|
362 } |
|
363 else |
|
364 { |
|
365 // should not come here |
|
366 __ASSERT_DEBUG( EFalse, Panic( EFSEmailUiUnexpectedValue ) ); |
|
367 } |
|
368 } |
|
369 else |
|
370 { |
|
371 TFSMailMsgId textPartId = body->GetPartId(); |
|
372 |
|
373 TRAP( iError, iBodyRequestId = body->FetchMessagePartL( textPartId, *this, 0 ) ); |
|
374 if ( KErrNone == iError ) |
|
375 { |
|
376 // fetching started successfully |
|
377 iFetchingBody = ETrue; |
|
378 } |
|
379 else |
|
380 { |
|
381 // error occurred |
|
382 Complete(); |
|
383 } |
|
384 } |
|
385 CleanupStack::PopAndDestroy( body ); |
|
386 } |
|
387 break; |
|
388 |
|
389 case EStateAttachments: |
|
390 { |
|
391 if ( TFsEmailUiUtility::HasUnfetchedAttachmentsL( *iMessage ) ) |
|
392 { |
|
393 RPointerArray<CFSMailMessagePart> attachments; |
|
394 CleanupResetAndDestroyClosePushL( attachments ); |
|
395 iMessage->AttachmentListL( attachments ); |
|
396 for ( TInt i=0; i<attachments.Count(); i++ ) |
|
397 { |
|
398 if ( !TFsEmailUiUtility::IsMessagePartFullyFetched( *attachments[i] ) ) |
|
399 { |
|
400 if ( iAppUi.DownloadInfoMediator() ) |
|
401 { |
|
402 TPartData data; |
|
403 data.iMailBoxId = iMailBox->GetId(); |
|
404 data.iFolderId = iMessage->GetFolderId(); |
|
405 data.iMessageId = iMessage->GetMessageId(); |
|
406 data.iMessagePartId = attachments[i]->GetPartId(); |
|
407 iParts.AppendL( data ); |
|
408 iAppUi.DownloadInfoMediator()->DownloadL( data, EFalse ); |
|
409 } |
|
410 else |
|
411 { |
|
412 iError = KErrGeneral; |
|
413 Complete(); |
|
414 } |
|
415 } |
|
416 } |
|
417 CleanupStack::PopAndDestroy( &attachments ); |
|
418 } |
|
419 else |
|
420 { |
|
421 Complete(); |
|
422 } |
|
423 } |
|
424 break; |
|
425 } |
|
426 } |
|
427 while ( doNextState ); |
|
428 } |
|
429 |
|
430 |
|
431 // ----------------------------------------------------------------------------- |
|
432 // CFsComposerFetchLogic::CancelFetchings |
|
433 // ----------------------------------------------------------------------------- |
|
434 // |
|
435 void CFsComposerFetchLogic::CancelFetchings() |
|
436 { |
|
437 FUNC_LOG; |
|
438 iFetchingCancelGoingOn = ETrue; //<cmail> during cancel other event may come |
|
439 |
|
440 // message structure fetching |
|
441 if ( iFetchingStructure ) |
|
442 { |
|
443 TRAPD( error, iClient.CancelL( iStructureRequestId ) ); |
|
444 if ( error ) |
|
445 { |
|
446 } |
|
447 else |
|
448 { |
|
449 iFetchingStructure = EFalse; |
|
450 } |
|
451 } |
|
452 |
|
453 // message body fetching |
|
454 if ( iFetchingBody ) |
|
455 { |
|
456 TRAPD( error, iClient.CancelL( iBodyRequestId ) ); |
|
457 if ( error ) |
|
458 { |
|
459 } |
|
460 else |
|
461 { |
|
462 iFetchingBody = EFalse; |
|
463 } |
|
464 } |
|
465 |
|
466 // message part downloads |
|
467 if ( iAppUi.DownloadInfoMediator() ) |
|
468 { |
|
469 // Note that we don't bother removing anything from iParts now; they |
|
470 // will be cleaned up later. |
|
471 for ( TInt i = iParts.Count() - 1; i >= 0; i-- ) |
|
472 { |
|
473 TRAP_IGNORE( iAppUi.DownloadInfoMediator()->CancelDownloadL( iParts[i].iMessagePartId ) ); |
|
474 } |
|
475 } |
|
476 |
|
477 if( !iRequestCompleted ) |
|
478 { |
|
479 if ( iObserver.FetchLogicComplete( iState, KErrCancel )) |
|
480 { |
|
481 // If the observer deleted this object, don't try to do anything |
|
482 // else. |
|
483 return; |
|
484 } |
|
485 iRequestCompleted = ETrue; //so that no stray events from plugins can cause panic |
|
486 } |
|
487 |
|
488 iFetchingCancelGoingOn = EFalse; |
|
489 } |
|
490 |
|
491 // ----------------------------------------------------------------------------- |
|
492 // CFsComposerFetchLogic::Complete |
|
493 // ----------------------------------------------------------------------------- |
|
494 // |
|
495 void CFsComposerFetchLogic::Complete() |
|
496 { |
|
497 FUNC_LOG; |
|
498 |
|
499 if(!iRequestCompleted) |
|
500 { |
|
501 if ( iAppUi.DownloadInfoMediator() ) |
|
502 { |
|
503 iAppUi.DownloadInfoMediator()->StopObserving( this, iMessage->GetMessageId() ); |
|
504 } |
|
505 // wait note not active, call observer |
|
506 iFetchingStructure = EFalse; |
|
507 iFetchingBody = EFalse; |
|
508 iRequestCompleted = ETrue; |
|
509 iObserver.FetchLogicComplete( iState, iError ); |
|
510 } |
|
511 } |
|
512 |