messagingappbase/sendui/meetingrequestsender/src/MeetingRequestSender.cpp
branchRCL_3
changeset 60 7fdbb852d323
equal deleted inserted replaced
57:ebe688cedc25 60:7fdbb852d323
       
     1 /*
       
     2 * Copyright (c) 2002-2005 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: MeetingRequestSender implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <e32base.h>
       
    22 #include <e32std.h>
       
    23 #include <SendUi.h>                     // TSendingCapabilities
       
    24 #include <e32svr.h>
       
    25 #include <mtclreg.h>                    // CClientMtmRegistry
       
    26 #include <mtclbase.h>                   // CBaseMtm
       
    27 #include <miuthdr.h>
       
    28 #include <txtrich.h>
       
    29 #include <MuiuMsvUiServiceUtilities.h>
       
    30 #include <s32mem.h>                     // CBufStore
       
    31 #include <apmstd.h>
       
    32 #include <mtmextendedcapabilities.hrh>  // KUidMsvMtmQuerySupportLinks
       
    33 #include <apgcli.h>
       
    34 #include <mtmuids.h>
       
    35 #include <mtmdef.h>
       
    36 
       
    37 #include <CSendingServiceInfo.h>
       
    38 #include <CMessageAddress.h>
       
    39 #include <SendUiConsts.h>               // UIDs for provider and service
       
    40 #include <CMessageData.h>               // CMessageData
       
    41 #include <MeetingRequestData.h>         // CMeetingRequestData
       
    42 #include <senduisingleton.h>
       
    43 
       
    44 #include "SendUiDummyMtm.h"
       
    45 #include "SendUiOperationWait.h"
       
    46 #include "SenduiDataUtils.h"
       
    47 #include "SenduiFileRightsEngine.h"
       
    48 #include "CSendUiAttachment.h"
       
    49 #include <MeetingRequestIds.hrh>
       
    50 #include "MeetingRequestSender.h"
       
    51 
       
    52 namespace
       
    53     {
       
    54     _LIT8( KContentType, "multipart" );
       
    55     _LIT8( KContentSubType,"/alternative; boundary=mr_part; method=");
       
    56     _LIT( KMsgInvalidSessionEvent, "CMeetingRequestSender: Invalid session event %x" );
       
    57     _LIT( KMsgEmptyAddreesseeArray,"CMeetingRequestSender:: Addressee array is empty! Message cannot be created." );
       
    58     _LIT( KMailtoMatchPattern, "mailto:*" ); // this is never localized
       
    59     const TInt KMailtoLength = 7; // "mailto:" length
       
    60     
       
    61     //  LOCAL CONSTANTS 
       
    62     // For address information separation (start)
       
    63     const TUint KSendUiMsgAddressStartChar         ('<');
       
    64 
       
    65     // For address information separation (end)
       
    66     const TUint KSendUiMsgAddressEndChar           ('>');
       
    67 
       
    68     const TInt KRichTextStoreGranularity = 512;
       
    69     const TInt KContentSubTypeMaxLength( 60 );
       
    70     
       
    71     const TUint KTransferBufAdditionalInfoMaxLen = 20;
       
    72     }
       
    73 
       
    74 // ============================ MEMBER FUNCTIONS ===============================
       
    75 
       
    76 // -----------------------------------------------------------------------------
       
    77 // CMeetingRequestSender::NewL
       
    78 // Two-phased constructor.
       
    79 // -----------------------------------------------------------------------------
       
    80 //
       
    81 CMeetingRequestSender* CMeetingRequestSender::NewL( TSendingServiceParams* aParams )
       
    82     {
       
    83     CMeetingRequestSender* self = CMeetingRequestSender::NewLC( aParams );
       
    84     CleanupStack::Pop();
       
    85 
       
    86     return self;
       
    87     }
       
    88 
       
    89 // -----------------------------------------------------------------------------
       
    90 // CMeetingRequestSender::NewLC
       
    91 // Two-phased constructor.
       
    92 // -----------------------------------------------------------------------------
       
    93 //
       
    94 CMeetingRequestSender* CMeetingRequestSender::NewLC( TSendingServiceParams* aParams )
       
    95     {
       
    96     CMeetingRequestSender* self = new( ELeave ) CMeetingRequestSender( aParams->iCoeEnv, aParams->iSingleton );
       
    97     CleanupStack::PushL( self );
       
    98 
       
    99     self->ConstructL();
       
   100     return self;
       
   101     }
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CMeetingRequestSender::~CMeetingRequestSender()
       
   105 // Destructor.
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 CMeetingRequestSender::~CMeetingRequestSender()
       
   109     {
       
   110     iServiceArray.ResetAndDestroy();
       
   111     iServiceArray.Close();
       
   112 
       
   113     delete iStore;
       
   114 
       
   115     delete iClientMtm;
       
   116     }
       
   117 
       
   118 // -----------------------------------------------------------------------------
       
   119 // CMeetingRequestSender::CMeetingRequestSender
       
   120 // Constructor.
       
   121 // -----------------------------------------------------------------------------
       
   122 //
       
   123 
       
   124 CMeetingRequestSender::CMeetingRequestSender( CCoeEnv& aCoeEnv, CSendUiSingleton& aSingleton ) : 
       
   125     CSendingService( aCoeEnv, aSingleton )
       
   126     {
       
   127     }
       
   128     
       
   129 // -----------------------------------------------------------------------------
       
   130 // CMeetingRequestSender::ConstructL
       
   131 // Symbian 2nd phase constructor can leave.
       
   132 // -----------------------------------------------------------------------------
       
   133 //
       
   134 void CMeetingRequestSender::ConstructL()
       
   135     {
       
   136     InitializeServiceL();   
       
   137     }
       
   138 
       
   139 // -----------------------------------------------------------------------------
       
   140 // CMeetingRequestSender::PopulateServicesListL
       
   141 // Populates given list with the services provided by this plugin.
       
   142 // The ownership of the pointed objects remains.
       
   143 // (other items were commented in a header).
       
   144 // -----------------------------------------------------------------------------
       
   145 //
       
   146 void CMeetingRequestSender::PopulateServicesListL(
       
   147     RPointerArray<CSendingServiceInfo>& aList )
       
   148     {
       
   149     CleanupClosePushL( aList );
       
   150     for ( TInt cc = 0; cc < iServiceArray.Count(); cc++ )
       
   151         {
       
   152         User::LeaveIfError( aList.Append( iServiceArray[cc] ) );
       
   153         }
       
   154     CleanupStack::Pop( &aList );
       
   155     }
       
   156 
       
   157 // -----------------------------------------------------------------------------
       
   158 // CMeetingRequestSender::CreateAndSendMessageL
       
   159 // Creates message to be sent and calls MTM to send the message.
       
   160 // (other items were commented in a header).
       
   161 // -----------------------------------------------------------------------------
       
   162 //
       
   163 void CMeetingRequestSender::CreateAndSendMessageL(
       
   164     TUid aServiceUid,
       
   165     const CMessageData* aMessageData,
       
   166     TBool /*aLaunchEditorEmbedded*/)
       
   167     {
       
   168 
       
   169     if( !aMessageData ||
       
   170         aServiceUid != KMeetingRequestSender ||
       
   171         aMessageData->DataType() != KSenduiMsgDataMeetingRequest ) 
       
   172         {
       
   173         User::Leave( KErrNotSupported );
       
   174         }
       
   175 
       
   176     CMeetingRequestData* mrData = CMeetingRequestData::NewLC();
       
   177     mrData->ReadFromBufferL( aMessageData->OpaqueData() );
       
   178 
       
   179     InitResourcesL( mrData );
       
   180 
       
   181     //In case of SMTP we just create message and don't check capabilities,
       
   182     //because SMTP MTM doesn't understand capabilities at the moment.
       
   183     if( iClientMtm->Type() == KSenduiMtmSmtpUid )
       
   184         {
       
   185         DoCreateAndSendMessageL( *aMessageData, mrData );
       
   186         }
       
   187     else
       
   188         {
       
   189         TUid supportMeetingRequestUid =  TUid::Uid(KMtmUiSupportMeetingRequest);
       
   190         TUid supportICalCapability =  TUid::Uid(KMtmUiSupportICalCapability);
       
   191         TInt capabilityResponse;
       
   192 
       
   193         TInt errorCode = iClientMtm->QueryCapability(supportMeetingRequestUid, capabilityResponse);
       
   194                 
       
   195         //Check if Meeting request is supported at all. If not then leave.
       
   196         if(errorCode == KErrNotSupported || capabilityResponse == 0)
       
   197             {
       
   198             User::Leave( KErrNotSupported );
       
   199             }
       
   200 
       
   201         errorCode = iClientMtm->QueryCapability(supportICalCapability, capabilityResponse);
       
   202         
       
   203         //Check if MTM supports supportICalCapability. 
       
   204         if ( (errorCode != KErrNotSupported) && (capabilityResponse != 0))
       
   205             {
       
   206             DoCreateAndSendMessageL( *aMessageData, mrData );
       
   207             }
       
   208         else
       
   209             {
       
   210             TransferIdsToClientL( *aMessageData );
       
   211             
       
   212             DoCreateAndSendMessageL( *aMessageData, mrData );
       
   213             }
       
   214         }
       
   215     CleanupStack::PopAndDestroy( mrData );
       
   216     }
       
   217 
       
   218 // -----------------------------------------------------------------------------
       
   219 // CMeetingRequestSender::DoCreateAndSendMessageL
       
   220 // Creates message to be sent and calls MTM to send the message.
       
   221 // (other items were commented in a header).
       
   222 // -----------------------------------------------------------------------------
       
   223 //
       
   224 void CMeetingRequestSender::DoCreateAndSendMessageL(
       
   225     const CMessageData& aMessageData,
       
   226     CMeetingRequestData* aMeetingRequestData )
       
   227     {
       
   228     CreateMessageL( aMessageData );
       
   229     
       
   230     TInt capabilityResponse;
       
   231     //Capability to support some kind of body checked 
       
   232     TInt errorCode = iClientMtm->QueryCapability( 
       
   233         TUid::Uid( KUidMtmQuerySupportedBodyValue ), 
       
   234         capabilityResponse );
       
   235     
       
   236     if(capabilityResponse)
       
   237         {
       
   238         SetBodyL( aMessageData );    
       
   239         }
       
   240 
       
   241     AddAttachmentsL( aMessageData );
       
   242 
       
   243     // Create message header(s)
       
   244     CreateHeaderL( aMessageData, aMeetingRequestData );
       
   245 
       
   246     iClientMtm->SaveMessageL();
       
   247         
       
   248     //QueryCapability() can't be used here because client gives false answer.
       
   249     //So only way to do this is check MTM type.
       
   250     if(iClientMtm->Type() == KSenduiMtmSmtpUid)
       
   251         {
       
   252         if( !ValidateEmail( ) )
       
   253             {
       
   254             User::Leave( KErrCompletion );
       
   255             }
       
   256         }
       
   257         
       
   258     SendEmailL( );
       
   259     }
       
   260 
       
   261 // -----------------------------------------------------------------------------
       
   262 // CMeetingRequestSender::TransferIdsToClientL
       
   263 // Transfers meeting request IDs to client MTM.
       
   264 // (other items were commented in a header).
       
   265 // -----------------------------------------------------------------------------
       
   266 //
       
   267 void CMeetingRequestSender::TransferIdsToClientL(
       
   268     const CMessageData& aMessageData )
       
   269     {
       
   270     // Create copy of opaque data. Needed because InvokeSyncFunctionL wants 
       
   271     // non-const buffer.
       
   272     HBufC8* tempBuf = aMessageData.OpaqueData().AllocLC();
       
   273     TPtr8 ptr = tempBuf->Des();
       
   274 
       
   275     // Dummy entry selection
       
   276     CMsvEntrySelection* entrySelection = new ( ELeave ) CMsvEntrySelection;
       
   277     CleanupStack::PushL( entrySelection );
       
   278     
       
   279     //Send data to MTM with InvokeSyncFunction()
       
   280     iClientMtm->InvokeSyncFunctionL(
       
   281             KMTMSendMeetingRequestFunctionId,
       
   282             *entrySelection,
       
   283             ptr );
       
   284                         
       
   285    CleanupStack::PopAndDestroy( 2, tempBuf ); // entrySelection, buf
       
   286     
       
   287    }
       
   288 
       
   289 // ---------------------------------------------------------
       
   290 // CMeetingRequestSender::ServiceProviderId
       
   291 // Returns the id of the service provider.
       
   292 // (other items were commented in a header).
       
   293 // ---------------------------------------------------------
       
   294 //
       
   295 TUid CMeetingRequestSender::ServiceProviderId() const
       
   296     {
       
   297     return KMeetingRequestSender; // defined in SendUiConsts.h
       
   298     }
       
   299 
       
   300 // -----------------------------------------------------------------------------
       
   301 // CMeetingRequestSender::InitializeServiceL
       
   302 // Initializes service info.
       
   303 // (other items were commented in a header).
       
   304 // -----------------------------------------------------------------------------
       
   305 //
       
   306 void CMeetingRequestSender::InitializeServiceL()
       
   307     {
       
   308     if( iServiceArray.Count() )
       
   309         {
       
   310         // Already initialized so do nothing
       
   311         return;
       
   312         }
       
   313 
       
   314     CSendingServiceInfo* serviceInfo = CSendingServiceInfo::NewLC();
       
   315 
       
   316     // Set service type.
       
   317     serviceInfo->SetServiceProviderId( KMeetingRequestSender );
       
   318     serviceInfo->SetServiceId( KMeetingRequestSender );
       
   319     iServiceArray.AppendL( serviceInfo );
       
   320 
       
   321     CleanupStack::Pop( serviceInfo );
       
   322     }
       
   323 
       
   324 // -----------------------------------------------------------------------------
       
   325 // CMeetingRequestSender::CreateMessageL
       
   326 // Creates new message with subject. Index entry is initialized and 
       
   327 // new message is created in drafs folder. 
       
   328 // (other items were commented in a header).
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 void CMeetingRequestSender::CreateMessageL(
       
   332     const CMessageData& aMessageData )
       
   333     {
       
   334     CMsvEntry* draftEntry = iSingleton.MsvSessionL().GetEntryL( KMsvDraftEntryId );
       
   335     CleanupStack::PushL(draftEntry);
       
   336     iClientMtm->SetCurrentEntryL( draftEntry ); // mtm takes ownership
       
   337     CleanupStack::Pop(draftEntry);
       
   338 
       
   339     // Create new message under drafts
       
   340     iClientMtm->CreateMessageL( iMailServiceId );
       
   341 
       
   342     // Load email signature, if any
       
   343     iClientMtm->LoadMessageL();
       
   344 
       
   345     // Set message subject
       
   346     iClientMtm->SetSubjectL( aMessageData.Subject() );
       
   347 
       
   348     // Set attributes on index entry
       
   349     TMsvEntry indexEntry = iClientMtm->Entry().Entry();
       
   350     indexEntry.SetInPreparation( ETrue );
       
   351     indexEntry.SetVisible( EFalse );
       
   352     indexEntry.iDate.UniversalTime();
       
   353     indexEntry.SetAttachment( EFalse );
       
   354 
       
   355     iClientMtm->Entry().ChangeL( indexEntry );
       
   356     
       
   357     
       
   358     }
       
   359 
       
   360 // -----------------------------------------------------------------------------
       
   361 // CMeetingRequestSender::InitResourcesL
       
   362 // Client MTM is initialized. Used SMTP service is validated. 
       
   363 // (other items were commented in a header).
       
   364 // -----------------------------------------------------------------------------
       
   365 //
       
   366 void CMeetingRequestSender::InitResourcesL(
       
   367     CMeetingRequestData* aMeetingRequestData )
       
   368     {
       
   369     iMailServiceId = aMeetingRequestData->Mailbox();
       
   370 
       
   371     if ( iMailServiceId == KMsvNullIndexEntryId )
       
   372         {
       
   373         User::Leave( KErrArgument );
       
   374         }
       
   375 
       
   376     ResolveClientMTMTypeL( iMailServiceId );
       
   377 
       
   378     if ( iClientMtmType == KNullUid )
       
   379         {
       
   380         User::Leave( KErrArgument );
       
   381         }
       
   382 
       
   383     // Create client side MTM object.
       
   384     delete iClientMtm;
       
   385     iClientMtm = NULL;
       
   386 
       
   387     iClientMtm = iSingleton.ClientMtmRegistryL().NewMtmL( iClientMtmType );
       
   388     }
       
   389 
       
   390 // -----------------------------------------------------------------------------
       
   391 // CMeetingRequestSender::ResolveClientMTMTypeL
       
   392 // Resolves the client MTM type by using service id. KNullUid is returned if
       
   393 // service id doesn't match to any available service.
       
   394 // (other items were commented in a header).
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 void CMeetingRequestSender::ResolveClientMTMTypeL( TMsvId aServiceId )
       
   398     {
       
   399     TInt i = 0;
       
   400 
       
   401     CMsvEntrySelection* entrySelection = 
       
   402         MsvUiServiceUtilities::GetListOfAccountsL( iSingleton.MsvSessionL(), ETrue );
       
   403     CleanupStack::PushL( entrySelection );
       
   404 
       
   405     CMsvEntry* rootEntry = CMsvEntry::NewL(
       
   406         iSingleton.MsvSessionL(),
       
   407         KMsvRootIndexEntryId,
       
   408         TMsvSelectionOrdering( KMsvNoGrouping, EMsvSortByNone, ETrue ) );
       
   409     CleanupStack::PushL( rootEntry );    
       
   410 
       
   411     TMsvId msvId;
       
   412     for ( i = 0; i < entrySelection->Count(); i++ )
       
   413         {
       
   414         msvId = entrySelection->At( i );
       
   415         
       
   416         if ( msvId == aServiceId )
       
   417             {
       
   418             TMsvEntry tEntry = rootEntry->ChildDataL( msvId );
       
   419             iClientMtmType = tEntry.iMtm;
       
   420             break;    
       
   421             }
       
   422         }
       
   423 
       
   424     CleanupStack::PopAndDestroy( 2, entrySelection ); // entrySelection, rootEntry
       
   425     }
       
   426 
       
   427 // -----------------------------------------------------------------------------
       
   428 // CMeetingRequestSender::SetBodyL
       
   429 // Sets email body. 
       
   430 // (other items were commented in a header).
       
   431 // -----------------------------------------------------------------------------
       
   432 //
       
   433 void CMeetingRequestSender::SetBodyL(
       
   434     const CMessageData& aMessageData )
       
   435     {
       
   436     // If body has been not set return immediately
       
   437     if( !aMessageData.BodyText()->DocumentLength() )
       
   438         {
       
   439         return;
       
   440         }
       
   441 
       
   442     const CRichText& bodyText = *( aMessageData.BodyText() );
       
   443     CRichText& mtmBody = iClientMtm->Body();
       
   444     
       
   445     delete iStore;
       
   446     iStore = NULL;
       
   447     
       
   448     iStore = CBufStore::NewL( KRichTextStoreGranularity );
       
   449 
       
   450     // If signature has been set then append it at the end of email
       
   451     if ( mtmBody.DocumentLength() )
       
   452         {
       
   453         CRichText* text = CRichText::NewL(
       
   454             static_cast<CEikonEnv&>( iCoeEnv ).SystemParaFormatLayerL(),
       
   455             static_cast<CEikonEnv&>( iCoeEnv ).SystemCharFormatLayerL() );
       
   456         CleanupStack::PushL( text );
       
   457 
       
   458         TInt len1 = bodyText.DocumentLength();
       
   459         TInt len2 = mtmBody.DocumentLength();
       
   460 
       
   461         HBufC* buf = HBufC::NewLC( len1 );
       
   462         TPtr ptr = buf->Des();
       
   463         bodyText.Extract( ptr, 0 );
       
   464         text->InsertL( 0, *buf );
       
   465         CleanupStack::PopAndDestroy( buf );
       
   466 
       
   467         len1 = text->DocumentLength();
       
   468         text->InsertL( len1, CEditableText::EParagraphDelimiter );
       
   469         len1 = text->DocumentLength();
       
   470         text->InsertL( len1, mtmBody.Read( 0, len2 ) );
       
   471 
       
   472         // Save and restore the rich text
       
   473         TStreamId id = text->StoreL( *iStore );
       
   474         mtmBody.RestoreL( *iStore, id );
       
   475 
       
   476         CleanupStack::PopAndDestroy(text);
       
   477         }
       
   478     else
       
   479         {
       
   480         // Save and restore the rich text
       
   481         TStreamId id = bodyText.StoreL( *iStore );
       
   482         mtmBody.RestoreL( *iStore, id );
       
   483         }
       
   484 
       
   485     // Get access to protected data
       
   486     CSendUiDummyMtm* mtm = ( CSendUiDummyMtm* ) iClientMtm;
       
   487 
       
   488     mtm->SetCharFormatL( *bodyText.GlobalCharFormatLayer() );
       
   489     mtm->SetParaFormatL( *bodyText.GlobalParaFormatLayer() );
       
   490     }
       
   491 
       
   492 // -----------------------------------------------------------------------------
       
   493 // CMeetingRequestSender::CreateHeaderL
       
   494 // Create email headers. "Standard" and MIME header is initialized.  
       
   495 // (other items were commented in a header).
       
   496 // -----------------------------------------------------------------------------
       
   497 //
       
   498 void CMeetingRequestSender::CreateHeaderL(
       
   499     const CMessageData& aMessageData,
       
   500     CMeetingRequestData* aMeetingRequestData )
       
   501     {
       
   502     InitStdHeaderL( aMessageData );
       
   503     
       
   504     //At the moment only way to check mime capability is to use iClientMtm->Type()
       
   505     if(iClientMtm->Type() == KSenduiMtmSmtpUid)
       
   506         {
       
   507         InitMimeHeaderL( aMeetingRequestData );
       
   508         }
       
   509     }
       
   510 
       
   511 // -----------------------------------------------------------------------------
       
   512 // CMeetingRequestSender::InitStdHeaderL
       
   513 // Initialize standard header. To, cc and bcc fields are set. 
       
   514 // (other items were commented in a header).
       
   515 // -----------------------------------------------------------------------------
       
   516 //
       
   517 void CMeetingRequestSender::InitStdHeaderL(
       
   518     const CMessageData& aMessageData )
       
   519     {
       
   520     // Nothing to do if aTo array is empty
       
   521     if ( aMessageData.ToAddressArray().Count() == 0 ) 
       
   522         {
       
   523         RDebug::Print( KMsgEmptyAddreesseeArray );
       
   524         User::Leave( KErrArgument );
       
   525         }
       
   526 
       
   527     AddAddresseesL( EMsvRecipientTo, aMessageData.ToAddressArray() );
       
   528 
       
   529     AddAddresseesL( EMsvRecipientCc, aMessageData.CcAddressArray() );    
       
   530 
       
   531     AddAddresseesL( EMsvRecipientBcc, aMessageData.BccAddressArray() );
       
   532     }
       
   533     
       
   534 // -----------------------------------------------------------------------------
       
   535 // CMeetingRequestSender::AddAddresseesL
       
   536 // Add To addressees.
       
   537 // (other items were commented in a header).
       
   538 // -----------------------------------------------------------------------------
       
   539 //    
       
   540 void CMeetingRequestSender::AddAddresseesL(
       
   541     TMsvRecipientType               aRecipientType,
       
   542     const CMessageAddressArray&     aAddressees )
       
   543     {
       
   544     TInt i(0);
       
   545 
       
   546     for( i = 0; i < aAddressees.Count(); i++ )
       
   547         {
       
   548         if( aAddressees[i]->Address().Length() > 0 )
       
   549             {
       
   550             // If address has an alias, process it            
       
   551             if( aAddressees[i]->Alias().Length() > 0 )
       
   552                 {
       
   553                 TPtrC alias = aAddressees[i]->Alias();
       
   554 
       
   555                 // Check if alias contains illegal characters. If it does
       
   556                 // remove them. 
       
   557                 if( ( alias.Locate( KSendUiMsgAddressStartChar ) != KErrNotFound  ) ||
       
   558                     ( alias.Locate( KSendUiMsgAddressEndChar ) != KErrNotFound ) )
       
   559                     {
       
   560                     HBufC* aliasNew = alias.AllocLC();
       
   561                     RemoveIllegalChars( aliasNew );
       
   562                     iClientMtm->AddAddresseeL(
       
   563                         aRecipientType, 
       
   564                         AttendeeAdressWithoutPrefix( aAddressees[i]->Address() ), 
       
   565                         *aliasNew );
       
   566 
       
   567                     CleanupStack::PopAndDestroy( aliasNew );
       
   568                     }
       
   569                 else
       
   570                     {
       
   571                     iClientMtm->AddAddresseeL(
       
   572                         aRecipientType, 
       
   573                         AttendeeAdressWithoutPrefix(aAddressees[i]->Address() ), 
       
   574                         alias );
       
   575                     }
       
   576                 }
       
   577             else 
       
   578                 {
       
   579                 // Address entry didn't have alias
       
   580                 iClientMtm->AddAddresseeL( aRecipientType, 
       
   581                     AttendeeAdressWithoutPrefix( aAddressees[i]->Address() ));
       
   582                 }
       
   583             }
       
   584         // Done setting one addressee
       
   585         }
       
   586     }
       
   587 
       
   588 // -----------------------------------------------------------------------------
       
   589 // CMeetingRequestSender::RemoveIllegalChars
       
   590 // Remove illegal chars from string. Illegal chars are replaced with space
       
   591 // and trimmed string is returned.
       
   592 // Should everything be removed between KSendUiMsgAddressStartChar and
       
   593 // KSendUiMsgAddressEndChar?
       
   594 // (other items were commented in a header).
       
   595 // -----------------------------------------------------------------------------
       
   596 //    
       
   597 void CMeetingRequestSender::RemoveIllegalChars( HBufC* aCheckedString )
       
   598     {
       
   599     TInt stringLength = aCheckedString->Length();
       
   600     TPtr string = aCheckedString->Des();
       
   601 
       
   602     while( stringLength-- )
       
   603         {
       
   604         if( string[stringLength] == KSendUiMsgAddressStartChar ||
       
   605             string[stringLength] == KSendUiMsgAddressEndChar )
       
   606             {
       
   607             string[stringLength] = CEditableText::ESpace;
       
   608             }
       
   609         }
       
   610     string.TrimAll();
       
   611     }
       
   612 
       
   613 // -----------------------------------------------------------------------------
       
   614 // CMeetingRequestSender::InitMimeHeaderL
       
   615 // Mime message header is initialized with user defined content type.
       
   616 // (other items were commented in a header).
       
   617 // -----------------------------------------------------------------------------
       
   618 //    
       
   619 void CMeetingRequestSender::InitMimeHeaderL(
       
   620     CMeetingRequestData* aMeetingRequestData )
       
   621     {
       
   622     CMsvEntry& entry = iClientMtm->Entry();
       
   623     CMsvStore* msvStore = entry.EditStoreL();
       
   624     CleanupStack::PushL( msvStore );
       
   625 
       
   626     CImMimeHeader* header = CImMimeHeader::NewLC();
       
   627 
       
   628     // Set content type
       
   629     header->SetContentTypeL( KContentType ); 
       
   630     
       
   631     TBuf8<KContentSubTypeMaxLength> subtype( KContentSubType() );
       
   632     subtype.Append( aMeetingRequestData->MailHeaderMethod() );
       
   633     header->SetContentSubTypeL( subtype ); 
       
   634 
       
   635     header->StoreL( *msvStore );
       
   636     msvStore->CommitL();
       
   637 
       
   638     CleanupStack::PopAndDestroy( 2, msvStore );
       
   639     }
       
   640 
       
   641 // -----------------------------------------------------------------------------
       
   642 // CMeetingRequestSender::AddAttachmentsL
       
   643 // Attachments are added to the email. Method will leave if there is not 
       
   644 // enough space for attachments.
       
   645 // (other items were commented in a header).
       
   646 // -----------------------------------------------------------------------------
       
   647 //    
       
   648 void CMeetingRequestSender::AddAttachmentsL(
       
   649     const CMessageData& aMessageData )
       
   650     {
       
   651     TInt i(0);
       
   652     
       
   653 
       
   654     CArrayPtrFlat<CSendUiAttachment>* attachments;
       
   655     attachments = CSendUiAttachment::InitAttachmentArrayLCC( 
       
   656         aMessageData.AttachmentArray(), 
       
   657         aMessageData.AttachmentHandleArray(),
       
   658         iCoeEnv.FsSession() );
       
   659     
       
   660     
       
   661     // If there are no attachments, return immediately. 
       
   662     if( !attachments->Count() )
       
   663         {
       
   664         return;
       
   665         }
       
   666 
       
   667     // Get total size of attachments.
       
   668     CSendUiFileRightsEngine* fileRightsEngine =
       
   669         CSendUiFileRightsEngine::NewLC( iCoeEnv.FsSession() );
       
   670 
       
   671     // Check if linked attachments are supported. 
       
   672     TInt supportsLinks = 0;
       
   673     TUid uidQuery = { KUidMsvMtmQuerySupportLinks };
       
   674     iClientMtm->QueryCapability( uidQuery, supportsLinks );
       
   675   
       
   676     TInt totalSize = fileRightsEngine->CalculateTotalSizeOfFiles( attachments, supportsLinks );
       
   677 
       
   678     CleanupStack::PopAndDestroy( fileRightsEngine );
       
   679     // following will leave if there is not enough space
       
   680     CheckDiskSpaceL( totalSize );
       
   681   
       
   682     const RArray<RFile>& attHandles = aMessageData.AttachmentHandleArray();
       
   683     const CDesCArray& attFilePaths = aMessageData.AttachmentArray();
       
   684 
       
   685 
       
   686     for( i = 0; i < attachments->Count(); i++ )
       
   687         {
       
   688         AddAttachmentL( attachments->At(i), supportsLinks );
       
   689         }
       
   690 
       
   691     CleanupStack::PopAndDestroy(2); // *attachments, attacments
       
   692     TMsvEntry entry = iClientMtm->Entry().Entry();
       
   693     entry.SetAttachment( ETrue );
       
   694     iClientMtm->Entry().ChangeL(entry);
       
   695     }
       
   696 
       
   697 // -----------------------------------------------------------------------------
       
   698 // CMeetingRequestSender::AddAttachmentL
       
   699 // Add attachment (file descriptor)
       
   700 // (other items were commented in a header).
       
   701 // -----------------------------------------------------------------------------
       
   702 //
       
   703 void CMeetingRequestSender::AddAttachmentL(
       
   704     CSendUiAttachment* aAttachment, 
       
   705     TInt aLinksSupported )
       
   706     {
       
   707     TDataType mimeType;
       
   708     
       
   709     CSendUiDataUtils* dataUtils = CSendUiDataUtils::NewL( iCoeEnv.FsSession() );
       
   710     CleanupStack::PushL( dataUtils );
       
   711     CSendUiOperationWait* waiter = CSendUiOperationWait::NewLC();
       
   712 
       
   713     if ( aAttachment->Type() == CSendUiAttachment::EAttachmentPath )
       
   714     	{
       
   715         dataUtils->ResolveFileMimeTypeL( *(aAttachment->Path()), mimeType );
       
   716 	  	
       
   717 	  	if ( aLinksSupported )
       
   718 	  		{
       
   719 	  		iClientMtm->AddLinkedAttachmentL(
       
   720                 *(aAttachment->Path()), mimeType.Des8(), 0, waiter->iStatus );
       
   721         	}
       
   722         	else
       
   723         		{
       
   724         	    iClientMtm->AddAttachmentL(
       
   725                     *(aAttachment->Path()), mimeType.Des8(), 0, waiter->iStatus );
       
   726         		}
       
   727 	  	}
       
   728 	  else
       
   729   		{
       
   730         dataUtils->ResolveFileMimeTypeL( *(aAttachment->Handle()), mimeType );
       
   731 	  	RFile attachmentFile;
       
   732 	    User::LeaveIfError( attachmentFile.Duplicate( *(aAttachment->Handle()) ) );
       
   733 	    CleanupClosePushL( attachmentFile );
       
   734 	    
       
   735 	    // File handle ownership transferred.
       
   736 	    iClientMtm->AddAttachmentL(
       
   737 	        attachmentFile,
       
   738 	        mimeType.Des8(),
       
   739 	        NULL,
       
   740 	        waiter->iStatus );
       
   741         CleanupStack::Pop( &attachmentFile );
       
   742 
       
   743   		}
       
   744     
       
   745 
       
   746     waiter->Start( iClientMtm );
       
   747 
       
   748     CleanupStack::PopAndDestroy( 2, dataUtils ); // waiter, dataUtils
       
   749     }
       
   750 // -----------------------------------------------------------------------------
       
   751 // CMeetingRequestSender::CheckDiskSpaceL
       
   752 // Check if there are enough space for email (includes attachments). Leaves 
       
   753 // if there are not enough space. 
       
   754 // (other items were commented in a header).
       
   755 // -----------------------------------------------------------------------------
       
   756 //            
       
   757 void CMeetingRequestSender::CheckDiskSpaceL(
       
   758     TInt aMsgSize )
       
   759     {
       
   760     if( MsvUiServiceUtilities::DiskSpaceBelowCriticalLevelL(
       
   761             iSingleton.MsvSessionL(), aMsgSize ) )
       
   762         {
       
   763         User::Leave( KErrDiskFull );
       
   764         }
       
   765     }
       
   766 
       
   767 // -----------------------------------------------------------------------------
       
   768 // CMeetingRequestSender::ValidateEmail
       
   769 // Validates email before sending it. Returns true if email is valid. 
       
   770 // (other items were commented in a header).
       
   771 // -----------------------------------------------------------------------------
       
   772 //            
       
   773 TBool CMeetingRequestSender::ValidateEmail( )
       
   774     {
       
   775     TMsvPartList msgCheckParts =
       
   776         KMsvMessagePartBody |
       
   777         KMsvMessagePartRecipient |
       
   778         KMsvMessagePartOriginator |
       
   779         KMsvMessagePartDate |
       
   780         KMsvMessagePartDescription;
       
   781 
       
   782     TMsvPartList msgFailParts =
       
   783         iClientMtm->ValidateMessage( msgCheckParts );
       
   784 
       
   785     return ( msgFailParts == KMsvMessagePartNone );
       
   786     }
       
   787 
       
   788 // -----------------------------------------------------------------------------
       
   789 // CMeetingRequestSender::SendEmailL
       
   790 // Sends an email.
       
   791 // (other items were commented in a header).
       
   792 // -----------------------------------------------------------------------------
       
   793 //            
       
   794 void CMeetingRequestSender::SendEmailL( )
       
   795     {
       
   796     TMsvEntry entry = iClientMtm->Entry().Entry();
       
   797 
       
   798     entry.SetInPreparation( EFalse );
       
   799     entry.SetVisible( ETrue );
       
   800     entry.SetSendingState( KMsvSendStateWaiting );
       
   801     
       
   802     iClientMtm->Entry().ChangeL( entry );
       
   803 
       
   804     iClientMtm->LoadMessageL();
       
   805     entry = iClientMtm->Entry().Entry();
       
   806     TMsvId id = entry.Id();
       
   807 
       
   808     if( entry.Parent() != KMsvGlobalOutBoxIndexEntryId )
       
   809         {
       
   810         // move message to outbox
       
   811         MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId );
       
   812         }
       
   813 
       
   814     CMsvEntrySelection*  entrySelection;
       
   815     entrySelection = new ( ELeave ) CMsvEntrySelection;
       
   816     CleanupStack::PushL( entrySelection );
       
   817 
       
   818     entrySelection->AppendL( iMailServiceId );
       
   819     entrySelection->AppendL( id );
       
   820     
       
   821     TBuf8<1> params;
       
   822 
       
   823     CSendUiOperationWait* waiter = CSendUiOperationWait::NewLC();
       
   824 
       
   825     CMsvOperation* op = 
       
   826         iClientMtm->InvokeAsyncFunctionL(
       
   827             KMTMStandardFunctionsSendMessage,
       
   828             *entrySelection,
       
   829             params,
       
   830             waiter->iStatus );
       
   831 
       
   832     waiter->Start( op );
       
   833 
       
   834     CleanupStack::PopAndDestroy( 2, entrySelection ); // entrySelectoin, waiter
       
   835     }
       
   836 
       
   837 // -----------------------------------------------------------------------------
       
   838 // CMeetingRequestSender::MoveMessageEntryL
       
   839 // Moves email to target folder (usually outbox). 
       
   840 // (other items were commented in a header).
       
   841 // -----------------------------------------------------------------------------
       
   842 //            
       
   843 void CMeetingRequestSender::MoveMessageEntryL( TMsvId aTarget )
       
   844     {
       
   845     TMsvSelectionOrdering sort;
       
   846     // we want to also handle the invisible entries
       
   847     sort.SetShowInvisibleEntries( ETrue );
       
   848 
       
   849     // Take a handle to the parent entry
       
   850     TMsvEntry msvEntry( iClientMtm->Entry().Entry() );
       
   851     CMsvEntry* parentEntry = 
       
   852         CMsvEntry::NewL(
       
   853             iClientMtm->Session(),
       
   854             msvEntry.Parent(),
       
   855             sort );
       
   856     CleanupStack::PushL( parentEntry );
       
   857 
       
   858     // Move original from the parent to the new location
       
   859     parentEntry->MoveL( msvEntry.Id(), aTarget );
       
   860 
       
   861     CleanupStack::PopAndDestroy( parentEntry );
       
   862     }
       
   863 
       
   864 // -----------------------------------------------------------------------------
       
   865 // CMeetingRequestSender::AttendeeAdressWithoutPrefix
       
   866 // Returns a new descriptor where "MAILTO:" prefix is removed if it existed.
       
   867 // (other items were commented in a header).
       
   868 // -----------------------------------------------------------------------------
       
   869 //
       
   870 TPtrC CMeetingRequestSender::AttendeeAdressWithoutPrefix( const TDesC& aAddress )
       
   871     {
       
   872     TPtrC attendeeAddrWithoutPrefix;
       
   873     if ( aAddress.MatchF( KMailtoMatchPattern ) != KErrNotFound )
       
   874         {
       
   875         attendeeAddrWithoutPrefix.Set( aAddress.Mid( KMailtoLength ) );
       
   876         }
       
   877     else
       
   878         {
       
   879         attendeeAddrWithoutPrefix.Set( aAddress );
       
   880         }
       
   881     return attendeeAddrWithoutPrefix;
       
   882     }
       
   883 
       
   884 // -----------------------------------------------------------------------------
       
   885 // TechnologyType
       
   886 // -----------------------------------------------------------------------------
       
   887 //
       
   888 TUid CMeetingRequestSender::TechnologyTypeId( ) const
       
   889     {
       
   890     return KNullUid;
       
   891     }
       
   892     
       
   893 //  END OF FILE