|
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 CIpsPlgSmtpService. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "emailtrace.h" |
|
20 #include "ipsplgheaders.h" |
|
21 |
|
22 // <cmail> const TInt KIpsSetUtilsCharAt = '@'; </cmail> |
|
23 const TInt KIpsSetUtilsCharLessThan = '<'; |
|
24 const TInt KIpsSetUtilsCharMoreThan = '>'; |
|
25 const TInt KIpsSetUtilsCntrCharacters = 2; |
|
26 |
|
27 // do we need smtp object instead set of static functions |
|
28 |
|
29 // --------------------------------------------------------------------------- |
|
30 // CIpsPlgSmtpService::CIpsPlgSmtpService |
|
31 // --------------------------------------------------------------------------- |
|
32 // |
|
33 CIpsPlgSmtpService::CIpsPlgSmtpService( |
|
34 CMsvSession& aSession, |
|
35 CIpsPlgSosBasePlugin& aPlugin ) : |
|
36 iPlugin( aPlugin ), |
|
37 iSession( aSession), |
|
38 iMsgMapper( NULL ) |
|
39 { |
|
40 FUNC_LOG; |
|
41 } |
|
42 |
|
43 // --------------------------------------------------------------------------- |
|
44 // CIpsPlgSmtpService::~CIpsPlgSmtpService |
|
45 // --------------------------------------------------------------------------- |
|
46 // |
|
47 CIpsPlgSmtpService::~CIpsPlgSmtpService() |
|
48 { |
|
49 FUNC_LOG; |
|
50 delete iMsgMapper; |
|
51 } |
|
52 |
|
53 // --------------------------------------------------------------------------- |
|
54 // CIpsPlgSmtpService::NewL |
|
55 // --------------------------------------------------------------------------- |
|
56 // |
|
57 EXPORT_C CIpsPlgSmtpService* CIpsPlgSmtpService::NewL( |
|
58 CMsvSession& aSession, |
|
59 CIpsPlgSosBasePlugin& aPlugin ) |
|
60 { |
|
61 FUNC_LOG; |
|
62 CIpsPlgSmtpService* self = CIpsPlgSmtpService::NewLC( |
|
63 aSession, aPlugin ); |
|
64 CleanupStack::Pop( self ); |
|
65 return self; |
|
66 } |
|
67 |
|
68 // --------------------------------------------------------------------------- |
|
69 // CIpsPlgSmtpService::NewLC |
|
70 // --------------------------------------------------------------------------- |
|
71 // |
|
72 EXPORT_C CIpsPlgSmtpService* CIpsPlgSmtpService::NewLC( |
|
73 CMsvSession& aSession, |
|
74 CIpsPlgSosBasePlugin& aPlugin ) |
|
75 { |
|
76 FUNC_LOG; |
|
77 CIpsPlgSmtpService* self = new( ELeave ) CIpsPlgSmtpService( |
|
78 aSession, aPlugin ); |
|
79 CleanupStack::PushL( self ); |
|
80 self->ConstructL(); |
|
81 return self; |
|
82 } |
|
83 |
|
84 // --------------------------------------------------------------------------- |
|
85 // CIpsPlgSmtpService::ConstructL |
|
86 // --------------------------------------------------------------------------- |
|
87 // |
|
88 void CIpsPlgSmtpService::ConstructL() |
|
89 { |
|
90 FUNC_LOG; |
|
91 iMsgMapper = CIpsPlgMsgMapper::NewL( iSession, iPlugin ); |
|
92 } |
|
93 |
|
94 // --------------------------------------------------------------------------- |
|
95 // CIpsPlgSmtpService::CreateDisplayStringLC |
|
96 // --------------------------------------------------------------------------- |
|
97 // |
|
98 HBufC* CIpsPlgSmtpService::CreateDisplayStringLC( |
|
99 const TDesC& aDisplayName, |
|
100 const TDesC& aEmailName ) |
|
101 { |
|
102 FUNC_LOG; |
|
103 TInt length( aDisplayName.Length() ); |
|
104 HBufC* fullName( NULL ); |
|
105 |
|
106 length += aEmailName.Length() + KIpsSetUtilsCntrCharacters; |
|
107 fullName = HBufC::NewLC( length ); |
|
108 fullName->Des().Append( aDisplayName ); |
|
109 |
|
110 if ( fullName->Length() ) |
|
111 { |
|
112 // We have display name, add angle brackets to address |
|
113 fullName->Des().Append( KIpsSetUtilsCharLessThan ); |
|
114 fullName->Des().Append( aEmailName ); |
|
115 fullName->Des().Append( KIpsSetUtilsCharMoreThan ); |
|
116 } |
|
117 else |
|
118 { |
|
119 fullName->Des().Append( aEmailName ); |
|
120 } |
|
121 return fullName; |
|
122 } |
|
123 |
|
124 // --------------------------------------------------------------------------- |
|
125 // CIpsPlgSmtpService::StoreMessageL |
|
126 // --------------------------------------------------------------------------- |
|
127 // |
|
128 void CIpsPlgSmtpService::StoreMessageL( |
|
129 TFSMailMsgId /* aMailBoxId */, CFSMailMessage& aMessage ) |
|
130 { |
|
131 FUNC_LOG; |
|
132 |
|
133 // Update flags i.e. Priority |
|
134 iMsgMapper->UpdateMessageFlagsL( aMessage.GetMessageId().Id(), aMessage ); |
|
135 |
|
136 // get message from store |
|
137 CMsvEntry* cEntry = CMsvEntry::NewL( |
|
138 iSession, aMessage.GetMessageId().Id(), TMsvSelectionOrdering() ); |
|
139 CleanupStack::PushL( cEntry ); // << cEntry |
|
140 TMsvEntry tEntry = cEntry->Entry(); |
|
141 |
|
142 // creating store object for editing message |
|
143 CMsvStore* store = cEntry->EditStoreL(); |
|
144 CleanupStack::PushL( store ); // << store |
|
145 |
|
146 // create symbian email header object |
|
147 CImHeader* header = CImHeader::NewLC(); // << header |
|
148 header->RestoreL( *store ); |
|
149 |
|
150 // From field, check that sender is set |
|
151 if ( aMessage.GetSender() ) |
|
152 { |
|
153 header->SetFromL( aMessage.GetSender()->GetEmailAddress() ); |
|
154 } |
|
155 |
|
156 // To Field |
|
157 const RPointerArray<CFSMailAddress>& toArray |
|
158 = aMessage.GetToRecipients(); |
|
159 // Reseting recipient list, because our client calls us many times |
|
160 // and we want to avoid duplicates |
|
161 header->ToRecipients().Reset(); |
|
162 // build new 'to' header |
|
163 for( TInt i = 0; i < toArray.Count(); i++ ) |
|
164 { |
|
165 TPtrC displayName = toArray[i]->GetDisplayName(); |
|
166 TPtrC emailName = toArray[i]->GetEmailAddress(); |
|
167 HBufC* fullName = CreateDisplayStringLC( displayName, emailName ); // << fullName |
|
168 header->ToRecipients().AppendL( *fullName ); // copy created |
|
169 // only first receiver |
|
170 if( i == 0 && fullName ) |
|
171 { |
|
172 tEntry.iDetails.Set( *fullName ); |
|
173 cEntry->ChangeL( tEntry ); |
|
174 // Load tEntry again |
|
175 // because old instance's iDetails member gets wiped |
|
176 // in PopAndDestroy below |
|
177 tEntry = cEntry->Entry(); |
|
178 } |
|
179 CleanupStack::PopAndDestroy( fullName ); // >>> fullName |
|
180 } |
|
181 |
|
182 // CC field |
|
183 const RPointerArray<CFSMailAddress>& ccArray |
|
184 = aMessage.GetCCRecipients(); |
|
185 header->CcRecipients().Reset(); |
|
186 for( TInt i = 0; i < ccArray.Count(); i++ ) |
|
187 { |
|
188 header->CcRecipients().AppendL( ccArray[i]->GetEmailAddress() ); // copy created |
|
189 } |
|
190 |
|
191 // BCC field |
|
192 const RPointerArray<CFSMailAddress>& bccArray |
|
193 = aMessage.GetBCCRecipients(); |
|
194 header->BccRecipients().Reset(); |
|
195 for( TInt i = 0; i < bccArray.Count(); i++ ) |
|
196 { |
|
197 header->BccRecipients().AppendL( bccArray[i]->GetEmailAddress() ); // copy created |
|
198 } |
|
199 |
|
200 // Subject, check null pointer |
|
201 if ( &aMessage.GetSubject() ) |
|
202 { |
|
203 header->SetSubjectL( aMessage.GetSubject() ); |
|
204 } |
|
205 |
|
206 // store header in cEntry's store |
|
207 header->StoreWithoutCommitL(*store); |
|
208 // commit header to store |
|
209 store->CommitL(); |
|
210 |
|
211 //change preparation state and set subject to description |
|
212 tEntry.SetInPreparation( EFalse ); |
|
213 tEntry.iDescription.Set( aMessage.GetSubject() ); |
|
214 |
|
215 cEntry->ChangeL( tEntry ); |
|
216 |
|
217 // release store |
|
218 CleanupStack::PopAndDestroy( 3, cEntry ); // >>> cEntry, header, store |
|
219 } |
|
220 |
|
221 // --------------------------------------------------------------------------- |
|
222 // CIpsPlgSmtpService::CreateNewSmtpMessageL |
|
223 // --------------------------------------------------------------------------- |
|
224 // |
|
225 CFSMailMessage* CIpsPlgSmtpService::CreateNewSmtpMessageL( |
|
226 const TFSMailMsgId& aMailBoxId ) |
|
227 { |
|
228 FUNC_LOG; |
|
229 TMsvPartList partList( KMsvMessagePartBody ); |
|
230 |
|
231 CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( ); |
|
232 |
|
233 TMsvEntry mboxEntry; |
|
234 TMsvId service; |
|
235 iSession.GetEntry( aMailBoxId.Id(), service, mboxEntry ); |
|
236 |
|
237 // new mail creating operation. Mail is created asynchronously |
|
238 CImEmailOperation* newMailOp = CImEmailOperation::CreateNewL( |
|
239 wait->iStatus, |
|
240 iSession, |
|
241 KMsvDraftEntryId, |
|
242 mboxEntry.iRelatedId, |
|
243 partList, |
|
244 0, |
|
245 KUidMsgTypeSMTP ); |
|
246 |
|
247 CleanupStack::PushL( newMailOp ); |
|
248 |
|
249 // wait until new mail is created |
|
250 wait->Start(); |
|
251 |
|
252 TMsvId msgId = GetIdFromProgressL( newMailOp->FinalProgress() ); |
|
253 |
|
254 CleanupStack::PopAndDestroy( 2, wait ); |
|
255 |
|
256 return CreateFSMessageAndSetFlagsL( |
|
257 msgId, KErrNotFound, aMailBoxId.Id() ); |
|
258 } |
|
259 |
|
260 // --------------------------------------------------------------------------- |
|
261 // CIpsPlgSmtpService::CreateForwardSmtpMessageL |
|
262 // --------------------------------------------------------------------------- |
|
263 // |
|
264 CFSMailMessage* CIpsPlgSmtpService::CreateForwardSmtpMessageL( |
|
265 const TFSMailMsgId& aMailBoxId, |
|
266 const TFSMailMsgId& aOriginalMessageId ) |
|
267 { |
|
268 FUNC_LOG; |
|
269 // 1. part of function checs that body text and all |
|
270 // attachments are fetched |
|
271 TMsvEntry orgMsg; |
|
272 TMsvId service; |
|
273 User::LeaveIfError( iSession.GetEntry( |
|
274 aOriginalMessageId.Id(), service, orgMsg ) ); |
|
275 |
|
276 if ( orgMsg.Id() == KMsvNullIndexEntryIdValue ) |
|
277 { |
|
278 User::Leave(KErrNotFound); |
|
279 } |
|
280 |
|
281 // In case original message is in Sent folder, it's serviceId must be |
|
282 // changed before starting forward/reply msg creation operation |
|
283 // (after forward msg is created, this is changed back) |
|
284 TMsvId orgServiceId( 0 ); |
|
285 if ( ( orgMsg.Parent() == KMsvSentEntryIdValue ) && |
|
286 ( orgMsg.iMtm == KSenduiMtmSmtpUid ) ) |
|
287 { |
|
288 orgServiceId = orgMsg.iServiceId; |
|
289 ChangeServiceIdL( orgMsg ); |
|
290 } |
|
291 |
|
292 TMsvPartList partList( KMsvMessagePartBody | KMsvMessagePartAttachments ); |
|
293 |
|
294 CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( ); |
|
295 CImEmailOperation* forwMailOp = CImEmailOperation::CreateForwardL( |
|
296 wait->iStatus, |
|
297 iSession, |
|
298 orgMsg.Id(), |
|
299 KMsvDraftEntryId, |
|
300 partList, |
|
301 0, |
|
302 KUidMsgTypeSMTP ); |
|
303 |
|
304 CleanupStack::PushL( forwMailOp ); |
|
305 |
|
306 wait->Start(); |
|
307 |
|
308 TMsvId msgId = GetIdFromProgressL( forwMailOp->FinalProgress() ); |
|
309 |
|
310 CleanupStack::PopAndDestroy( 2, wait ); |
|
311 |
|
312 // If original message's serviceId was changed prior to forward/reply msg |
|
313 // creation op, changing it back to the original |
|
314 if ( orgServiceId ) |
|
315 { |
|
316 ChangeServiceIdL( orgMsg, orgServiceId ); |
|
317 } |
|
318 |
|
319 return CreateFSMessageAndSetFlagsL( msgId, orgMsg.Id(), aMailBoxId.Id() ); |
|
320 } |
|
321 |
|
322 // --------------------------------------------------------------------------- |
|
323 // CIpsPlgSmtpService::CreateReplySmtpMessageL |
|
324 // --------------------------------------------------------------------------- |
|
325 // |
|
326 CFSMailMessage* CIpsPlgSmtpService::CreateReplySmtpMessageL( |
|
327 const TFSMailMsgId& aMailBoxId, |
|
328 const TFSMailMsgId& aOriginalMessageId, |
|
329 TBool aReplyToAll ) |
|
330 { |
|
331 FUNC_LOG; |
|
332 // find orginal message header and check that body is fetched |
|
333 TMsvEntry orgMsg; |
|
334 TMsvId service; |
|
335 User::LeaveIfError( |
|
336 iSession.GetEntry( aOriginalMessageId.Id(), service, orgMsg ) ); |
|
337 |
|
338 if ( orgMsg.Id() == KMsvNullIndexEntryIdValue ) |
|
339 { |
|
340 User::Leave(KErrNotFound); |
|
341 } |
|
342 |
|
343 // In case original message is in Sent folder, it's serviceId must be |
|
344 // changed before starting forward/reply msg creation operation |
|
345 // (after forward msg is created, this is changed back) |
|
346 TMsvId orgServiceId( 0 ); |
|
347 if ( ( orgMsg.Parent() == KMsvSentEntryIdValue ) && |
|
348 ( orgMsg.iMtm == KSenduiMtmSmtpUid ) ) |
|
349 { |
|
350 orgServiceId = orgMsg.iServiceId; |
|
351 ChangeServiceIdL( orgMsg ); |
|
352 } |
|
353 |
|
354 // partList flags control e.g. what kind of recipient set is created |
|
355 TMsvPartList partList = KMsvMessagePartBody | KMsvMessagePartDescription |
|
356 | KMsvMessagePartOriginator; |
|
357 if( aReplyToAll ) |
|
358 { |
|
359 partList |= KMsvMessagePartRecipient; |
|
360 } |
|
361 |
|
362 // Ask Symbian messaging fw to create reply message "skeleton" |
|
363 CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( ); |
|
364 CImEmailOperation* replMailOp = CImEmailOperation::CreateReplyL( |
|
365 wait->iStatus, |
|
366 iSession, |
|
367 orgMsg.Id(), |
|
368 KMsvDraftEntryId, |
|
369 partList, |
|
370 0, |
|
371 KUidMsgTypeSMTP ); |
|
372 CleanupStack::PushL( replMailOp ); |
|
373 wait->Start(); |
|
374 TMsvId msgId = GetIdFromProgressL( replMailOp->FinalProgress() ); |
|
375 CleanupStack::PopAndDestroy( 2, wait ); |
|
376 |
|
377 // If original message's serviceId was changed prior to forward/reply msg |
|
378 // creation op, changing it back to the original |
|
379 if ( orgServiceId ) |
|
380 { |
|
381 ChangeServiceIdL( orgMsg, orgServiceId ); |
|
382 } |
|
383 |
|
384 // Start finalising new FS style message |
|
385 CFSMailMessage* fsMsg = CreateFSMessageAndSetFlagsL( |
|
386 msgId, orgMsg.Id(), aMailBoxId.Id() ); |
|
387 CleanupStack::PushL( fsMsg ); // *** |
|
388 |
|
389 // dig out new reply message's header |
|
390 CMsvEntry* cEntry = iSession.GetEntryL( msgId ); |
|
391 CleanupStack::PushL( cEntry ); // *** |
|
392 CMsvStore* store = cEntry->ReadStoreL(); |
|
393 CleanupStack::PushL( store ); // *** |
|
394 if( store->IsPresentL( KUidMsgFileIMailHeader ) == EFalse ) |
|
395 { |
|
396 User::Leave(KErrCorrupt); |
|
397 } |
|
398 CImHeader* header = CImHeader::NewLC(); // *** |
|
399 header->RestoreL( *store ); |
|
400 |
|
401 // Start handling recipients |
|
402 HBufC* emailAddr( NULL ); |
|
403 CFSMailAddress* fsAddr( NULL ); |
|
404 // copy to recipients |
|
405 for( TInt i = 0; i < header->ToRecipients().Count(); i++ ) |
|
406 { |
|
407 emailAddr = header->ToRecipients()[i].AllocLC(); // *** |
|
408 fsAddr = CFSMailAddress::NewLC(); // *** |
|
409 fsAddr->SetEmailAddress( *emailAddr ); // Copy created |
|
410 fsMsg->AppendToRecipient( fsAddr ); // No copy |
|
411 CleanupStack::Pop( fsAddr ); // fsAddr belong now to fsMsg |
|
412 CleanupStack::PopAndDestroy( emailAddr ); // emailAddr not used |
|
413 } |
|
414 // copy cc recipients |
|
415 // <cmail> |
|
416 TFSMailMsgId folderId; |
|
417 TFSMailDetails details( EFSMsgDataEnvelope ); |
|
418 CFSMailMessage* originalMessage = iPlugin.GetMessageByUidL( aMailBoxId, |
|
419 folderId, aOriginalMessageId, details ); |
|
420 CleanupStack::PushL( originalMessage ); |
|
421 RPointerArray<CFSMailAddress>& originalToRecipients = |
|
422 originalMessage->GetToRecipients(); |
|
423 TInt originalToRecipientsCount = originalToRecipients.Count(); |
|
424 TBool present = EFalse; |
|
425 // </cmail> |
|
426 for( TInt i = 0; i < header->CcRecipients().Count(); i++ ) |
|
427 { |
|
428 emailAddr = header->CcRecipients()[i].AllocLC(); // *** |
|
429 fsAddr = CFSMailAddress::NewLC(); // *** |
|
430 fsAddr->SetEmailAddress( *emailAddr ); // Copy created |
|
431 // <cmail> |
|
432 if( aReplyToAll ) |
|
433 { |
|
434 // check if CC recipient read from header was present in To field |
|
435 // of original message. If so, copy it into To recipietns |
|
436 present = EFalse; |
|
437 for( TInt j = 0; j < originalToRecipientsCount; j++ ) |
|
438 { |
|
439 if( emailAddr->Find( originalToRecipients[j]->GetEmailAddress()) |
|
440 != KErrNotFound ) |
|
441 { |
|
442 present = ETrue; |
|
443 break; |
|
444 } |
|
445 } |
|
446 if( present ) |
|
447 { |
|
448 fsMsg->AppendToRecipient( fsAddr ); // No copy |
|
449 } |
|
450 else |
|
451 { |
|
452 fsMsg->AppendCCRecipient( fsAddr ); // No copy |
|
453 } |
|
454 } |
|
455 else |
|
456 { |
|
457 fsMsg->AppendCCRecipient( fsAddr ); // No copy |
|
458 } |
|
459 // </cmail> |
|
460 CleanupStack::Pop( fsAddr ); // fsAddr belong now to fsMsg |
|
461 CleanupStack::PopAndDestroy( emailAddr ); // emailAddr not used |
|
462 } |
|
463 // <cmail> |
|
464 CleanupStack::PopAndDestroy( originalMessage ); |
|
465 // </cmail> |
|
466 // copy bcc recipients |
|
467 for( TInt i = 0; i < header->BccRecipients().Count(); i++ ) |
|
468 { |
|
469 emailAddr = header->BccRecipients()[i].AllocLC(); // *** |
|
470 fsAddr = CFSMailAddress::NewLC(); // *** |
|
471 fsAddr->SetEmailAddress( *emailAddr ); // Copy created |
|
472 fsMsg->AppendBCCRecipient( fsAddr ); // No copy |
|
473 CleanupStack::Pop( fsAddr ); // fsAddr belong now to fsMsg |
|
474 CleanupStack::PopAndDestroy( emailAddr ); // emailAddr not used |
|
475 } |
|
476 |
|
477 CleanupStack::PopAndDestroy( 3, cEntry ); // header, store, cEntry |
|
478 CleanupStack::Pop( fsMsg ); // fsMsg is given to client |
|
479 return fsMsg; |
|
480 } |
|
481 |
|
482 // --------------------------------------------------------------------------- |
|
483 // CIpsPlgSmtpService::ChangeServiceIdL |
|
484 // --------------------------------------------------------------------------- |
|
485 // |
|
486 void CIpsPlgSmtpService::ChangeServiceIdL( TMsvEntry& aEntry ) |
|
487 { |
|
488 FUNC_LOG; |
|
489 TMsvEntry serviceEntry; |
|
490 TMsvId service; |
|
491 CMsvEntry* cEntry = iSession.GetEntryL( aEntry.iServiceId ); |
|
492 CleanupStack::PushL( cEntry ); |
|
493 User::LeaveIfError( iSession.GetEntry( cEntry->EntryId(), service, serviceEntry ) ); |
|
494 if( aEntry.iServiceId != serviceEntry.iRelatedId ) |
|
495 { |
|
496 aEntry.iServiceId = serviceEntry.iRelatedId; |
|
497 cEntry->SetEntryL( aEntry.Id() ); |
|
498 cEntry->ChangeL( aEntry ); |
|
499 } |
|
500 CleanupStack::PopAndDestroy( cEntry ); |
|
501 } |
|
502 |
|
503 // --------------------------------------------------------------------------- |
|
504 // CIpsPlgSmtpService::ChangeServiceIdL |
|
505 // --------------------------------------------------------------------------- |
|
506 // |
|
507 void CIpsPlgSmtpService::ChangeServiceIdL( TMsvEntry& aEntry, TMsvId aServiceId ) |
|
508 { |
|
509 FUNC_LOG; |
|
510 CMsvEntry* cEntry = iSession.GetEntryL( aEntry.Id() ); |
|
511 CleanupStack::PushL( cEntry ); |
|
512 aEntry.iServiceId = aServiceId; |
|
513 cEntry->ChangeL( aEntry ); |
|
514 CleanupStack::PopAndDestroy( cEntry ); |
|
515 } |
|
516 |
|
517 // --------------------------------------------------------------------------- |
|
518 // CIpsPlgSmtpService::CreateFSMessageAndSetFlagsL |
|
519 // --------------------------------------------------------------------------- |
|
520 // |
|
521 CFSMailMessage* CIpsPlgSmtpService::CreateFSMessageAndSetFlagsL( |
|
522 TMsvId aMessageId, TMsvId aOriginalMsgId,TMsvId aMailboxId ) |
|
523 { |
|
524 FUNC_LOG; |
|
525 |
|
526 // Default charset |
|
527 TUid charset; |
|
528 charset.iUid = KCharacterSetIdentifierUtf8; |
|
529 |
|
530 // set in preparation flag, altought |
|
531 // not known where this affects |
|
532 TMsvId dummy; |
|
533 TMsvEmailEntry newEmailMsg; |
|
534 iSession.GetEntry( aMessageId, dummy, newEmailMsg ); |
|
535 newEmailMsg.SetInPreparation( ETrue ); |
|
536 |
|
537 // when creating new message from scratch theres no |
|
538 // orginal message, so it is set to KErrNotFound |
|
539 if ( aOriginalMsgId != KErrNotFound ) |
|
540 { |
|
541 TMsvEntry orgMsg; |
|
542 //get entry errors not handled |
|
543 iSession.GetEntry( aOriginalMsgId, dummy, orgMsg ); |
|
544 const TMsvEmailEntry& orgEmailMsg(orgMsg); |
|
545 |
|
546 // symbian not mark same priority to reply / forward messages |
|
547 if ( orgEmailMsg.Priority() != newEmailMsg.Priority() ) |
|
548 { |
|
549 newEmailMsg.SetPriority( orgEmailMsg.Priority() ); |
|
550 } |
|
551 //get charset from original message |
|
552 charset = GetOriginalCharsetL( aOriginalMsgId ); |
|
553 } |
|
554 |
|
555 // set in preparation |
|
556 CMsvEntry* cEntry = iSession.GetEntryL( aMessageId ); |
|
557 CleanupStack::PushL( cEntry ); |
|
558 cEntry->ChangeL( newEmailMsg ); |
|
559 |
|
560 //no need to set if we for some reason don't have it. |
|
561 //system default will be used. |
|
562 if ( KNullUidValue != charset.iUid ) |
|
563 { |
|
564 SetCharactersetL( *cEntry, charset ); |
|
565 } |
|
566 // delete operations we don't need anymore |
|
567 CleanupStack::PopAndDestroy( cEntry ); |
|
568 |
|
569 // create a Freestyle mail message object and set to it all |
|
570 // needed data from just created symbian mail message |
|
571 CFSMailMessage* fsMsg = CFSMailMessage::NewL( |
|
572 TFSMailMsgId( iPlugin.PluginId(), aMessageId ) ); |
|
573 fsMsg->SetMailBoxId( TFSMailMsgId( iPlugin.PluginId(), aMailboxId ) ); |
|
574 fsMsg->SetFolderId( |
|
575 TFSMailMsgId( iPlugin.PluginId(), KMsvDraftEntryId ) ); |
|
576 |
|
577 //update flags |
|
578 iMsgMapper->SetFSMessageFlagsL( newEmailMsg, *fsMsg ); |
|
579 |
|
580 return fsMsg; |
|
581 } |
|
582 |
|
583 // --------------------------------------------------------------------------- |
|
584 // CIpsPlgSmtpService::GetIdFromProgressL |
|
585 // inline static |
|
586 // --------------------------------------------------------------------------- |
|
587 // |
|
588 inline TMsvId CIpsPlgSmtpService::GetIdFromProgressL( const TDesC8& aProg ) |
|
589 { |
|
590 FUNC_LOG; |
|
591 // Taken from symbian os help example code |
|
592 // Create and initialise a temporary TPckg object that |
|
593 // can hold a message Id. |
|
594 TMsvId msgId; |
|
595 TPckg<TMsvId> param(msgId); |
|
596 |
|
597 // Copy the message Id returned from the ProgressL() call into the |
|
598 // temporary TPckg object. |
|
599 param.Copy( aProg ); |
|
600 |
|
601 // Check the value of the returned message Id in the TPckg object. |
|
602 if ( msgId == KMsvNullIndexEntryId ) |
|
603 { |
|
604 // Email is not correctly created, so leave |
|
605 User::Leave( KErrNotFound ); |
|
606 } |
|
607 return msgId; |
|
608 } |
|
609 |
|
610 // --------------------------------------------------------------------------- |
|
611 // CIpsPlgSmtpService::GetOriginalCharsetL |
|
612 // --------------------------------------------------------------------------- |
|
613 // |
|
614 TUid CIpsPlgSmtpService::GetOriginalCharsetL( TMsvId aOriginalMsgId ) |
|
615 { |
|
616 FUNC_LOG; |
|
617 TUid ret; |
|
618 CMsvEntry* oEntry = iSession.GetEntryL( aOriginalMsgId ); |
|
619 CleanupStack::PushL( oEntry ); |
|
620 |
|
621 CImEmailMessage* cMessage = CImEmailMessage::NewLC( *oEntry ); |
|
622 |
|
623 // <cmail> Added check for body text because GetCharacterSetL will |
|
624 // hang if there is no body text |
|
625 CMsvStore* store = oEntry->EditStoreL(); |
|
626 CleanupStack::PushL(store); |
|
627 |
|
628 TUint charId; |
|
629 |
|
630 if( store->HasBodyTextL() ) |
|
631 { |
|
632 TBool override=EFalse; |
|
633 cMessage->GetCharacterSetL( aOriginalMsgId, charId, override ); |
|
634 ret.iUid = charId; |
|
635 } |
|
636 else |
|
637 { |
|
638 ret.iUid = KCharacterSetIdentifierUtf8; |
|
639 } |
|
640 |
|
641 CleanupStack::PopAndDestroy( 3, oEntry );//oEntry, cMessage, store |
|
642 // </cmail> |
|
643 |
|
644 return ret; |
|
645 } |
|
646 |
|
647 // --------------------------------------------------------------------------- |
|
648 // CIpsPlgSmtpService::SetCharactersetL |
|
649 // --------------------------------------------------------------------------- |
|
650 // |
|
651 void CIpsPlgSmtpService::SetCharactersetL( CMsvEntry& aEntry, TUid aCharset ) |
|
652 { |
|
653 FUNC_LOG; |
|
654 //Set character set for outgoing message. We use the one |
|
655 //that was in the original message. |
|
656 CMsvStore* store = aEntry.EditStoreL(); |
|
657 CleanupStack::PushL(store); |
|
658 |
|
659 CImHeader* header = CImHeader::NewLC(); |
|
660 header->RestoreL( *store ); |
|
661 |
|
662 TImEmailTransformingInfo info; |
|
663 info.SetToDefault(ESendAsMimeEmail); |
|
664 info.SetHeaderAndBodyCharset( aCharset.iUid ); |
|
665 info.StoreL( *store ); |
|
666 |
|
667 header->StoreL( *store ); |
|
668 store->CommitL(); |
|
669 CleanupStack::PopAndDestroy( 2, store ); // store, header |
|
670 } |
|
671 // End of File |
|
672 |