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