www.pudn.com > LDFUCK.rar > MtmsEngine.cpp


/* 
* ============================================================================ 
*  Name     : CMtmsEngine from SMSExampleMtmsEngine.h 
*  Part of  : SMSExample 
*  Created  : 12.03.2005 by Forum Nokia 
*  Version  : 1.0 
*  Copyright: Nokia Corporation 
* ============================================================================ 
*/ 
 
// INCLUDE FILES 
#include "MtmsEngine.h" 
 
// SYSTEM FILES 
#include         // TParsePtrC 
#include       // CMmsClientMtm 
#include         // CClientMtmRegistry  
#include          // KMsvMessagePartBody  
#include         // CSmsClientMtm 
#include         // ESmsMtmCommandScheduleCopy 
#include         // CSmsHeader 
#include         // CSmsSettings 
#include         // CRichText 
#include  
 
const TInt KMessageAddressLength 	= 32; 
const TInt KMessageBodySize 		= 256; 
const TInt KListInfoLength			= 512; 
 
#define		MEMORY_FREE_EX(a) if(a) {delete a; a = NULL;} 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::NewL(MSMSExampleMtmsEngineObserver& aObserver) 
// 
// Symbian OS 2 phase constructor. 
// ---------------------------------------------------------------------------- 
CMtmsEngine* CMtmsEngine::NewL(MMtmsEngineObserver& aObserver) 
{ 
    CMtmsEngine* self = new (ELeave) CMtmsEngine(aObserver); 
    CleanupStack::PushL(self); 
    self->ConstructL(); 
    CleanupStack::Pop(self); 
    return self; 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::CMtmsEngine(MSMSExampleMtmsEngineObserver&  
//												aObserver) 
// 
// Symbian OS 2 phase constructor. 
// ---------------------------------------------------------------------------- 
CMtmsEngine::CMtmsEngine(MMtmsEngineObserver& aObserver) 
: CActive(0), 
iObserver(aObserver), 
iIdArray(NULL), 
iSmsId(KMsvNullIndexEntryId) 
{ 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::ConstructL() 
// 
// Symbian OS 2nd phase constructor. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::ConstructL() 
{ 
    CActiveScheduler::Add(this); 
	 
    // iEntrySelection encapsulates an array of entry IDs 
    iEntrySelection = 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. 
    iSession = CMsvSession::OpenAsyncL(*this); 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::CreateMtmClientL() 
// 
// Create a CSmsClientMtm after session has been opened. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::CreateMtmClientL() 
{ 
    // Client-side MTM registry.  
    iClientMtmReg = CClientMtmRegistry::NewL(*iSession); 
	 
    // Get the SMS Mtm client from the registry 
    iSmsMtm = static_cast(iClientMtmReg->NewMtmL(KUidMsgTypeSMS)); 
	 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::~CMtmsEngine() 
// 
// Destructor. 
// ---------------------------------------------------------------------------- 
CMtmsEngine::~CMtmsEngine() 
{ 
    Cancel(); 
    delete iMsvOper; 
    delete iEntrySelection; 
    delete iSmsMtm; 
    delete iClientMtmReg; 
    delete iSession; 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::DoCancel() 
// 
// From CActive, cancel CMsvOperation  
// ---------------------------------------------------------------------------- 
void CMtmsEngine::DoCancel() 
{ 
    if (iMsvOper) 
	{ 
        iMsvOper->Cancel(); 
        delete iMsvOper; 
        iMsvOper = NULL; 
	} 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::RunL() 
// 
// Sending SMS is asynchronous operation. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::RunL() 
{ 
    iObserver.HandleMessageSentL(iStatus.Int()); 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::CreateSMSMessageL(const TDesC& aAddress,  
//											const TDesC& aMessage) 
// 
// Create an SMS message 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::CreateSMSMessageL(const TDesC& aAddress, const TDesC& aMessage) 
{ 
    // Set SMS parameters  
    TMsvEntry indexEntry; 
	indexEntry.iDate.HomeTime(); 
    indexEntry.SetInPreparation(ETrue); 
	// This is an SMS message 
    indexEntry.iMtm = KUidMsgTypeSMS; 
    indexEntry.iType = KUidMsvMessageEntry; 
	//Gets the ID of the current SMS service. 
    indexEntry.iServiceId = iSmsMtm->ServiceId(); 
     
    // Create entry to drafts 
    iSmsMtm->SwitchCurrentEntryL(KMsvDraftEntryId); 
	 
	// Creates a new child entry owned by the context synchronously. 
    iSmsMtm->Entry().CreateL(indexEntry); 
	 
    // Set the MTM's active context to the new message 
    iSmsId = indexEntry.Id(); 
    iSmsMtm->SwitchCurrentEntryL(iSmsId); 
	 
//modify by tommy 
	CSmsHeader& header = iSmsMtm->SmsHeader(); 
    CSmsSettings* sendOptions = CSmsSettings::NewL(); 
    CleanupStack::PushL(sendOptions); 
    sendOptions->CopyL(iSmsMtm->ServiceSettings()); // restore existing settings 
    // set send options 
    sendOptions->SetDelivery(ESmsDeliveryImmediately); // set to be delivered 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 = iSmsMtm->Body(); 
    body.Reset(); 
    body.InsertL(0, aMessage); 
    indexEntry.iDescription.Set(aMessage); 
	 
    // Add destination address (recipient). Copy address also to the index entry 
    iSmsMtm->AddAddresseeL(aAddress); 
    indexEntry.iDetails.Set(aAddress); 
	 
    // Commit changes because index entry is only a local variable 
    iSmsMtm->Entry().ChangeL(indexEntry); 
	 
    // Save full message data to the store 
    iSmsMtm->SaveMessageL(); 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::ValidateCreatedSMS() 
// 
// Validate message. This should be done before sending the SMS. 
// ---------------------------------------------------------------------------- 
TBool CMtmsEngine::ValidateCreatedSMS() 
{ 
    TMsvPartList partsToBeChecked = KMsvMessagePartBody | KMsvMessagePartRecipient | 
        KMsvMessagePartOriginator | KMsvMessagePartDate; 
	 
	// ValidateMessage return KErrNone if message is valid. 
    TMsvPartList failedParts = iSmsMtm->ValidateMessage(partsToBeChecked); 
     
	if (failedParts == KMsvMessagePartNone) 
	{ 
		return ETrue; 
	} 
	else  
	{ 
		return EFalse; 
	} 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::SendSMSL() 
// 
// Before sending sms message should be created CreateSMSMessageL() and 
// Validated ValidateCreatedSMS(). 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::SendSMSL() 
{ 
    // Changes the entry on which later actions are performed to the entry with the  
	// specified TMsvId.  
    iSmsMtm->SwitchCurrentEntryL(iSmsId); 
	 
    // Load the created message 
    iSmsMtm->LoadMessageL(); 
	 
    // Gets the current SMS service settings 
    CSmsSettings& serviceSettings = iSmsMtm->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)); 
		 
        iSmsMtm->SmsHeader().SetServiceCenterAddressL(serviceCentreNumber->Address()); 
	} 
	else  
	{ 
		// Leave if there is no service center number 
		User::Leave(0); 
	} 
	 
    iSmsMtm->SaveMessageL(); 
	 
    // Index entry must be Updated 
    TMsvEntry indexEntry = iSmsMtm->Entry().Entry(); 
	// Set in-preparation flag 
    indexEntry.SetInPreparation(EFalse); 
	// Sets the sending state 
    indexEntry.SetSendingState(KMsvSendStateWaiting); 
    iSmsMtm->Entry().ChangeL(indexEntry); 
	 
    // Time to send the message 
    Cancel(); // prepare iMsvOper for use 
	iEntrySelection->Reset(); 
	iEntrySelection->AppendL(iSmsId); 
	 
    TBuf8<1> dummyParam; 
	// There is also InvokeSyncFunctionL which is synchronous. 
	iMsvOper = iSmsMtm->InvokeAsyncFunctionL(ESmsMtmCommandScheduleCopy, *iEntrySelection, dummyParam, iStatus); 
    SetActive(); 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::MoveToFolderL( TMsvId aMessageId,  TMsvId aFolder ) 
// 
// Move message to folder. Notice that the iSmsMtm points to the parent, not 
// to the message itself. If you move messages from inbox to drafts, those 
// messages cannot be edited because their complete flag is true. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::MoveToFolderL(TInt aIndex, TMsvId aFolder) 
{ 
	MoveToFolderL((*iIdArray)[aIndex], aFolder); 
} 
 
void CMtmsEngine::MoveToFolderL( TMsvId aMessageId,  TMsvId aFolder ) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aMessageId ); 
	TMsvSelectionOrdering selection; 
	selection.SetShowInvisibleEntries(ETrue); 
	CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(),  
		iSmsMtm->Entry().Entry().Parent(), selection ); 
	CleanupStack::PushL(parentEntry); 
	// Move the message 
	parentEntry->MoveL( aMessageId, aFolder ); 
	CleanupStack::PopAndDestroy(); // parentEntry 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::DeleteMessageL( TMsvId aMessageId ) 
// 
// Delete message from a folder. Notice that the iSmsMtm points to the parent,  
// not to the message itself. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::DeleteMessageL(TInt nCurrent) 
{ 
	DeleteMessageL((*iIdArray)[nCurrent]); 
	iIdArray->Remove(nCurrent); 
} 
 
void CMtmsEngine::DeleteMessageL( TMsvId aMessageId ) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aMessageId ); 
	TMsvId parent = iSmsMtm->Entry().Entry().Parent(); 
	 
	iSmsMtm->SwitchCurrentEntryL( parent ); 
	iSmsMtm->Entry().DeleteL( aMessageId ); 
} 
 
void CMtmsEngine::GetMessageInfo(TInt aIndex, TDes& aDate) 
{ 
	iSmsMtm->SwitchCurrentEntryL( (*iIdArray)[aIndex] ); 
	TTime tmTmp = iSmsMtm->Entry().Entry().iDate; 
	 
	TBuf<32> sTmp; 
	sTmp.Format(_L("%04d-%02d-%02d\r\n"), tmTmp.DateTime().Year(), tmTmp.DateTime().Month(), tmTmp.DateTime().Day()); 
	aDate.Append(sTmp); 
	sTmp.Format(_L("%02d:%02d:%02d\r\n"), tmTmp.DateTime().Hour(), tmTmp.DateTime().Minute(), tmTmp.DateTime().Second()); 
	aDate.Append(sTmp); 
} 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::GetMessageAddressL( TMsvId aMessageId,  
//										      TDes& aAddress ) 
// 
// Get originator address from SmsHeader. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::GetMessageAddressL( TMsvId aMessageId, TDes& aAddress ) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aMessageId );	 
	 
	// Remember to load before using the SmsHeader 
	iSmsMtm->LoadMessageL(); 
	 
	CSmsHeader&	header = iSmsMtm->SmsHeader(); 
	 
	aAddress.Append( header.FromAddress() ); 
	// Other possibility is this: (It's little bit faster than the previous one). 
	// aAddress.Append( iSmsMtm->Entry().Entry().iDetails ); 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::GetMessageL( TMsvId aMessageId, TDes& aMessage) 
// 
// Get message body from entry storage (CMsvStore). CMsvStore stores whole 
// message, not summary information ( see GetMessageIndexBodyTextL() ). 
// ---------------------------------------------------------------------------- 
TBool CMtmsEngine::GetMessageL( TMsvId aMessageId, TDes& aMessage) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aMessageId ); 
	 
	if ( iSmsMtm->Entry().HasStoreL() )  
	{ 
		// SMS message is stored inside Messaging store. 
		CMsvStore* store = iSmsMtm->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 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; 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::GetMessageIndexBodyTextL( TMsvId aMessageId, TDes& aMessage) 
// 
// Get beginning of message's body. Index entry is just a summary of the whole 
// message. 
// ---------------------------------------------------------------------------- 
TBool CMtmsEngine::GetMessageIndexBodyTextL( TMsvId aMessageId, TDes& aMessage) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aMessageId ); 
	aMessage.Append(iSmsMtm->Entry().Entry().iDescription ); 
	return ETrue; 
} 
 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::CopyMessageL( TMsvId aMessageId, TMsvId aFolder ) 
// 
// Copy message to another folder.  
// ---------------------------------------------------------------------------- 
void CMtmsEngine::CopyMessageL( TMsvId aMessageId, TMsvId aFolder ) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aMessageId ); 
	TMsvSelectionOrdering selection; 
	selection.SetShowInvisibleEntries(ETrue); 
	CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(),  
		iSmsMtm->Entry().Entry().Parent(), selection ); 
	CleanupStack::PushL(parentEntry); 
	// iSmsMtm points to the parent 
	parentEntry->CopyL( aMessageId, aFolder ); 
	CleanupStack::PopAndDestroy(); // parentEntry 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::GetMessageIds() 
// 
// ids of messages that has been got using ListMessagesL 
// ---------------------------------------------------------------------------- 
RArray* CMtmsEngine::GetMessageIds() 
{ 
	return iIdArray; 
} 
 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::GetFolderSMSMessageInformation( TMsvId aFolderID,  
//														   CDesCArrayFlat* aAddresses,  
//														   CDesCArrayFlat* aMessages ) 
// 
// Get all folder's children which are SMS messages. 
// Note that the folder can contain .sis files which have to be filtered out. 
// IdArray is made here because it makes finding the SMS easier later on. 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::GetFolderSMSMessageInformation(TMsvId aFolderID, CDesCArrayFlat*& aIsRead, CDesCArrayFlat*& aMobile, CDesCArrayFlat*& aMessage) 
{ 
	iSmsMtm->SwitchCurrentEntryL( aFolderID ); 
	CMsvEntry& entry = iSmsMtm->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(iIdArray) 
	{ 
		iIdArray->Reset(); 
		delete iIdArray; 
	} 
	iIdArray = new (ELeave) RArray; 
 
	for (TInt i = entries->Count()-1; i >= 0; i-- )  
	{ 
//		TBuf body; 
//		TBuf address; 
		 
		iIdArray->Append((*entries)[i]); 
		//of READ FLAG 
		iSmsMtm->SwitchCurrentEntryL( (*entries)[i] ); 
		sTmp.Format(_L("%d"), !iSmsMtm->Entry().Entry().Unread()); 
		aIsRead->AppendL(sTmp); 
		//of message. 
		iSmsMtm->SwitchCurrentEntryL( (*entries)[i] ); 
		aMessage->AppendL(iSmsMtm->Entry().Entry().iDescription); 
		//of mobile 
		iSmsMtm->SwitchCurrentEntryL( (*entries)[i] );	 
		iSmsMtm->LoadMessageL(); 
		CSmsHeader&	header = iSmsMtm->SmsHeader(); 
		aMobile->AppendL(header.FromAddress()); 
	} 
		 
	// Delete entries. This is your responsibility. 
	entries->Reset(); 
	delete entries; 
	entries = 0; 
 
//	aIsRead		= arrayRead; 
//	aMobile		= arrayAddr; // address array 
//	aMessage	= arrayMsgBody; // msg body array 
} 
// ---------------------------------------------------------------------------- 
// CMtmsEngine::HandleSessionEventL(TMsvSessionEvent aEvent, TAny*  
//	/*aArg1*/, TAny* /*aArg2*/, TAny* /*aArg3*/) 
// 
// Tells when the session has been opened 
// ---------------------------------------------------------------------------- 
void CMtmsEngine::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; 
	} 
}