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