📄 mtmengine.cpp
字号:
#include "MtmEngine.h"
// SYSTEM FILES
#include <f32file.h> // TParsePtrC
#include <mmsclient.h> // CMmsClientMtm
#include <mtclreg.h> // CClientMtmRegistry
#include <mtmdef.h> // KMsvMessagePartBody
#include <smsclnt.h> // CSmsClientMtm
#include <smscmds.h> // ESmsMtmCommandScheduleCopy
#include <smuthdr.h> // CSmsHeader
#include <smutset.h> // CSmsSettings
#include <txtrich.h> // CRichText
#include <eikenv.h>
#include <stringloader.h>
//#include <infoman.rsg>
const TInt KMessageAddressLength = 32;
const TInt KMessageBodySize = 256;
const TInt KListInfoLength = 512;
CMtmEngine* CMtmEngine::NewL(MMtmsEngineObserver& aObserver)
{
CMtmEngine* self = new(ELeave) CMtmEngine(aObserver);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
CMtmEngine::CMtmEngine(MMtmsEngineObserver& aObserver)
:CActive(0),
m_Observer(aObserver),
m_pIdArray(NULL),
m_SmsId(KMsvNullIndexEntryId)
{
}
void CMtmEngine::ConstructL()
{
CActiveScheduler::Add(this);
// m_pEntrySelection encapsulates an array of entry IDs
m_pEntrySelection = new(ELeave) CMsvEntrySelection;
// Represents a channel of communication between a client thread (Client-side MTM, User
// Interface MTM, or message client application) and the Message Server thread.
// Session is opened asynchorously. CreateMtmClientL() is called afterwards.
// Another possibility is use OpenSyncL which is synchronous.
m_pSession = CMsvSession::OpenAsyncL(*this);
}
void CMtmEngine::CreateMtmClientL()
{
// Client-side MTM registry.
m_pClientMtmReg = CClientMtmRegistry::NewL(*m_pSession);
// Get the SMS Mtm client from the registry
m_pSmsMtm = static_cast<CSmsClientMtm*>(m_pClientMtmReg->NewMtmL(KUidMsgTypeSMS));
}
CMtmEngine::~CMtmEngine()
{
Cancel();
delete m_pMsvOper;
delete m_pEntrySelection;
delete m_pSmsMtm;
delete m_pClientMtmReg;
delete m_pSession;
if(m_pIdArray)
{
m_pIdArray->Reset();
delete m_pIdArray;
m_pIdArray = NULL;
}
}
void CMtmEngine::DoCancel()
{
if(m_pMsvOper)
{
m_pMsvOper->Cancel();
delete m_pMsvOper;
m_pMsvOper = NULL;
}
}
void CMtmEngine::RunL()
{
m_Observer.HandleMessageSentL(iStatus.Int());
}
TMsvEntry CMtmEngine::CreateSMSMessageL(const TDesC& aAddress,const TDesC& aMessage)
{
// Set SMS parameters 设置短信参数
TMsvEntry indexEntry;
indexEntry.iDate.HomeTime();
indexEntry.SetInPreparation(EFalse);
// This is an SMS message
indexEntry.iMtm = KUidMsgTypeSMS;
indexEntry.iType = KUidMsvMessageEntry;
// Gets the ID of the current SMS service 取得当前的短信服务编号
indexEntry.iServiceId = m_pSmsMtm->ServiceId();
// Create entry to drafts
m_pSmsMtm->SwitchCurrentEntryL(KMsvDraftEntryId);
// Creates a new child entry owned by the context synchronously //同步
m_pSmsMtm->Entry().CreateL(indexEntry);
// Set the MTM's active context to the new message
m_SmsId = indexEntry.Id();
m_pSmsMtm->SwitchCurrentEntryL(m_SmsId);
// modify by tommy
CSmsHeader& header = m_pSmsMtm->SmsHeader();
CSmsSettings* sendOptions = CSmsSettings::NewL();
CleanupStack::PushL(sendOptions);
sendOptions->CopyL(m_pSmsMtm->ServiceSettings()); //restore existing settings
// set send options
sendOptions->SetDelivery(ESmsDeliveryImmediately); // set to be deliverred immediately 立即发送
// here we modified the character set
sendOptions->SetCharacterSet(TSmsDataCodingScheme::ESmsAlphabetUCS2);
// end
header.SetSmsSettingsL(*sendOptions);
CleanupStack::PopAndDestroy(sendOptions);
// Add message body. Body is set twice because index entry keeps a copy
// of some summary information. Index entry and full stored entry
// must be in sync.
CRichText& body = m_pSmsMtm->Body();
body.Reset();
body.InsertL(0,aMessage);
indexEntry.iDescription.Set(aMessage);
// Add destination address (recipient). Copy address also to the index entry
m_pSmsMtm->AddAddresseeL(aAddress);
indexEntry.iDetails.Set(aAddress);
// commit changes because index entry is only a local variable
m_pSmsMtm->Entry().ChangeL(indexEntry);
// Save full message data to the store
m_pSmsMtm->SaveMessageL();
return indexEntry;
}
TBool CMtmEngine::ValidateCreatedSMS()
{
TMsvPartList partsToBeChecked = KMsvMessagePartBody | KMsvMessagePartRecipient |
KMsvMessagePartOriginator | KMsvMessagePartDate;
// ValidateMessage return KErrNone if message is valid.
TMsvPartList failedParts = m_pSmsMtm->ValidateMessage(partsToBeChecked);
if (failedParts == KMsvMessagePartNone)
{
return ETrue;
}
else
{
return EFalse;
}
}
void CMtmEngine::SendSMSL()
{
// Changes the entry on which later actions are performed to the entry with the
// specified TMsvId.
m_pSmsMtm->SwitchCurrentEntryL(m_SmsId);
// Load the created message
m_pSmsMtm->LoadMessageL();
// Gets the current SMS service settings
CSmsSettings& serviceSettings = m_pSmsMtm->ServiceSettings();
// Gets the number of service centre addresses stored in this object.
const TInt numSCAddresses = serviceSettings.NumSCAddresses();
// There should always be a service center number
if (numSCAddresses > 0)
{
CSmsNumber* serviceCentreNumber = NULL;
// get the service center number
if ((serviceSettings.DefaultSC() >= 0) && (serviceSettings.DefaultSC() < numSCAddresses))
serviceCentreNumber = &(serviceSettings.SCAddress(serviceSettings.DefaultSC()));
else
serviceCentreNumber = &(serviceSettings.SCAddress(0));
m_pSmsMtm->SmsHeader().SetServiceCenterAddressL(serviceCentreNumber->Address());
}
else
{
// Leave if there is no service center number
User::Leave(0);
}
m_pSmsMtm->SaveMessageL();
// Index entry must be Updated 索引条目必须更新
TMsvEntry indexEntry = m_pSmsMtm->Entry().Entry();
// Set in-preparation flag
indexEntry.SetInPreparation(EFalse);
// Sets the sending state
indexEntry.SetSendingState(KMsvSendStateWaiting);
m_pSmsMtm->Entry().ChangeL(indexEntry);
// Time to send the message
Cancel(); // prepare iMsvOper for use
m_pEntrySelection->Reset();
m_pEntrySelection->AppendL(m_SmsId);
TBuf8<1> dummyParam;
// There is also InvokeSyncFunctionL which is synchronous.
m_pMsvOper = m_pSmsMtm->InvokeAsyncFunctionL(ESmsMtmCommandScheduleCopy, *m_pEntrySelection, dummyParam, iStatus);
SetActive();
}
void CMtmEngine::GetFolderSMSMessageInformation(TMsvId aFolderID, CDesCArrayFlat*& aMobile, CDesCArrayFlat*& aMessage)
{
m_pSmsMtm->SwitchCurrentEntryL( aFolderID );
CMsvEntry& entry = m_pSmsMtm->Entry();
// Remember to delete this entry after no longer needed!
// Only intrested in messages. Filter out service etries.
CMsvEntrySelection* entries = entry.ChildrenWithMtmL(KUidMsgTypeSMS);
TBuf<2> sTmp;
// CDesCArrayFlat* arrayRead = new (ELeave) CDesCArrayFlat(10);
// CDesCArrayFlat* arrayAddr = new (ELeave) CDesCArrayFlat(10);
// CDesCArrayFlat* arrayMsgBody = new (ELeave) CDesCArrayFlat(10);
if(m_pIdArray)
{
m_pIdArray->Reset();
delete m_pIdArray;
}
m_pIdArray = new (ELeave) RArray<TMsvId>;
for (TInt i = entries->Count()-1; i >= 0; i-- )
{
// TBuf<KMessageBodySize> body;
// TBuf<KMessageAddressLength> address;
m_pIdArray->Append((*entries)[i]);
//of message.
m_pSmsMtm->SwitchCurrentEntryL( (*entries)[i] );
aMessage->AppendL(m_pSmsMtm->Entry().Entry().iDescription);
//of mobile
m_pSmsMtm->SwitchCurrentEntryL( (*entries)[i] );
m_pSmsMtm->LoadMessageL();
// CSmsHeader& header = iSmsMtm->SmsHeader();
// aMobile->AppendL(header.FromAddress());
aMobile->AppendL(m_pSmsMtm->Entry().Entry().iDetails );
}
// Delete entries. This is your responsibility.
entries->Reset();
delete entries;
entries = 0;
// aIsRead = arrayRead;
// aMobile = arrayAddr; // address array
// aMessage = arrayMsgBody; // msg body array
}
void CMtmEngine::MoveToFolderL(TInt aIndex,TMsvId aFolder)
{
MoveToFolderL((*m_pIdArray)[aIndex], aFolder);
}
void CMtmEngine::MoveToFolderL(TMsvId aMessageId,TMsvId aFolder)
{
m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
TMsvSelectionOrdering selection;
selection.SetShowInvisibleEntries(ETrue);
CMsvEntry* parentEntry = CMsvEntry::NewL( m_pSmsMtm->Session(),
m_pSmsMtm->Entry().Entry().Parent(), selection );
CleanupStack::PushL(parentEntry);
// Move the message
parentEntry->MoveL( aMessageId, aFolder );
CleanupStack::PopAndDestroy(); // parentEntry
}
void CMtmEngine::DeleteMessageL(TInt aCurrent)
{
DeleteMessageL((*m_pIdArray)[aCurrent]);
m_pIdArray->Remove(aCurrent);
}
void CMtmEngine::DeleteMessageL(TMsvId aMessageId )
{
m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
TMsvId parent = m_pSmsMtm->Entry().Entry().Parent();
m_pSmsMtm->SwitchCurrentEntryL( parent );
m_pSmsMtm->Entry().DeleteL( aMessageId );
}
TBool CMtmEngine::GetMessageL(TMsvId aMessageId,TDes& aMessage)
{
m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
if ( m_pSmsMtm->Entry().HasStoreL() )
{
// SMS message is stored inside Messaging store.
CMsvStore* store = m_pSmsMtm->Entry().ReadStoreL();
CleanupStack::PushL(store);
if (store->HasBodyTextL())
{
CRichText* richText = CRichText::NewL(
CEikonEnv::Static()->SystemParaFormatLayerL(),
CEikonEnv::Static()->SystemCharFormatLayerL());
richText->Reset();
CleanupStack::PushL(richText);
// Get the SMS body text.
store->RestoreBodyTextL(*richText);
const TInt length = richText->DocumentLength();
TBuf<KMessageBodySize> message;
// Check length because message is read to limited size TBuf.
if ( length >= KMessageBodySize )
{
message.Append( richText->Read(0, KMessageBodySize -1) );
}
else
{
message.Append( richText->Read(0, length) );
}
aMessage.Append( message );
CleanupStack::PopAndDestroy(richText);
}
CleanupStack::PopAndDestroy(store);
}
else
{
return EFalse;
}
return ETrue;
}
void CMtmEngine::GetMessageAddressL(TMsvId aMessageId,TDes& aAddress)
{
m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
// Remember to load before using the SmsHeader
m_pSmsMtm->LoadMessageL();
// CSmsHeader& header = m_pSmsMtm->SmsHeader();
//
// aAddress.Append( header.FromAddress() );
// Other possibility is this: (It's little bit faster than the previous one).
aAddress.Append( m_pSmsMtm->Entry().Entry().iDetails );
}
TBool CMtmEngine::GetMessageIndexBodyTextL(TMsvId aMessageId,TDes& aMessage)
{
m_pSmsMtm->SwitchCurrentEntryL( aMessageId );
aMessage.Append(m_pSmsMtm->Entry().Entry().iDescription );
return ETrue;
}
RArray<TMsvId>* CMtmEngine::GetMessageIds()
{
return m_pIdArray;
}
void CMtmEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* aArg3)
{
switch (aEvent)
{
// This event tells us that the session has been opened
case EMsvServerReady:
CreateMtmClientL();
break;
default:
// do nothing
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -