mobilemessaging/unieditor/smsplugin/src/UniSmsPlugin.cpp
branchRCL_3
changeset 60 7fdbb852d323
equal deleted inserted replaced
57:ebe688cedc25 60:7fdbb852d323
       
     1 /*
       
     2 * Copyright (c) 2005-2008 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:  
       
    15 *       Provides UniEditor SMS Plugin methods.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 
       
    24 // Symbian: 
       
    25 #include <e32base.h>
       
    26 #include <implementationproxy.h>
       
    27 #include <ecom.h>
       
    28 #include <txtetext.h>
       
    29 #include <txtrich.h>
       
    30 
       
    31 #include <mmsvattachmentmanager.h>
       
    32 #include <mmsvattachmentmanagersync.h>
       
    33 #include <gsmerror.h>                       // KErrGsmOfflineOpNotAllowed
       
    34 #include <featmgr.h> 
       
    35 
       
    36 #include <mtclreg.h>
       
    37 #include <smsclnt.h>
       
    38 #include <smscmds.h>
       
    39 #include <smuthdr.h>
       
    40 #include <csmsemailfields.h>
       
    41 #include <csmsaccount.h>
       
    42 #include <charconv.h>
       
    43 #include <smut.h>
       
    44 #include <smumutil.h>
       
    45 #include <cmsvmimeheaders.h>
       
    46 #include <badesca.h>
       
    47 #include <e32cmn.h>
       
    48 #include <muiumsvuiserviceutilitiesinternal.h> 
       
    49 #include <gsmuset.h>
       
    50 
       
    51 // S60
       
    52 #include <mmsgenutils.h>
       
    53 #include <MuiuOperationWait.h>
       
    54 #include <vcard.h>
       
    55 #include <SenduiMtmUids.h>
       
    56 #include <MsgBioUids.h>
       
    57 #include <MsgMimeTypes.h>
       
    58 #include "UniSendingSettings.h"
       
    59 #include "UniClientMtm.h"
       
    60 #include "UniEditorUids.hrh"
       
    61 #include "messagingvariant.hrh"
       
    62 #include "UniSmsPlugin.h"
       
    63 #include "UniSmsUtils.h"
       
    64 #include "MsgAttachmentUtils.h" 
       
    65 #include "UniMsvEntry.h"
       
    66 
       
    67 // resources
       
    68 #include <UniSmsPluginD.rsg>                   
       
    69 #include <avkon.rsg>              
       
    70 
       
    71 //LOGGING
       
    72 #include "UniEditorLogging.h"
       
    73 
       
    74 // CONSTANTS
       
    75 const TImplementationProxy KImplementationTable[] = 
       
    76 	{
       
    77 	IMPLEMENTATION_PROXY_ENTRY( KUidUniEditorSmsPlugin, CUniSmsPlugin::NewL)
       
    78 	};
       
    79 
       
    80 // Used to set msg in unparsed state
       
    81 const TInt KSmsPluginBioMsgUnparsed = 0;
       
    82 
       
    83 // Description length for sms messages
       
    84 const TInt KSmsMessageEntryDescriptionAmountOfChars = 60;
       
    85 
       
    86 //used for descriptor array containing recipients
       
    87 const TInt KRecipientsArrayGranularity = 8;
       
    88 
       
    89 // For address information separation (start)
       
    90 const TUint KMsgSmsAddressStartChar         ('<'); 
       
    91 
       
    92 // For address information separation (end)
       
    93 const TUint KMsgSmsAddressEndChar           ('>');
       
    94 
       
    95 const TUint KUniSmsStartParenthesis ('(');
       
    96 const TUint KUniSmsEndParenthesis (')');
       
    97 
       
    98 // String length for Service centre name
       
    99 const TInt KUniSmsSCStringLength = 50;
       
   100 
       
   101 const TUid KUidMsvSMSHeaderStream_COPY_FROM_SMUTHDR_CPP  = {0x10001834};
       
   102 
       
   103 // Amount of to be converted chars during extracting description
       
   104 const TInt KSmsEdExtrDescReplaceCharacterCount = 3;
       
   105 
       
   106 // Unicode char for linefeed regocnised by basic phones
       
   107 const TUint KSmsEdUnicodeLFSupportedByBasicPhones = 0x000A;
       
   108 // ========== LOCAL FUNCTIONS ==================================================
       
   109 GLDEF_C void Panic( TInt aCategory );
       
   110 
       
   111 
       
   112 // ============================ MEMBER FUNCTIONS ===============================
       
   113 
       
   114 // -----------------------------------------------------------------------------
       
   115 // Two-phased constructor.
       
   116 // -----------------------------------------------------------------------------
       
   117 //
       
   118 CUniSmsPlugin* CUniSmsPlugin::NewL( TAny* aConstructionParameters )
       
   119     {
       
   120 	TUniPluginParams* params = reinterpret_cast<TUniPluginParams*>( aConstructionParameters );
       
   121     CUniSmsPlugin* self = new ( ELeave ) CUniSmsPlugin( params->iSession, params->iUniMtm ); 
       
   122     CleanupStack::PushL( self );
       
   123     self->ConstructL();
       
   124     CleanupStack::Pop( self );
       
   125     return self;
       
   126     }
       
   127 
       
   128 // -----------------------------------------------------------------------------
       
   129 // Destructor
       
   130 // -----------------------------------------------------------------------------
       
   131 //
       
   132 CUniSmsPlugin::~CUniSmsPlugin()
       
   133     {
       
   134     delete iRichText;
       
   135     delete iParaFormatLayer;
       
   136     delete iCharFormatLayer;
       
   137     delete iSmsHeader;
       
   138     delete iSmsMtm;
       
   139     delete iMtmRegistry;
       
   140     delete iEmailOverSmsC;
       
   141     delete iRecipients;	
       
   142     }
       
   143 
       
   144 // -----------------------------------------------------------------------------
       
   145 // C++ default constructor
       
   146 // -----------------------------------------------------------------------------
       
   147 //
       
   148 CUniSmsPlugin::CUniSmsPlugin( CMsvSession& aSession, CUniClientMtm& aUniMtm )
       
   149     : iSession( aSession ),
       
   150     iUniMtm( aUniMtm ),
       
   151     iBioMsg( EFalse ),
       
   152     iOfflineSupported( EFalse )
       
   153     {
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // Symbian 2nd phase constructor
       
   158 // -----------------------------------------------------------------------------
       
   159 //
       
   160 void CUniSmsPlugin::ConstructL()
       
   161     {
       
   162     UNILOGGER_ENTERFN("CUniSmsPlugin::ConstructL");
       
   163     iParaFormatLayer = CParaFormatLayer::NewL();
       
   164     iCharFormatLayer = CCharFormatLayer::NewL();
       
   165     iRichText = CRichText::NewL( iParaFormatLayer, iCharFormatLayer );
       
   166     iEmailOverSmsC = CSmsNumber::NewL();
       
   167 	
       
   168     CMsvEntry& entry = SmsMtmL()->Entry();
       
   169     entry.SetEntryL( KMsvRootIndexEntryId );
       
   170     
       
   171     TSmsUtilities::ServiceIdL( entry, iSmsServiceId );
       
   172     
       
   173     FeatureManager::InitializeLibL();
       
   174     if ( FeatureManager::FeatureSupported( KFeatureIdOfflineMode ) )
       
   175         {
       
   176         iOfflineSupported = ETrue;   
       
   177         }
       
   178     else
       
   179         {
       
   180         iOfflineSupported = EFalse;  
       
   181         }
       
   182     
       
   183     //Turkish SMS-PREQ2265 Specific
       
   184     if ( FeatureManager::FeatureSupported( KFeatureIdNltSupport ) )
       
   185         {
       
   186         iNLTFeatureSupport = ETrue;
       
   187         }
       
   188     else
       
   189         {
       
   190         iNLTFeatureSupport = EFalse;
       
   191         }
       
   192     
       
   193     FeatureManager::UnInitializeLib();
       
   194     iStoreChanged = EFalse;
       
   195     
       
   196     UNILOGGER_LEAVEFN("CUniSmsPlugin::ConstructL");
       
   197     }
       
   198 
       
   199 // -----------------------------------------------------------------------------
       
   200 // LoadHeadersL
       
   201 // -----------------------------------------------------------------------------
       
   202 //
       
   203 void CUniSmsPlugin::LoadHeadersL( CMsvStore* aStore )
       
   204     {
       
   205     UNILOGGER_ENTERFN("CUniSmsPlugin::LoadHeadersL");
       
   206     delete iSmsHeader;
       
   207     iSmsHeader = NULL;
       
   208 
       
   209     if ( aStore && aStore->HasBodyTextL() )
       
   210         {
       
   211     	aStore->RestoreBodyTextL( *iRichText );
       
   212         }
       
   213 
       
   214 	iSmsHeader = CSmsHeader::NewL( CSmsPDU::ESmsSubmit, *iRichText );
       
   215 	
       
   216 	if ( aStore && aStore->IsPresentL( KUidMsvSMSHeaderStream_COPY_FROM_SMUTHDR_CPP ) )
       
   217 	    {
       
   218 	    iSmsHeader->RestoreL( *aStore );
       
   219 	    }
       
   220 	else
       
   221 	    {
       
   222         CSmsSettings* settings = CSmsSettings::NewLC();
       
   223     	CSmsAccount* account = CSmsAccount::NewLC();
       
   224     	account->LoadSettingsL( *settings );
       
   225     	CleanupStack::PopAndDestroy( account );
       
   226         iSmsHeader->SetSmsSettingsL( *settings );
       
   227         CleanupStack::PopAndDestroy( settings );
       
   228 	    }
       
   229 		TSmsUserDataSettings smsSettings;		
       
   230 		smsSettings.SetTextCompressed( EFalse );
       
   231 		TRAP_IGNORE(iSmsHeader->Message().SetUserDataSettingsL( smsSettings ));
       
   232     UNILOGGER_LEAVEFN("CUniSmsPlugin::LoadHeadersL");
       
   233     }
       
   234 
       
   235 // -----------------------------------------------------------------------------
       
   236 // SaveHeadersL 
       
   237 // -----------------------------------------------------------------------------
       
   238 //
       
   239 void CUniSmsPlugin::SaveHeadersL( CMsvStore& aStore )
       
   240     {
       
   241     if ( iSmsHeader )
       
   242         {
       
   243         iSmsHeader->StoreL( aStore );
       
   244         }
       
   245     }
       
   246 // -----------------------------------------------------------------------------
       
   247 // ResetUniAddresselist
       
   248 // -----------------------------------------------------------------------------
       
   249 //
       
   250 void CUniSmsPlugin::ResetUniAddresselist()
       
   251     {
       
   252     const CMsvRecipientList& uniRecipients = iUniMtm.AddresseeList();       
       
   253     while ( uniRecipients.Count() )
       
   254         {
       
   255         iUniMtm.RemoveAddressee( 0 );
       
   256         }  
       
   257     }
       
   258 // -----------------------------------------------------------------------------
       
   259 // ConvertFromL
       
   260 // -----------------------------------------------------------------------------
       
   261 //
       
   262 TMsvId CUniSmsPlugin::ConvertFromL( TMsvId aId )
       
   263     {
       
   264     return DoConvertFromL( aId, EFalse );
       
   265     }
       
   266 
       
   267 // -----------------------------------------------------------------------------
       
   268 // DoConvertFromL
       
   269 // -----------------------------------------------------------------------------
       
   270 //
       
   271 TMsvId CUniSmsPlugin::DoConvertFromL( TMsvId aId, TBool aIsForward )
       
   272 	{
       
   273     UNILOGGER_ENTERFN("CUniSmsPlugin::ConvertFromL");
       
   274     UNILOGGER_WRITE_TIMESTAMP("CUniSmsPlugin::ConvertFromL start");
       
   275     SmsMtmL()->SwitchCurrentEntryL( aId );
       
   276     SmsMtmL()->LoadMessageL();
       
   277     iUniMtm.SwitchCurrentEntryL( aId );
       
   278     iUniMtm.LoadMessageL(); 
       
   279     ResetUniAddresselist();
       
   280     TPtrC name;
       
   281     TPtrC address;  
       
   282 
       
   283 
       
   284 	const CSmsEmailFields& emailFields = SmsMtmL( )->SmsHeader( ).EmailFields();
       
   285 
       
   286 	if( emailFields.HasAddress( ) && !aIsForward )
       
   287 		{ // If email address set -> copy them here
       
   288 	    const MDesCArray& emailRecipients = emailFields.Addresses();
       
   289 		for( TInt id = 0; id < emailRecipients.MdcaCount( ); id++ )
       
   290 			{
       
   291 	        NameAndAddress( emailRecipients.MdcaPoint( id ), name, address );
       
   292 	        iUniMtm.AddAddresseeL( 
       
   293 	            EMsvRecipientTo,
       
   294 	            address,
       
   295 	            name );
       
   296 			}
       
   297 		}
       
   298 
       
   299     // Copy non-email over sms addresses if needed
       
   300     const CMsvRecipientList& smsRecipients = SmsMtmL()->AddresseeList();
       
   301 
       
   302     while ( smsRecipients.Count() )
       
   303         { // Go thru all the recipients
       
   304 		if( !emailFields.HasAddress( ) && !aIsForward )
       
   305 			{ // and copy them only if email addresses did not exist
       
   306 	        NameAndAddress( smsRecipients[ 0 ], name, address );
       
   307 	        iUniMtm.AddAddresseeL( 
       
   308 	            EMsvRecipientTo,
       
   309 	            address,
       
   310 	            name );
       
   311 			}
       
   312         SmsMtmL()->RemoveAddressee( 0 );
       
   313         }
       
   314     
       
   315     if( emailFields.Subject( ).Length( ) )
       
   316     	{ // If email subject exists -> copy it
       
   317     	iUniMtm.SetSubjectL( emailFields.Subject( ) );
       
   318     	}
       
   319     
       
   320     //Get sms entry 
       
   321     TMsvEntry smsTEntry = SmsMtmL()->Entry().Entry();
       
   322     
       
   323     if (  smsTEntry.iBioType == KMsgBioUidVCard.iUid
       
   324         || smsTEntry.iBioType == KMsgBioUidVCalendar.iUid )
       
   325         { 
       
   326         //We must check here if there is two attachments. This happens in case
       
   327         //if sending fails and message opened from drafts
       
   328         CMsvStore* store = iUniMtm.Entry().EditStoreL();
       
   329         CleanupStack::PushL( store );
       
   330         MMsvAttachmentManagerSync& managerSync = store->AttachmentManagerExtensionsL();        
       
   331         MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
   332         if ( manager.AttachmentCount() == 2)
       
   333         	{
       
   334             managerSync.RemoveAttachmentL( 1 ); 	
       
   335         	}
       
   336         store->CommitL();  	
       
   337         CleanupStack::PopAndDestroy( store );
       
   338         }     
       
   339     else   //plain text
       
   340         {
       
   341         TInt totalLength( SmsMtmL()->Body().DocumentLength() );
       
   342         if ( totalLength > 0 )
       
   343             {
       
   344             HBufC* bodyText = HBufC::NewLC ( totalLength ); 
       
   345             TPtr bodyTextPtr ( bodyText->Des() ); 
       
   346             
       
   347             SmsMtmL()->Body().Extract( bodyTextPtr, 0, totalLength );
       
   348             
       
   349             iUniMtm.Body().InsertL( 0, bodyTextPtr );
       
   350                         
       
   351             CleanupStack::PopAndDestroy( bodyText );            
       
   352             }
       
   353         }
       
   354     
       
   355     SmsMtmL()->Body().Reset();
       
   356     SmsMtmL()->SaveMessageL();
       
   357     TMsvEntry uniTEntry = iUniMtm.Entry().Entry();
       
   358     CMsvStore* store = iUniMtm.Entry().EditStoreL();
       
   359     CleanupStack::PushL( store );
       
   360    
       
   361     iUniMtm.SaveMessageL(*store, uniTEntry);
       
   362     
       
   363     store->CommitL();
       
   364     CleanupStack::PopAndDestroy(store);  
       
   365     // Lets convert the bits to Uni mode
       
   366 	TUniMsvEntry::SetForwardedMessage( uniTEntry, aIsForward );
       
   367 	
       
   368     uniTEntry.iMtm.iUid = KUidUniMtm;
       
   369     iUniMtm.Entry().ChangeL( uniTEntry );
       
   370     UNILOGGER_LEAVEFN("CUniSmsPlugin::ConvertFromL");    
       
   371     UNILOGGER_WRITE_TIMESTAMP("CUniSmsPlugin::ConvertFromL end");
       
   372     return aId;
       
   373     }
       
   374 
       
   375 TInt32 CUniSmsPlugin::AttachmentsSizeL( CMsvStore& aStore )
       
   376     {
       
   377     TInt32 size = 0;
       
   378 
       
   379     MMsvAttachmentManager& attachMan = aStore.AttachmentManagerL();
       
   380     TInt numAttachments = attachMan.AttachmentCount();
       
   381 
       
   382     for ( TInt i = 0; i < numAttachments; i++ )
       
   383         {
       
   384         CMsvAttachment* attachmentInfo = attachMan.GetAttachmentInfoL( i );
       
   385         CleanupStack::PushL( attachmentInfo );
       
   386         
       
   387         CMsvMimeHeaders* mimeHeaders = CMsvMimeHeaders::NewL();
       
   388         CleanupStack::PushL( mimeHeaders );
       
   389         
       
   390         mimeHeaders->RestoreL( *attachmentInfo );
       
   391         
       
   392         RFile attaFile = attachMan.GetAttachmentFileL( i );
       
   393         CleanupClosePushL( attaFile );
       
   394         TInt fileSize = 0;
       
   395         
       
   396         // If we cannot access the file, we are in trouble
       
   397         User::LeaveIfError( attaFile.Size( fileSize ) ); 
       
   398         
       
   399         // This adds up mime header size + actual attachment binary data
       
   400         size += mimeHeaders->Size() + fileSize;
       
   401 
       
   402         CleanupStack::PopAndDestroy( &attaFile );
       
   403         CleanupStack::PopAndDestroy( mimeHeaders );
       
   404         CleanupStack::PopAndDestroy( attachmentInfo );
       
   405         }
       
   406 
       
   407     return size;
       
   408     }
       
   409 	
       
   410 // -----------------------------------------------------------------------------
       
   411 // ConvertToL
       
   412 // -----------------------------------------------------------------------------
       
   413 //
       
   414 TMsvId CUniSmsPlugin::ConvertToL( TMsvId aId )
       
   415     {    
       
   416     UNILOGGER_ENTERFN("CUniSmsPlugin::ConvertToL");
       
   417     SmsMtmL()->SwitchCurrentEntryL( aId );
       
   418     SmsMtmL()->LoadMessageL();
       
   419     iUniMtm.SwitchCurrentEntryL( aId );
       
   420     iUniMtm.LoadMessageL();
       
   421  
       
   422     const CMsvRecipientList& uniRecipients = iUniMtm.AddresseeList();
       
   423     
       
   424     //Save for email over sms  
       
   425     if ( iRecipients )
       
   426     	{
       
   427     	delete iRecipients;
       
   428     	iRecipients = NULL;
       
   429     	}
       
   430     iRecipients = new ( ELeave ) CDesCArrayFlat( KRecipientsArrayGranularity );   
       
   431          
       
   432     CSmsEmailFields *emailFields = CSmsEmailFields::NewL();
       
   433     CleanupStack::PushL( emailFields );
       
   434    
       
   435     while ( uniRecipients.Count() )
       
   436         {
       
   437         if ( IsEmailAddress( TMmsGenUtils::PureAddress( uniRecipients[ 0 ] )))
       
   438             {
       
   439             emailFields->AddAddressL( TMmsGenUtils::PureAddress( uniRecipients[ 0 ] ) );
       
   440             }
       
   441         else
       
   442             {
       
   443             SmsMtmL()->AddAddresseeL( 
       
   444                 TMmsGenUtils::PureAddress( uniRecipients[ 0 ] ),
       
   445                 TMmsGenUtils::Alias( uniRecipients[ 0 ] ) );    
       
   446             }
       
   447 
       
   448         iRecipients->AppendL( uniRecipients[ 0 ]  );
       
   449         iUniMtm.RemoveAddressee( 0 );
       
   450         }   
       
   451     if ( iUniMtm.SubjectL().Length() )
       
   452         {
       
   453         emailFields->SetSubjectL( iUniMtm.SubjectL() );
       
   454         }
       
   455     
       
   456     SmsMtmL()->SmsHeader().SetEmailFieldsL( *emailFields );
       
   457     CleanupStack::PopAndDestroy( emailFields );        
       
   458     
       
   459     CMsvStore* store = iUniMtm.Entry().EditStoreL();
       
   460     CleanupStack::PushL( store );
       
   461     MMsvAttachmentManager& manager = store->AttachmentManagerL();
       
   462     MMsvAttachmentManagerSync& managerSync = store->AttachmentManagerExtensionsL();
       
   463     TUid bioType =
       
   464         {
       
   465         0 
       
   466         };
       
   467    
       
   468     CMsvAttachment* atta ( NULL );
       
   469     switch ( manager.AttachmentCount() )
       
   470         {
       
   471         case 0:
       
   472             {
       
   473             //In case of empty message.
       
   474             //There is not even smil.
       
   475             SmsMtmL()->Body().Reset();
       
   476             break;
       
   477             }
       
   478         case 1:  
       
   479         	{
       
   480         	atta = manager.GetAttachmentInfoL( 0 );
       
   481         	 if ( atta->MimeType() == KMsgMimeSmil )
       
   482                 {                        
       
   483                 managerSync.RemoveAttachmentL( 0 ); 
       
   484                 delete atta;
       
   485                 atta= NULL;
       
   486                 }
       
   487         	 else
       
   488         	     CleanupStack::PushL(atta);
       
   489         	break;
       
   490         	}
       
   491         case 2:  //There is usually a SMIL also.
       
   492             {
       
   493             //In these case branch we assume that there is only one text atta
       
   494             //or one text atta and a SMIL
       
   495             //Everything else is a programming error in the caller
       
   496 
       
   497             CMsvAttachment* tempAtta1 = manager.GetAttachmentInfoL( 0 );
       
   498             CleanupStack::PushL(tempAtta1);
       
   499             CMsvAttachment* tempAtta2 = manager.GetAttachmentInfoL( 1 );
       
   500             CleanupStack::PushL(tempAtta2);
       
   501                    
       
   502             if ( tempAtta1->MimeType() == KMsgMimeSmil )
       
   503                 {
       
   504                 CleanupStack::Pop( tempAtta2 );
       
   505                 CleanupStack::PopAndDestroy( tempAtta1 );
       
   506                 CleanupStack::PushL( tempAtta2 );
       
   507                      
       
   508                 managerSync.RemoveAttachmentL( 0 ); 
       
   509                 atta=tempAtta2;
       
   510                 }
       
   511             else if ( tempAtta2->MimeType() == KMsgMimeSmil )    
       
   512                 {
       
   513                 CleanupStack::PopAndDestroy( tempAtta2 );
       
   514                 managerSync.RemoveAttachmentL( 1 ); 
       
   515                 atta=tempAtta1;
       
   516                 }
       
   517             else
       
   518                 { 
       
   519                 //Programming error in caller code
       
   520 #ifdef _DEBUG 
       
   521                 UNILOGGER_WRITEF(_L("PANIC: Two attas but no smil"));
       
   522                 Panic ( EIllegalArguments );     
       
   523 #endif 
       
   524                 User::Leave( KErrArgument );
       
   525                 
       
   526                 }
       
   527             break;
       
   528             }
       
   529         default:
       
   530             {
       
   531             //Programming error in caller code
       
   532 #ifdef _DEBUG 
       
   533             UNILOGGER_WRITEF(_L("PANIC: Two many attas"));
       
   534             Panic ( EIllegalArguments );
       
   535 #endif            
       
   536             User::Leave( KErrArgument );
       
   537             break;
       
   538             }
       
   539         }
       
   540 
       
   541     if ( atta )
       
   542         {  	
       
   543         UNILOGGER_WRITEF8(_L8("Mime Type: %S"),&(atta->MimeType()));
       
   544         UNILOGGER_WRITEF(_L("Atta Name: %S"),&(atta->AttachmentName()));
       
   545 
       
   546         RFile file = manager.GetAttachmentFileL( 0 );
       
   547         CleanupClosePushL( file );
       
   548                    
       
   549         //Note that the attachments is not removed in case of smart messaging
       
   550         if ( atta->MimeType().CompareF( KMsgMimeTextPlain ) == 0 )
       
   551             {
       
   552             iBioMsg=EFalse;
       
   553             CreatePlainTextSMSL( file );
       
   554             managerSync.RemoveAttachmentL( 0 ); 
       
   555             }
       
   556         else if ( atta->MimeType().CompareF(KMsgMimeVCard) == 0 )
       
   557             {
       
   558             iBioMsg=ETrue;
       
   559             CreateVCardSMSL( file );
       
   560             bioType = KMsgBioUidVCard;
       
   561             SmsMtmL()->BioTypeChangedL( bioType );
       
   562             //Do not remove vCard atta here. 
       
   563             }
       
   564         else if ( atta->MimeType().CompareF(KMsgMimeVCal ) == 0 ||
       
   565                   atta->MimeType().CompareF(KMsgMimeICal ) == 0 )
       
   566             {
       
   567             iBioMsg=ETrue;
       
   568             CreateVCalSMSL( file );
       
   569             bioType = KMsgBioUidVCalendar;
       
   570             SmsMtmL()->BioTypeChangedL( bioType );
       
   571             //Do not remove vCal atta here. 
       
   572             }
       
   573         else
       
   574             {
       
   575             User::Leave( KErrArgument );
       
   576             } 
       
   577         CleanupStack::PopAndDestroy( &file );
       
   578         CleanupStack::PopAndDestroy( atta );
       
   579         }
       
   580         	
       
   581     TMsvEntry tEntry = SmsMtmL()->Entry().Entry();
       
   582     tEntry.SetAttachment( EFalse ); 
       
   583     tEntry.iMtm = KSenduiMtmSmsUid;
       
   584     tEntry.iType = KUidMsvMessageEntry;
       
   585     tEntry.iRelatedId = iSmsServiceId;
       
   586     tEntry.iServiceId = KMsvLocalServiceIndexEntryId;
       
   587     tEntry.iDate.UniversalTime();
       
   588     tEntry.SetInPreparation( ETrue );
       
   589     tEntry.SetVisible( EFalse );
       
   590 
       
   591     CSmsSettings* sendOptions = CSmsSettings::NewL();
       
   592     CleanupStack::PushL( sendOptions );
       
   593     
       
   594     // "ConvertToL" might be called right after constructor.
       
   595     // In this case iSmsHeader is still NULL. Need to initialise.
       
   596     if ( !iSmsHeader )
       
   597         {
       
   598         LoadHeadersL( store );
       
   599         }
       
   600   	iSmsHeader->GetSmsSettingsL( *sendOptions );
       
   601 	
       
   602     sendOptions->CopyL( *sendOptions );
       
   603     
       
   604 	if ( !iBioMsg )
       
   605 	    {
       
   606 	    if( iUnicodeMode )
       
   607 		    {
       
   608 		    sendOptions->SetCharacterSet( TSmsDataCodingScheme::ESmsAlphabetUCS2 );
       
   609 		    }
       
   610 	    else
       
   611 		    {
       
   612 		    sendOptions->SetCharacterSet( TSmsDataCodingScheme::ESmsAlphabet7Bit );
       
   613 		    }
       
   614 	    }
       
   615     else
       
   616         {
       
   617         // make sure bio messages have no conversion
       
   618         tEntry.iBioType = bioType.iUid;
       
   619         sendOptions->SetMessageConversion( ESmsConvPIDNone );
       
   620         sendOptions->SetCharacterSet( TSmsDataCodingScheme::ESmsAlphabet8Bit );
       
   621         }
       
   622     
       
   623     // Update some global SMS settings affecting all messages.
       
   624     // These might have changed from the ones retrieved when
       
   625     // the message was created and so needs to be updated.
       
   626     CSmsSettings* defaultSettings = CSmsSettings::NewLC();
       
   627 	
       
   628 	CSmsAccount* account = CSmsAccount::NewLC();
       
   629 	account->LoadSettingsL( *defaultSettings );
       
   630 	CleanupStack::PopAndDestroy( account );
       
   631     
       
   632     sendOptions->SetDeliveryReport( defaultSettings->DeliveryReport() );
       
   633     sendOptions->SetSmsBearer( defaultSettings->SmsBearer() );
       
   634     sendOptions->SetValidityPeriod( defaultSettings->ValidityPeriod() );
       
   635     sendOptions->SetReplyPath( defaultSettings->ReplyPath() );
       
   636     
       
   637     CleanupStack::PopAndDestroy( defaultSettings );
       
   638     
       
   639     iSmsHeader->SetSmsSettingsL( *sendOptions );
       
   640 
       
   641 	// Move all the stuff from iSmsHeader::SmsSettings to SmsMtm::SmsHeader::SmsSettings
       
   642 	SmsMtmL()->SmsHeader( ).SetSmsSettingsL( *sendOptions );
       
   643 	SmsMtmL()->SmsHeader( ).Message( ).
       
   644 		SetServiceCenterAddressL( iSmsHeader->Message( ).ServiceCenterAddress( ) );
       
   645 
       
   646     if(iNLTFeatureSupport)
       
   647         {
       
   648         //Turkish SMS-PREQ2265 Specific
       
   649         TSmsEncoding currAlternateEncoding = iSmsHeader->Message().Alternative7bitEncoding();
       
   650         SmsMtmL()->SmsHeader().Message().SetAlternative7bitEncoding(currAlternateEncoding);       
       
   651         }
       
   652 	
       
   653     CleanupStack::PopAndDestroy( sendOptions ); 
       
   654 
       
   655     SmsMtmL()->SaveMessageL(*store, tEntry);
       
   656     store->CommitL();           
       
   657     tEntry.iSize = store->SizeL();
       
   658     if( AttachmentsSizeL( *store ) > 0 )
       
   659         {
       
   660         tEntry.SetAttachment( ETrue );
       
   661         }
       
   662     CleanupStack::PopAndDestroy( store );
       
   663     
       
   664     SmsMtmL()->Entry().ChangeL( tEntry );
       
   665     UNILOGGER_LEAVEFN("CUniSmsPlugin::ConvertToL");
       
   666     return aId;
       
   667     }
       
   668 
       
   669 // -----------------------------------------------------------------------------
       
   670 // CreateReplyL
       
   671 // -----------------------------------------------------------------------------
       
   672 //
       
   673 TMsvId CUniSmsPlugin::CreateReplyL( TMsvId aSrc, TMsvId aDest, TMsvPartList aParts )
       
   674     {
       
   675     return DoCreateReplyOrForwardL( ETrue, aSrc, aDest, aParts );
       
   676     }
       
   677 
       
   678 // -----------------------------------------------------------------------------
       
   679 // CreateForwardL
       
   680 // -----------------------------------------------------------------------------
       
   681 //
       
   682 TMsvId CUniSmsPlugin::CreateForwardL( TMsvId aSrc, TMsvId aDest, TMsvPartList aParts )
       
   683     {
       
   684     return DoCreateReplyOrForwardL( EFalse, aSrc, aDest, aParts );
       
   685     }
       
   686         
       
   687 // -----------------------------------------------------------------------------
       
   688 // SendL
       
   689 // -----------------------------------------------------------------------------
       
   690 //
       
   691 void CUniSmsPlugin::SendL( TMsvId aId )
       
   692     {
       
   693     UNILOGGER_ENTERFN("CUniSmsPlugin::SendL");
       
   694     SmsMtmL()->SwitchCurrentEntryL( aId );
       
   695     SmsMtmL()->LoadMessageL();
       
   696     MoveMessagesToOutboxL();
       
   697     UNILOGGER_LEAVEFN("CUniSmsPlugin::SendL");
       
   698     }
       
   699 
       
   700 // -----------------------------------------------------------------------------
       
   701 // ValidateServiceL
       
   702 // -----------------------------------------------------------------------------
       
   703 //
       
   704 TBool CUniSmsPlugin::ValidateServiceL( TBool aEmailOverSms )
       
   705     {
       
   706     TBool valid = ValidateSCNumberL();
       
   707     
       
   708     if ( aEmailOverSms )
       
   709         { 
       
   710         valid = ValidateSCNumberForEmailOverSmsL();
       
   711         }
       
   712     
       
   713     return valid;
       
   714     }
       
   715         
       
   716 // -----------------------------------------------------------------------------
       
   717 // GetSendingSettingsL
       
   718 // -----------------------------------------------------------------------------
       
   719 //
       
   720 void CUniSmsPlugin::GetSendingSettingsL( TUniSendingSettings& aSettings )
       
   721     {
       
   722     // Modify only the settings this mtm plugin supports
       
   723     CSmsSettings* smsSettings = CSmsSettings::NewLC();
       
   724 	iSmsHeader->GetSmsSettingsL( *smsSettings );
       
   725 
       
   726     switch ( smsSettings->ValidityPeriod().Int() )
       
   727         {
       
   728         case ESmsVPHour:
       
   729             aSettings.iValidityPeriod = TUniSendingSettings::EUniValidityPeriod1h;
       
   730             break;
       
   731         case ESmsVPSixHours:
       
   732             aSettings.iValidityPeriod = TUniSendingSettings::EUniValidityPeriod6h;
       
   733             break;
       
   734         case (3 * (TInt) ESmsVP24Hours):
       
   735             aSettings.iValidityPeriod = TUniSendingSettings::EUniValidityPeriod3Days;
       
   736             break;
       
   737         case ESmsVPWeek:
       
   738             aSettings.iValidityPeriod = TUniSendingSettings::EUniValidityPeriodWeek;
       
   739             break;
       
   740         case ESmsVPMaximum:
       
   741             aSettings.iValidityPeriod = TUniSendingSettings::EUniValidityPeriodMax;
       
   742             break;
       
   743         default: // default to 24h
       
   744         case ESmsVP24Hours:
       
   745             aSettings.iValidityPeriod = TUniSendingSettings::EUniValidityPeriod24h;
       
   746             break;
       
   747         }
       
   748 
       
   749 	switch( smsSettings->MessageConversion( ) )
       
   750 		{
       
   751 		case ESmsConvFax:
       
   752 			aSettings.iMessageType = TUniSendingSettings::EUniMessageTypeFax;
       
   753 			break;
       
   754 		case ESmsConvPaging:
       
   755 			aSettings.iMessageType = TUniSendingSettings::EUniMessageTypePaging;
       
   756 			break;
       
   757 		default: // any other is text
       
   758 			aSettings.iMessageType = TUniSendingSettings::EUniMessageTypeText;
       
   759 			break;
       
   760 		}
       
   761 
       
   762     aSettings.iDeliveryReport = smsSettings->DeliveryReport();
       
   763     aSettings.iReplyViaSameCentre = smsSettings->ReplyPath();
       
   764     CleanupStack::PopAndDestroy( smsSettings );
       
   765     }
       
   766     
       
   767 
       
   768 
       
   769 
       
   770 // -----------------------------------------------------------------------------
       
   771 // SetSendingSettingsL
       
   772 // -----------------------------------------------------------------------------
       
   773 //
       
   774 void CUniSmsPlugin::SetSendingSettingsL( TUniSendingSettings& aSettings )
       
   775     {
       
   776     CSmsSettings* smsSettings = CSmsSettings::NewLC();
       
   777 	iSmsHeader->GetSmsSettingsL( *smsSettings );
       
   778 
       
   779     TTimeIntervalMinutes validityPeriod = smsSettings->ValidityPeriod().Int();
       
   780     switch ( aSettings.iValidityPeriod )
       
   781         {
       
   782         case TUniSendingSettings::EUniValidityPeriod1h:
       
   783             validityPeriod = ( TInt ) ESmsVPHour;
       
   784             break;
       
   785         case TUniSendingSettings::EUniValidityPeriod6h:
       
   786             validityPeriod = ( TInt ) ESmsVPSixHours;
       
   787             break;
       
   788         case TUniSendingSettings::EUniValidityPeriod3Days:   
       
   789             validityPeriod = ( 3 * ( TInt ) ESmsVP24Hours );// Instead of modifying smutset.h
       
   790             break;
       
   791         case TUniSendingSettings::EUniValidityPeriodWeek:
       
   792             validityPeriod = ( TInt ) ESmsVPWeek;
       
   793             break;
       
   794         case TUniSendingSettings::EUniValidityPeriodMax:
       
   795             validityPeriod = ( TInt ) ESmsVPMaximum;
       
   796             break;
       
   797         default: // default to 24h
       
   798         case TUniSendingSettings::EUniValidityPeriod24h:
       
   799             validityPeriod = ( TInt ) ESmsVP24Hours;
       
   800             break;
       
   801         }
       
   802 	switch( aSettings.iMessageType )
       
   803 		{
       
   804 		case TUniSendingSettings::EUniMessageTypeFax:
       
   805 			smsSettings->SetMessageConversion( ESmsConvFax );
       
   806 			break;
       
   807 		case TUniSendingSettings::EUniMessageTypePaging:
       
   808 			smsSettings->SetMessageConversion( ESmsConvPaging );
       
   809 			break;
       
   810 		default: // any other is text
       
   811 			smsSettings->SetMessageConversion( ESmsConvPIDNone );
       
   812 			break;
       
   813 		}
       
   814 
       
   815     smsSettings->SetValidityPeriod( validityPeriod );
       
   816     smsSettings->SetDeliveryReport( aSettings.iDeliveryReport );
       
   817     smsSettings->SetReplyPath( aSettings.iReplyViaSameCentre );
       
   818     
       
   819 	iSmsHeader->SetSmsSettingsL( *smsSettings );
       
   820     CleanupStack::PopAndDestroy( smsSettings );
       
   821     }
       
   822 
       
   823 // -----------------------------------------------------------------------------
       
   824 // IsServiceValidL
       
   825 // -----------------------------------------------------------------------------
       
   826 //
       
   827 TBool CUniSmsPlugin::IsServiceValidL()
       
   828     {
       
   829     // Not implemented.
       
   830     return ETrue;
       
   831     }
       
   832 
       
   833 
       
   834 // -----------------------------------------------------------------------------
       
   835 // SmsMtmL
       
   836 // -----------------------------------------------------------------------------
       
   837 //
       
   838 CSmsClientMtm* CUniSmsPlugin::SmsMtmL()
       
   839     {
       
   840     if ( !iSmsMtm )
       
   841         {        
       
   842         if ( !iMtmRegistry )
       
   843             {            
       
   844             iMtmRegistry = CClientMtmRegistry::NewL( iSession );
       
   845             }
       
   846         iSmsMtm = static_cast<CSmsClientMtm*>( iMtmRegistry->NewMtmL( KSenduiMtmSmsUid ) );
       
   847         }
       
   848     return iSmsMtm; 
       
   849     }
       
   850     
       
   851 // -----------------------------------------------------------------------------
       
   852 // DoCreateReplyOrForwardL
       
   853 // -----------------------------------------------------------------------------
       
   854 //
       
   855 TMsvId CUniSmsPlugin::DoCreateReplyOrForwardL( 
       
   856     TBool aReply, 
       
   857     TMsvId aSrc, 
       
   858     TMsvId aDest, 
       
   859     TMsvPartList aParts )
       
   860     {
       
   861     SmsMtmL()->SwitchCurrentEntryL( aSrc );
       
   862     
       
   863     CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
       
   864     
       
   865     CMsvOperation* oper = aReply
       
   866         ? SmsMtmL()->ReplyL( aDest, aParts, wait->iStatus )
       
   867         : SmsMtmL()->ForwardL( aDest, aParts, wait->iStatus );
       
   868         
       
   869     CleanupStack::PushL( oper );
       
   870     wait->Start();
       
   871 
       
   872     TMsvId newId;
       
   873     TPckgC<TMsvId> paramPack( newId );
       
   874     const TDesC8& progress = oper->FinalProgress();
       
   875     paramPack.Set( progress );
       
   876     newId = paramPack();
       
   877     CleanupStack::PopAndDestroy( oper );
       
   878     CleanupStack::PopAndDestroy( wait );
       
   879     
       
   880     return DoConvertFromL( newId, !aReply );   
       
   881     }
       
   882 
       
   883 // ----------------------------------------------------------------------------
       
   884 // MoveMessagesToOutboxL
       
   885 // ----------------------------------------------------------------------------
       
   886 void CUniSmsPlugin::MoveMessagesToOutboxL()
       
   887     {
       
   888     iStoreChanged = EFalse;
       
   889     if ( !iRecipients || !iRecipients->Count() )
       
   890         {
       
   891         User::Leave( KErrGeneral );
       
   892         }
       
   893 
       
   894     //we must create an entry selection for message copies
       
   895     CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection;
       
   896     CleanupStack::PushL( selection );
       
   897 
       
   898     CMsvEntry& entry = SmsMtmL()->Entry();
       
   899     TMsvEntry msvEntry( entry.Entry() );
       
   900     
       
   901     if ( iOfflineSupported && MsvUiServiceUtilitiesInternal::IsPhoneOfflineL() )  
       
   902     	{
       
   903     	msvEntry.SetSendingState( KMsvSendStateSuspended );
       
   904         msvEntry.iError = KErrGsmOfflineOpNotAllowed;
       
   905     	}	
       
   906     else
       
   907     	{
       
   908     	msvEntry.SetSendingState( KMsvSendStateWaiting );
       
   909     	}	
       
   910      
       
   911     CSmsHeader& header = SmsMtmL()->SmsHeader();  
       
   912     TBuf<KSmsMessageEntryDescriptionAmountOfChars> buf;
       
   913     
       
   914     if (!iBioMsg  )
       
   915         {
       
   916         ExtractDescriptionFromMessageL( 
       
   917             header.Message(), 
       
   918             buf, 
       
   919             KSmsMessageEntryDescriptionAmountOfChars );
       
   920         msvEntry.iDescription.Set( buf );
       
   921         } 
       
   922     
       
   923     CSmsNumber* rcpt = CSmsNumber::NewL();
       
   924     CleanupStack::PushL( rcpt );
       
   925 
       
   926     TPtrC name;
       
   927     TPtrC address;
       
   928     TBool cantExit = ETrue; 
       
   929     while ( cantExit )
       
   930         {
       
   931         HBufC* addressBuf = NULL;
       
   932         TPtr addressPtr( 0, 0);
       
   933         
       
   934         NameAndAddress( iRecipients->MdcaPoint(0) , name, address );
       
   935         UNILOGGER_WRITEF( _L("iRecipients: %S"),   &iRecipients->MdcaPoint(0) );       
       
   936  
       
   937         // set To-field stuff into the Details of the entry
       
   938         if ( name.Length() )
       
   939             {
       
   940             msvEntry.iDetails.Set( name );
       
   941             }
       
   942         else
       
   943             {
       
   944             // Internal data structures always holds the address data in western format.
       
   945             // UI is responsible of doing language specific conversions.    
       
   946             addressBuf = HBufC::NewLC( address.Length() );
       
   947             addressPtr.Set( addressBuf->Des() );
       
   948             addressPtr.Copy( address );
       
   949 
       
   950             AknTextUtils::ConvertDigitsTo( addressPtr, EDigitTypeWestern );      
       
   951             msvEntry.iDetails.Set( addressPtr );
       
   952             }
       
   953         UNILOGGER_WRITEF( _L("TMsvEntry::iDetails: %S"),   &msvEntry.iDetails );
       
   954         UNILOGGER_WRITEF( _L("TMsvEntry::iDescription: %S"),  &msvEntry.iDescription ); 
       
   955         TMsvId copyId;
       
   956        
       
   957         if ( iRecipients->Count() == 1 )
       
   958             {
       
   959             //Note that we came here also in case of many recipients. ...eventually.
       
   960             
       
   961             if ( IsEmailAddress( address ) )
       
   962                 {
       
   963                 FillEmailInformationDataL( header, address );              
       
   964                 //Let's remove the recipient and replace it with Email over SMS gateway address
       
   965                 //But let's first cehck if it exists
       
   966                 if( SmsMtmL( )->AddresseeList().Count() )
       
   967                 	{
       
   968                     SmsMtmL( )->RemoveAddressee( 0 );	
       
   969                 	}
       
   970                 SmsMtmL()->AddAddresseeL( 
       
   971 	            iEmailOverSmsC->Address( ) ,
       
   972 		        KNullDesC( ) );
       
   973                 iStoreChanged = ETrue;
       
   974                 }
       
   975             else
       
   976                 {                           
       
   977                 InsertSubjectL( header, SmsMtmL()->Body() );                                 
       
   978                 }
       
   979 
       
   980             entry.ChangeL( msvEntry );
       
   981             if( iStoreChanged )
       
   982                 {
       
   983             	SmsMtmL()->SaveMessageL();
       
   984                 }
       
   985             // Move it
       
   986             copyId = MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId );
       
   987             cantExit = EFalse;
       
   988             }
       
   989         else 
       
   990             {// Many recipients in array
       
   991             
       
   992             // Own copy function for Emails
       
   993             // This is because EmailOverSms messages can 
       
   994             // contain adresses longer than 21 digits
       
   995             if ( IsEmailAddress( address ) )
       
   996                 {
       
   997                 copyId = CreateMessageInOutboxL(
       
   998                 msvEntry, address );
       
   999 
       
  1000                 }
       
  1001             else // For MSISDN's
       
  1002                 {
       
  1003                 rcpt->SetAddressL( address );
       
  1004                 if ( name.Length() )
       
  1005                     { // add name only if we have alias
       
  1006                     rcpt->SetNameL( name );
       
  1007                     }
       
  1008                 
       
  1009                 copyId = CreateMessageInOutboxL(
       
  1010                     msvEntry, *rcpt, SmsMtmL()->Body());
       
  1011  
       
  1012                 SmsMtmL()->RemoveAddressee( 0 );
       
  1013                 iStoreChanged = ETrue;
       
  1014                 }
       
  1015             //If hundreds of recipient, make sure viewserver
       
  1016             //timers are reseted
       
  1017             if ( iRecipients->Count() > 100 && ( iRecipients->Count() ) % 30 == 0 )
       
  1018                 {
       
  1019                 User::ResetInactivityTime();
       
  1020                 }
       
  1021                 
       
  1022             iRecipients->Delete(0);   
       
  1023             }
       
  1024         if ( addressBuf )
       
  1025             {
       
  1026             CleanupStack::PopAndDestroy( addressBuf );
       
  1027             }
       
  1028         
       
  1029         // let's add the entry id into the cmsventryselection
       
  1030         selection->AppendL( copyId );
       
  1031         }
       
  1032     CleanupStack::PopAndDestroy( rcpt );    
       
  1033 
       
  1034 #ifdef USE_LOGGER 
       
  1035     for ( TInt i=0; i<selection->Count(); i++ ) 
       
  1036         {
       
  1037         SmsMtmL()->SwitchCurrentEntryL( selection->At(i) );
       
  1038         SmsMtmL()->LoadMessageL();
       
  1039         const CMsvRecipientList& testRecipients = SmsMtmL()->AddresseeList(); 
       
  1040         UNILOGGER_WRITEF( _L("Recipient: %S"), &(testRecipients[ 0 ]) ); 
       
  1041         UNILOGGER_WRITEF( _L("Body: %S"), &(SmsMtmL()->Body().Read( 0,80 )  ));   
       
  1042         UNILOGGER_WRITEF( _L("EmailOverSMS address: %S"), &iEmailOverSmsC->Address( ) );
       
  1043     	UNILOGGER_WRITEF( _L("EmailOverSMS name : %S"),   &iEmailOverSmsC->Name( ) );
       
  1044      
       
  1045         CSmsHeader& testHeader = SmsMtmL()->SmsHeader();
       
  1046         const CSmsEmailFields& testEmailFields = testHeader.EmailFields();
       
  1047         
       
  1048         if ( testEmailFields.Addresses().MdcaCount() )
       
  1049             {
       
  1050         	UNILOGGER_WRITEF( _L("CSmsEmailFields::iAddresses: %S"), &(testEmailFields.Addresses().MdcaPoint(0) ));
       
  1051             }
       
  1052         else
       
  1053             {
       
  1054             UNILOGGER_WRITEF(_L("CSmsEmailFields::iAddresses is empty"));	
       
  1055             }    
       
  1056         
       
  1057         
       
  1058         UNILOGGER_WRITEF( _L("CSmsEmailFields::iSubject : %S"),   &testEmailFields.Subject() );
       
  1059         
       
  1060         }  
       
  1061 #endif    
       
  1062     
       
  1063     //Let's free some memory
       
  1064     if ( iRecipients )
       
  1065         { 
       
  1066         delete iRecipients;	
       
  1067         iRecipients = NULL; 
       
  1068         }
       
  1069     
       
  1070     SetScheduledSendingStateL( selection );
       
  1071     CleanupStack::PopAndDestroy( selection ); 
       
  1072     }
       
  1073 
       
  1074 
       
  1075 // ----------------------------------------------------------------------------
       
  1076 // MoveMessageEntryL
       
  1077 // ----------------------------------------------------------------------------
       
  1078 TMsvId CUniSmsPlugin::MoveMessageEntryL( TMsvId aTarget )
       
  1079     {
       
  1080     TMsvEntry msvEntry( SmsMtmL()->Entry().Entry() );
       
  1081     TMsvId id = msvEntry.Id();
       
  1082     
       
  1083     if ( msvEntry.Parent() != aTarget )
       
  1084         {
       
  1085         TMsvSelectionOrdering sort;
       
  1086         sort.SetShowInvisibleEntries( ETrue );
       
  1087         CMsvEntry* parentEntry= CMsvEntry::NewL( iSession, msvEntry.Parent(), sort );
       
  1088         CleanupStack::PushL( parentEntry );
       
  1089         
       
  1090         // Copy original from the parent to the new location
       
  1091         CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
       
  1092 
       
  1093         CMsvOperation* op = parentEntry->MoveL(
       
  1094             msvEntry.Id(), 
       
  1095             aTarget, 
       
  1096             wait->iStatus );
       
  1097         
       
  1098         CleanupStack::PushL( op );
       
  1099         wait->Start();
       
  1100         TMsvLocalOperationProgress prog = McliUtils::GetLocalProgressL( *op );
       
  1101         User::LeaveIfError( prog.iError );
       
  1102 
       
  1103         id = prog.iId;
       
  1104         
       
  1105         CleanupStack::PopAndDestroy( op );
       
  1106         CleanupStack::PopAndDestroy( wait );
       
  1107         CleanupStack::PopAndDestroy( parentEntry );
       
  1108         }
       
  1109     
       
  1110     return id;
       
  1111     }
       
  1112 
       
  1113 // ----------------------------------------------------------------------------
       
  1114 // CreateMessageInOutboxL
       
  1115 // Use this function for non-email messages
       
  1116 // ----------------------------------------------------------------------------
       
  1117 TMsvId CUniSmsPlugin::CreateMessageInOutboxL(
       
  1118     const TMsvEntry& aEntry, 
       
  1119     const CSmsNumber& aRecipient, 
       
  1120     const CRichText& aBody )
       
  1121     {
       
  1122     // Initialize the richtext object
       
  1123     CRichText* richText = CRichText::NewL( iParaFormatLayer, iCharFormatLayer );
       
  1124     CleanupStack::PushL( richText );
       
  1125     
       
  1126     // Initialise header and store
       
  1127     CSmsHeader* header = CSmsHeader::NewL( CSmsPDU::ESmsSubmit, *richText );
       
  1128     CleanupStack::PushL( header );
       
  1129     CMsvStore* sourceStore = SmsMtmL()->Entry().ReadStoreL();
       
  1130     CleanupStack::PushL( sourceStore );
       
  1131     
       
  1132     // Read store
       
  1133     header->RestoreL( *sourceStore );
       
  1134 
       
  1135     // Initialise number with parameters
       
  1136     CSmsNumber* rcpt = CSmsNumber::NewL( aRecipient );
       
  1137     CleanupStack::PushL( rcpt );
       
  1138     header->Recipients().ResetAndDestroy();
       
  1139     header->Recipients().AppendL( rcpt );
       
  1140     CleanupStack::Pop( rcpt );  
       
  1141     
       
  1142     // Create entry to Outbox
       
  1143     TMsvEntry entry( aEntry );
       
  1144     entry.iMtmData3 = KSmsPluginBioMsgUnparsed;
       
  1145     CMsvEntry* outbox = iSession.GetEntryL( KMsvGlobalOutBoxIndexEntryId );
       
  1146     CleanupStack::PushL( outbox );
       
  1147     outbox->CreateL( entry );
       
  1148     iSession.CleanupEntryPushL( entry.Id() );
       
  1149     outbox->SetEntryL( entry.Id());
       
  1150     
       
  1151     //Initialize target store
       
  1152     CMsvStore* targetStore;
       
  1153     targetStore = outbox->EditStoreL();
       
  1154     CleanupStack::PushL( targetStore );
       
  1155     
       
  1156     //Add attachment  
       
  1157     MMsvAttachmentManager& attaManager = sourceStore->AttachmentManagerL(); 
       
  1158     RFile tmpFile;
       
  1159      
       
  1160     //Check if attachment exists and add it  
       
  1161     if( sourceStore->AttachmentManagerL().AttachmentCount() )
       
  1162     	{       	    		    		
       
  1163         tmpFile = attaManager.GetAttachmentFileL( 0 );      
       
  1164     	CleanupClosePushL( tmpFile );  
       
  1165     		
       
  1166     	MMsvAttachmentManager& targetAttaMan = targetStore->AttachmentManagerL();
       
  1167 		CMsvAttachment* targetAtta = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
  1168 		CleanupStack::PushL( targetAtta );
       
  1169 
       
  1170         CMuiuOperationWait* waiter = CMuiuOperationWait::NewLC(); 
       
  1171 		targetAttaMan.AddAttachmentL( tmpFile, targetAtta, waiter->iStatus );			
       
  1172 		waiter->Start();
       
  1173 
       
  1174      	CleanupStack::PopAndDestroy( waiter ); //waiter 
       
  1175 		CleanupStack::Pop(targetAtta );// targetAtta
       
  1176 		CleanupStack::Pop( &tmpFile );//tmpFile
       
  1177     	}
       
  1178     
       
  1179     TInt totalLength( aBody.DocumentLength() );
       
  1180     HBufC* bodyText = HBufC::NewLC ( totalLength ); 
       
  1181     TPtr bodyTextPtr ( bodyText->Des() ); 
       
  1182     
       
  1183     aBody.Extract( bodyTextPtr, 0, totalLength );
       
  1184     richText->InsertL( 0, bodyTextPtr );
       
  1185     CleanupStack::PopAndDestroy( bodyText );
       
  1186 
       
  1187     InsertSubjectL( *header, *richText );
       
  1188                 
       
  1189     targetStore->StoreBodyTextL( *richText );
       
  1190     
       
  1191     header->StoreL( *targetStore );
       
  1192     targetStore->CommitL();
       
  1193        
       
  1194     // Usually SMCM takes care of updating iSize, but now when msg is
       
  1195     // created to Outbox for several recipients this has to be done manually.
       
  1196     entry.iSize = targetStore->SizeL();
       
  1197     entry.iRelatedId = iSmsServiceId;
       
  1198     entry.iServiceId = KMsvLocalServiceIndexEntryId;
       
  1199     outbox->ChangeL( entry );
       
  1200     CleanupStack::PopAndDestroy( targetStore );
       
  1201     
       
  1202     iSession.CleanupEntryPop();
       
  1203     CleanupStack::PopAndDestroy( outbox ); 
       
  1204     CleanupStack::PopAndDestroy( sourceStore );
       
  1205     CleanupStack::PopAndDestroy( header );
       
  1206     CleanupStack::PopAndDestroy( richText );
       
  1207     return entry.Id();
       
  1208     }
       
  1209 
       
  1210 // ---------------------------------------------------------
       
  1211 // CMsgSmsEditorAppUi::CreateMessageInOutboxL
       
  1212 // Creates message in outbox in case of multiple recipients 
       
  1213 // with some e-mail over SMS addresses
       
  1214 // ---------------------------------------------------------
       
  1215 TMsvId CUniSmsPlugin::CreateMessageInOutboxL(
       
  1216     const TMsvEntry& aEntry, 
       
  1217     const TDesC& aAddress )
       
  1218     {
       
  1219     CRichText* richText = CRichText::NewL( iParaFormatLayer, iCharFormatLayer );
       
  1220     CleanupStack::PushL( richText );
       
  1221     // Initialise header and store
       
  1222     CSmsHeader* header = CSmsHeader::NewL( CSmsPDU::ESmsSubmit, *richText );
       
  1223     CleanupStack::PushL( header );
       
  1224     CMsvStore* store = SmsMtmL()->Entry().ReadStoreL();
       
  1225      
       
  1226     CleanupStack::PushL( store );
       
  1227     // Read store
       
  1228     header->RestoreL( *store );
       
  1229     CleanupStack::PopAndDestroy( store );
       
  1230     // Initialise number
       
  1231     CSmsNumber* rcpt = CSmsNumber::NewL();
       
  1232     CleanupStack::PushL( rcpt );
       
  1233     header->Recipients().ResetAndDestroy();
       
  1234     // Save Email specific information in header
       
  1235     FillEmailInformationDataL( *header, aAddress );
       
  1236     // Fill the recipient data for Email
       
  1237     // Address = Email gateway
       
  1238     // Alias = The real address
       
  1239     rcpt->SetAddressL( iEmailOverSmsC->Address()  );
       
  1240     rcpt->SetNameL( aAddress ); // This takes only 21 chars
       
  1241 
       
  1242     header->Recipients().AppendL( rcpt );
       
  1243     CleanupStack::Pop( rcpt );
       
  1244     // Create entry to Outbox
       
  1245     TMsvEntry entry( aEntry );
       
  1246     entry.iMtmData3 = KSmsPluginBioMsgUnparsed;
       
  1247      
       
  1248     CMsvEntry* outbox = iSession.GetEntryL( KMsvGlobalOutBoxIndexEntryId );
       
  1249     CleanupStack::PushL( outbox );
       
  1250     outbox->CreateL( entry );
       
  1251     iSession.CleanupEntryPushL( entry.Id());
       
  1252     outbox->SetEntryL( entry.Id());
       
  1253     // Save 
       
  1254     store = outbox->EditStoreL();
       
  1255     CleanupStack::PushL( store );
       
  1256     header->StoreL( *store );
       
  1257     
       
  1258     richText->Reset();
       
  1259     richText->InsertL( 0 , SmsMtmL()->Body().Read( 0 ) );
       
  1260     
       
  1261     store->StoreBodyTextL( *richText );
       
  1262     store->CommitL();
       
  1263     // Usually SMCM takes care of updating iSize, but now when msg is
       
  1264     // created to Outbox for several recipients this has to be done manually.
       
  1265     entry.iSize = store->SizeL();
       
  1266     entry.iRelatedId = iSmsServiceId;
       
  1267     entry.iServiceId = KMsvLocalServiceIndexEntryId;
       
  1268     outbox->ChangeL( entry );
       
  1269     
       
  1270     CleanupStack::PopAndDestroy( store );
       
  1271     iSession.CleanupEntryPop();
       
  1272     CleanupStack::PopAndDestroy( outbox );
       
  1273     CleanupStack::PopAndDestroy( header );
       
  1274     CleanupStack::PopAndDestroy( richText );
       
  1275     return entry.Id();
       
  1276     }
       
  1277 
       
  1278 // ----------------------------------------------------------------------------
       
  1279 // SetScheduledSendingStateL
       
  1280 // ----------------------------------------------------------------------------
       
  1281 void CUniSmsPlugin::SetScheduledSendingStateL( CMsvEntrySelection* aSelection )
       
  1282     {
       
  1283     const TMsvEntry msvEntry = SmsMtmL()->Entry().Entry();
       
  1284     if ( msvEntry.SendingState() == KMsvSendStateWaiting )
       
  1285         {
       
  1286         // Add entry to task scheduler
       
  1287         TBuf8<1> dummyParams;
       
  1288 
       
  1289         CMuiuOperationWait* waiter = CMuiuOperationWait::NewLC();
       
  1290         waiter->iStatus = KRequestPending;
       
  1291 
       
  1292         CMsvOperation* op= SmsMtmL()->InvokeAsyncFunctionL(
       
  1293             ESmsMtmCommandScheduleCopy,
       
  1294             *aSelection,
       
  1295             dummyParams,
       
  1296             waiter->iStatus );
       
  1297         CleanupStack::PushL( op );
       
  1298         waiter->Start();
       
  1299         
       
  1300         CleanupStack::PopAndDestroy( op );  
       
  1301         CleanupStack::PopAndDestroy( waiter );
       
  1302         } 
       
  1303     }
       
  1304 
       
  1305 // ----------------------------------------------------------------------------
       
  1306 // NameAndAddress
       
  1307 // ----------------------------------------------------------------------------
       
  1308 void CUniSmsPlugin::NameAndAddress( const TDesC& aMsvAddress, TPtrC& aName, TPtrC& aAddress )
       
  1309     {
       
  1310     TInt addressStart = aMsvAddress.LocateReverse( KMsgSmsAddressStartChar );
       
  1311     TInt addressEnd = aMsvAddress.LocateReverse( KMsgSmsAddressEndChar );
       
  1312 
       
  1313     if ( addressStart != KErrNotFound && addressEnd != KErrNotFound 
       
  1314         && addressEnd > addressStart )
       
  1315         {
       
  1316         // verified address, will be used as selected from contacts manager
       
  1317         aName.Set( aMsvAddress.Ptr(), addressStart );
       
  1318         aAddress.Set( 
       
  1319             aMsvAddress.Mid( addressStart + 1 ).Ptr(), 
       
  1320             ( addressEnd - addressStart ) -1 );
       
  1321         if ( !aAddress.Length())
       
  1322             {
       
  1323             aAddress.Set( aName );
       
  1324             aName.Set( KNullDesC ); // empty string
       
  1325             }
       
  1326         }
       
  1327     else
       
  1328         {
       
  1329         // unverified string, will be used as entered in the header field
       
  1330         aName.Set( KNullDesC ); // empty string
       
  1331         aAddress.Set( aMsvAddress.Ptr(), aMsvAddress.Length() ); // a whole string to address
       
  1332         }
       
  1333     
       
  1334     if ( aName.CompareF( aAddress ) == 0 )
       
  1335         {
       
  1336         aName.Set( KNullDesC ); // empty string
       
  1337         }
       
  1338     }
       
  1339 
       
  1340 // ----------------------------------------------------------------------------
       
  1341 // CUniSmsPlugin::ExtractDescriptionFromMessageL
       
  1342 // ----------------------------------------------------------------------------
       
  1343 void CUniSmsPlugin::ExtractDescriptionFromMessageL(
       
  1344     const CSmsMessage& aMessage, 
       
  1345     TDes& aDescription, 
       
  1346     TInt aMaxLength)
       
  1347     {  
       
  1348     if ( iUniMtm.SubjectL().Length() )
       
  1349         {
       
  1350         aDescription.Copy( iUniMtm.SubjectL() );
       
  1351         }
       
  1352     else
       
  1353         {// Extract from message body
       
  1354         aMessage.Buffer().Extract(
       
  1355             aDescription, 
       
  1356             0, 
       
  1357             Min( 
       
  1358                 aMaxLength, 
       
  1359                 aMessage.Buffer().Length()));
       
  1360         }
       
  1361 
       
  1362     //replace paragraphs with spaces.
       
  1363     TBuf<KSmsEdExtrDescReplaceCharacterCount> replaceChars;
       
  1364     replaceChars.Zero();
       
  1365     replaceChars.Append( CEditableText::EParagraphDelimiter );
       
  1366     replaceChars.Append( KSmsEdUnicodeLFSupportedByBasicPhones );
       
  1367     replaceChars.Append( CEditableText::ELineBreak );
       
  1368     AknTextUtils::ReplaceCharacters(
       
  1369         aDescription, 
       
  1370         replaceChars, 
       
  1371         CEditableText::ESpace );
       
  1372 
       
  1373     aDescription.Trim();
       
  1374     }
       
  1375 
       
  1376 // ----------------------------------------------------------------------------
       
  1377 // CreatePlainTextSMSL 
       
  1378 // ----------------------------------------------------------------------------
       
  1379 void CUniSmsPlugin::CreatePlainTextSMSL( RFile& aFile)
       
  1380     {       
       
  1381     RFileReadStream stream( aFile );
       
  1382     CleanupClosePushL( stream );
       
  1383           
       
  1384     CPlainText::TImportExportParam param;
       
  1385     param.iForeignEncoding = KCharacterSetIdentifierUtf8;
       
  1386     param.iOrganisation = CPlainText::EOrganiseByParagraph; 
       
  1387             
       
  1388     CPlainText::TImportExportResult result;
       
  1389     
       
  1390     SmsMtmL()->Body().ImportTextL( 0, stream, param, result );
       
  1391                     
       
  1392     CleanupStack::PopAndDestroy( &stream );        
       
  1393     }
       
  1394     
       
  1395 // ----------------------------------------------------------------------------
       
  1396 // InsertSubjectL
       
  1397 // Insert subject for non email addresses into the body
       
  1398 // ----------------------------------------------------------------------------
       
  1399 void CUniSmsPlugin::InsertSubjectL( CSmsHeader& aHeader, CRichText& aText  ) 
       
  1400     {
       
  1401     if ( iUniMtm.SubjectL().Length() && !iBioMsg )
       
  1402         {
       
  1403         TPtrC subject = iUniMtm.SubjectL();
       
  1404         TInt writePosition = subject.Length()+2;//+2 for the parentesis
       
  1405     
       
  1406         if ( subject.Locate( KUniSmsStartParenthesis )!= KErrNotFound ||
       
  1407             subject.Locate( KUniSmsEndParenthesis ) != KErrNotFound)
       
  1408             {
       
  1409             HBufC* modifiableSubject = subject.Alloc();
       
  1410             CleanupStack::PushL(modifiableSubject);
       
  1411             TPtr ptr = modifiableSubject->Des();
       
  1412             
       
  1413             TBuf<1> replaceChars;
       
  1414             replaceChars.Zero();
       
  1415             replaceChars.Append( KUniSmsStartParenthesis );
       
  1416             // Replace '(' chars with '<'
       
  1417             AknTextUtils::ReplaceCharacters(
       
  1418                 ptr, 
       
  1419                 replaceChars, 
       
  1420                 TChar('<') );
       
  1421             
       
  1422             replaceChars.Zero();
       
  1423             replaceChars.Append( KUniSmsEndParenthesis );    
       
  1424         
       
  1425             // Replace ')' chars with '>'
       
  1426             AknTextUtils::ReplaceCharacters(
       
  1427                 ptr, 
       
  1428                 replaceChars, 
       
  1429                 TChar('>') );  
       
  1430             
       
  1431             aText.InsertL( 0, KUniSmsStartParenthesis );
       
  1432             aText.InsertL( 1, ptr );
       
  1433             aText.InsertL( writePosition-1, KUniSmsEndParenthesis );
       
  1434             CleanupStack::PopAndDestroy( modifiableSubject );
       
  1435             }
       
  1436  
       
  1437         else
       
  1438             {
       
  1439             aText.InsertL( 0, KUniSmsStartParenthesis );
       
  1440             aText.InsertL( 1, subject );
       
  1441             aText.InsertL( writePosition-1, KUniSmsEndParenthesis );
       
  1442             }
       
  1443         iStoreChanged = ETrue;
       
  1444         }
       
  1445     
       
  1446     // Clears the CSmsHeaders EmailFields for non Email addresses
       
  1447     CSmsEmailFields* emailFields = CSmsEmailFields::NewL();
       
  1448     CleanupStack::PushL( emailFields );
       
  1449     aHeader.SetEmailFieldsL( *emailFields );
       
  1450     CleanupStack::PopAndDestroy( emailFields );  
       
  1451         iStoreChanged = ETrue;
       
  1452     }
       
  1453            
       
  1454 // ----------------------------------------------------------------------------
       
  1455 // CreateVCardSMS
       
  1456 // ----------------------------------------------------------------------------
       
  1457 void CUniSmsPlugin::CreateVCardSMSL( RFile& aFile )
       
  1458     {   
       
  1459     TInt fileSize;
       
  1460     TInt err ( aFile.Size( fileSize ) );
       
  1461     User::LeaveIfError(err);
       
  1462     
       
  1463     // Create two buffers: 8-bit for reading from file and 16-bit for
       
  1464     // converting to 16-bit format
       
  1465     HBufC8* buf8 = HBufC8::NewLC( fileSize );
       
  1466     TPtr8 ptr8 = buf8->Des();
       
  1467     HBufC16* buf16 = HBufC16::NewLC( fileSize );
       
  1468     TPtr16 ptr16 = buf16->Des();
       
  1469 
       
  1470     for (TInt err = aFile.Read(ptr8); 
       
  1471         ptr8.Length() > 0; 
       
  1472         err = aFile.Read(ptr8))
       
  1473         {
       
  1474         User::LeaveIfError(err);
       
  1475         ptr16.Copy(ptr8);
       
  1476         SmsMtmL()->Body().InsertL(SmsMtmL()->Body().DocumentLength(), ptr16);
       
  1477         }
       
  1478 
       
  1479     // Cleanup and return
       
  1480     CleanupStack::PopAndDestroy( buf16 );   
       
  1481     CleanupStack::PopAndDestroy( buf8 );   
       
  1482     }
       
  1483         
       
  1484 // ----------------------------------------------------------------------------
       
  1485 // CreateVCalSMS
       
  1486 // ----------------------------------------------------------------------------
       
  1487 void CUniSmsPlugin::CreateVCalSMSL( RFile& aFile )
       
  1488     {
       
  1489     TInt err (KErrNone);
       
  1490     TInt fileSize;
       
  1491     err = aFile.Size( fileSize );
       
  1492     User::LeaveIfError(err);
       
  1493      
       
  1494     HBufC8* buf8 = HBufC8::NewLC( fileSize );
       
  1495     TPtr8 ptr8 = buf8->Des();
       
  1496     
       
  1497     err = aFile.Read( ptr8 );
       
  1498     User::LeaveIfError(err);
       
  1499     
       
  1500     HBufC16* buf16 = HBufC16::NewLC( fileSize );
       
  1501     TPtr16 ptr16 = buf16->Des();
       
  1502    
       
  1503     ptr16.Copy(ptr8);
       
  1504     SmsMtmL()->Body().InsertL(0, ptr16);
       
  1505     
       
  1506     CleanupStack::PopAndDestroy( buf16 );
       
  1507     CleanupStack::PopAndDestroy( buf8 );
       
  1508     }
       
  1509 
       
  1510 // ----------------------------------------------------------------------------
       
  1511 // CUniSmsPlugin::ValidateSCNumberL
       
  1512 // ----------------------------------------------------------------------------
       
  1513 TBool CUniSmsPlugin::ValidateSCNumberL()
       
  1514     {
       
  1515     TBool valid( ETrue );
       
  1516     if ( iSmsHeader->Message().ServiceCenterAddress().Length() == 0 ||
       
  1517          !iSmsHeader->ReplyPathProvided() )
       
  1518         {
       
  1519         if ( !SmsMtmL()->ServiceSettings().ServiceCenterCount() )
       
  1520             {
       
  1521             if ( !SmsScDialogL())
       
  1522                 {
       
  1523                 valid = EFalse;
       
  1524                 }
       
  1525             else
       
  1526                 {
       
  1527                 valid = ETrue;    
       
  1528                 CSmsServiceCenter& sc = SmsMtmL()->ServiceSettings().GetServiceCenter( 0 );
       
  1529 
       
  1530 			    // Update service settings' sc address list and set it to default.
       
  1531 	            SmsMtmL()->ServiceSettings().SetDefaultServiceCenter( 0 ); 
       
  1532 	                
       
  1533 	            CSmsAccount* smsAccount = CSmsAccount::NewLC();
       
  1534 	            smsAccount->SaveSettingsL( SmsMtmL()->ServiceSettings() );
       
  1535 	            CleanupStack::PopAndDestroy( smsAccount );  
       
  1536 	
       
  1537 			    // Set the SC addres for this message
       
  1538                 iSmsHeader->Message().SetServiceCenterAddressL( 
       
  1539                 	sc.Address() );
       
  1540                 }
       
  1541             }
       
  1542         else
       
  1543             {
       
  1544             //Else use the default - or then the first one on the sc address list.
       
  1545             TInt index = Max( 0, SmsMtmL()->ServiceSettings().DefaultServiceCenter() );
       
  1546             CSmsServiceCenter& sc = SmsMtmL()->ServiceSettings().GetServiceCenter( index );
       
  1547             iSmsHeader->Message().SetServiceCenterAddressL( sc.Address() );
       
  1548             }
       
  1549         }
       
  1550     return valid;
       
  1551     }
       
  1552 
       
  1553 // ---------------------------------------------------------
       
  1554 // CUniSmsPlugin::ValidateSCNumberForEmailOverSmsL
       
  1555 // ---------------------------------------------------------
       
  1556 TBool CUniSmsPlugin::ValidateSCNumberForEmailOverSmsL()
       
  1557     {
       
  1558     TBool confNeeded( EFalse );
       
  1559     // Read the email settings
       
  1560     TBuf<KUniSmsSCStringLength> emailSmscNumber;
       
  1561     TBuf<KUniSmsSCStringLength> emailGateWayNumber;
       
  1562     TBool notUsed( EFalse );
       
  1563     // The file may not exist
       
  1564     TInt readResult = SmumUtil::ReadEmailOverSmsSettingsL( 
       
  1565                         emailSmscNumber,
       
  1566                         emailGateWayNumber,
       
  1567                         notUsed );
       
  1568     if ( KErrNone == readResult )
       
  1569         {
       
  1570         // Check that both have valid values
       
  1571         // In any otther case we need to show the conf pop-up window
       
  1572         if ( emailSmscNumber == KNullDesC )
       
  1573             {
       
  1574             // Use the sms smsc as default
       
  1575             CSmsSettings* serviceSettings = &( SmsMtmL()->ServiceSettings() );
       
  1576             
       
  1577             if ( SmsMtmL()->ServiceSettings().DefaultServiceCenter() > 0 )
       
  1578                 {
       
  1579                 emailSmscNumber = 
       
  1580                 	serviceSettings->GetServiceCenter( 
       
  1581                 	    SmsMtmL()->ServiceSettings().DefaultServiceCenter() ).Address();
       
  1582                 }
       
  1583             else
       
  1584                 {
       
  1585                 emailSmscNumber = 
       
  1586                 	serviceSettings->GetServiceCenter( 0 ).Address();
       
  1587                 }
       
  1588             confNeeded = ETrue;
       
  1589             }
       
  1590         if ( emailGateWayNumber == KNullDesC )
       
  1591             {
       
  1592             confNeeded = ETrue;
       
  1593             }
       
  1594         }
       
  1595     else
       
  1596         {
       
  1597         confNeeded = ETrue;
       
  1598         }
       
  1599     if ( confNeeded ) // Show the query
       
  1600         {
       
  1601         CUniSmsEMultilineQueryDialog* dlg = 
       
  1602             CUniSmsEMultilineQueryDialog::NewL( 
       
  1603                 emailGateWayNumber, 
       
  1604                 emailSmscNumber, 
       
  1605                 ETrue );
       
  1606         if ( dlg->ExecuteLD( R_ADDEMAILSC_QUERY ) )
       
  1607             {
       
  1608             // Save settings to Smum
       
  1609             SmumUtil::WriteEmailOverSmsSettingsL( 
       
  1610                         emailSmscNumber,        
       
  1611                         emailGateWayNumber,
       
  1612                         ETrue );
       
  1613             }
       
  1614         else
       
  1615             {
       
  1616             return EFalse;
       
  1617             }
       
  1618         }
       
  1619     // Use them
       
  1620     iEmailOverSmsC->SetNameL( emailSmscNumber );
       
  1621 	iEmailOverSmsC->SetAddressL( emailGateWayNumber );
       
  1622 	return ETrue;
       
  1623     }
       
  1624 
       
  1625 // ----------------------------------------------------------------------------
       
  1626 // CUniSmsPlugin::SmsScDialogL
       
  1627 // ----------------------------------------------------------------------------
       
  1628 TBool CUniSmsPlugin::SmsScDialogL()
       
  1629     {
       
  1630     TBuf<KUniSmsSCStringLength> name;
       
  1631     TBuf<KUniSmsSCStringLength> number;
       
  1632     TBool retVal = EFalse;
       
  1633      
       
  1634     // Read the default name
       
  1635     SmumUtil::FindDefaultNameForSCL( name, EFalse );
       
  1636     CUniSmsEMultilineQueryDialog* dlg = 
       
  1637         CUniSmsEMultilineQueryDialog::NewL( name, number );
       
  1638     if ( dlg->ExecuteLD( R_ADDSC_QUERY ) )
       
  1639         {	
       
  1640         retVal = ETrue;
       
  1641         if ( !name.Length())
       
  1642             {
       
  1643             // read default name again 
       
  1644             SmumUtil::FindDefaultNameForSCL( name, EFalse );
       
  1645             }        
       
  1646         SmsMtmL()->ServiceSettings().AddServiceCenterL( name, number );
       
  1647         }
       
  1648     return retVal;
       
  1649     }
       
  1650 
       
  1651 // ---------------------------------------------------------
       
  1652 // CUniSmsPlugin::FillEmailInformationDataL
       
  1653 // ---------------------------------------------------------
       
  1654 void CUniSmsPlugin::FillEmailInformationDataL( 
       
  1655     CSmsHeader& aHeader, 
       
  1656     const TPtrC& aAddress ) 
       
  1657     {
       
  1658     UNILOGGER_ENTERFN( "CUniSmsPlugin::FillEmailInformationDataL()" )
       
  1659  
       
  1660     CSmsEmailFields* emailFields = CSmsEmailFields::NewL();
       
  1661     CleanupStack::PushL( emailFields );
       
  1662 
       
  1663     // The Email SMSC may differ from sms SMSC
       
  1664     UNILOGGER_WRITEF( _L("Set EMailOverSMS SC: %S"), &iEmailOverSmsC->Name() );
       
  1665     aHeader.Message().SetServiceCenterAddressL( iEmailOverSmsC->Name() );
       
  1666         
       
  1667     // Check if there is need to save as EmailFieds with header
       
  1668     if ( aAddress.Length() ) 
       
  1669         {
       
  1670         // Set the address
       
  1671         UNILOGGER_WRITEF( _L("Recipient: %S"), &aAddress );
       
  1672         emailFields->AddAddressL( aAddress );
       
  1673         }
       
  1674            
       
  1675     if ( iUniMtm.SubjectL().Length() )
       
  1676         { // Handle the subject
       
  1677         HBufC* buf = iUniMtm.SubjectL().AllocL();
       
  1678         CleanupStack::PushL( buf );
       
  1679         TPtr text = buf->Des();    
       
  1680            
       
  1681         TBuf<1> replaceChars;
       
  1682         replaceChars.Zero();
       
  1683         replaceChars.Append( KUniSmsStartParenthesis );
       
  1684         // Replace '(' chars with '<'
       
  1685         AknTextUtils::ReplaceCharacters(
       
  1686             text, 
       
  1687             replaceChars, 
       
  1688             TChar('<') );
       
  1689             
       
  1690         replaceChars.Zero();
       
  1691         replaceChars.Append( KUniSmsEndParenthesis );
       
  1692         // Replace ')' chars with '>'
       
  1693         AknTextUtils::ReplaceCharacters(
       
  1694             text, 
       
  1695             replaceChars, 
       
  1696             TChar('>') );
       
  1697             
       
  1698         // For Emails save it to CSmsEmailFields
       
  1699         emailFields->SetSubjectL( text );
       
  1700         CleanupStack::PopAndDestroy( buf ); 
       
  1701         }  
       
  1702      
       
  1703         
       
  1704     aHeader.SetEmailFieldsL( *emailFields );
       
  1705     CleanupStack::PopAndDestroy( emailFields ); 
       
  1706     UNILOGGER_LEAVEFN( "CUniSmsPlugin::FillEmailInformationDataL()" )
       
  1707     } 
       
  1708 
       
  1709 
       
  1710 
       
  1711 // ----------------------------------------------------
       
  1712 //  CUniSmsPlugin::IsEmailAddress()
       
  1713 // ----------------------------------------------------
       
  1714 TBool CUniSmsPlugin::IsEmailAddress( const TPtrC& aAddress ) const
       
  1715     {
       
  1716     UNILOGGER_ENTERFN( "CMsgSmsEmailOverSmsFunc::IsEmailAddress()" )
       
  1717     TBool isEmailAddress( EFalse );
       
  1718     if (  aAddress.Locate('@')  != KErrNotFound)
       
  1719         {
       
  1720         UNILOGGER_WRITEF(
       
  1721             _L("IsEmailAddress - Address: %s"), aAddress.Ptr() );
       
  1722         isEmailAddress = ETrue;
       
  1723         }
       
  1724     UNILOGGER_LEAVEFN( "CMsgSmsEmailOverSmsFunc::IsEmailAddress()" )
       
  1725     return isEmailAddress;
       
  1726     }
       
  1727     
       
  1728 // ----------------------------------------------------------------------------
       
  1729 // Panic
       
  1730 // ----------------------------------------------------------------------------
       
  1731 GLDEF_C void Panic( TInt aCategory )
       
  1732     {
       
  1733     _LIT( KUniSmsPluginPanic, "CUniSmsPlugin-Panic" );
       
  1734     User::Panic( KUniSmsPluginPanic, aCategory );
       
  1735     }
       
  1736 
       
  1737 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
  1738 
       
  1739 // ------------------------------------------------------------------------------------------------
       
  1740 // ImplementationProxy
       
  1741 // -----------------------------------------------------------------------------
       
  1742 //
       
  1743 EXPORT_C const TImplementationProxy* ImplementationGroupProxy( TInt& aTableCount )
       
  1744 	{
       
  1745 	aTableCount = sizeof( KImplementationTable ) / sizeof( TImplementationProxy );
       
  1746 	return KImplementationTable;
       
  1747 	}
       
  1748 
       
  1749 //------------------------------------------------------------------------------
       
  1750 // CUniSmsPlugin::SetEncodingSetings
       
  1751 // Turkish SMS-PREQ2265 Specific
       
  1752 // To Set encoding settings like encoding type, character support
       
  1753 // and alternative encoding if any
       
  1754 // 
       
  1755 // IMPORTANT NOTE: 
       
  1756 // This function is usually called from UniEditorAppUI to reset/set alternative encoding or char support
       
  1757 // when corresponding feilds change. Hence aUnicodeMode is always set to false
       
  1758 //------------------------------------------------------------------------------
       
  1759 void CUniSmsPlugin::SetEncodingSettings( TBool aUnicodeMode, TSmsEncoding aAlternativeEncodingType, TInt aCharSupportType)
       
  1760     {
       
  1761     UNILOGGER_WRITE_TIMESTAMP("CUniSmsPlugin::SetEncodingSettings Start <<<---- ");
       
  1762     TSmsUserDataSettings smsSettings;
       
  1763     CSmsMessage& smsMsg = iSmsHeader->Message();
       
  1764     TBool settingsChanged = EFalse;
       
  1765     
       
  1766     iCharSupportType = aCharSupportType;
       
  1767     iAlternativeEncodingType = aAlternativeEncodingType;
       
  1768     if( iUnicodeMode != aUnicodeMode )
       
  1769         {
       
  1770         iUnicodeMode = aUnicodeMode;
       
  1771     if(iUnicodeMode)
       
  1772         {
       
  1773         smsSettings.SetAlphabet( TSmsDataCodingScheme::ESmsAlphabetUCS2 );
       
  1774         }
       
  1775     else
       
  1776         {
       
  1777         smsSettings.SetAlphabet( TSmsDataCodingScheme::ESmsAlphabet7Bit );
       
  1778         }
       
  1779         settingsChanged = ETrue;
       
  1780         }
       
  1781     if( smsSettings.TextCompressed())
       
  1782         {
       
  1783     smsSettings.SetTextCompressed( EFalse );
       
  1784         settingsChanged = ETrue;
       
  1785         }
       
  1786     if( settingsChanged )
       
  1787         {
       
  1788     TRAP_IGNORE(smsMsg.SetUserDataSettingsL( smsSettings ));
       
  1789 #ifdef USE_LOGGER
       
  1790         UNILOGGER_WRITE("SetEncodingSettings: SetUserDataSettingsL");
       
  1791 #endif /* USE_LOGGER */
       
  1792         }
       
  1793     //First try without any alternate encoding
       
  1794     if( aAlternativeEncodingType != smsMsg.Alternative7bitEncoding() )
       
  1795         {
       
  1796         smsMsg.SetAlternative7bitEncoding( aAlternativeEncodingType );// Optimal
       
  1797 #ifdef USE_LOGGER
       
  1798         UNILOGGER_WRITEF(_L("SetEncodingSettings: aAlternativeEncodingType-> %d"), aAlternativeEncodingType);
       
  1799 #endif /* USE_LOGGER */
       
  1800     }
       
  1801     UNILOGGER_WRITE_TIMESTAMP("CUniSmsPlugin::SetEncodingSettings End ---->>> ");
       
  1802     }
       
  1803 //------------------------------------------------------------------------------
       
  1804 // CUniSmsPlugin::GetNumPDUsL
       
  1805 // Turkish SMS-PREQ2265 Specific
       
  1806 // To get PDU Info: extracts details of number of PDUs, number of remaining chars in last PDU
       
  1807 // and encoding types used.
       
  1808 //------------------------------------------------------------------------------
       
  1809 void CUniSmsPlugin::GetNumPDUsL( 
       
  1810         TDesC& aBuf,
       
  1811         TInt& aNumOfRemainingChars,
       
  1812         TInt& aNumOfPDUs,
       
  1813         TBool& aUnicodeMode, 
       
  1814         TSmsEncoding & aAlternativeEncodingType )
       
  1815     {
       
  1816     UNILOGGER_WRITE_TIMESTAMP("<<<<<<<<---------------------CUniSmsPlugin::GetNumPDUsL Start: ");
       
  1817     TInt numOfUnconvChars, numOfDowngradedChars, isAltEncSupported;
       
  1818     TSmsEncoding currentAlternativeEncodingType;
       
  1819 
       
  1820     CSmsMessage& smsMsg = iSmsHeader->Message();
       
  1821     
       
  1822 #ifdef USE_LOGGER
       
  1823     HBufC* tempBuff = HBufC::NewL( aBuf.Length() + 2 );
       
  1824     tempBuff->Des().Copy( aBuf );
       
  1825     UNILOGGER_WRITEF(_L("GetNumPDUsL:->> Buf Length: %d"), aBuf.Length() );
       
  1826     UNILOGGER_WRITEF(_L("GetNumPDUsL:->> buffer    : %s"), tempBuff->Des().PtrZ() );
       
  1827     delete tempBuff;
       
  1828 #endif /* USE_LOGGER */
       
  1829     // need to set the input buffer to SMS buffer through iRichText(which is reference to SMS Buffer object)
       
  1830     iRichText->Reset();
       
  1831     iRichText->InsertL(0, aBuf);
       
  1832     
       
  1833     //call SMS stack API to get PDU info
       
  1834     TRAPD( err, smsMsg.GetEncodingInfoL( aNumOfPDUs, numOfUnconvChars, numOfDowngradedChars, aNumOfRemainingChars ) );
       
  1835     if (err != KErrNone)
       
  1836         {
       
  1837             User::Leave(err);
       
  1838         }
       
  1839     
       
  1840 #ifdef USE_LOGGER
       
  1841     UNILOGGER_WRITE(" ---Get Encoding Info details:--- ");
       
  1842     UNILOGGER_WRITEF(_L("      aNumPdus     : %d"), aNumOfPDUs);
       
  1843     UNILOGGER_WRITEF(_L("      numOfUnconvChars : %d"), numOfUnconvChars);
       
  1844     UNILOGGER_WRITEF(_L("      numOfDowngradedChars: %d"), numOfDowngradedChars);
       
  1845     UNILOGGER_WRITEF(_L("      aNumOfRemainingChars: %d"), aNumOfRemainingChars);
       
  1846 #endif /* USE_LOGGER */
       
  1847     //Algo to switch to Unicode if required
       
  1848     while( (numOfUnconvChars || numOfDowngradedChars) && !iUnicodeMode )
       
  1849         {
       
  1850         currentAlternativeEncodingType = smsMsg.Alternative7bitEncoding();
       
  1851 #ifdef USE_LOGGER
       
  1852         UNILOGGER_WRITEF(_L("GetNumPDUsL: currAltEnc -> %d"), currentAlternativeEncodingType);
       
  1853 #endif /* USE_LOGGER */
       
  1854         if( currentAlternativeEncodingType != iAlternativeEncodingType )
       
  1855             {
       
  1856             //try with this new alternative encoding type
       
  1857             isAltEncSupported = smsMsg.SetAlternative7bitEncoding( iAlternativeEncodingType );
       
  1858             if( isAltEncSupported == KErrNotSupported )
       
  1859                 {
       
  1860                 // if required alternative encoding plugin is not supported, retain the existing encoding mechanism.
       
  1861                 iAlternativeEncodingType = currentAlternativeEncodingType;
       
  1862                 continue;
       
  1863                 }
       
  1864             }
       
  1865         else if( numOfUnconvChars || (TUniSendingSettings::TUniCharSupport)iCharSupportType == TUniSendingSettings::EUniCharSupportFull)
       
  1866             {
       
  1867             //switch to Unicode
       
  1868             //iUnicodeMode = ETrue;
       
  1869             SetEncodingSettings( ETrue, /*ESmsEncodingNone*/ iAlternativeEncodingType, iCharSupportType);
       
  1870             }
       
  1871         else
       
  1872             {
       
  1873             //Get out of while loop and return the results
       
  1874             break;
       
  1875             }
       
  1876         //get the PDU info with new settings
       
  1877         iRichText->Reset();
       
  1878         iRichText->InsertL(0, aBuf);
       
  1879         smsMsg.GetEncodingInfoL( aNumOfPDUs, numOfUnconvChars, numOfDowngradedChars, aNumOfRemainingChars );
       
  1880 #ifdef USE_LOGGER
       
  1881         UNILOGGER_WRITE("******* Get Encoding Info details (Again):***** ");
       
  1882         UNILOGGER_WRITEF(_L("     aNumPdus     : %d"), aNumOfPDUs);
       
  1883         UNILOGGER_WRITEF(_L("     numOfUnconvChars : %d"), numOfUnconvChars);
       
  1884         UNILOGGER_WRITEF(_L("     numOfDowngradedChars: %d"), numOfDowngradedChars);
       
  1885         UNILOGGER_WRITEF(_L("     aNumOfRemainingChars: %d"), aNumOfRemainingChars);
       
  1886 #endif /* USE_LOGGER */
       
  1887         }
       
  1888 
       
  1889     /*
       
  1890      * Enable the below code to debug if something wrong with characters sent even in unicode mode
       
  1891      */
       
  1892     /*
       
  1893     If((numOfUnconvChars || numOfDowngradedChars) && iUnicodeMode)
       
  1894         UNILOGGER_WRITEF("GOTCHA... some chars are not convertable in unicode mode as well...????");
       
  1895     */
       
  1896     aUnicodeMode = iUnicodeMode;
       
  1897     aAlternativeEncodingType = iAlternativeEncodingType;
       
  1898     if(iUnicodeMode)
       
  1899         {
       
  1900         //In case of Unicode mode, SMS Stack returns number of available free User Data units.
       
  1901         //Need to convert them w.r.t characters(each char takse 2 UD units).
       
  1902         aNumOfRemainingChars = aNumOfRemainingChars/2;
       
  1903         }
       
  1904     UNILOGGER_WRITE_TIMESTAMP("CUniSmsPlugin::GetNumPDUsL End -------------------->>>>>>>>>>> ");
       
  1905     }
       
  1906 
       
  1907 //  End of File