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