--- /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