ipsservices/ipssosplugin/src/ipsplgsmtpservice.cpp
changeset 0 8466d47a6819
child 4 e7aa27f58ae1
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     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