|
1 /* |
|
2 * Copyright (c) 2002-2006 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: Mail forward operation |
|
15 * |
|
16 */ |
|
17 |
|
18 // INCLUDE FILES |
|
19 #include "CMailForwardOperation.h" |
|
20 #include "MsgMailViewerDocument.h" |
|
21 #include "MailLog.h" |
|
22 #include "MailUtils.h" |
|
23 #include "MsgMailDRMHandler.h" |
|
24 #include "cmailwaitoperation.h" |
|
25 #include <CMailMessage.h> |
|
26 #include <MsgMailViewer.rsg> |
|
27 #include <e32base.h> |
|
28 #include <mtmuibas.h> |
|
29 #include <mtmuidef.hrh> |
|
30 #include <mtmdef.h> |
|
31 #include <impicmds.h> |
|
32 #include <imapcmds.h> |
|
33 #include <MsgAttachmentInfo.h> |
|
34 #include <mmsvattachmentmanager.h> |
|
35 #include <MsvPrgReporter.h> |
|
36 #include <MuiuMsvSingleOpWatcher.h> |
|
37 |
|
38 // CONSTANTS |
|
39 enum TOperationState |
|
40 { |
|
41 ESuspendOperation = 1, |
|
42 ELoadAttachments, |
|
43 EGetAttachments, |
|
44 EConnectToService, |
|
45 EUpdateEntryFlags, |
|
46 EForwardMessage |
|
47 }; |
|
48 |
|
49 // ============================ MEMBER FUNCTIONS =============================== |
|
50 |
|
51 // ----------------------------------------------------------------------------- |
|
52 // CMailForwardOperation::CMailForwardOperation |
|
53 // C++ default constructor can NOT contain any code, that |
|
54 // might leave. |
|
55 // ----------------------------------------------------------------------------- |
|
56 // |
|
57 CMailForwardOperation::CMailForwardOperation( |
|
58 CMsgMailViewerDocument& aDocument, |
|
59 TRequestStatus& aObserverRequestStatus ): |
|
60 CMailOperation( aDocument.Session(), |
|
61 CActive::EPriorityStandard, |
|
62 aObserverRequestStatus ), |
|
63 iDocument( aDocument ), |
|
64 iOperationState( KErrArgument ) |
|
65 { |
|
66 CActiveScheduler::Add( this ); |
|
67 } |
|
68 |
|
69 // ----------------------------------------------------------------------------- |
|
70 // CMailForwardOperation::ConstructL |
|
71 // Symbian 2nd phase constructor can leave. |
|
72 // ----------------------------------------------------------------------------- |
|
73 // |
|
74 inline void CMailForwardOperation::ConstructL() |
|
75 { |
|
76 iSelection = new(ELeave) CMsvEntrySelection; |
|
77 iMtm = iDocument.Mtm().Type(); |
|
78 // Issue first step |
|
79 NexStateL(); |
|
80 } |
|
81 |
|
82 // ----------------------------------------------------------------------------- |
|
83 // CMailForwardOperation::NewL |
|
84 // Two-phased constructor. |
|
85 // ----------------------------------------------------------------------------- |
|
86 // |
|
87 CMailForwardOperation* CMailForwardOperation::NewL( |
|
88 MMsvProgressReporter& aReporter, |
|
89 CMsgMailViewerDocument& aDocument, |
|
90 TRequestStatus& aObserverRequestStatus, |
|
91 TBool aSetSuspend ) |
|
92 { |
|
93 CMailForwardOperation* self = new( ELeave ) CMailForwardOperation( |
|
94 aDocument, |
|
95 aObserverRequestStatus ); |
|
96 |
|
97 CleanupStack::PushL( self ); |
|
98 self->iReporter = &aReporter; |
|
99 self->iOperationState = aSetSuspend ? ESuspendOperation : ELoadAttachments; |
|
100 self->ConstructL(); |
|
101 CleanupStack::Pop( self ); |
|
102 return self; |
|
103 } |
|
104 |
|
105 |
|
106 // Destructor |
|
107 CMailForwardOperation::~CMailForwardOperation() |
|
108 { |
|
109 LOG("CMailForwardOperation::~CMailForwardOperation"); |
|
110 Cancel(); |
|
111 delete iOperation; |
|
112 delete iSelection; |
|
113 } |
|
114 |
|
115 // ----------------------------------------------------------------------------- |
|
116 // CMailForwardOperation::SuspendL |
|
117 // ----------------------------------------------------------------------------- |
|
118 // |
|
119 void CMailForwardOperation::SuspendL( TBool aSetSuspend ) |
|
120 { |
|
121 LOG1("CMailForwardOperation::SuspendL:%d", aSetSuspend); |
|
122 if ( aSetSuspend ) |
|
123 { |
|
124 ASSERT( iOperation == NULL ); |
|
125 iOperation = CMailWaitOperation::NewL( |
|
126 iDocument.Session(), |
|
127 iStatus ); |
|
128 LOG1("CMailForwardOperation::SuspendL::%08x", |
|
129 iOperation); |
|
130 SetActive(); |
|
131 iOperationState = ESuspendOperation; |
|
132 } |
|
133 else |
|
134 { |
|
135 if ( iOperationState == ESuspendOperation ) |
|
136 { |
|
137 delete iOperation; |
|
138 iOperation = NULL; |
|
139 iOperationState = ELoadAttachments; |
|
140 } |
|
141 } |
|
142 } |
|
143 |
|
144 // ----------------------------------------------------------------------------- |
|
145 // Called when UI gets Operation completed notification |
|
146 // ----------------------------------------------------------------------------- |
|
147 // |
|
148 TBool CMailForwardOperation::CompletedL( TInt /*aCompletionCode*/ ) |
|
149 { |
|
150 TBool ret(ETrue); |
|
151 /* if ( aCompletionCode == KErrCancel && |
|
152 (iOperationState == ESuspendOperation || |
|
153 iOperationState == EGetAttachments || |
|
154 iOperationState == EConnectToService ) ) |
|
155 { |
|
156 LOG("CMailForwardOperation::CompletedL - continue"); |
|
157 // Let's forward what we can |
|
158 iOperationState = EUpdateEntryFlags; |
|
159 NexStateL(); |
|
160 ret = EFalse; |
|
161 }*/ |
|
162 return ret; |
|
163 } |
|
164 |
|
165 // ----------------------------------------------------------------------------- |
|
166 // CMailForwardOperation::ProgressL |
|
167 // ----------------------------------------------------------------------------- |
|
168 // |
|
169 const TDesC8& CMailForwardOperation::ProgressL() |
|
170 { |
|
171 LOG("CMailForwardOperation::ProgressL"); |
|
172 // Used CMsvProgressReporterOperation is set to display only wait bar. |
|
173 // --> So there is no need to resolve the progress |
|
174 return KNullDesC8(); |
|
175 } |
|
176 // ----------------------------------------------------------------------------- |
|
177 // CMailForwardOperation::DoCancel |
|
178 // ----------------------------------------------------------------------------- |
|
179 // |
|
180 void CMailForwardOperation::DoCancel() |
|
181 { |
|
182 LOG1("CMailForwardOperation::DoCancel iOperationState:%d", |
|
183 iOperationState); |
|
184 LOG1("CMailForwardOperation::DoCancel iOperation::%08x", |
|
185 iOperation); |
|
186 if ( iOperation ) |
|
187 { |
|
188 iOperation->Cancel(); |
|
189 } |
|
190 |
|
191 if( iOperationState == EGetAttachments ) |
|
192 { // Actually we are still LOADING attachments in this case, but this |
|
193 // state machine has been implemented so that iOperationState has |
|
194 // already been incremented... |
|
195 LOG("CMailForwardOperation::DoCancel, Canceling attachment loading"); |
|
196 iDocument.MailMessage().Cancel(); |
|
197 // Note: Canceling CMailMessage::LoadAttachmentsL() does not cancel |
|
198 // our own pending request or even notify us, so we must do it manually |
|
199 TRequestStatus* status = &iStatus; |
|
200 User::RequestComplete( status, KErrCancel ); |
|
201 } |
|
202 |
|
203 // Complete observer |
|
204 CompleteObserver( iStatus.Int() ); |
|
205 } |
|
206 // ----------------------------------------------------------------------------- |
|
207 // CMailForwardOperation::RunL |
|
208 // ----------------------------------------------------------------------------- |
|
209 // |
|
210 void CMailForwardOperation::RunL() |
|
211 { |
|
212 LOG1("CMailForwardOperation::RunL iStatus:%d", iStatus.Int()); |
|
213 |
|
214 if ( iStatus.Int() != KErrNone || !NexStateL() ) |
|
215 { |
|
216 CompleteObserver( iStatus.Int() ); |
|
217 // Deque(); |
|
218 } |
|
219 } |
|
220 // ----------------------------------------------------------------------------- |
|
221 // CMailForwardOperation::RunError |
|
222 // ----------------------------------------------------------------------------- |
|
223 // |
|
224 TInt CMailForwardOperation::RunError( TInt aError ) |
|
225 { |
|
226 LOG1("CMailForwardOperation::RunError aError:%d", aError); |
|
227 CompleteObserver( aError ); |
|
228 return KErrNone; // must return KErrNone to active sheduler |
|
229 } |
|
230 |
|
231 // ----------------------------------------------------------------------------- |
|
232 // CMailForwardOperation::MessageLoadingL |
|
233 // From |
|
234 // ----------------------------------------------------------------------------- |
|
235 // |
|
236 void CMailForwardOperation::MessageLoadingL( |
|
237 TInt aStatus, CMailMessage& /*aMessage*/) |
|
238 { |
|
239 if( aStatus == CMailMessage::EAttachmentsReady ) |
|
240 { |
|
241 // next state |
|
242 LOG("CMailForwardOperation::MessageLoadingL"); |
|
243 TRequestStatus* status = &iStatus; |
|
244 User::RequestComplete( status, KErrNone ); |
|
245 } |
|
246 } |
|
247 // ----------------------------------------------------------------------------- |
|
248 // CMailForwardOperation::CompleteObserver |
|
249 // ----------------------------------------------------------------------------- |
|
250 // |
|
251 void CMailForwardOperation::CompleteObserver( TInt aStatus ) |
|
252 { |
|
253 TRequestStatus* status = &iObserverRequestStatus; |
|
254 User::RequestComplete( status, aStatus ); |
|
255 } |
|
256 |
|
257 |
|
258 // ----------------------------------------------------------------------------- |
|
259 // CMailForwardOperation::ConnectToServiceL |
|
260 // ----------------------------------------------------------------------------- |
|
261 // |
|
262 void CMailForwardOperation::ConnectToServiceL() |
|
263 { |
|
264 LOG("CMailForwardOperation::ConnectToServiceL"); |
|
265 // connect to service |
|
266 TBuf8<1> param; |
|
267 |
|
268 // set context to imap service |
|
269 TMsvId imapservice = iDocument.Mtm().Entry().OwningService(); |
|
270 iDocument.Mtm().SwitchCurrentEntryL( imapservice ); |
|
271 |
|
272 if ( !iDocument.Mtm().Entry().Entry().Connected() ) |
|
273 { |
|
274 CMsvEntrySelection* imapbox = new(ELeave) CMsvEntrySelection; |
|
275 CleanupStack::PushL(imapbox); |
|
276 imapbox->AppendL( imapservice ); |
|
277 ASSERT( iOperation == NULL ); |
|
278 |
|
279 iOperation = |
|
280 iDocument.MtmUi().InvokeAsyncFunctionL( |
|
281 KIMAP4MTMConnect, *imapbox, iStatus, param ); |
|
282 LOG1("CMailForwardOperation::ConnectToServiceL::%08x", |
|
283 iOperation); |
|
284 CleanupStack::PopAndDestroy( imapbox ); |
|
285 SetActive(); |
|
286 } |
|
287 else |
|
288 { |
|
289 // We are online, start fetch |
|
290 ASSERT( iSelection ); |
|
291 FetchAttachmentsL( *iSelection ); |
|
292 } |
|
293 } |
|
294 |
|
295 // ----------------------------------------------------------------------------- |
|
296 // CMailForwardOperation::CheckAttachmentsL |
|
297 // ----------------------------------------------------------------------------- |
|
298 // |
|
299 void CMailForwardOperation::CheckAttachmentsL() |
|
300 { |
|
301 MMsvAttachmentManager& attachmentManager = |
|
302 iDocument.MailMessage().AttachmentManager(); |
|
303 LOG1("CMailForwardOperation::CheckAttachmentsL attachmentCount:%d", |
|
304 attachmentManager.AttachmentCount()); |
|
305 |
|
306 TInt maxSize(0); |
|
307 // attachment count not static |
|
308 for( TInt index(0); index<attachmentManager.AttachmentCount(); ++index ) |
|
309 { |
|
310 CMsvAttachment* info = attachmentManager.GetAttachmentInfoL( index ); |
|
311 CleanupStack::PushL( info ); |
|
312 |
|
313 if( !info->Complete() ) |
|
314 { |
|
315 // if not fetched, append to the list |
|
316 iSelection->AppendL( info->Id() ); |
|
317 // check if this is 1st or largest unfetched attachment |
|
318 if ( info->Size() > maxSize ) |
|
319 { |
|
320 maxSize = info->Size(); |
|
321 } |
|
322 } |
|
323 CleanupStack::PopAndDestroy( info ); |
|
324 } |
|
325 |
|
326 FetchAttachmentsL( *iSelection, maxSize ); |
|
327 } |
|
328 |
|
329 // ----------------------------------------------------------------------------- |
|
330 // CMailForwardOperation::LoadAttachmentsL |
|
331 // ----------------------------------------------------------------------------- |
|
332 // |
|
333 void CMailForwardOperation::LoadAttachmentsL() |
|
334 { |
|
335 iDocument.MailMessage().LoadAttachmentsL( *this ); |
|
336 iStatus = KRequestPending; |
|
337 SetActive(); |
|
338 } |
|
339 // ----------------------------------------------------------------------------- |
|
340 // CMailForwardOperation::ForwardMessageL |
|
341 // ----------------------------------------------------------------------------- |
|
342 // |
|
343 void CMailForwardOperation::ForwardMessageL() |
|
344 { |
|
345 LOG("CMailForwardOperation::ForwardMessageL"); |
|
346 |
|
347 iOperationState = EForwardMessage; |
|
348 TMsvId msgId = iDocument.MailMessage().MessageEntry().Id(); |
|
349 TMsvPartList parts = |
|
350 KMsvMessagePartBody | |
|
351 KMsvMessagePartDescription | |
|
352 KMsvMessagePartAttachments; |
|
353 iDocument.SetEntryWithoutNotificationL( msgId ); |
|
354 CBaseMtmUi& mtmUi = iDocument.MtmUi(); |
|
355 |
|
356 mtmUi.SetPreferences( |
|
357 mtmUi.Preferences() | |
|
358 EMtmUiFlagEditorPreferEmbedded ); |
|
359 // Set context to message |
|
360 iDocument.Mtm().SwitchCurrentEntryL( msgId ); |
|
361 iDocument.Mtm().Entry().Entry(); |
|
362 |
|
363 // hide the progress note |
|
364 iReporter->MakeProgressVisibleL( EFalse ); |
|
365 |
|
366 ASSERT( iOperation == NULL ); |
|
367 iOperation = mtmUi.ForwardL( |
|
368 iDocument.DefaultMsgFolder(), |
|
369 parts, |
|
370 iStatus ); |
|
371 LOG1("CMailForwardOperation::ForwardMessageL::%08x", |
|
372 iOperation); |
|
373 SetActive(); |
|
374 } |
|
375 |
|
376 // ----------------------------------------------------------------------------- |
|
377 // CMailForwardOperation::UpdateEntryFlagsL |
|
378 // ----------------------------------------------------------------------------- |
|
379 // |
|
380 void CMailForwardOperation::UpdateEntryFlagsL() |
|
381 { |
|
382 LOG("CMailForwardOperation::UpdateEntryFlagsL"); |
|
383 TMsvId msgID = iDocument.MailMessage().MessageEntry().Id(); |
|
384 iDocument.Mtm().SwitchCurrentEntryL( msgID ); |
|
385 |
|
386 TMsvEntry msgEntry = iDocument.Mtm().Entry().Entry(); |
|
387 ASSERT( msgEntry.iType == KUidMsvMessageEntry ); |
|
388 msgEntry.SetComplete( ETrue ); |
|
389 |
|
390 ASSERT( iOperation == NULL ); |
|
391 iOperation = iDocument.Mtm().Entry().ChangeL( |
|
392 msgEntry, |
|
393 iStatus ); |
|
394 LOG1("CMailForwardOperation::UpdateEntryFlagsL::%08x", |
|
395 iOperation); |
|
396 iOperationState = EUpdateEntryFlags; |
|
397 SetActive(); |
|
398 } |
|
399 |
|
400 // ------------------------------------------------------------------------------ |
|
401 // CMailForwardOperation::FetchAttachmentsL() |
|
402 // ------------------------------------------------------------------------------ |
|
403 // |
|
404 void CMailForwardOperation::FetchAttachmentsL( |
|
405 CMsvEntrySelection& aSelection, TInt aMaxSize) |
|
406 { |
|
407 LOG1("CMailForwardOperation::FetchAttachmentsL aMaxSize:%d", aMaxSize); |
|
408 // if some files are not on device, fetch them |
|
409 if ( aSelection.Count() ) |
|
410 { |
|
411 TInt status( MailUtils::EQueryForward ); |
|
412 if ( !iDocument.IsOnLineL() ) |
|
413 { |
|
414 status |= MailUtils::EConnectionOffline; |
|
415 } |
|
416 // check if large attachment is not fetched and if user |
|
417 // wants to fetch it |
|
418 if ( MailUtils::LargeAttachmentQueryL( aMaxSize, status ) ) |
|
419 { |
|
420 ConnectToServiceL(); |
|
421 } |
|
422 else |
|
423 { |
|
424 // User does not want to fetch, let's just forward the message. |
|
425 // After this entry completed flag is updated incorrectly, but |
|
426 // that should not cause any problems. If completed flag is not set |
|
427 // forward operation tries to make connection to mailbox. |
|
428 UpdateEntryFlagsL(); |
|
429 } |
|
430 } |
|
431 else |
|
432 { |
|
433 // Attachments are fetched, make sure entry flag is updated |
|
434 UpdateEntryFlagsL(); |
|
435 } |
|
436 |
|
437 } |
|
438 |
|
439 // ------------------------------------------------------------------------------ |
|
440 // CMailForwardOperation::FetchAttachmentsL() |
|
441 // ------------------------------------------------------------------------------ |
|
442 // |
|
443 void CMailForwardOperation::FetchAttachmentsL( |
|
444 CMsvEntrySelection& aSelection ) |
|
445 { |
|
446 TBuf8<1> param; |
|
447 // Do actual fetch operation |
|
448 ASSERT( iOperation == NULL ); |
|
449 iOperation = iDocument.Mtm().InvokeAsyncFunctionL( |
|
450 KIMAP4MTMPopulate, aSelection, param, iStatus ); |
|
451 LOG1("CMailForwardOperation::FetchAttachmentsL::%08x", |
|
452 iOperation); |
|
453 SetActive(); |
|
454 } |
|
455 |
|
456 // ------------------------------------------------------------------------------ |
|
457 // void CMailForwardOperation::NexStateL() |
|
458 // ------------------------------------------------------------------------------ |
|
459 // |
|
460 TBool CMailForwardOperation::NexStateL() |
|
461 { |
|
462 // Reset previous operation |
|
463 delete iOperation; |
|
464 iOperation = NULL; |
|
465 |
|
466 TBool valid( ETrue ); |
|
467 switch( iOperationState ) |
|
468 { |
|
469 case ESuspendOperation: |
|
470 SuspendL( ETrue ); |
|
471 break; |
|
472 |
|
473 case ELoadAttachments: |
|
474 LoadAttachmentsL(); |
|
475 iOperationState++; |
|
476 break; |
|
477 |
|
478 case EGetAttachments: |
|
479 CheckAttachmentsL(); |
|
480 iOperationState++; |
|
481 break; |
|
482 |
|
483 case EConnectToService: |
|
484 // Now we are online let's fetch 'em |
|
485 FetchAttachmentsL( *iSelection ); |
|
486 iOperationState++; |
|
487 break; |
|
488 |
|
489 case EUpdateEntryFlags: |
|
490 // Now we are ready to forward |
|
491 // Attachment model is not updated, but that's not a problem? |
|
492 UpdateEntryFlagsL(); |
|
493 iOperationState++; |
|
494 break; |
|
495 |
|
496 case EForwardMessage: |
|
497 ForwardMessageL(); |
|
498 iOperationState++; |
|
499 break; |
|
500 default: |
|
501 LOG("CMailForwardOperation::NexStateL - all done"); |
|
502 valid = EFalse; |
|
503 break; |
|
504 }; |
|
505 |
|
506 return valid; |
|
507 } |
|
508 |
|
509 // End of File |