mobilemessaging/smum/src/SMSU.CPP
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mobilemessaging/smum/src/SMSU.CPP	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,1745 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*     Sms Ui Mtm.
+*
+*/
+
+
+
+// INCLUDE FILES
+
+// Specific includes
+#include <SMUM.rsg>                     // resource ids
+#include <etelmm.h>
+#include <smuthdr.h>                    // for CSmsHeader
+#include <smutset.h>                    // CSmsNumber
+#include <smscmds.h>                    // TSmsMtmCommand
+#include <aknViewAppUi.h>               // iAvkonViewAppUi
+#include <MtmExtendedCapabilities.hrh>
+// Standard includes
+#include <txtrich.h>                    // CRichText
+#include <aknnotewrappers.h>
+// Comms includes
+#include <MuiuMsgEditorLauncher.h>          // MsgEditorLauncher
+#include <MsgBioUids.h>					 // KMsgBioUidPictureMsg
+#include <akninputblock.h>			    // CAknInputBlock
+#include <Muiumsginfo.h>                // CMsgInfoMessageInfoDialog
+#include <MuiuOperationWait.h>              // MuiuOperationWait
+// other includes
+#include <StringLoader.h>               // StringLoader
+#include <ErrorUI.h>                    // CErrorUI
+
+#include <centralrepository.h>
+#include <messaginginternalcrkeys.h>
+#include <messagingvariant.hrh>
+#include <BTSapDomainPSKeys.h>          // KPSUidBluetoothSapConnectionState, KBTSapConnectionState
+#include <startupdomainpskeys.h>
+#include <gmsModel.h>
+
+#include <e32property.h>                // RProperty
+#include <PSVariables.h>                // RProperty
+#include <sacls.h>
+
+#include <csmsaccount.h>
+#include <csmsemailfields.h>            // CSmsEmailFields
+// locals
+#include "SmumSettingsDialogGSM.h"         // CSmumMainSettingsDialogGSM
+#include "SmumUtil.h"                   // SmumUtil
+#include "SMSU.HRH"                     // for KMtmUiFunctionSimDialog
+#include "SMSU.H"                       // CSmsMtmUi
+#include "smsui.pan"                    // panics
+#include "simdlgplugininterface.h"
+#include "BioOpenOp.h"					// CBioOpenOp
+#include "MsgSimSCNumberDetector.h"     // CMsgSimOperation    
+
+// Includes for fix to error SPAN-6B7K33
+#include <rmmcustomapi.h>
+#include <mmtsy_names.h>
+
+//For logging
+#include "SmumLogging.h"
+
+//  LOCAL CONSTANTS AND MACROS
+const TInt KMaxSubjectLength = 30;
+const TInt KSmumAdditionalCharsStringLength = 7;
+const TUint KSmumLRMarker = 0x200E;
+const TUint KSmumChineseOffset = 8;
+_LIT( KSmsuResourceFile, "SMUM" );
+_LIT( KSmumSpace, " " );
+_LIT( KSmumCharLeftAddressIterator, "<" );
+_LIT( KSmumCharRightAddressIterator, ">" );
+_LIT( KSmumCharCommaAndSpace, ", " );
+_LIT( KSmumSmsService, "Sms Service" );
+_LIT( KSmumChinaCountryCode, "+86");
+_LIT( KSmumInternationalPrefix, "+");
+
+// Default values, if shared data reading fails
+const TInt KDefDeliveryReport = 1;
+const TInt KDefValidityPeriod = 1440;
+const TInt KDefMessageConversion = 0;
+const TInt KDefPreferredConnection = 3;
+const TInt KDefReplyViaSameCentre = 0;
+// Constants for sms initialization
+const TInt KInitializationReady = 2;
+const TInt KInitializationReadSim = 3;
+
+//  MEMBER FUNCTIONS
+
+// Factory constructor function
+CSmsMtmUi* CSmsMtmUi::NewL( CBaseMtm& aBaseMtm, CRegisteredMtmDll& aRegisteredMtmDll )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::NewL");
+    CSmsMtmUi* smsmtmui=new ( ELeave ) CSmsMtmUi( aBaseMtm, aRegisteredMtmDll );
+    CleanupStack::PushL( smsmtmui );
+    smsmtmui->ConstructL();
+    CleanupStack::Pop();
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::NewL");
+    return smsmtmui;
+    }
+
+// C++ constructor can NOT contain any code, that
+// might leave.
+CSmsMtmUi::CSmsMtmUi( CBaseMtm& aBaseMtm, CRegisteredMtmDll& aRegisteredMtmDll ):
+    CBaseMtmUi( aBaseMtm, aRegisteredMtmDll )
+    {
+    }
+
+// Symbian OS default constructor can leave.
+void CSmsMtmUi::ConstructL()
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::ConstructL");
+    CBaseMtmUi::ConstructL();
+
+	TInt err( KErrGeneral );
+	// connect etel server
+    User::LeaveIfError( iServer.Connect() );
+    // load tsy
+    err = iServer.LoadPhoneModule( KMmTsyModuleName );
+    if ( err != KErrAlreadyExists )
+        {
+        // may return also KErrAlreadyExists if some other
+        // is already loaded the tsy module. And that is
+        // not an error.
+        User::LeaveIfError( err );
+        }
+	User::LeaveIfError( iPhone.Open( iServer, KMmTsyPhoneName ) );
+	
+    // Error resolver
+    iErrorResolver = CTextResolver::NewL( *iCoeEnv );
+    // Create the session
+    iCenRepSession = CRepository::NewL( KCRUidSmum );
+	// create sim-dialog plugin interface
+    iSimDlgPluginIntf = CSimDlgPluginInterface::NewL(*this, Session());    
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::ConstructL");
+    }
+
+// Destructor
+CSmsMtmUi::~CSmsMtmUi()
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::~CSmsMtmUi");
+    //close ETel connection
+    if (iServer.Handle())
+        {
+        iPhone.Close();           
+        iServer.UnloadPhoneModule(KMmTsyModuleName);
+        iServer.Close();
+        }
+    delete iErrorResolver;
+    delete iCenRepSession;
+    delete iSimDlgPluginIntf;
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::~CSmsMtmUi");
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CreateL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CreateL(const TMsvEntry& aEntry, CMsvEntry& aParent, TRequestStatus& aStatus)
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::CreateL");
+    //    Create a Sms message (services are provided "for nothing", created invisibly by the UI layer.
+    __ASSERT_DEBUG( aEntry.iMtm == Type(), Panic( ESmsuWrongMtmType ));
+    __ASSERT_DEBUG( aEntry.iType == KUidMsvMessageEntry, Panic( ESmsuNotAMessage ));
+    __ASSERT_DEBUG( aParent.Entry().iServiceId == KMsvLocalServiceIndexEntryId ||
+        aParent.Entry().iServiceId == KMsvNullIndexEntryId, Panic( ESmsuMessageNotLocal ));
+    __ASSERT_DEBUG(( aParent.Entry().iType == KUidMsvFolderEntry &&
+        aParent.Entry().iServiceId == KMsvLocalServiceIndexEntryId), 
+        Panic( ESmsuMessageParentNotLocalFolder ));
+
+    if( !CheckEntry( aEntry ))
+        {
+        User::Leave( KErrNotSupported );    //    Not SMS, or not a message
+        }
+ 
+    CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );
+    
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::CreateL");
+    return LaunchEditorApplicationL( aStatus, aParent.Session(), ECreateNewMessage );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::OpenL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::OpenL(TRequestStatus& aStatus)
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::OpenL");
+
+    __ASSERT_DEBUG( 
+        BaseMtm().Entry().Entry().iMtm == Type(), Panic( ESmsuWrongMtmType ));
+    __ASSERT_DEBUG( BaseMtm().Entry().Entry().iType != 
+        KUidMsvFolderEntry, Panic( ESmsuFoldersNotSupported ));
+    __ASSERT_DEBUG( BaseMtm().Entry().Entry().iType != KUidMsvAttachmentEntry, 
+        Panic( ESmsuAttachmentsNotSupported ));
+
+    const TMsvEntry myEntry = BaseMtm().Entry().Entry();
+    if( myEntry.iType == KUidMsvFolderEntry || myEntry.iType == KUidMsvAttachmentEntry )
+        {
+        User::Leave(KErrNotSupported);
+        }
+    else if ( myEntry.iType == KUidMsvMessageEntry )
+        {
+        CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );
+        }
+    else // Lint
+        {
+        }
+    CSmsClientMtm& smsClientMtm = SmsClientMtm();
+    smsClientMtm.LoadMessageL();
+    const CSmsPDU::TSmsPDUType pduType = smsClientMtm.SmsHeader().Type();
+    CSmsPDU& pdu = smsClientMtm.SmsHeader().Message().SmsPDU();
+    TSmsDataCodingScheme::TSmsClass smsClass;
+    pdu.Class( smsClass );
+    /* 
+    Fix to error SPAN-6B7K33
+    In case this happens to be an unread message stored on sim, 
+    TSY sets the status of the message to 'read' on the sim also.
+    */
+    if( pduType == CSmsPDU::ESmsDeliver && 
+            smsClass == TSmsDataCodingScheme::ESmsClass2)
+        {
+        CSmsDeliver& deliv = smsClientMtm.SmsHeader().Deliver();
+
+        TTime scTime;
+        TInt scQh;
+        deliv.ServiceCenterTimeStamp(scTime, scQh);
+
+        RMmCustomAPI ca;
+        if ( KErrNone == ca.Open( iPhone ) )
+            {
+            ca.SetSimMessageStatusRead( scTime, scQh );
+            ca.Close();
+            }
+        }
+    // Check are we dealing with delivery raport	
+    // No support for 8-bit non GMS messages
+    if ( !(pduType == CSmsPDU::ESmsDeliver || pduType == CSmsPDU::ESmsSubmit) || 
+        ( pdu.Alphabet() == TSmsDataCodingScheme::ESmsAlphabet8Bit && !IsBioTypeSupported( myEntry ) ) )
+        {
+        if ( myEntry.Unread() )
+            {
+            // Mark the entry as read
+            CMsvEntry* cEntry = &(BaseMtm().Entry());
+            TMsvEntry entry = cEntry->Entry();
+            entry.SetUnread( EFalse );
+            cEntry->ChangeL( entry );
+            }
+            
+        TSmsSmumProgress progress;
+        progress.iError = KErrNotSupported;
+        progress.iType = TSmsSmumProgress::ESmsSmumSmsOpening;
+        TSmsSmumProgressBuf progressBuf( progress );
+
+        SMUMLOGGER_ENTERFN(" CSmsMtmUi::OpenL - completedOp");
+        return CMsvCompletedOperation::NewL(
+            Session(), 
+            Type(), 
+            progressBuf, 
+            KMsvLocalServiceIndexEntryId, 
+            aStatus, 
+            KErrNotSupported );
+        }
+
+    if (KMsvDraftEntryIdValue == myEntry.Parent())
+        {
+        SMUMLOGGER_ENTERFN(" CSmsMtmUi::OpenL- EditL");
+        return EditL( aStatus );
+        }
+    else
+        {
+        SMUMLOGGER_ENTERFN(" CSmsMtmUi::OpenL- viewL");
+        return ViewL( aStatus );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CloseL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CloseL(TRequestStatus& /*aStatus*/)
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::CloseL");
+    User::Leave( KErrNotSupported );
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::CloseL");
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::EditL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::EditL( TRequestStatus& aStatus ) 
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::EditL");
+    __ASSERT_DEBUG( BaseMtm().Entry().Entry().iMtm == 
+        Type(), Panic( ESmsuWrongMtmType ));
+
+    CMsvOperation* msvoperation = NULL;
+    
+    if( BaseMtm().Entry().Entry().iBioType != 0 )
+        { // BIO msg
+        msvoperation = CBioOpenOp::NewL( 
+            Session(),
+            aStatus,
+            BaseMtm().Entry().EntryId(), 
+            Preferences());
+        }
+    else
+        { // not BIO msg
+        // What kind of entry are we going to edit?
+        switch ( iBaseMtm.Entry().Entry().iType.iUid )
+            {
+            case KUidMsvServiceEntryValue:
+                CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );
+                msvoperation = LaunchSettingsDialogL( aStatus );
+                break;
+            case KUidMsvMessageEntryValue:
+                if ( BaseMtm().Entry().Entry().ReadOnly() )
+                    {
+                    User::Leave(KErrAccessDenied);
+                    }
+                msvoperation = LaunchEditorApplicationL( aStatus, iBaseMtm.Entry().Session());
+                break;
+            case KUidMsvFolderEntryValue:
+            case KUidMsvAttachmentEntryValue:
+            default:
+            #if defined( _DEBUG )
+                Panic( ESmsuWrongEntryType );
+            #else
+                User::Leave( KErrNotSupported );
+            #endif
+            }   
+        }
+
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::EditL");
+    return msvoperation;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ViewL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::ViewL( TRequestStatus& aStatus )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::ViewL");
+     __ASSERT_DEBUG( BaseMtm().Entry().Entry().iMtm == Type(), 
+         Panic( EBioViewNotAllowed ));
+ 
+    CMsvOperation* msvoperation = NULL;
+    
+    if( iBaseMtm.Entry().Entry().iType.iUid == KUidMsvMessageEntryValue )
+        {
+        msvoperation = LaunchEditorApplicationL( aStatus, iBaseMtm.Entry().Session(), EReadOnly);
+        }
+    else
+        {
+        #if defined( _DEBUG )
+            Panic( ESmsuWrongEntryType );
+            #else
+            User::Leave( KErrNotSupported );
+            #endif        
+        }
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::ViewL");
+
+    return msvoperation;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::OpenL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::OpenL( TRequestStatus& aStatus, const CMsvEntrySelection& aSelection )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::OpenL");
+    __ASSERT_DEBUG( aSelection.Count() > 0, Panic( ESmsuEmptySelection ));
+    
+    //    Open the first entry in the selection
+    BaseMtm().SwitchCurrentEntryL( aSelection[0] );
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::OpenL");
+    return OpenL( aStatus );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CloseL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CloseL( TRequestStatus& /*aStatus*/, const CMsvEntrySelection& /*aSelection*/ )
+    {
+    SMUMLOGGER_WRITE(" CSmsMtmUi::CloseL");
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::EditL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::EditL( TRequestStatus& aStatus, const CMsvEntrySelection& aSelection )  
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::EditL - AGAIN");
+    __ASSERT_ALWAYS( aSelection.Count() > 0 , Panic( ESmsuEmptySelection ));
+
+    //    Edit the first entry in the selection
+    BaseMtm().SwitchCurrentEntryL( aSelection[0] );
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::EditL - AGAIN");
+    return EditL( aStatus );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ViewL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::ViewL( TRequestStatus& aStatus, const CMsvEntrySelection& aSelection )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::ViewL - AGAIN");
+    __ASSERT_DEBUG( aSelection.Count() > 0, Panic( ESmsuEmptySelection ));
+
+    //    View the first entry in the selection
+    BaseMtm().SwitchCurrentEntryL( aSelection[0] );
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::ViewL - AGAIN");
+    return ViewL( aStatus );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CancelL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CancelL( TRequestStatus& aStatus, const CMsvEntrySelection& aSelection )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::CancelL");
+    TInt loop = aSelection.Count();
+
+    __ASSERT_DEBUG( loop > 0, Panic( ESmsuEmptySelection ));
+
+    CMsvEntry* entry = Session().GetEntryL( aSelection[0] );
+    CleanupStack::PushL( entry );
+
+    while ( loop-- )
+        {
+        entry->SetEntryL( aSelection[loop] );
+        TMsvEntry tempEntry = entry->Entry();
+        tempEntry.SetSendingState( KMsvSendStateSuspended );
+        tempEntry.iDate.UniversalTime();
+        tempEntry.iRelatedId = tempEntry.iServiceId;
+        tempEntry.iServiceId = KMsvLocalServiceIndexEntryId;
+        entry->ChangeL( tempEntry );
+        }
+
+    CleanupStack::PopAndDestroy();// entry
+    
+    TSmsProgressBuf progress;
+    Session().ServiceProgress( SmsClientMtm().ServiceId(), progress ); //ignore error
+
+    TBuf8<1> dummy;
+    dummy.Zero();
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::CancelL");
+    return CBaseMtmUi::InvokeAsyncFunctionL( ESmsMtmCommandDeleteSchedule, aSelection, aStatus, dummy );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::DeleteFromL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::DeleteFromL( const CMsvEntrySelection& /*aSelection*/, TRequestStatus& /*aStatus*/ )
+    {
+    SMUMLOGGER_WRITE(" CSmsMtmUi::DeleteFromL");
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::DeleteServiceL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::DeleteServiceL( const TMsvEntry& /*aService*/, TRequestStatus& /*aStatus*/ )
+    {
+    SMUMLOGGER_WRITE(" CSmsMtmUi::DeleteServiceL");
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ReplyL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::ReplyL( 
+    TMsvId aDestination, 
+    TMsvPartList /*aPartlist*/, 
+    TRequestStatus& aCompletionStatus )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::ReplyL");
+    CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );
+
+    // Set params
+    TEditorParameters editorParams;
+    editorParams.iFlags |= EMsgReplyToMessageSender;
+    
+    editorParams.iId = BaseMtm().Entry().EntryId();
+    editorParams.iDestinationFolderId = aDestination; 
+	editorParams.iFlags &=~ ( EMtmUiFlagEditorPreferEmbedded | EMtmUiFlagEditorNoWaitForExit );
+	editorParams.iFlags |= ( Preferences() & EMtmUiFlagEditorPreferEmbedded ? EMsgLaunchEditorEmbedded : 0 );
+	editorParams.iFlags |= ( Preferences() & EMtmUiFlagEditorNoWaitForExit ? 0 : EMsgLaunchEditorThenWait );
+
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::ReplyL");
+    return MsgEditorLauncher::LaunchEditorApplicationL(Session(), Type(), aCompletionStatus, editorParams, KNullDesC /*, paramPack*/);
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ForwardL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::ForwardL(
+    TMsvId aDestination, 
+    TMsvPartList /*aPartList*/, 
+    TRequestStatus& aCompletionStatus )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::ForwardL");
+    CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );
+
+    // Set params
+    TEditorParameters editorParams;
+    editorParams.iFlags |= EMsgForwardMessage;
+    
+    editorParams.iId = BaseMtm().Entry().EntryId();
+	editorParams.iFlags &=~ ( EMtmUiFlagEditorPreferEmbedded | EMtmUiFlagEditorNoWaitForExit );
+	editorParams.iFlags |= ( Preferences() & EMtmUiFlagEditorPreferEmbedded ? EMsgLaunchEditorEmbedded : 0 );
+	editorParams.iFlags |= (Preferences() & EMtmUiFlagEditorNoWaitForExit ? 0 : EMsgLaunchEditorThenWait );
+    editorParams.iDestinationFolderId = aDestination;
+    
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::ForwardL");
+    return MsgEditorLauncher::LaunchEditorApplicationL(Session(), Type(), aCompletionStatus, editorParams, KNullDesC /*, paramPack*/);
+    }
+
+//    In the following two functions, the user has chosen to move or copy the message
+//    to a service i.e. send it.
+//
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CopyToL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CopyToL( const CMsvEntrySelection& aSelection, TRequestStatus& aStatus )
+    {
+    return CopyMoveToL( aSelection, aStatus, ETrue );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::MoveToL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::MoveToL( const CMsvEntrySelection& aSelection, TRequestStatus& aStatus )
+    {
+    return CopyMoveToL( aSelection, aStatus, EFalse );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CopyMoveToL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CopyMoveToL(
+    const CMsvEntrySelection& aSelection, 
+    TRequestStatus& aStatus, 
+    TBool aCopyOnly )
+    {
+    SMUMLOGGER_ENTERFN(" CSmsMtmUi::CopyMoveToL");
+    __ASSERT_DEBUG(
+        BaseMtm().Entry().Entry().iMtm == Type(), Panic( ESmsuWrongMtmType ));
+    __ASSERT_DEBUG(
+        BaseMtm().Entry().Entry().iType == KUidMsvServiceEntry, 
+        Panic( ESmsuNotAServiceEntry ));
+    
+  	TInt count = aSelection.Count();
+    __ASSERT_DEBUG( count > 0 , Panic( ESmsuEmptySelection ));
+
+    // --- Carry out the operation ---
+    TMsvEntry smsServiceEntry( BaseMtm().Entry().Entry());
+    CMsvEntry* parentEntry= Session().GetEntryL( aSelection[count-1] );
+    CleanupStack::PushL( parentEntry );
+
+	//Must set the sending state of Suspended messages to Waiting, otherwise they will not send
+	while ( count-- )
+		{
+		parentEntry->SetEntryL( aSelection[count] );
+		TMsvEntry entry( parentEntry->Entry());
+		switch ( entry.SendingState())
+            {
+            case KMsvSendStateSuspended:
+            case KMsvSendStateUponRequest:
+            case KMsvSendStateScheduled:
+            case KMsvSendStateResend:
+            case KMsvSendStateFailed:
+			    entry.SetSendingState( KMsvSendStateWaiting );
+			    parentEntry->ChangeL( entry );
+                break;
+            default:
+                break;
+            }
+		}
+
+    parentEntry->SetEntryL( parentEntry->Entry().Parent());
+    
+    //    Do the copy/move
+    CMsvOperation* op= aCopyOnly ? 
+        parentEntry->CopyL( aSelection, smsServiceEntry.Id(), aStatus ) : 
+        parentEntry->MoveL( aSelection, smsServiceEntry.Id(), aStatus );
+    
+    CleanupStack::PopAndDestroy();    //parentEntry
+    SMUMLOGGER_LEAVEFN(" CSmsMtmUi::CopyMoveToL");
+    return op;
+    }
+
+//    Copy/move from commands return KErrNotSupported because SMS messages are 
+//    automatically placed in the inbox after being received. Should therefore 
+//    be no need for this kind of thing.
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CopyFromL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::CopyFromL( 
+    const CMsvEntrySelection& /*aSelection*/, 
+    TMsvId /*aTargetId*/, 
+    TRequestStatus& /*aStatus*/ )
+    {
+    SMUMLOGGER_WRITE(" CSmsMtmUi::CopyFromL");
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::MoveFromL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::MoveFromL(
+    const CMsvEntrySelection& /*aSelection*/, 
+    TMsvId /*aTargetId*/, 
+    TRequestStatus& /*aStatus*/ )
+    {
+    SMUMLOGGER_WRITE(" CSmsMtmUi::MoveFromL");
+    User::Leave( KErrNotSupported );
+    return NULL;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::QueryCapability
+//
+// ---------------------------------------------------------
+TInt CSmsMtmUi::QueryCapability( TUid aCapability, TInt& aResponse )
+    {
+    SMUMLOGGER_WRITE(" CSmsMtmUi::QueryCapability");
+    switch ( aCapability.iUid )
+        {
+        case KUidMsvMtmQuerySupportValidateService:
+        case KUidMsvMtmUiQueryMessagingInitialisation:
+        case KUidMsvMtmQueryFactorySettings:
+            {
+            aResponse=ETrue;
+            return KErrNone;
+            }
+        default:
+            return CBaseMtmUi::QueryCapability(aCapability, aResponse);
+        }
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::InvokeSyncFunctionL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::InvokeSyncFunctionL(
+    TInt aFunctionId, 
+    const CMsvEntrySelection& aSelection, 
+    TDes8& aParameter )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::InvokeSyncFunctionL");
+    switch ( aFunctionId )
+        {
+        case KMtmUiFunctionMessageInfo:
+            {
+            ShowMessageInfoL( );
+            break;
+            }
+        case KMtmUiFunctionValidateService:
+            {
+            CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );     
+            
+            // Suppose everything is ok, because function above didn't Leave.
+            // return the result via aParameter as a TInt packaged into a TDes8
+            TPckgBuf<TInt> resultPackage( KErrNone );
+            aParameter.Copy( resultPackage );
+            break;
+            }
+        case KMtmUiFunctionSimDialog:
+            {
+            TInt simState = CheckSimStateL();
+			TInt phoneOnOff( ESAPhoneOn );
+			TInt err = RProperty::Get( KUidSystemCategory, KUidPhonePwrValue, phoneOnOff );
+            if( simState == ESimNotPresent ) // Sim removed
+                {
+                // Show note and exit 
+                HBufC* noteString = StringLoader::LoadLC( R_QTN_SU_NOTE_INSERT_SIM, iCoeEnv );
+                CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+                note->ExecuteLD( *noteString );
+                CleanupStack::PopAndDestroy(); // noteString
+                }
+            else if( err || phoneOnOff == ESAPhoneOff )    
+            	{            	
+            	// Show note and exit 
+                HBufC* noteString = StringLoader::LoadLC( R_QTN_OFFLINE_NOT_POSSIBLE, iCoeEnv );
+                CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );                
+                note->ExecuteLD( *noteString );
+                CleanupStack::PopAndDestroy(); // noteString                
+            	}            	
+            else // Sim is present
+                {
+                // Check if the Sim access profile is on
+                TInt btSapState( EBTSapNotConnected );
+			    TInt err = RProperty::Get( 
+			    	KPSUidBluetoothSapConnectionState, 
+			        KBTSapConnectionState, 
+			        btSapState );
+			    if ( err )
+			        { // Reset 
+			        btSapState = EBTSapNotConnected;
+			        }
+			    if( EBTSapNotConnected == btSapState  ) // Normal case
+			    	{
+			    	CheckAndEnsureSmsServiceOkL( ETrue, ETrue, ETrue );
+					//launch sim-dialog
+	                iSimDlgPluginIntf->LaunchL();
+			    	}
+                else // Sim Access Profile is on
+	                {
+	                // Show note and exit 
+	                HBufC* noteString = StringLoader::LoadLC( R_QTN_OFFLINE_NOT_POSSIBLE_SAP, iCoeEnv );
+	                CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+	                note->ExecuteLD( *noteString );
+	                CleanupStack::PopAndDestroy(); // noteString
+	                }
+                }
+            break;
+            }
+        case KMtmUiMessagingInitialisation:
+        case KMtmUiFunctionRestoreFactorySettings: 
+            {
+            TMsvId serviceEntryId = KMsvNullIndexEntryId;
+            serviceEntryId = CreateSmsServiceL( EFalse );
+            __ASSERT_DEBUG( serviceEntryId, Panic( ESmsuNotAServiceEntry ));
+            CreateDefaultSettingsL( serviceEntryId, ( aFunctionId == KMtmUiMessagingInitialisation ) );
+            break;
+            }
+        default:
+            CBaseMtmUi::InvokeSyncFunctionL( aFunctionId, aSelection, aParameter );
+            SMUMLOGGER_LEAVEFN("CSmsMtmUi::InvokeSyncFunctionL- DEFAULT");
+            return;
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::InvokeSyncFunctionL");
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::InvokeAsyncFunctionL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::InvokeAsyncFunctionL(
+    TInt aFunctionId, 
+    const CMsvEntrySelection& aSelection, 
+    TRequestStatus& aCompletionStatus, 
+    TDes8& aParameter )
+    {
+    SMUMLOGGER_WRITE("CSmsMtmUi::InvokeAsyncFunctionL");
+
+    //    Invoke asynchronous functions supported by client     
+    switch ( aFunctionId )
+        {
+        case KMtmUiFunctionMessageInfo:
+            {
+            return ShowMessageInfoL( aCompletionStatus, aParameter );
+            }
+        default:
+            {
+            return CBaseMtmUi::InvokeAsyncFunctionL( aFunctionId, aSelection, aCompletionStatus, aParameter );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::DisplayProgressSummary
+//
+// ---------------------------------------------------------
+TInt CSmsMtmUi::DisplayProgressSummary( const TDesC8& aProgress ) const
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::DisplayProgressSummary");
+    
+    // Check are we surely dealing with sms progress    
+    const TInt progressSize = aProgress.Size();
+
+    if ( progressSize == sizeof( TSmsSmumProgress ))
+	    {// yes, smum-progress
+	    TSmsSmumProgressBuf smumProgressPack;
+	    smumProgressPack.Copy( aProgress );
+	    TSmsSmumProgress smumProgress( smumProgressPack());
+
+	    // Show "not supported"-notes if msg cannot be shown
+    	if ( smumProgress.iError == KErrNotSupported && 
+            smumProgress.iType == TSmsSmumProgress::ESmsSmumSmsOpening )
+            {
+            TRAP_IGNORE
+                (
+                HBufC* string = StringLoader::LoadLC( R_QTN_MCE_INFO_MESSAGE_NOT_OPENED, iCoeEnv );
+                CAknInformationNote* note = new ( ELeave ) CAknInformationNote( ETrue );
+                note->ExecuteLD( *string );
+                CleanupStack::PopAndDestroy(); // string
+                )
+            }         
+        }
+    else if ( progressSize == sizeof( TSmsProgress ))
+        {// yes, sms-progress
+        TSmsProgressBuf progressPack;
+        progressPack.Copy( aProgress );
+        TSmsProgress progress ( progressPack());
+        
+        if ( progress.iError && ( progress.iType != TSmsProgress::ESmsProgressTypeSending ))
+            {
+            TRAP_IGNORE( 
+                const TDesC& errorTxt = iErrorResolver->ResolveErrorString( progress.iError );
+                CAknErrorNote* note = new ( ELeave ) CAknErrorNote();
+                note->ExecuteLD( errorTxt ); );
+            }
+        }
+    else
+        {// not sms progress, don't care
+        return KErrCancel;
+        }
+    
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::DisplayProgressSummary - no err");
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::LaunchSettingsDialogL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::LaunchSettingsDialogL( TRequestStatus& aStatus )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::LaunchSettingsDialogL");
+    __ASSERT_DEBUG(
+        BaseMtm().Entry().Entry().iMtm == Type(), Panic( ESmsuWrongMtmType ));
+    __ASSERT_DEBUG(
+        BaseMtm().Entry().Entry().iType.iUid == 
+        KUidMsvServiceEntryValue, Panic( ESmsuNotAServiceEntry ));
+    TInt exitCode = ESmumSmsSettingsInitialvalue;
+    TInt err = KErrNone;
+    // load settings
+    CSmsSettings* smsSettings = CSmsSettings::NewLC();
+    CSmsAccount* smsAccount = CSmsAccount::NewLC();
+	TRAPD( error, smsAccount->LoadSettingsL( *smsSettings ) );
+	if ( error == KErrNone )
+		{
+		//    Launch the service settings dialog on the current entry
+        TInt notUsed( 0 );
+        CSmumMainSettingsDialog* mainSettingsDialog = CSmumMainSettingsDialog::NewL(
+            *smsSettings, ESmumMainSmsSettings, exitCode, notUsed );
+        mainSettingsDialog->ExecuteLD( R_MAIN_SETTINGS_DIALOG );
+        // Try to save, continue anyway
+        TRAP( err, smsAccount->SaveSettingsL( *smsSettings ) );
+		}
+	else
+    	{
+    	User::Leave( error );
+    	}
+    CleanupStack::PopAndDestroy( 2 ); // smsSettings, smsAccount
+    // Check if user wants to exit to idle = ESmumSmsSettingsMenuExit
+    // (...in system exits system keeps closing apps one by one until all down, not done here...)
+    if ( exitCode == ESmumSmsSettingsMenuExit )
+            { // Exiting...
+            err = EEikCmdExit;
+            }
+
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::LaunchSettingsDialogL");
+    
+    return CMsvCompletedOperation::NewL(
+        Session(), 
+        Type(), 
+        KNullDesC8, 
+        KMsvLocalServiceIndexEntryId, 
+        aStatus, 
+        err);
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::LaunchEditorApplicationL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::LaunchEditorApplicationL(
+    TRequestStatus& aStatus, 
+    CMsvSession& aSession, 
+    TEditorType aEditorType, 
+    TMsvId aParentId )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::LaunchEditorApplicationL");
+
+    TEditorParameters temp;    
+  	temp.iFlags &=~ ( EMtmUiFlagEditorPreferEmbedded | EMtmUiFlagEditorNoWaitForExit );
+	temp.iFlags |= ( Preferences() & EMtmUiFlagEditorPreferEmbedded ? EMsgLaunchEditorEmbedded : 0 );
+    temp.iFlags |= ( Preferences() & EMtmUiFlagEditorNoWaitForExit ? 0 : EMsgLaunchEditorThenWait );
+
+    if ( iBaseMtm.HasContext())
+        {
+        temp.iId = iBaseMtm.Entry().EntryId();
+        }
+
+    switch( aEditorType )
+        {
+        case EReadOnly:
+            temp.iFlags |= EMsgReadOnly;
+            break;                             
+        case ECreateNewMessage:
+            temp.iFlags |= EMsgCreateNewMessage ;
+            temp.iId = aParentId;
+            break;
+        case EEditExisting:
+        default:
+            break;
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::LaunchEditorApplicationL");
+       
+	return MsgEditorLauncher::LaunchEditorApplicationL( 
+        aSession, 
+        Type(), 
+        aStatus, 
+        temp, 
+        KNullDesC, 
+        KNullDesC8 );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::GetResourceFileName
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::GetResourceFileName( TFileName& aFileName ) const
+    {
+    aFileName = KSmsuResourceFile;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CheckEntry
+//
+// ---------------------------------------------------------
+TBool CSmsMtmUi::CheckEntry( const TMsvEntry& aEntry ) const
+    {
+    //    Ensures that the TMsvEntry is a suitable candidate for treatment by
+    //    this MtmUi layer.
+    return aEntry.iType == KUidMsvMessageEntry && aEntry.iMtm == Type();
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CreateSmsServiceL
+//
+// ---------------------------------------------------------
+TMsvId CSmsMtmUi::CreateSmsServiceL( TBool aNoServiceNoCheckNeeded )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::CreateSmsServiceL");
+    // Keep shared data uptodate
+    SetSharedDataL( 
+        KSmumSmsStatus, 
+        1 );// sms initialisation in progress
+
+    // Check for service if needed
+    TMsvId serviceEntryId = KMsvNullIndexEntryId;
+    TInt err = KErrNone;
+    if ( !aNoServiceNoCheckNeeded )
+        {
+        TRAP( err, serviceEntryId = ServiceIdL());
+        }
+
+    // If no service, create one
+    if ( err == KErrNotFound || aNoServiceNoCheckNeeded )
+        {
+	    TMsvEntry entry;
+	    entry.iMtm = KUidMsgTypeSMS;
+	    entry.iType = KUidMsvServiceEntry;
+	    entry.SetReadOnly( EFalse );
+        entry.SetVisible( EFalse );
+        entry.iDate.HomeTime();
+        entry.iDetails.Set( KSmumSmsService );
+        CMsvEntry* root = Session().GetEntryL( KMsvRootIndexEntryId );
+        CleanupStack::PushL( root );
+        // In case no root store, create one...
+        if ( !root->HasStoreL() )
+            {
+            // --- The entry does not have a store. EditStoreL() will create one ---
+            CMsvStore* store = root->EditStoreL();
+            CleanupStack::PushL( store );
+            store->CommitL();
+            CleanupStack::PopAndDestroy(); // store
+            store = NULL; // destroyed
+            }
+        root->CreateL( entry );
+        CleanupStack::PopAndDestroy(); // root
+        BaseMtm().SwitchCurrentEntryL( entry.Id());
+        serviceEntryId = entry.Id();
+        iNewSmsSettings = ETrue;
+        }
+    else
+        {
+		User::LeaveIfError( err );
+        }
+
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::CreateSmsServiceL");
+    return serviceEntryId;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ServiceIdL
+//
+// ---------------------------------------------------------
+TMsvId CSmsMtmUi::ServiceIdL()
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::ServiceIdL");
+    TMsvId id = KMsvNullIndexEntryId;
+    CMsvEntry* root = Session().GetEntryL(KMsvRootIndexEntryId);
+    CleanupStack::PushL(root);
+    TSmsUtilities::ServiceIdL(*root, id);
+    CleanupStack::PopAndDestroy(root);
+
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::ServiceIdL");
+    return id;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ReadDefaultSettingsFromSharedDataL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::ReadDefaultSettingsFromSharedDataL( CSmsSettings* aServiceSettings )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::ReadDefaultSettingsFromSharedDataL");
+    if ( iCenRepSession )
+        {
+        TInt readedSetting;
+        // Delivery report 
+        if ( iCenRepSession->Get( KSmumDeliveryReport, readedSetting ) != KErrNone )
+        	{
+	        readedSetting = KDefDeliveryReport;
+	        }
+        aServiceSettings->SetDeliveryReport( readedSetting );
+
+        // Validity period
+        if ( iCenRepSession->Get( KSmumValidityPeriod, readedSetting ) != KErrNone )
+            {
+            readedSetting = KDefValidityPeriod;
+            }
+        aServiceSettings->SetValidityPeriod( readedSetting );
+
+        // Message conversion
+        if ( iCenRepSession->Get( KSmumMessageConversion, readedSetting ) != KErrNone )
+            {
+            readedSetting = KDefMessageConversion;
+            }
+        aServiceSettings->SetMessageConversion(( TSmsPIDConversion ) readedSetting );
+
+        // Preferred connection
+        if ( iCenRepSession->Get( KSmumPreferredConnection, readedSetting ) != KErrNone )
+            {
+            readedSetting = KDefPreferredConnection;
+            }
+        aServiceSettings->SetSmsBearer( ( CSmsSettings::TMobileSmsBearer ) readedSetting );
+
+        // Reply via same centre 
+        if(iCenRepSession->Get( KSmumRemoveReplyViaSameCentre, readedSetting ) != KErrNone )
+        	{
+        	if( iCenRepSession->Get( KSmumReplyViaSameCentre, readedSetting ) != KErrNone )	
+            	{
+        		readedSetting = KDefReplyViaSameCentre;
+            	}
+        	}
+        else 
+            {
+            if(!readedSetting)
+            	{
+            	if( iCenRepSession->Get( KSmumReplyViaSameCentre, readedSetting ) != KErrNone )	
+            		{
+            		readedSetting = KDefReplyViaSameCentre;	
+            		}
+            	}
+            }
+        	
+        aServiceSettings->SetReplyPath( readedSetting );
+        
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::ReadDefaultSettingsFromSharedDataL");
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CopySCentresFromOldToNewSettingsL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::CopySCentresFromOldToNewSettingsL(CSmsSettings* aServiceSettings)
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::CopySCentresFromOldToNewSettingsL");
+    // Copy Service centres from old setting to new settings
+    CSmsSettings* oldServiceSettings = &SmsClientMtm().ServiceSettings();
+    TInt serviceCentres = oldServiceSettings->ServiceCenterCount();
+    // Do copying, if we have something to copy
+    if ( serviceCentres )
+        {
+        for ( TInt loop=0; loop < serviceCentres; loop++ )
+            {
+            aServiceSettings->AddServiceCenterL(
+                oldServiceSettings->GetServiceCenter( loop ).Name(),
+                oldServiceSettings->GetServiceCenter( loop ).Address());
+            }
+        aServiceSettings->SetDefaultServiceCenter( 
+            oldServiceSettings->DefaultServiceCenter());
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::CopySCentresFromOldToNewSettingsL");
+    }
+        
+// ---------------------------------------------------------
+// CSmsMtmUi::CreateDefaultSettingsL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::CreateDefaultSettingsL( TMsvId aServiceId, TBool aMailInit )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::CreateDefaultSettingsL");
+    CSmsSettings* serviceSettings = CSmsSettings::NewL();
+    CleanupStack::PushL( serviceSettings );
+    CSmsAccount* smsAccount = CSmsAccount::NewLC();
+    // Read the RFS related settings from shared data.
+    TInt originalCount = 0;
+    if ( aMailInit )
+        {
+        smsAccount->LoadSettingsL( *serviceSettings );
+        originalCount = serviceSettings->ServiceCenterCount();
+        }
+
+    if ( !originalCount )
+        {        
+        ReadDefaultSettingsFromSharedDataL( serviceSettings );
+
+        // Rest of the sms settings, which are fixed.
+        serviceSettings->SetValidityPeriodFormat( TSmsFirstOctet::ESmsVPFInteger ); //relative
+        serviceSettings->SetDelivery( ESmsDeliveryImmediately );
+        serviceSettings->SetCanConcatenate( ETrue );
+        serviceSettings->SetStatusReportHandling( CSmsSettings::EMoveReportToInboxInvisible );
+        serviceSettings->SetSpecialMessageHandling( CSmsSettings::EMoveReportToInboxVisible );
+        serviceSettings->SetRejectDuplicate( ETrue );
+        TInt descriptionLength = KSmsDescriptionLength;
+        // Read the value for description length 
+        CRepository* repository = CRepository::NewLC( KCRUidMuiuSettings );
+        if (KErrNone == repository->Get(KMuiuDescriptionLength, descriptionLength))
+          {
+          //Make sure value is not zero
+          descriptionLength = Max(descriptionLength, KSmsDescriptionLength);
+          }
+        CleanupStack::PopAndDestroy(); // repository
+        serviceSettings->SetDescriptionLength( descriptionLength );
+        // Set saving to commsdb
+        serviceSettings->SetCommDbAction( CSmsSettings::EStoreToCommDb ); 
+        serviceSettings->SetSmsBearerAction( CSmsSettings::EStoreToCommDb );
+        
+        // If we're refreshing old settings (RFS:normal level)
+        // then copy the scentres from old to new.
+        if ( !iNewSmsSettings )
+            {
+            CopySCentresFromOldToNewSettingsL( serviceSettings );
+            }
+        }
+    else
+        {
+        iNewSmsSettings = EFalse;
+        }
+    
+    // Save settings
+    CMsvEntry* service = Session().GetEntryL( aServiceId );
+    CleanupStack::PushL( service );
+    CMsvStore* msvstore = service->EditStoreL();
+    CleanupStack::PushL( msvstore );
+
+    TInt maxTries( 5 );
+    TBool done( EFalse );
+    while ( maxTries && !done )
+        {
+        TRAPD( err, smsAccount->SaveSettingsL( *serviceSettings ) );
+        if ( err == KErrNone )
+            {
+            done = ETrue;
+            }
+        else if ( err == KErrLocked )
+            {
+            // Some other thread has locked (probably the CommDb) repository.
+            // Wait a while and retry.
+            User::After( 100000 ); // 0.1 seconds
+            maxTries--;
+            }
+        else
+            {
+            User::Leave( err );
+            }
+        }
+
+    msvstore->CommitL();    
+    CleanupStack::PopAndDestroy( 2 ); // msvstore, service
+    
+    // Keep shared data uptodate
+    if ( iNewSmsSettings )
+        { // Let's try reading SCs from SIM
+        SetSharedDataL( 
+            KSmumSmsStatus, 
+            KInitializationReadSim ); // notify NCN to read SCs from SIM
+        iNewSmsSettings = EFalse;
+        }
+    else
+        {
+        SetSharedDataL( 
+            KSmumSmsStatus, 
+            KInitializationReady ); // sms initialisation ready
+        }
+    CleanupStack::PopAndDestroy( 2 ); // serviceSettings, smsAccount
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::CreateDefaultSettingsL");
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ShowMessageInfoL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::ShowMessageInfoL() const
+    {
+    SMUMLOGGER_WRITE("CSmsMtmUi::ShowMessageInfoL");
+    ConstructAndShowInfoDialogL();    
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ShowMessageInfoL
+//
+// ---------------------------------------------------------
+CMsvOperation* CSmsMtmUi::ShowMessageInfoL(TRequestStatus& aCompletionStatus, TDes8& /*aParameter*/) const
+    {
+    SMUMLOGGER_WRITE("CSmsMtmUi::ShowMessageInfoL(...)");
+    ConstructAndShowInfoDialogL();
+    return CMsvCompletedOperation::NewL( 
+        Session(), KUidMsvLocalServiceMtm, KNullDesC8, 
+        KMsvLocalServiceIndexEntryId, aCompletionStatus, KErrNone );
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ConstructAndShowInfoDialogL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::ConstructAndShowInfoDialogL() const
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::ConstructAndShowInfoDialogL");
+    CSmsClientMtm& smsClientMtm = SmsClientMtm();
+    smsClientMtm.LoadMessageL();
+    CSmsHeader& smsHeader = smsClientMtm.SmsHeader();
+    TMsgInfoMessageInfoData infoData;
+    TBool emailMessage( EFalse );
+    
+    //Get info if local timestamping needed for SMS
+    CRepository* cenRep = CRepository::NewLC( KCRUidMuiuVariation );
+    TBool useLocalSmsTimeStamp = EFalse;
+    TBool useChineseTimezoneOverriding = EFalse;
+    TInt  featureFlags = 0;
+     
+    cenRep->Get(KMuiuSmsFeatures,  featureFlags);
+ 	CleanupStack::PopAndDestroy(cenRep);
+ 	useLocalSmsTimeStamp = (featureFlags & KSmsFeatureIdUseLocalTimeStamp);
+ 	useChineseTimezoneOverriding = (featureFlags & KSmsFeatureIdOverrideChineseTimeZone);
+  		
+ 	//Make sure only one flag is enabled
+ 	if( useChineseTimezoneOverriding ) 	
+ 	    {
+ 	    useLocalSmsTimeStamp = EFalse;
+ 	    }        
+	      	
+    // Check if we are dealing with E-mail sms message
+    // We use TP-PID as the only validation rule
+    CSmsPDU& pdu = smsHeader.Message().SmsPDU();
+	if( pdu.ProtocolIdentifierPresent() )
+		{
+		if(	pdu.PIDType() == TSmsProtocolIdentifier::ESmsPIDTelematicInterworking &&
+			pdu.TelematicDeviceIndicator() == TSmsProtocolIdentifier::ESmsTelematicDevice &&
+			pdu.TelematicDeviceType() == TSmsProtocolIdentifier::ESmsInternetElectronicMail )
+			{
+			emailMessage = ETrue;
+			}
+		}
+    const TMsvEntry tentry = smsClientMtm.Entry().Entry();
+
+    // Subject
+    HBufC* subject = NULL;
+    // Set the subject text
+    GetSubjectTextL( tentry, smsClientMtm, subject, emailMessage );
+    CleanupStack::PushL( subject );
+    infoData.iSubject.Set( *subject );
+    
+    // Holds the message info text for both sms and bio messages
+    HBufC* messageType = NULL; 
+    if( tentry.iBioType )
+        { //this is a bio message which has been created on the phone
+        TInt resourceId = GetBioResourceId( tentry );
+        if ( resourceId != KErrNotFound )
+            {
+            messageType = iEikonEnv->AllocReadResourceLC( resourceId );
+            infoData.iType.Set( *messageType );
+            }
+        else
+            {
+            infoData.iType.Set( tentry.iDescription );
+            }
+        }
+    else
+        {
+        //sms type
+        messageType = StringLoader::LoadLC( R_QTN_SMS_MINFO_TYPE_SMS, iCoeEnv );
+        infoData.iType.Set( *messageType );
+        }
+
+    //sms date and time
+    TInt type = smsHeader.Type();
+    TTime smsDate;    
+       
+    TInt notUsed = 0;
+    if ( CSmsPDU::ESmsDeliver == type || CSmsPDU::ESmsStatusReport == type )
+        {        
+        //UTC time or local time
+      	if( useLocalSmsTimeStamp )
+      		{
+      		smsDate = tentry.iDate;
+      		}
+      	else if( useChineseTimezoneOverriding )
+      	    {
+      	     //get Service Center address and recipient's address. Check if chinese countrycode 
+      	     //is found or if national number 
+            if ( (pdu.ServiceCenterAddress()).Find( KSmumChinaCountryCode ) != KErrNotFound ||
+                smsHeader.FromAddress().Find( KSmumChinaCountryCode ) != KErrNotFound ||
+                ( pdu.ServiceCenterAddress().Find( KSmumInternationalPrefix ) == KErrNotFound && 
+                  smsHeader.FromAddress().Find( KSmumInternationalPrefix ) == KErrNotFound ) )
+                {
+                CSmsDeliver& deliv = smsHeader.Deliver();
+
+                TTime smsstackSCTime; // In UTC time
+                TTime origSCTime; // In local time
+                TTime utcSCTime;
+                
+                TInt origSCQuarterHours;
+                deliv.ServiceCenterTimeStamp( smsstackSCTime, origSCQuarterHours );
+                        
+                //Calculate orig (local) time from SMSStack's SC-time
+                TInt offsetInHours = origSCQuarterHours * CSmsMessage::E15MinutesRepresentedInSeconds;
+                TTimeIntervalSeconds offsetFromUTCToLocal( offsetInHours );        
+                origSCTime = smsstackSCTime + offsetFromUTCToLocal;
+                      
+                //subtract 8 eight hours ( = Chinese timezone offset )
+                TTimeIntervalSeconds chineseOffset( KSmumChineseOffset * 60 * 60 );        
+                utcSCTime = origSCTime - chineseOffset;
+
+                smsDate = utcSCTime;                        
+                }
+            else
+             	{//make sure smsDate is not empty
+      		    smsHeader.Deliver().ServiceCenterTimeStamp( smsDate, notUsed );
+      		    }
+      		}
+      	else
+      		{
+      		smsHeader.Deliver().ServiceCenterTimeStamp( smsDate, notUsed );
+      		}
+      		       	           
+        }
+    else
+        {
+        // message entry time is in UTC time
+        smsDate = tentry.iDate;
+        }
+    
+    infoData.iDateTime = smsDate;
+    //
+    // Recipient info
+    if ( CSmsPDU::ESmsDeliver == type )
+        { // want to show 'viewer' type fields
+        //sms 'from' field
+        HBufC* senderNumber = smsHeader.FromAddress().AllocLC();
+        HBufC* fromText = HBufC::NewLC( 
+            tentry.iDetails.Length() 
+            + senderNumber->Length() 
+            // for the chars: '<' '>' 2 x KSmumLRMarker
+            + KSmumAdditionalCharsStringLength ); 
+        
+        if ( !emailMessage ) // TP-PID sms
+            {
+	        // Do we have alias?
+	        if ( senderNumber->Compare( tentry.iDetails ))
+	            { // yes
+	            TPtr fromTextPtr = fromText->Des();
+	            fromTextPtr.Append( tentry.iDetails );
+	            fromTextPtr.Append( KSmumSpace );
+	            fromTextPtr.Append( KSmumLRMarker );
+	            fromTextPtr.Append( KSmumCharLeftAddressIterator );
+	            fromTextPtr.Append( *senderNumber );
+	            fromTextPtr.Append( KSmumCharRightAddressIterator );
+	            fromTextPtr.Append( KSmumLRMarker );
+	            infoData.iFrom.Set( *fromText );
+	            }
+	        else
+	            { // no
+	            infoData.iFrom.Set( *senderNumber );
+	            }
+            }
+        else
+            { // TP-PID set for interworking with email
+            TPtr fromTextPtr = fromText->Des();
+            fromTextPtr.Append( tentry.iDetails );
+            infoData.iFrom.Set( *fromText );
+            }
+        
+        CMsgInfoMessageInfoDialog* infoDialog = CMsgInfoMessageInfoDialog::NewL();
+        infoDialog->ExecuteLD( infoData, CMsgInfoMessageInfoDialog::ESmsViewer );
+        
+        CleanupStack::PopAndDestroy( 2 ); // senderNumber, fromText
+        }
+    else  
+        { //editType is ETrue, want to show 'editor' type fields
+        //sms 'to:' list
+        HBufC* toList = TurnRecipientsArrayIntoStringLC( 
+            smsHeader.Recipients(), 
+            emailMessage );
+
+        infoData.iTo.Set( *toList );
+
+        CMsgInfoMessageInfoDialog* infoDialog = CMsgInfoMessageInfoDialog::NewL();
+        if( tentry.iBioType )
+            {
+            infoDialog->ExecuteLD( infoData, CMsgInfoMessageInfoDialog::EBiosEditor );
+            }
+        else
+            {
+            infoDialog->ExecuteLD( infoData, CMsgInfoMessageInfoDialog::ESmsEditor );
+            }
+
+        CleanupStack::PopAndDestroy(toList);
+        }
+    if ( messageType )
+        {
+        CleanupStack::PopAndDestroy( messageType );
+        }
+    if ( subject )
+        {
+        CleanupStack::PopAndDestroy( subject );
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::ConstructAndShowInfoDialogL");
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ExtractTitleFromGMSBodyL
+//
+// ---------------------------------------------------------
+HBufC* CSmsMtmUi::ExtractTitleFromGMSBodyL( const CRichText& aBody, TInt aMaxLength ) const
+    {           
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::ExtractTitleFromGMSBodyL");
+    CGmsModel* model = CGmsModel::NewL(CCoeEnv::Static()->FsSession(), KErrCorrupt);
+    CleanupStack::PushL(model);
+    model->ImportGMSL(aBody);
+    HBufC* text = model->TextAsHBufC16LC();
+    HBufC* result = NULL;
+    if (text->Length() <= aMaxLength)
+        {
+        result = text->AllocL();
+        }
+    else
+        {
+        // length is greater than max
+        result = text->Left(aMaxLength).AllocL();
+        }
+    CleanupStack::PopAndDestroy(2, model); // text model
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::ExtractTitleFromGMSBodyL");
+    return result;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::TurnRecipientsArrayIntoStringLC
+//
+// ---------------------------------------------------------
+HBufC* CSmsMtmUi::TurnRecipientsArrayIntoStringLC( 
+    const CArrayPtrFlat<CSmsNumber>& aRecip, 
+    const TBool aEmailMessage ) const
+    {
+    //calc length of string needed
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::TurnRecipientsArrayIntoStringLC");
+    TInt stringLength = 0;
+    TInt index;
+    HBufC* toList = NULL;
+    if ( !aEmailMessage )
+        {
+        TInt count = aRecip.Count();
+        for( index = 0; index < count; index++ )
+            {
+            stringLength += aRecip[index]->Name().Length();
+            stringLength += aRecip[index]->Address().Length();
+            // for the 7 chars: '<' '>' ', ' 2 x KSmumLRMarker, ' '
+            stringLength += KSmumAdditionalCharsStringLength; 
+            }
+        //construct string
+        toList = HBufC::NewLC( stringLength );
+        TPtr toListPtr = toList->Des();
+        // Loop through recipients
+        for( index=0; index < count; index++ )
+            {
+            TPtrC name = aRecip[index]->Name();
+            TPtrC number = aRecip[index]->Address();
+            if( name.Length() )
+                {
+                toListPtr.Append( name );
+                toListPtr.Append( KSmumSpace );
+                toListPtr.Append( KSmumLRMarker );
+                toListPtr.Append( KSmumCharLeftAddressIterator );
+                toListPtr.Append( number );
+                toListPtr.Append( KSmumCharRightAddressIterator );
+                toListPtr.Append( KSmumLRMarker );
+                }
+            else
+                {
+                toListPtr.Append( number );
+                }
+        
+            if ( index < ( count - 1 )) // comma needed?
+                {
+                toListPtr.Append( KSmumCharCommaAndSpace );
+                }
+            }
+        }
+    else // Loop the Email addresses
+        {
+        CSmsHeader& smsHeader = SmsClientMtm().SmsHeader();
+        const MDesCArray& array = smsHeader.EmailFields().Addresses();
+        TInt emailAddressCount = array.MdcaCount();
+        for( index = 0; index < emailAddressCount; index++ )
+            {
+            stringLength += array.MdcaPoint(index).Length() + 2;
+            }
+        toList = HBufC::NewLC( stringLength );
+        TPtr toListPtr = toList->Des();
+        for( index = 0; index < emailAddressCount; index++ )
+            {
+            toListPtr.Append( array.MdcaPoint(index) );
+            if ( index < ( emailAddressCount - 1 ) ) // comma needed?
+                {
+                toListPtr.Append( KSmumCharCommaAndSpace );
+                }
+            }
+        
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::TurnRecipientsArrayIntoStringLC");
+    return toList;
+    }       
+
+// ---------------------------------------------------------
+// CSmsMtmUi::SetSharedDataL
+//
+// ---------------------------------------------------------
+void CSmsMtmUi::SetSharedDataL( const TUint32 aId, const TInt aVal )
+    {
+    if( iCenRepSession )    
+        {
+        //IMPORT_C TInt Set(TUint32 aId, TInt aVal);
+        iCenRepSession->Set( aId, aVal );
+        }
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CheckAndEnsureSmsServiceOkL
+//
+// ---------------------------------------------------------
+TInt CSmsMtmUi::CheckAndEnsureSmsServiceOkL( TBool aCreateService, TBool aCreateStore, TBool aFetchSMSCs )
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::CheckAndEnsureSmsServiceOkL");
+    TInt recreation = ESmsReCreatedNone;
+    TMsvId currContext = iBaseMtm.Entry().Entry().Id(); // take current context to safe
+    TMsvId serviceEntryId = KMsvNullIndexEntryId;
+    
+    // Check first do we have service entry...
+    TRAPD( err, serviceEntryId = ServiceIdL());
+    if ( err == KErrNotFound && aCreateService )
+        { // ...no, let's create one
+        serviceEntryId = CreateSmsServiceL( ETrue );
+        __ASSERT_DEBUG( serviceEntryId, Panic( ESmsuNotAServiceEntry ));
+        iNewSmsSettings = EFalse;
+        CreateDefaultSettingsL( serviceEntryId );
+        recreation = ESmsReCreatedService;
+        iBaseMtm.SwitchCurrentEntryL( currContext );
+        }
+    else if ( err == KErrNone ) 
+        {
+        // If service ok, then check do we have msg store for it...
+        iBaseMtm.SwitchCurrentEntryL( serviceEntryId );
+        if ( !iBaseMtm.Entry().HasStoreL() && aCreateStore )
+            { // ...no, let's create one
+            iNewSmsSettings = EFalse;
+            CreateDefaultSettingsL( serviceEntryId );
+            recreation = recreation ? ESmsReCreatedBoth : ESmsReCreatedServicesStore;
+            }
+        iBaseMtm.SwitchCurrentEntryL( currContext );
+        }
+    else // Lint
+        {
+        }
+        
+    // Read SMSC from SIM, if some recreation done
+    if ( ( recreation != ESmsReCreatedNone ) && aFetchSMSCs )
+        {
+        if ( KErrNone != ReadSMSCsFromSIML())
+            {
+            // Something went wrong, notify NCN to read SCs from SIM in next boot
+            SetSharedDataL( 
+                KSmumSmsStatus, 
+                KInitializationReadSim ); 
+            }
+        }
+    
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::CheckAndEnsureSmsServiceOkL");
+    return recreation;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::ReadSMSCsFromSIML
+// ---------------------------------------------------------
+TInt CSmsMtmUi::ReadSMSCsFromSIML()
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::ReadSMSCsFromSIML");
+    CMuiuOperationWait* wait = CMuiuOperationWait::NewLC();
+    CMsgSimOperation* simOperation = CMsgSimOperation::NewL( wait->iStatus );
+    CleanupStack::PushL( simOperation );
+    wait->Start();
+    TInt returnValue = wait->iStatus.Int();
+    CleanupStack::PopAndDestroy( 2 ); // wait, simOperation
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::ReadSMSCsFromSIML");
+    return returnValue;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::CheckSimOkL
+// ---------------------------------------------------------
+TInt CSmsMtmUi::CheckSimStateL()
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::CheckSimStateL");
+    TInt simState( ESimUsable );
+    TInt err = RProperty::Get( KPSUidStartup, KPSSimStatus, simState );
+    if ( err != KErrNone )
+        {
+        simState = ESimNotPresent;
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::CheckSimStateL");
+    return simState;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::GetSubjectTextL
+// ---------------------------------------------------------
+void CSmsMtmUi::GetSubjectTextL( 
+    const TMsvEntry& aTEntry, 
+    const CSmsClientMtm& aSmsClientMtm,
+    HBufC*& aSubject,
+    TBool aIsEmailMessage /*= EFalse*/) const
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::GetSubjectTextL");
+	// show subject only if email-over-sms
+    TInt subLength = aSmsClientMtm.SmsHeader().EmailFields().Subject().Length();
+    if ( !aTEntry.iBioType && aIsEmailMessage && subLength)
+        { 
+        // dialog truncates text to fit screen width and 
+        // adds '...' so we don't need to do it here
+        TBuf<KMaxSubjectLength> subjText;
+        // Read the subject from CSmsHeader
+        subjText = 
+        	aSmsClientMtm.SmsHeader().EmailFields().Subject().Left( KMaxSubjectLength );
+        subjText.TrimAll();
+        aSubject = subjText.AllocL();
+        }
+    else
+        { // Alloc as empty so it can be pushed to CleanupStack
+        aSubject = KNullDesC().AllocL();
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::GetSubjectTextL");
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::GetBioResourceId
+// ---------------------------------------------------------
+TInt CSmsMtmUi::GetBioResourceId( const TMsvEntry& aTEntry ) const
+    {
+    SMUMLOGGER_ENTERFN("CSmsMtmUi::GetBioResourceId");
+    TInt resourceId( KErrNotFound );
+    if ( aTEntry.iBioType == KMsgBioUidVCard.iUid )
+        {
+        resourceId = R_QTN_SM_INFO_BUSINESS_CARD;
+        }
+    else if ( aTEntry.iBioType == KMsgBioUidVCalendar.iUid )
+        {
+        resourceId = R_QTN_SM_INFO_CALENDAR;
+        }
+    else if ( aTEntry.iBioType == KMsgBioUidWmlBrSettings.iUid )
+        {
+        resourceId = R_QTN_SM_TITLE_CONFIGURATION;
+        }
+    else if ( aTEntry.iBioType == KMsgBioUidPictureMsg.iUid )
+        {
+        resourceId = R_QTN_SM_INFO_GMS;
+        }
+    else
+        {
+        // Don't change the resourceId
+        }
+    SMUMLOGGER_LEAVEFN("CSmsMtmUi::GetBioResourceId");
+    return resourceId;
+    }
+
+// ---------------------------------------------------------
+// CSmsMtmUi::GetBioResourceId
+// ---------------------------------------------------------
+TBool CSmsMtmUi::IsBioTypeSupported( const TMsvEntry& aTEntry ) const    
+	{
+    SMUMLOGGER_WRITE("CSmsMtmUi::IsBioTypeSupported");
+	TBool retryVal( EFalse );
+	 if ( aTEntry.iBioType == KMsgBioUidVCard.iUid ||
+	 	  aTEntry.iBioType == KMsgBioUidVCalendar.iUid ||
+	 	  aTEntry.iBioType == KMsgBioUidWmlBrSettings.iUid ||
+	 	  aTEntry.iBioType == KMsgBioUidPictureMsg.iUid )
+	 	{
+	 	retryVal = ETrue;
+	 	}
+	 else
+	 	{
+	 	}
+	 return retryVal;
+	}
+//  End of File