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; } }