mobilemessaging/unieditor/mtm/src/UniClientMtm.cpp
changeset 79 2981cb3aa489
parent 0 72b543305e3a
equal deleted inserted replaced
25:84d9eb65b26f 79:2981cb3aa489
       
     1 /*
       
     2 * Copyright (c) 2005-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: UniClientMtm implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES 
       
    21 #include <txtrich.h>
       
    22 #include <msvids.h>
       
    23 #include <badesca.h>
       
    24 #include <msvstore.h>
       
    25 #include <mtmuids.h> 
       
    26 #include <mtclbase.h>
       
    27 #include <mtmdef.h>
       
    28 #include <msvftext.h>       // CMsvFindText 
       
    29 #include <cmsvmimeheaders.h>
       
    30 #include <mmsvattachmentmanager.h>
       
    31 #include <mmsvattachmentmanagersync.h>
       
    32 
       
    33 #include <msgtextutils.h>
       
    34 #include <mmsgenutils.h>
       
    35 #include <mmsattachmentwaiter.h>
       
    36 #include <mmsattachmenthandler.h>
       
    37 
       
    38 #include "UniMsvEntry.h"
       
    39 #include "UniMtmPanic.h"
       
    40 #include "UniHeaders.h"
       
    41 #include "UniClientMtm.h"
       
    42 #include "UniEditorUids.hrh"
       
    43 #include "UniEditorLogging.h"
       
    44 
       
    45 // ================= MEMBER FUNCTIONS =======================
       
    46 
       
    47 // ---------------------------------------------------------
       
    48 // Factory function
       
    49 // ---------------------------------------------------------
       
    50 // 
       
    51 EXPORT_C CUniClientMtm* CUniClientMtm::NewL(
       
    52     CRegisteredMtmDll& aRegisteredMtmDll,
       
    53     CMsvSession& aSession )
       
    54     {
       
    55     CUniClientMtm* self=new ( ELeave ) CUniClientMtm(
       
    56         aRegisteredMtmDll, aSession );
       
    57     
       
    58     CleanupStack::PushL( self );
       
    59     self->ConstructL();
       
    60     CleanupStack::Pop( self );
       
    61     return self;
       
    62     }
       
    63 
       
    64 // ---------------------------------------------------------
       
    65 // Constructor
       
    66 // ---------------------------------------------------------
       
    67 // 
       
    68 CUniClientMtm::CUniClientMtm(
       
    69     CRegisteredMtmDll& aRegisteredMtmDll,
       
    70     CMsvSession& aSession )
       
    71     : CBaseMtm( aRegisteredMtmDll, aSession ),
       
    72     iUniHeaders ( NULL )
       
    73     {
       
    74     }
       
    75 
       
    76 // ---------------------------------------------------------
       
    77 // Destructor
       
    78 // ---------------------------------------------------------
       
    79 //     
       
    80 CUniClientMtm::~CUniClientMtm()
       
    81     {
       
    82     delete iAttaWaiter;
       
    83     delete iUniHeaders;
       
    84     delete iTextUtils;
       
    85     }
       
    86 
       
    87 // ---------------------------------------------------------
       
    88 // CUniClientMtm::CreateNewEntryL
       
    89 // ---------------------------------------------------------
       
    90 //
       
    91 TMsvId CUniClientMtm::CreateNewEntryL( TMsvId aDestination )
       
    92     {
       
    93     UNILOGGER_WRITE_TIMESTAMP( "CUniClientMtm::CreateNewEntryL start" );
       
    94     // Create new message entry
       
    95     TMsvEntry entry;
       
    96     entry.iType = KUidMsvMessageEntry;
       
    97     entry.iServiceId = KMsvLocalServiceIndexEntryId;
       
    98     entry.iMtm = TUid::Uid( KUidUniMtm );
       
    99     entry.iDate.UniversalTime();
       
   100 
       
   101     // The following ones will be set in completion.
       
   102     entry.SetInPreparation( ETrue );    
       
   103     entry.SetVisible( EFalse );         
       
   104     entry.iSize = 0;
       
   105             
       
   106     // Check that sufficient disk space available
       
   107     // for index entry
       
   108     if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL(
       
   109             &Session().FileSession(), 
       
   110             sizeof( TMsvEntry ),
       
   111             Session().CurrentDriveL() ) )
       
   112         {
       
   113         // we use standard error code here
       
   114         User::Leave( KErrDiskFull );
       
   115         }
       
   116 
       
   117     SwitchCurrentEntryL( aDestination );
       
   118     iMsvEntry->CreateL( entry );
       
   119     SwitchCurrentEntryL( entry.Id() );
       
   120     
       
   121     UNILOGGER_WRITE_TIMESTAMP( "CUniClientMtm::CreateNewEntryL end" );
       
   122     
       
   123     return entry.Id();
       
   124     }
       
   125 
       
   126 //----------------------------------------------------------
       
   127 // METHODS FROM BASE CLASS
       
   128 //----------------------------------------------------------
       
   129 
       
   130 // ---------------------------------------------------------
       
   131 // CUniClientMtm::SaveMessageL
       
   132 // Stores the multimedia message
       
   133 // ---------------------------------------------------------
       
   134 //
       
   135 void CUniClientMtm::SaveMessageL()
       
   136     {
       
   137     // First we should assert that iMsvEntry is not NULL, and panic, if it is
       
   138     __ASSERT_DEBUG( iMsvEntry!=NULL, Panic( EUniNotAMessage ));
       
   139     // SaveMessageL should only be supported for message entries.
       
   140     __ASSERT_DEBUG( iMsvEntry->Entry().iType.iUid == KUidMsvMessageEntryValue,
       
   141         Panic( EUniNotAMessage ) );
       
   142 
       
   143     CMsvStore* store = iMsvEntry->EditStoreL();
       
   144     CleanupStack::PushL( store );
       
   145 
       
   146     TMsvEntry indexEntry = iMsvEntry->Entry();
       
   147 
       
   148     SaveMessageL( *store, indexEntry ); 
       
   149     
       
   150     // Commit the stream store
       
   151     store->CommitL();
       
   152     CleanupStack::PopAndDestroy( store );
       
   153 
       
   154     // commit the index changes.
       
   155     iMsvEntry->ChangeL( indexEntry );
       
   156     }
       
   157     
       
   158 // ---------------------------------------------------------
       
   159 // CUniClientMtm::SaveMessageL
       
   160 // Stores the multimedia message
       
   161 // ---------------------------------------------------------
       
   162 //
       
   163 void CUniClientMtm::SaveMessageL( CMsvStore& aEditStore, TMsvEntry& aEntry ) 
       
   164     {
       
   165     // Store headers of a message
       
   166 
       
   167     // Because of attachments are handled using the new
       
   168     // attacment manager, the caller must store and commit the attachments
       
   169     // either one by one or after all have been added.
       
   170     // After saving all attachments the edit store used for that purpose
       
   171     // must be freed.
       
   172     // The store must be freed because all attachment info and uni headers
       
   173     // are saved in the actual message entry, there are no separate 
       
   174     // attachment entries anymore.
       
   175     
       
   176     // Check that sufficient disk space available
       
   177     if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( 
       
   178         &Session().FileSession(), 
       
   179         iUniHeaders->Size(),
       
   180         iMessageDrive ) )
       
   181         {
       
   182         User::Leave( KErrDiskFull );
       
   183         }
       
   184        
       
   185     // Note: Body text not supported.
       
   186     iUniHeaders->StoreL( aEditStore );
       
   187     
       
   188     // needed to convert unimessages to sms messages
       
   189     StoreBodyL( aEditStore ); 
       
   190     
       
   191     // attachment size
       
   192     TInt32 totalSizeOfAllAttachments = AttachmentsSizeL( aEditStore );
       
   193     aEntry.iSize = iUniHeaders->Size() + totalSizeOfAllAttachments;
       
   194 
       
   195     // If there are multiple recipients then set the flag
       
   196     if (( iUniHeaders->ToRecipients().Count() + //lint !e115 !e1013 !e48 !e10 !e1055 !e746 !e628
       
   197         iUniHeaders->CcRecipients().Count() +  //lint !e115 !e1013 !e48 !e10 !e1055 !e746 !e628
       
   198         iUniHeaders->BccRecipients().Count() ) >= 2 ) //lint !e115 !e1013 !e48 !e10 !e1055 !e746 !e628
       
   199         {
       
   200         aEntry.SetMultipleRecipients( ETrue );
       
   201         }
       
   202     else
       
   203         {
       
   204         // clear multiple recipients in case recipients have
       
   205         // been deleted after the message was saved the last time
       
   206         aEntry.SetMultipleRecipients( EFalse );
       
   207         }
       
   208 
       
   209     // Set iDetails (recipient)
       
   210     TPtrC to;
       
   211     if ( iUniHeaders->ToRecipients().Count() ) //lint !e115 !e1013 !e48 !e10
       
   212         {
       
   213         to.Set( TMmsGenUtils::Alias( iUniHeaders->ToRecipients()[0] ) ); //lint !e115 !e1013 !e48 !e10 !e64
       
   214         if ( to.Length() <= 0 )
       
   215             {
       
   216             // If no alias part then set the real address in details
       
   217             to.Set( iUniHeaders->ToRecipients()[0] ); //lint !e115 !e1013 !e48 !e10 !e1025 !e1703 !e64 !e118
       
   218             }
       
   219         }
       
   220     aEntry.iDetails.Set( to );
       
   221     
       
   222     if ( totalSizeOfAllAttachments > 0 )
       
   223         {
       
   224         aEntry.SetAttachment( ETrue );
       
   225         }
       
   226         
       
   227     switch ( iUniHeaders->MessageTypeLocking() )
       
   228         {
       
   229         case EUniMessageTypeLocked:
       
   230             TUniMsvEntry::SetMessageTypeLocked( aEntry, ETrue );
       
   231             break;
       
   232         case EUniMessageTypeNotLocked:
       
   233             TUniMsvEntry::SetMessageTypeLocked( aEntry, EFalse );
       
   234             break;
       
   235         case EUniMessageTypeLockingNotSet:
       
   236         default:
       
   237             // Don't touch TMsvEntry.
       
   238             break;
       
   239         }
       
   240     }
       
   241 
       
   242 // ---------------------------------------------------------
       
   243 // CUniClientMtm::LoadMessageL
       
   244 // Loads the unified message
       
   245 // ---------------------------------------------------------
       
   246 //
       
   247 void CUniClientMtm::LoadMessageL()
       
   248     {
       
   249     // First we should assert that iMsvEntry is not NULL, and panic, if it is
       
   250    	__ASSERT_DEBUG( iMsvEntry, Panic( EUniNotAMessage ) );
       
   251     // LoadMessageL should only be supported for message entries.
       
   252     __ASSERT_DEBUG( iMsvEntry->Entry().iType.iUid == KUidMsvMessageEntryValue,
       
   253         Panic( EUniNotAMessage ) );
       
   254 
       
   255     // Old data must be reset first....
       
   256     // CMmsSettings resets itself before doing restore, so that's ok.
       
   257 
       
   258     TMsvEntry indexEntry = iMsvEntry->Entry(); //lint !e1924
       
   259     
       
   260 
       
   261     // load the correct data
       
   262     // get read-only message store
       
   263     CMsvStore* store = iMsvEntry->ReadStoreL();
       
   264     CleanupStack::PushL( store );
       
   265 
       
   266     // Restore headers of unified message
       
   267     // if headers do not exist does nothing. Default headers will be used.
       
   268     iUniHeaders->RestoreL( *store );
       
   269 
       
   270     if ( iUniHeaders->MessageTypeLocking() == EUniMessageTypeLockingNotSet &&
       
   271         TUniMsvEntry::IsMessageTypeLocked( indexEntry ) )
       
   272         {
       
   273         switch ( TUniMsvEntry::CurrentMessageType( indexEntry ) )
       
   274             {
       
   275             case EUniMessageCurrentTypeSms:
       
   276                 {
       
   277                 iUniHeaders->SetMessageTypeSetting( EUniMessageTypeSettingSms );
       
   278                 iUniHeaders->SetMessageTypeLocking( EUniMessageTypeLocked );
       
   279                 break;
       
   280                 }
       
   281             case EUniMessageCurrentTypeMms:
       
   282                 {
       
   283                 iUniHeaders->SetMessageTypeSetting( EUniMessageTypeSettingMms );
       
   284                 iUniHeaders->SetMessageTypeLocking( EUniMessageTypeLocked );
       
   285                 break;
       
   286                 }
       
   287             default:
       
   288                 break;
       
   289             }
       
   290         }
       
   291 
       
   292     // Attachment info is not restored.
       
   293     // It makes no sense to cache the attachment info as new attachments
       
   294     // can be added with the help of the attachment magager without 
       
   295     // informing uni Client MTM of the additions.
       
   296     // Caller must use attachment manager to get attachment info.
       
   297     
       
   298     CleanupStack::PopAndDestroy( store );  
       
   299     store = NULL;
       
   300 
       
   301     // Build the iAddresseeList up
       
   302     BuildAddresseeListL();
       
   303     }
       
   304 
       
   305 // ---------------------------------------------------------
       
   306 // CUniClientMtm::ReplyL
       
   307 // Send a reply to current message
       
   308 // ---------------------------------------------------------
       
   309 //
       
   310 CMsvOperation* CUniClientMtm::ReplyL(
       
   311     TMsvId /*aDestination*/,
       
   312     TMsvPartList /*aPartList*/,
       
   313     TRequestStatus& /*aCompletionStatus*/ )
       
   314     {
       
   315     User::Leave( KErrNotSupported );
       
   316     return NULL;
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------
       
   320 // CUniClientMtm::ForwardL
       
   321 // Forward current message
       
   322 // ---------------------------------------------------------
       
   323 //
       
   324 CMsvOperation* CUniClientMtm::ForwardL(
       
   325     TMsvId /*aDestination*/,
       
   326     TMsvPartList /*aPartList*/,
       
   327     TRequestStatus& /*aCompletionStatus*/ )
       
   328     {
       
   329     User::Leave( KErrNotSupported );
       
   330     return NULL;
       
   331     }
       
   332 
       
   333 // ---------------------------------------------------------
       
   334 // CUniClientMtm::ValidateMessage
       
   335 // Validate selected parts of current message
       
   336 // ---------------------------------------------------------
       
   337 //
       
   338 TMsvPartList CUniClientMtm::ValidateMessage(
       
   339     TMsvPartList aPartList )
       
   340     {
       
   341     __ASSERT_DEBUG( iMsvEntry, Panic( EUniNotAMessage ));
       
   342     
       
   343     TMsvPartList retVal = 0;
       
   344     if ( iMsvEntry->Entry().iType.iUid != KUidMsvMessageEntryValue )
       
   345         {
       
   346         // not a message, no part is valid
       
   347         retVal = aPartList;
       
   348         }
       
   349 
       
   350     if ( aPartList & KMsvMessagePartRecipient )
       
   351         {
       
   352         if ( iAddresseeList->Count() == 0)
       
   353             {
       
   354             retVal |= KMsvMessagePartRecipient;
       
   355             }
       
   356         else
       
   357             {
       
   358             // check the recipient list for valid 'addresses'
       
   359             for (TInt ii=0; ii < iAddresseeList->Count(); ++ii)
       
   360                 {
       
   361                 TPtrC oneAddress = (*iAddresseeList)[ii];
       
   362                 TPtrC pureAddress = TMmsGenUtils::PureAddress( oneAddress );
       
   363                 if ( ( pureAddress.Length() == 0 ) || 
       
   364                     !TMmsGenUtils::IsValidAddress( pureAddress, ETrue ) )
       
   365                     {
       
   366                     retVal |= KMsvMessagePartRecipient;
       
   367                     break;
       
   368                     }
       
   369                 }
       
   370             }
       
   371         }
       
   372 
       
   373     // all attachments are considered valid - even no attachments
       
   374 
       
   375     return retVal;
       
   376 
       
   377     }
       
   378 
       
   379 // ---------------------------------------------------------
       
   380 // CUniClientMtm::Find
       
   381 // Find text in selected message parts
       
   382 // ---------------------------------------------------------
       
   383 //
       
   384 TMsvPartList CUniClientMtm::Find(
       
   385     const TDesC& aTextToFind,
       
   386     TMsvPartList aPartList )
       
   387 	{
       
   388 	TMsvPartList foundList( KMsvMessagePartNone );
       
   389 	TRAP_IGNORE( foundList = DoFindL( aTextToFind, aPartList) );
       
   390 	return foundList;
       
   391 	}
       
   392 
       
   393 // ---------------------------------------------------------
       
   394 // CUniClientMtm::DoFindL
       
   395 // Find text in selected message parts
       
   396 // ---------------------------------------------------------
       
   397 //
       
   398 TMsvPartList CUniClientMtm::DoFindL(
       
   399     const TDesC& aTextToFind,
       
   400     TMsvPartList aPartList )
       
   401     {
       
   402     // The final version will not have a rich text body, but we could
       
   403     // search for example the originator and description.
       
   404 
       
   405     __ASSERT_DEBUG( iMsvEntry, Panic( EUniNotAMessage ) );
       
   406     TMsvPartList foundList = KMsvMessagePartNone;
       
   407     TMsvEntry entry = iMsvEntry->Entry();
       
   408 
       
   409     CMsvFindText* findText = CMsvFindText::NewL();
       
   410     CleanupStack::PushL( findText );
       
   411 
       
   412     if ( aPartList & KMsvMessagePartRecipient )
       
   413         {
       
   414         // Find from To, Cc and Bcc fields
       
   415         if ( FindInRecipientL( aTextToFind, 
       
   416             aPartList, iUniHeaders->ToRecipients(), *findText))
       
   417             {
       
   418             foundList |= KMsvMessagePartRecipient;
       
   419             }
       
   420         else if ( FindInRecipientL( aTextToFind, 
       
   421             aPartList, iUniHeaders->CcRecipients(), *findText ))
       
   422             {
       
   423             foundList |= KMsvMessagePartRecipient;
       
   424             }
       
   425         else if ( FindInRecipientL( aTextToFind, 
       
   426             aPartList, iUniHeaders->BccRecipients(), *findText ))
       
   427             {
       
   428             foundList |= KMsvMessagePartRecipient;
       
   429             }
       
   430         }
       
   431     
       
   432     if ( aPartList & KMsvMessagePartDescription )
       
   433         {
       
   434         if ( findText->FindTextL( aTextToFind, entry.iDescription, 
       
   435             aPartList ) )
       
   436             {
       
   437             foundList |= KMsvMessagePartDescription;
       
   438             }
       
   439         }
       
   440 
       
   441     CleanupStack::PopAndDestroy( findText );
       
   442     return foundList;
       
   443     }
       
   444 
       
   445 // ---------------------------------------------------------
       
   446 // CUniClientMtm::AddAddresseeL
       
   447 // ---------------------------------------------------------
       
   448 //
       
   449 void CUniClientMtm::AddAddresseeL( const TDesC& aRealAddress )
       
   450     {
       
   451     // Add to general list
       
   452     // When no type is specified, the address will have type "to"
       
   453     iAddresseeList->AppendL( EMsvRecipientTo, aRealAddress );
       
   454     
       
   455     // Add to "To" recipient list
       
   456     iUniHeaders->AddTypedAddresseeL( aRealAddress, EMsvRecipientTo ); //lint !e115 !e1013 !e48 !e10 !e1514 !e64
       
   457     }
       
   458 
       
   459 // ---------------------------------------------------------
       
   460 // CUniClientMtm::AddAddresseeL
       
   461 // ---------------------------------------------------------
       
   462 //
       
   463 void CUniClientMtm::AddAddresseeL(
       
   464     const TDesC& aRealAddress,
       
   465     const TDesC& aAlias )
       
   466     {
       
   467 
       
   468     if ( aAlias.Length() > 0 )
       
   469         {
       
   470         HBufC* buf = TMmsGenUtils::GenerateAddressL( aRealAddress, aAlias );
       
   471         CleanupStack::PushL( buf );
       
   472         AddAddresseeL( buf->Des() );
       
   473         CleanupStack::PopAndDestroy( buf );  
       
   474         }
       
   475     else
       
   476         {        
       
   477         AddAddresseeL( aRealAddress );
       
   478         }
       
   479     }
       
   480     
       
   481 // ---------------------------------------------------------
       
   482 // CUniClientMtm::AddAddresseeL
       
   483 // ---------------------------------------------------------
       
   484 //
       
   485 void CUniClientMtm::AddAddresseeL( TMsvRecipientType aType,
       
   486     const TDesC& aRealAddress )
       
   487     {
       
   488     // Add to general list
       
   489     // When no type is specified, the address will have type "to",
       
   490     // "cc" or "bcc"
       
   491     iAddresseeList->AppendL( aType, aRealAddress );
       
   492     
       
   493     // Add to recipient list
       
   494     iUniHeaders->AddTypedAddresseeL( aRealAddress, aType );
       
   495 
       
   496     }
       
   497 
       
   498 // ---------------------------------------------------------
       
   499 // CUniClientMtm::AddAddresseeL
       
   500 // ---------------------------------------------------------
       
   501 //
       
   502 void CUniClientMtm::AddAddresseeL(
       
   503     TMsvRecipientType aType,
       
   504     const TDesC& aRealAddress,
       
   505     const TDesC& aAlias )
       
   506     {
       
   507 
       
   508     if ( aAlias.Length() > 0 )
       
   509         {
       
   510         HBufC* buf = TMmsGenUtils::GenerateAddressL( aRealAddress, aAlias );
       
   511         CleanupStack::PushL( buf );
       
   512         AddAddresseeL(aType, buf->Des());
       
   513         CleanupStack::PopAndDestroy( buf ); 
       
   514         }
       
   515     else
       
   516         {        
       
   517         AddAddresseeL( aType, aRealAddress );
       
   518         }
       
   519     }
       
   520 
       
   521 // ---------------------------------------------------------
       
   522 // CUniClientMtm::RemoveAddressee
       
   523 // ---------------------------------------------------------
       
   524 //
       
   525 void CUniClientMtm::RemoveAddressee( TInt aIndex )
       
   526     {
       
   527 
       
   528 	if ( aIndex < 0 )
       
   529 		{
       
   530 		return;	
       
   531 		}
       
   532     if ( iAddresseeList->Count() > aIndex )
       
   533         {
       
   534         // Delete from typed list
       
   535         TPtrC address = (*iAddresseeList)[ aIndex ];
       
   536         iUniHeaders->RemoveAddressee( address );
       
   537         // delete from untyped list
       
   538         iAddresseeList->Delete( aIndex );
       
   539         }
       
   540         
       
   541     }
       
   542 
       
   543 // ---------------------------------------------------------
       
   544 // CUniClientMtm::SetSubjectL
       
   545 // ---------------------------------------------------------
       
   546 //
       
   547 void CUniClientMtm::SetSubjectL( const TDesC& aSubject )
       
   548     {
       
   549     iUniHeaders->SetSubjectL( aSubject ); //lint !e115 !e1013 !e48 !e10 !e1514 !e64
       
   550     }
       
   551 
       
   552 // ---------------------------------------------------------
       
   553 // CUniClientMtm::SubjectL
       
   554 // ---------------------------------------------------------
       
   555 //
       
   556 const TPtrC CUniClientMtm::SubjectL() const
       
   557     {
       
   558     return iUniHeaders->Subject(); //lint !e115 !e1013 !e48 !e10 !e746 !e64 !e1055 !e628
       
   559     }
       
   560 
       
   561 // ---------------------------------------------------------
       
   562 // CUniClientMtm::AddAttachmentL
       
   563 // ---------------------------------------------------------
       
   564 //
       
   565 void CUniClientMtm::AddAttachmentL( const TDesC& aFilePath,
       
   566     const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus )
       
   567     {
       
   568     
       
   569     TInt error = KErrNone;
       
   570     TUint charset = aCharset;
       
   571     RFile file;
       
   572     if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && charset == 0 )
       
   573         {
       
   574         // try to recognize character set
       
   575         // We trap the recognization process
       
   576         // If cannot recognize, the result will be 0 and default to us-ascii
       
   577         TRAP ( error,
       
   578             {
       
   579             error = file.Open( Session().FileSession(), aFilePath,
       
   580                 EFileRead|EFileShareReadersOnly );
       
   581             if ( error == KErrNone )
       
   582                 {
       
   583                 CleanupClosePushL( file );
       
   584                 charset = RecognizeCharSetL( file );
       
   585                 CleanupStack::PopAndDestroy( &file ); 
       
   586                 }
       
   587             }
       
   588             );
       
   589         }
       
   590         
       
   591     // if the attachment character set is unicode, it should be converted to utf-8
       
   592     // (see MMS conformance document)
       
   593     
       
   594     if ( aMimeType.CompareF( KMmsTextPlain ) == 0 &&
       
   595         ( charset == KCharacterSetMIBEnumIso10646Ucs2  ||
       
   596         charset == KCharacterSetMIBEnumUTF16 ||
       
   597         charset == KCharacterSetMIBEnumUTF16BE ||
       
   598         charset == KCharacterSetMIBEnumUTF16LE ) )
       
   599         {
       
   600         // If we have unicode character set, we must convert the file to utf8
       
   601         error = file.Open( Session().FileSession(), aFilePath,
       
   602             EFileRead|EFileShareReadersOnly );
       
   603         if ( error == KErrNone )
       
   604             {
       
   605             CleanupClosePushL( file );
       
   606               CMsvStore* store = iMsvEntry->EditStoreL();
       
   607             CleanupStack::PushL( store );
       
   608             TMsvAttachmentId attaId = 0;
       
   609             CMmsAttachmentHandler::CreateUTF8TextAttachmentFromFileL(
       
   610                 *store, attaId, file, Session().FileSession(),
       
   611                 Session().CurrentDriveL() );
       
   612                 
       
   613             SetContentLocationForConvertedAttL( *store, attaId, aFilePath ); 
       
   614                 
       
   615             store->CommitL();
       
   616             CleanupStack::PopAndDestroy( store );
       
   617             CleanupStack::PopAndDestroy( &file );  
       
   618             }
       
   619         TRequestStatus* status = &aStatus;
       
   620         aStatus = KRequestPending;
       
   621         User::RequestComplete( status, error );
       
   622         return;    
       
   623         }
       
   624     else
       
   625         {
       
   626         // Disk space is checked in AddFilePathAttachmentL after everything has been initialized
       
   627         AddFilePathAttachmentL( aFilePath, aMimeType, CMsvAttachment::EMsvFile, aStatus, charset );
       
   628         }
       
   629     }
       
   630     
       
   631 // ---------------------------------------------------------
       
   632 // CUniClientMtm::AddAttachmentL
       
   633 // ---------------------------------------------------------
       
   634 //
       
   635 void CUniClientMtm::AddAttachmentL( RFile& aFile, const TDesC8& aMimeType,
       
   636     TUint aCharset, TRequestStatus& aStatus )
       
   637     {
       
   638     TInt size = 0;
       
   639     User::LeaveIfError( aFile.Size( size ) );
       
   640 
       
   641     TFileName fileName;
       
   642     User::LeaveIfError( aFile.Name( fileName ) );
       
   643 
       
   644     TInt charset = aCharset;
       
   645     if ( aMimeType.CompareF( KMmsTextPlain ) == 0  && charset == 0 )
       
   646         {
       
   647         // If no character set defined for a plain text attachment
       
   648         // we try to recognize the character set.
       
   649         // But if recogization fails, we say 0 (us-ascii)
       
   650         TRAP_IGNORE ( charset = RecognizeCharSetL( aFile ) );
       
   651         }
       
   652 
       
   653     if ( aMimeType.CompareF( KMmsTextPlain ) == 0 )
       
   654         {
       
   655         // If we have unicode character set, we must convert the file to utf8
       
   656         if ( charset == KCharacterSetMIBEnumIso10646Ucs2  ||
       
   657             charset == KCharacterSetMIBEnumUTF16 ||
       
   658             charset == KCharacterSetMIBEnumUTF16BE ||
       
   659             charset == KCharacterSetMIBEnumUTF16LE ) 
       
   660             {
       
   661             CMsvStore* store = iMsvEntry->EditStoreL();
       
   662             CleanupStack::PushL( store );
       
   663             TMsvAttachmentId attaId = 0;
       
   664             CMmsAttachmentHandler::CreateUTF8TextAttachmentFromFileL( *store,
       
   665                 attaId, aFile, Session().FileSession(),
       
   666                 Session().CurrentDriveL() );
       
   667               
       
   668             SetContentLocationForConvertedAttL( *store, attaId, fileName );    
       
   669 
       
   670             store->CommitL();
       
   671             CleanupStack::PopAndDestroy( store ); // store
       
   672             // We must close the file handle because the attachment manager will also
       
   673             // close the handle.
       
   674             // The open file handle is always closed unless the funtion leaves
       
   675             aFile.Close();
       
   676             TRequestStatus* status = &aStatus;
       
   677             aStatus = KRequestPending;
       
   678             User::RequestComplete( status, KErrNone );
       
   679             return;
       
   680             }
       
   681         }
       
   682     
       
   683     if( !iAttaWaiter )
       
   684         {
       
   685         iAttaWaiter = CMmsAttachmentWaiter::NewL();
       
   686         }
       
   687 
       
   688     // store must be the first item allocated because it is the last one to be popped
       
   689     CMsvStore* store = iMsvEntry->EditStoreL();
       
   690     CleanupStack::PushL( store );
       
   691     MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
   692     
       
   693     CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
   694     CleanupStack::PushL( attachment );
       
   695 
       
   696     size += InitializeAttachmentL(
       
   697         manager,
       
   698         *attachment,
       
   699         fileName,
       
   700         aMimeType,
       
   701         size,
       
   702         charset );
       
   703     
       
   704     // Check that sufficient disk space available
       
   705     if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( 
       
   706         &Session().FileSession(), 
       
   707         size,
       
   708         iMessageDrive ) )
       
   709             {
       
   710             User::Leave( KErrDiskFull );
       
   711             }
       
   712 
       
   713     // attachment is initialised, pass to the attachment manager
       
   714     if ( iAttaWaiter->IsActive() )
       
   715         {
       
   716         // can't start an active operation because already active
       
   717         User::Leave( KErrInUse );
       
   718         }
       
   719     manager.AddAttachmentL( aFile, attachment, iAttaWaiter->iStatus ); 
       
   720     CleanupStack::Pop( attachment ); //ownership passed to manager
       
   721     // We cannot start waiting before we know that the function we are waiting for
       
   722     // did not leave. If we become active, and the function leaves, we are in trouble    
       
   723     iAttaWaiter->StartWaitingL( aStatus, store, &manager );
       
   724     CleanupStack::Pop( store ); //ownership passed
       
   725     }
       
   726 // ---------------------------------------------------------
       
   727 // CUniClientMtm::AddLinkedAttachmentL
       
   728 // ---------------------------------------------------------
       
   729 //
       
   730 void CUniClientMtm::AddLinkedAttachmentL( const TDesC& aFilePath,
       
   731     const TDesC8& aMimeType, TUint aCharset, TRequestStatus& aStatus )
       
   732     {
       
   733     TInt error = KErrNone;
       
   734     TUint charset = aCharset;
       
   735     if ( aMimeType.CompareF( KMmsTextPlain ) == 0 && aCharset == 0)
       
   736         {
       
   737         // try to recognize character set
       
   738         // We trap the recognization process
       
   739         // If cannot recognize, the result will be 0 and default to us-ascii
       
   740         TRAP ( error,
       
   741             {
       
   742             RFile file;
       
   743             error = file.Open( Session().FileSession(), aFilePath,
       
   744                 EFileRead|EFileShareReadersOnly);
       
   745             if ( error == KErrNone )
       
   746                 {
       
   747                 CleanupClosePushL( file );
       
   748                 charset = RecognizeCharSetL( file );
       
   749                 CleanupStack::PopAndDestroy( &file );  
       
   750                 }
       
   751             }
       
   752             );
       
   753         }
       
   754     // Linked files cannot be converted to utf8. They must be sent as is no
       
   755     // matter what the character set is.
       
   756     
       
   757     // Disk space is checked in AddFilePathAttachmentL after everything has
       
   758     // been initialized.
       
   759     if ( aMimeType.CompareF( KMmsTextPlain ) == 0 &&
       
   760         ( charset == KCharacterSetMIBEnumIso10646Ucs2  ||
       
   761         charset == KCharacterSetMIBEnumUTF16 ||
       
   762         charset == KCharacterSetMIBEnumUTF16BE ||
       
   763         charset == KCharacterSetMIBEnumUTF16LE ) )
       
   764         {
       
   765         AddAttachmentL( aFilePath, aMimeType, charset, aStatus );
       
   766         }
       
   767     else
       
   768         {
       
   769         AddFilePathAttachmentL( aFilePath, aMimeType,
       
   770             CMsvAttachment::EMsvLinkedFile, aStatus, charset );
       
   771         }
       
   772     }
       
   773 
       
   774 // ---------------------------------------------------------
       
   775 // CUniClientMtm::AddEntryAsAttachmentL
       
   776 // ---------------------------------------------------------
       
   777 //
       
   778 void CUniClientMtm::AddEntryAsAttachmentL( TMsvId /*aAttachmentId*/,
       
   779     TRequestStatus& aStatus )
       
   780     {
       
   781     TRequestStatus* status = &aStatus;
       
   782     User::RequestComplete( status, KErrNotSupported );
       
   783     } 
       
   784 
       
   785 // ---------------------------------------------------------
       
   786 // CUniClientMtm::CreateAttachmentL
       
   787 // ---------------------------------------------------------
       
   788 //
       
   789 void CUniClientMtm::CreateAttachmentL( const TDesC& aFileName,
       
   790     RFile& aAttachmentFile, const TDesC8& aMimeType,
       
   791     TUint aCharset, TRequestStatus& aStatus )
       
   792     {
       
   793     if( !iAttaWaiter )
       
   794         {
       
   795         iAttaWaiter = CMmsAttachmentWaiter::NewL();
       
   796         }
       
   797 
       
   798     // store must be the first item allocated because it is the last one to be popped
       
   799     CMsvStore* store = iMsvEntry->EditStoreL();
       
   800     CleanupStack::PushL( store );
       
   801     MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
   802     
       
   803     CMsvAttachment* attachment = 
       
   804         CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
   805     CleanupStack::PushL( attachment );
       
   806     
       
   807     TInt size = InitializeAttachmentL(
       
   808         manager,
       
   809         *attachment,
       
   810         aFileName,
       
   811         aMimeType,
       
   812         0, // Creating empty attachment!
       
   813         aCharset );
       
   814 
       
   815     // Check that sufficient disk space available
       
   816     if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( 
       
   817         &Session().FileSession(), 
       
   818         size,
       
   819         iMessageDrive ) )
       
   820             {
       
   821             User::Leave( KErrDiskFull );
       
   822             }
       
   823 
       
   824     if ( iAttaWaiter->IsActive() )
       
   825         {
       
   826         // can't start an active operation because already active
       
   827         User::Leave( KErrInUse );
       
   828         }
       
   829     manager.CreateAttachmentL( aFileName, aAttachmentFile, attachment,
       
   830         iAttaWaiter->iStatus );
       
   831     CleanupStack::Pop( attachment ); //ownership passed to manager
       
   832     iAttaWaiter->StartWaitingL( aStatus, store, &manager );
       
   833     CleanupStack::Pop( store ); //ownership passed
       
   834     }
       
   835 // ---------------------------------------------------------
       
   836 // CUniClientMtm::CancelAttachmentOperation
       
   837 // ---------------------------------------------------------
       
   838 //
       
   839 void CUniClientMtm::CancelAttachmentOperation()
       
   840     {
       
   841     
       
   842     if ( iAttaWaiter )
       
   843         {
       
   844         iAttaWaiter->Cancel();
       
   845         delete iAttaWaiter;
       
   846         iAttaWaiter = NULL;
       
   847         }
       
   848     }
       
   849 
       
   850     
       
   851 // ---------------------------------------------------------
       
   852 // CUniClientMtm::CreateTextAttachmentL
       
   853 // ---------------------------------------------------------
       
   854 //
       
   855 void CUniClientMtm::CreateTextAttachmentL(
       
   856             CMsvStore& aStore,
       
   857             TMsvAttachmentId& aAttachmentId,
       
   858             const TDesC& aText,
       
   859             const TDesC& aFile,
       
   860             TBool aConvertParagraphSeparator )
       
   861     {
       
   862 
       
   863     CMmsAttachmentHandler::CreateTextAttachmentL( aStore,
       
   864         aAttachmentId,
       
   865         aText,
       
   866         aFile,
       
   867         Session().FileSession(),
       
   868         Session().CurrentDriveL(),
       
   869         aConvertParagraphSeparator );
       
   870  
       
   871     }
       
   872 
       
   873 // ---------------------------------------------------------
       
   874 // CUniClientMtm::MessageTypeSetting
       
   875 // ---------------------------------------------------------
       
   876 //
       
   877 TUniMessageTypeSetting CUniClientMtm::MessageTypeSetting() const
       
   878     {
       
   879     return TUniMessageTypeSetting( iUniHeaders->MessageTypeSetting() );
       
   880     }
       
   881 
       
   882 // ---------------------------------------------------------
       
   883 // CUniClientMtm::SetMessageTypeSetting
       
   884 // ---------------------------------------------------------
       
   885 //
       
   886 void CUniClientMtm::SetMessageTypeSetting( TUniMessageTypeSetting aSetting )
       
   887     {
       
   888     iUniHeaders->SetMessageTypeSetting( aSetting );
       
   889     }
       
   890 
       
   891 // ---------------------------------------------------------
       
   892 // CUniClientMtm::MessageTypeLocking
       
   893 // ---------------------------------------------------------
       
   894 //
       
   895 TUniMessageTypeLocking CUniClientMtm::MessageTypeLocking() const
       
   896     {
       
   897     return TUniMessageTypeLocking( iUniHeaders->MessageTypeLocking() );
       
   898     }
       
   899 
       
   900 // ---------------------------------------------------------
       
   901 // CUniClientMtm::SetMessageTypeLocking
       
   902 // ---------------------------------------------------------
       
   903 //
       
   904 void CUniClientMtm::SetMessageTypeLocking( TUniMessageTypeLocking aLocking )
       
   905     {
       
   906     iUniHeaders->SetMessageTypeLocking( aLocking );
       
   907     }
       
   908 
       
   909 // ---------------------------------------------------------
       
   910 // CUniClientMtm::MessageRoot
       
   911 // ---------------------------------------------------------
       
   912 //
       
   913 TMsvAttachmentId CUniClientMtm::MessageRoot() const
       
   914     {
       
   915     return iUniHeaders->MessageRoot();
       
   916     }
       
   917 
       
   918 // ---------------------------------------------------------
       
   919 // CUniClientMtm::SetMessageRoot
       
   920 // ---------------------------------------------------------
       
   921 //
       
   922 void CUniClientMtm::SetMessageRoot( TMsvAttachmentId aRoot )
       
   923     {
       
   924     iUniHeaders->SetMessageRoot( aRoot );
       
   925     }
       
   926 
       
   927 // ---------------------------------------------------------
       
   928 // CUniClientMtm::CreateMessageL
       
   929 // ---------------------------------------------------------
       
   930 //
       
   931 void CUniClientMtm::CreateMessageL(
       
   932     TMsvId aServiceId )
       
   933     {
       
   934     // Check that sufficient disk space available
       
   935     // for index entry
       
   936     if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( 
       
   937         &Session().FileSession(), 
       
   938         KMmsIndexEntryExtra,
       
   939         iMessageDrive ) )
       
   940             {
       
   941             // we use standard error code here
       
   942             User::Leave( KErrDiskFull );
       
   943             }
       
   944 
       
   945     // just call the base class function
       
   946     CBaseMtm::CreateMessageL( aServiceId );
       
   947     
       
   948     iUniHeaders->Reset();
       
   949     }
       
   950     
       
   951 // ---------------------------------------------------------
       
   952 // CUniClientMtm::BioTypeChangedL
       
   953 // ---------------------------------------------------------
       
   954 //
       
   955 void CUniClientMtm::BioTypeChangedL( TUid /*aBioTypeUid*/ )
       
   956     {
       
   957     // Do nothing.
       
   958     }
       
   959     
       
   960 // ---------------------------------------------------------
       
   961 // CUniClientMtm::DefaultServiceL
       
   962 // ---------------------------------------------------------
       
   963 //
       
   964 TMsvId CUniClientMtm::DefaultServiceL() const
       
   965     {
       
   966     return KMsvLocalServiceIndexEntryId;
       
   967     }
       
   968 
       
   969 // ---------------------------------------------------------
       
   970 // CUniClientMtm::RemoveDefaultServiceL
       
   971 // ---------------------------------------------------------
       
   972 //
       
   973 void CUniClientMtm::RemoveDefaultServiceL()
       
   974     {
       
   975     // not supported
       
   976     }
       
   977 
       
   978 // ---------------------------------------------------------
       
   979 // CUniClientMtm::ChangeDefaultServiceL
       
   980 // ---------------------------------------------------------
       
   981 //
       
   982 void CUniClientMtm::ChangeDefaultServiceL( const TMsvId& /*aService*/ )
       
   983     {
       
   984     // not supported
       
   985     }
       
   986 
       
   987 // ---------------------------------------------------------
       
   988 // CUniClientMtm::QueryCapability
       
   989 // ---------------------------------------------------------
       
   990 //
       
   991 TInt CUniClientMtm::QueryCapability(
       
   992     TUid aCapability,
       
   993     TInt& aResponse )
       
   994     {
       
   995     TInt error = KErrNone;
       
   996     switch ( aCapability.iUid )
       
   997         {
       
   998         // Supported:
       
   999         case KUidMtmQueryMaxTotalMsgSizeValue:
       
  1000             aResponse = KMaxTInt;
       
  1001             break;
       
  1002         case KUidMsvMtmQueryEditorUidValue:
       
  1003             aResponse = KUidMsgMmsEditor;
       
  1004             break;
       
  1005         case KUidMtmQuerySupportSubjectValue:
       
  1006         case KUidMtmQuerySupportAttachmentsValue:
       
  1007         case KUidMtmQueryCanSendMsgValue:
       
  1008         case KUidMtmQuerySendAsMessageSendSupportValue:
       
  1009         case KUidMtmQuerySupportsRecipientTypeValue:
       
  1010             // returns KErrNone
       
  1011             break;
       
  1012         // All others - Not Supported:
       
  1013         default:
       
  1014             error = KErrNotSupported;
       
  1015         }
       
  1016     return error;
       
  1017 
       
  1018     } //lint !e1746
       
  1019 
       
  1020 // ---------------------------------------------------------
       
  1021 // CUniClientMtm::InvokeSyncFunctionL
       
  1022 // ---------------------------------------------------------
       
  1023 //
       
  1024 void CUniClientMtm::InvokeSyncFunctionL(
       
  1025     TInt /*aFunctionId*/,
       
  1026     const CMsvEntrySelection& /*aSelection*/,
       
  1027     TDes8& /*aParameter*/ )
       
  1028     {
       
  1029     User::Leave( KErrNotSupported );
       
  1030     }
       
  1031 
       
  1032 // ---------------------------------------------------------
       
  1033 // CUniClientMtm::InvokeAsyncFunctionL
       
  1034 // ---------------------------------------------------------
       
  1035 //
       
  1036 CMsvOperation* CUniClientMtm::InvokeAsyncFunctionL(
       
  1037     TInt /* aFunctionId */,
       
  1038     const CMsvEntrySelection& /* aSelection*/,
       
  1039     TDes8& /* aParameter*/,
       
  1040     TRequestStatus& aCompletionStatus )
       
  1041     {
       
  1042     TPckgC < TMsvId > progress = 0;
       
  1043     return  CMsvCompletedOperation::NewL( Session(), Type(), progress, 
       
  1044             KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNotSupported );
       
  1045     }
       
  1046 
       
  1047 // ---------------------------------------------------------
       
  1048 // CUniClientMtm::ContextEntrySwitched
       
  1049 // ---------------------------------------------------------
       
  1050 //
       
  1051 void CUniClientMtm::ContextEntrySwitched()
       
  1052     {
       
  1053     // Context change notification.
       
  1054     // Reset data.
       
  1055 
       
  1056     // Note: Body text reset would be here if supported.
       
  1057     iAddresseeList->Reset();
       
  1058     iUniHeaders->Reset();
       
  1059     }
       
  1060 
       
  1061 // ---------------------------------------------------------
       
  1062 // CUniClientMtm::HandleEntryEventL
       
  1063 // ---------------------------------------------------------
       
  1064 //
       
  1065 void CUniClientMtm::HandleEntryEventL(
       
  1066     TMsvEntryEvent /*aEvent*/,
       
  1067     TAny* /*arg1*/,
       
  1068     TAny* /*arg2*/,
       
  1069     TAny* /*arg3*/ )
       
  1070     {
       
  1071     // No operation
       
  1072     }
       
  1073 
       
  1074 // ---------------------------------------------------------
       
  1075 // CUniClientMtm::ConstructL
       
  1076 // ---------------------------------------------------------
       
  1077 //
       
  1078 void CUniClientMtm::ConstructL()
       
  1079     {
       
  1080     iMessageDrive = EDriveC;
       
  1081     TInt error = KErrNone;
       
  1082 
       
  1083     TRAP ( error, { iMessageDrive = Session().CurrentDriveL(); } );
       
  1084     
       
  1085     if ( error != KErrNone )
       
  1086         {
       
  1087         // if cannot ask, use default
       
  1088         iMessageDrive = EDriveC;
       
  1089         }
       
  1090 
       
  1091     iUniHeaders = CUniHeaders::NewL();
       
  1092     }
       
  1093 
       
  1094 // ---------------------------------------------------------
       
  1095 // CUniClientMtm::MessageSize
       
  1096 // ---------------------------------------------------------
       
  1097 //
       
  1098 TInt32 CUniClientMtm::MessageSize()
       
  1099     {
       
  1100     // First we should assert that iMsvEntry is not NULL, and panic, if it is
       
  1101     __ASSERT_DEBUG( iMsvEntry, Panic( EUniNotAMessage ));
       
  1102     TUint size = 0;
       
  1103     TRAPD( error, {size = AttachmentsSizeL() + iUniHeaders->Size();} );
       
  1104     if ( error != KErrNone ) // this is needed to get rid of compiler warning
       
  1105         {
       
  1106         size = 0;
       
  1107         }
       
  1108     return size;  //lint !e713 nothing lost here
       
  1109     }
       
  1110 
       
  1111 // ---------------------------------------------------------
       
  1112 // CUniClientMtm::SetMessageDescriptionL
       
  1113 // ---------------------------------------------------------
       
  1114 //
       
  1115 void CUniClientMtm::SetMessageDescriptionL( const TDesC& aText )
       
  1116     {
       
  1117     // First we should assert that iMsvEntry is not NULL, and panic, if it is
       
  1118     __ASSERT_DEBUG( iMsvEntry, Panic( EUniNotAMessage ) );
       
  1119     TMsvEntry entry = iMsvEntry->Entry();
       
  1120     entry.iDescription.Set( aText );
       
  1121     iMsvEntry->ChangeL( entry );
       
  1122     }
       
  1123     
       
  1124 // ---------------------------------------------------------
       
  1125 // CUniClientMtm::BuildAddresseeListL
       
  1126 // ---------------------------------------------------------
       
  1127 //
       
  1128 void CUniClientMtm::BuildAddresseeListL() 
       
  1129     {
       
  1130 
       
  1131     iAddresseeList->Reset();
       
  1132 
       
  1133     const CDesCArray& array1 = iUniHeaders->ToRecipients(); //lint !e115 !e1013 !e48 !e10 !e64 
       
  1134     const CDesCArray& array2 = iUniHeaders->CcRecipients(); //lint !e115 !e1013 !e48 !e10 !e64
       
  1135     const CDesCArray& array3 = iUniHeaders->BccRecipients(); //lint !e115 !e1013 !e48 !e10 !e64
       
  1136 
       
  1137     BuildAddresseeListL( array1, EMsvRecipientTo );
       
  1138     BuildAddresseeListL( array2, EMsvRecipientCc );
       
  1139     BuildAddresseeListL( array3, EMsvRecipientBcc );
       
  1140 
       
  1141     }
       
  1142 
       
  1143 // ---------------------------------------------------------
       
  1144 // CUniClientMtm::BuildAddresseeListL
       
  1145 // ---------------------------------------------------------
       
  1146 //
       
  1147 void CUniClientMtm::BuildAddresseeListL(
       
  1148     const CDesCArray& aArray, TMsvRecipientType aValue ) 
       
  1149     {
       
  1150 
       
  1151     TInt size;
       
  1152     size = aArray.Count();
       
  1153     for ( TInt i=0; i < size; i++ )
       
  1154         {
       
  1155         iAddresseeList->AppendL( aValue, aArray[i] );
       
  1156         }
       
  1157     }
       
  1158 
       
  1159 // ---------------------------------------------------------
       
  1160 // CUniClientMtm::AttachmentsSizeL
       
  1161 // ---------------------------------------------------------
       
  1162 //
       
  1163 TInt32 CUniClientMtm::AttachmentsSizeL()
       
  1164     {
       
  1165     CMsvStore* store = iMsvEntry->ReadStoreL();
       
  1166     CleanupStack::PushL( store );
       
  1167     TInt32 attaSize = AttachmentsSizeL( *store );
       
  1168     CleanupStack::PopAndDestroy( store );
       
  1169     return attaSize;
       
  1170     }
       
  1171 
       
  1172 // ---------------------------------------------------------
       
  1173 // CUniClientMtm::AttachmentsSizeL
       
  1174 // ---------------------------------------------------------
       
  1175 //
       
  1176 TInt32 CUniClientMtm::AttachmentsSizeL( CMsvStore& aStore )
       
  1177     {
       
  1178     TInt32 size = 0;
       
  1179 
       
  1180     MMsvAttachmentManager& attachMan = aStore.AttachmentManagerL();
       
  1181     TInt numAttachments = attachMan.AttachmentCount();
       
  1182 
       
  1183     for ( TInt i = 0; i < numAttachments; i++ )
       
  1184         {
       
  1185         CMsvAttachment* attachmentInfo = attachMan.GetAttachmentInfoL( i );
       
  1186         CleanupStack::PushL( attachmentInfo );
       
  1187         
       
  1188         CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
       
  1189         CleanupStack::PushL( mimeHeaders );
       
  1190         
       
  1191         mimeHeaders->RestoreL( *attachmentInfo );
       
  1192         
       
  1193         RFile attaFile = attachMan.GetAttachmentFileL( i );
       
  1194         CleanupClosePushL( attaFile );
       
  1195         TInt fileSize = 0;
       
  1196         
       
  1197         // If we cannot access the file, we are in trouble
       
  1198         User::LeaveIfError( attaFile.Size( fileSize ) ); 
       
  1199         
       
  1200         // This adds up mime header size + actual attachment binary data
       
  1201         size += mimeHeaders->Size() + fileSize;
       
  1202 
       
  1203         CleanupStack::PopAndDestroy( &attaFile );
       
  1204         CleanupStack::PopAndDestroy( mimeHeaders );
       
  1205         CleanupStack::PopAndDestroy( attachmentInfo );
       
  1206         }
       
  1207 
       
  1208     return size;
       
  1209     }
       
  1210 
       
  1211 // ---------------------------------------------------------
       
  1212 // CUniClientMtm::FindInRecipientL
       
  1213 // ---------------------------------------------------------
       
  1214 //
       
  1215 TBool CUniClientMtm::FindInRecipientL( 
       
  1216     const TDesC& aTextToFind,
       
  1217     TMsvPartList aPartlist,
       
  1218     const CDesCArray& aRecipients,
       
  1219     CMsvFindText& aFindText )
       
  1220     {
       
  1221     TInt count = aRecipients.Count();
       
  1222     TBool found = EFalse;
       
  1223     for  (TInt i=0; i < count; i++ )
       
  1224         {
       
  1225         // Check alias and real address parts
       
  1226         // separately. Otherwise separator character could 
       
  1227         // spoil the check.
       
  1228         if ( aFindText.FindTextL( aTextToFind, 
       
  1229             TMmsGenUtils::Alias( aRecipients[i] ), aPartlist ) )
       
  1230             {
       
  1231             found = ETrue;
       
  1232             break;
       
  1233             }
       
  1234         else if ( aFindText.FindTextL( aTextToFind, 
       
  1235             TMmsGenUtils::PureAddress( aRecipients[i] ), aPartlist ) )
       
  1236             {
       
  1237             found = ETrue;
       
  1238             break;
       
  1239             }
       
  1240         }
       
  1241     return found;
       
  1242     }
       
  1243 
       
  1244 // ---------------------------------------------------------
       
  1245 // CUniClientMtm::AddFilePathAttachmentL
       
  1246 // ---------------------------------------------------------
       
  1247 //
       
  1248 void CUniClientMtm::AddFilePathAttachmentL(
       
  1249     const TDesC& aFilePath,
       
  1250     const TDesC8& aMimeType,
       
  1251     CMsvAttachment::TMsvAttachmentType aType,
       
  1252     TRequestStatus& aStatus,
       
  1253     const TUint aCharacterSet /* = 0 */ )
       
  1254 	{
       
  1255     __ASSERT_DEBUG( aType != CMsvAttachment::EMsvMessageEntry,
       
  1256         User::Invariant() );
       
  1257 
       
  1258     TEntry fileEntry;
       
  1259     User::LeaveIfError( Session().FileSession().Entry( aFilePath, fileEntry ) );
       
  1260 
       
  1261     if( !iAttaWaiter )
       
  1262         {
       
  1263         iAttaWaiter = CMmsAttachmentWaiter::NewL();
       
  1264         }
       
  1265     
       
  1266     // store must be the first item allocated because it is the last one to be popped
       
  1267     CMsvStore* store = iMsvEntry->EditStoreL();
       
  1268     CleanupStack::PushL( store );
       
  1269     MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
  1270     
       
  1271     CMsvAttachment* attachment = CMsvAttachment::NewL( aType );
       
  1272     CleanupStack::PushL( attachment );
       
  1273 
       
  1274     TInt size = InitializeAttachmentL(
       
  1275         manager,
       
  1276         *attachment,
       
  1277         aFilePath,
       
  1278         aMimeType,
       
  1279         fileEntry.iSize,
       
  1280         aCharacterSet );
       
  1281         
       
  1282     // now we know how much disk space we need
       
  1283     if ( aType == CMsvAttachment::EMsvFile )
       
  1284         {
       
  1285         size += attachment->Size();
       
  1286         }
       
  1287         
       
  1288     // Check that sufficient disk space available
       
  1289     if ( TMmsGenUtils::DiskSpaceBelowCriticalLevelL( 
       
  1290         &Session().FileSession(), 
       
  1291         size,
       
  1292         iMessageDrive ) )
       
  1293             {
       
  1294             // we use standard error code here
       
  1295             User::Leave( KErrDiskFull );
       
  1296             }
       
  1297     
       
  1298     // attachment is initialised, pass to the attachment manager
       
  1299     if ( iAttaWaiter->IsActive() )
       
  1300         {
       
  1301         // can't start an active operation because already active
       
  1302         User::Leave( KErrInUse );
       
  1303         }
       
  1304     switch( aType )
       
  1305         {
       
  1306         case CMsvAttachment::EMsvLinkedFile:
       
  1307             manager.AddLinkedAttachmentL( aFilePath, attachment,
       
  1308                 iAttaWaiter->iStatus );
       
  1309             break;
       
  1310         default: // CMsvAttachment::EMsvFile
       
  1311             manager.AddAttachmentL( aFilePath, attachment,
       
  1312                 iAttaWaiter->iStatus );
       
  1313             break;
       
  1314         }
       
  1315 
       
  1316     CleanupStack::Pop( attachment); //ownership passed to manager
       
  1317     // We cannot start waiting before we know that the function we are waiting for
       
  1318     // did not leave. If we become active, and the function leaves, we are in trouble    
       
  1319     iAttaWaiter->StartWaitingL( aStatus, store, &manager );
       
  1320     CleanupStack::Pop( store ); // ownership passed to iAttaWaiter
       
  1321     }
       
  1322     
       
  1323 // ---------------------------------------------------------
       
  1324 // CUniClientMtm::RecognizeCharSetL
       
  1325 // ---------------------------------------------------------
       
  1326 //
       
  1327 TUint CUniClientMtm::RecognizeCharSetL( RFile& aFile )
       
  1328     {
       
  1329     TUint charSet = CMsgTextUtils::RecognizeCharSetL( Session().FileSession(), aFile );
       
  1330     if ( !iTextUtils )
       
  1331         {
       
  1332         iTextUtils = CMsgTextUtils::NewL( Session().FileSession() );
       
  1333         }
       
  1334     return iTextUtils->CharconvIdToMibIdL( charSet );
       
  1335     }
       
  1336     
       
  1337 // ---------------------------------------------------------
       
  1338 // CUniClientMtm::InitializeAttachmentL
       
  1339 // ---------------------------------------------------------
       
  1340 //
       
  1341 TInt CUniClientMtm::InitializeAttachmentL(
       
  1342     MMsvAttachmentManager& aManager,
       
  1343     CMsvAttachment& aAttachment,
       
  1344     const TDesC& aFileName,
       
  1345     const TDesC8& aMimeType,
       
  1346     TInt aFileSize,
       
  1347     TUint aCharset )
       
  1348     {
       
  1349     CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
       
  1350     CleanupStack::PushL( mimeHeaders );
       
  1351     
       
  1352     aAttachment.SetSize( aFileSize );
       
  1353     
       
  1354     // set the mime-type if provided
       
  1355     if ( aMimeType.Length() > 0 )
       
  1356         {
       
  1357         aAttachment.SetMimeTypeL( aMimeType );
       
  1358         TInt position = aMimeType.Find( KMmsSlash8 );
       
  1359         if ( position > 0 )
       
  1360             {
       
  1361             mimeHeaders->SetContentTypeL( aMimeType.Left( position ) );
       
  1362             }
       
  1363         if ( position < aMimeType.Length() - 1 )
       
  1364             {
       
  1365             mimeHeaders->SetContentSubTypeL( aMimeType.Mid( position + 1 ) );
       
  1366             }
       
  1367         }
       
  1368 
       
  1369     TParsePtrC parse( aFileName );
       
  1370     mimeHeaders->SetSuggestedFilenameL( parse.NameAndExt() );
       
  1371     HBufC* contentLocation = CMsgTextUtils::GetSafeAttachmentNameLC(
       
  1372         aManager,
       
  1373         parse.NameAndExt(),
       
  1374         aAttachment.Id(),
       
  1375         ETrue );
       
  1376 	mimeHeaders->SetContentLocationL( *contentLocation );
       
  1377     CleanupStack::PopAndDestroy( contentLocation );
       
  1378 
       
  1379     mimeHeaders->SetMimeCharset( aCharset );
       
  1380 
       
  1381     TInt size = KMmsIndexEntryExtra + mimeHeaders->Size();    
       
  1382     mimeHeaders->StoreL( aAttachment );
       
  1383     
       
  1384     // mime headers have been streamed to CMsvAttachment, they can go now
       
  1385     CleanupStack::PopAndDestroy( mimeHeaders );  
       
  1386     return size;
       
  1387     }
       
  1388     
       
  1389 // ---------------------------------------------------------
       
  1390 // CUniClientMtm::SetContentLocationForConvertedAttL
       
  1391 // ---------------------------------------------------------
       
  1392 //
       
  1393 void CUniClientMtm::SetContentLocationForConvertedAttL(
       
  1394     CMsvStore& aStore,
       
  1395     TMsvAttachmentId aAttaId,
       
  1396     const TDesC& aFileName )
       
  1397     {
       
  1398     MMsvAttachmentManager& manager = aStore.AttachmentManagerL();    
       
  1399     CMsvAttachment* attachment = manager.GetAttachmentInfoL( aAttaId );    
       
  1400     CleanupStack::PushL( attachment );
       
  1401     
       
  1402     CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
       
  1403     CleanupStack::PushL( mimeHeaders );
       
  1404     mimeHeaders->RestoreL( *attachment );
       
  1405     
       
  1406     TParsePtrC parse( aFileName );
       
  1407     HBufC* contentLocation = CMsgTextUtils::GetSafeAttachmentNameLC(
       
  1408         manager,
       
  1409         parse.NameAndExt(),
       
  1410         aAttaId,
       
  1411         ETrue );
       
  1412     mimeHeaders->SetContentLocationL( *contentLocation );
       
  1413     CleanupStack::PopAndDestroy( contentLocation );
       
  1414     
       
  1415     mimeHeaders->StoreL( *attachment );
       
  1416     // Mime headers have been streamed into the attachment info
       
  1417     CleanupStack::PopAndDestroy( mimeHeaders );
       
  1418 
       
  1419     MMsvAttachmentManagerSync& syncManager = aStore.AttachmentManagerExtensionsL();
       
  1420         
       
  1421     syncManager.ModifyAttachmentInfoL( attachment );
       
  1422     // Ownership transferred
       
  1423     CleanupStack::Pop( attachment );
       
  1424     }
       
  1425     
       
  1426 
       
  1427 //  End of File