www.pudn.com > smssend-vc.rar > csmshandler.cpp
/* Copyright (c) 2003, Nokia. All rights reserved */ // INCLUDE FILES #include#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CSmsHandler.h" #include "CSmsAppUi.h" #include "smutset.h" #include "smuthdr.h" // ============================ MEMBER FUNCTIONS =============================== // ----------------------------------------------------------------------------- // CSmsHandler::CSmsHandler() // C++ default constructor can NOT contain any code, that might leave. // ----------------------------------------------------------------------------- // CSmsHandler::CSmsHandler( CSmsAppUi* aSmsAppUi ) : CActive( CActive::EPriorityStandard ) { CActiveScheduler::Add( this ); iSmsAppUi = aSmsAppUi; // pointer to AppUi iNextUnread = 0; // index of next unread message in iSelection } // ----------------------------------------------------------------------------- // CSmsHandler::ConstructL() // Symbian 2nd phase constructor can leave. // ----------------------------------------------------------------------------- // void CSmsHandler::ConstructL() { // Session to message server is opened asynchronously. iSession = CMsvSession::OpenAsyncL( *this ); // Entry selection for all received messages. iSelection = new ( ELeave ) CMsvEntrySelection(); } // ----------------------------------------------------------------------------- // CSmsHandler::NewL() // Two-phased constructor. // ----------------------------------------------------------------------------- // CSmsHandler* CSmsHandler::NewL( CSmsAppUi* aSmsAppUi ) { CSmsHandler* self = NewLC( aSmsAppUi ); CleanupStack::Pop( self ); return self; } // ----------------------------------------------------------------------------- // CSmsHandler::NewLC() // Two-phased constructor. // ----------------------------------------------------------------------------- // CSmsHandler* CSmsHandler::NewLC( CSmsAppUi* aSmsAppUi ) { CSmsHandler* self = new ( ELeave ) CSmsHandler( aSmsAppUi ); CleanupStack::PushL( self ); self->ConstructL(); return self; } // ---------------------------------------------------------- // CSmsHandler::~CSmsHandler() // Destructor. // ---------------------------------------------------------- // CSmsHandler::~CSmsHandler() { Cancel(); // cancel any outstanding request delete iOperation; delete iMtmUiRegistry; delete iSelection; delete iSmsMtm; delete iMtmRegistry; delete iSession; // session must be deleted last } // ----------------------------------------------------------------------------- // CSmsHandler::DoCancel() // Cancels a request. // ----------------------------------------------------------------------------- // void CSmsHandler::DoCancel() { if ( iOperation ) { iOperation->Cancel(); } } // ----------------------------------------------------------------------------- // CSmsHandler::RunL() // Handles request completion events. // ----------------------------------------------------------------------------- // void CSmsHandler::RunL() { User::LeaveIfError( iStatus != KErrNone ); // Determine the current operations progress. // ProgressL returns an 8 bit descriptor. TBufC8 progress( iOperation->ProgressL() ); _LIT8( KCompare, "KErrNone" ); User::LeaveIfError( !progress.Compare( KCompare ) ); // The pointer to the current CMsvOperation object is no longer needed. delete iOperation; iOperation = NULL; // Determine which request has finished. switch ( iState ) { case EWaitingForMoving: // Once a message is moved to Outbox it is scheduled for sending. ScheduleL(); break; case EWaitingForScheduling: { TMsvEntry entry( iSmsMtm->Entry().Entry() ); TInt state( entry.SendingState() ); if ( state == KMsvSendStateWaiting || state == KMsvSendStateScheduled) { HBufC* text = StringLoader::LoadLC( R_SMS_MOVED_TO_OUTBOX ); CAknInformationNote* informationNote = new ( ELeave ) CAknInformationNote; informationNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); } break; } default: break; } } // ----------------------------------------------------------------------------- // CSmsHandler::HandleSessionEventL() // Handles notifications of events from the Message Server. // ----------------------------------------------------------------------------- // void CSmsHandler::HandleSessionEventL( TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/) { switch ( aEvent ) { // Session to server established case EMsvServerReady: { TMsvId serviceId( KUidMsgTypeSMS.iUid ); // SMS service id // Determine if the event was succesful. // ServiceProgress inserts TBuf8 value in progress. TBuf8 progress; iSession->ServiceProgress( serviceId, progress ); _LIT8( KCompare, "KErrNone" ); if ( progress.Compare( KCompare ) ) { HBufC* text = StringLoader::LoadLC( R_SMS_SERVER_SESSION ); CAknInformationNote* informationNote = new ( ELeave ) CAknInformationNote; informationNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); // Check that MtmRegistry has not already been accessed. if ( !iMtmRegistry ) { AccessMtmL(); } } else { HBufC* text = StringLoader::LoadLC( R_SMS_SESSION_ERROR ); CAknErrorNote* errorNote = new ( ELeave ) CAknErrorNote; errorNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); } break; } // A new entry has been created on the message server. case EMsvEntriesCreated: { // Entry id is obtained from the session event arguments. TMsvId* entryId = STATIC_CAST( TMsvId*, aArg2 ); // We are interested in messages that are created in Inbox. if ( *entryId != KMsvGlobalInBoxIndexEntryId ) { break; } // We take the created entries into a selection CMsvEntrySelection* newEntries = STATIC_CAST( CMsvEntrySelection*, aArg1 ); // Process each created entry. for ( TInt i( 0 ); i < newEntries->Count(); i++ ) { // We are interested in SMS messages. if ( ( iSession->GetEntryL( newEntries->At( i ) ) ) ->Entry().iMtm == KUidMsgTypeSMS ) { // Add the entry to the selection of all received messages. iSelection->AppendL( newEntries->At( i ), 1 ); // Set received messages visible. MessageReceivedL( newEntries->At( i ) ); } } break; } case EMsvCloseSession: case EMsvServerTerminated: case EMsvGeneralError: case EMsvServerFailedToStart: { iSmsAppUi->ServerDown( aEvent ); // close application break; } // All other events are ignored. default: break; } } // ----------------------------------------------------------------------------- // CSmsHandler::AccessMtmL() // Access the MTM Registry and create a SMS specific Client MTM instance. // ----------------------------------------------------------------------------- // void CSmsHandler::AccessMtmL() { // Create an MTM Registry object. iMtmRegistry = CClientMtmRegistry::NewL( *iSession ); // Create an SMS Client MTM object. iSmsMtm = STATIC_CAST( CSmsClientMtm*, iMtmRegistry->NewMtmL( KUidMsgTypeSMS ) ); } // ----------------------------------------------------------------------------- // CSmsHandler::SendL() // Starts the process of creating and sending an SMS message. // ----------------------------------------------------------------------------- // TBool CSmsHandler::SendL( const TDesC& aRecipientNumber, const TDesC& aMessageText ) { iRecipientNumber = aRecipientNumber; iMessageText = aMessageText; if ( CreateMsgL() ) { return ETrue; } return EFalse; } // ----------------------------------------------------------------------------- // CSmsHandler::CreateMsgL() // Create an SMS message. // ----------------------------------------------------------------------------- // TBool CSmsHandler::CreateMsgL() { // Current entry is the Draft folder. iSmsMtm->SwitchCurrentEntryL( KMsvDraftEntryId ); // Create a new SMS message entry as a child of the current context. iSmsMtm->CreateMessageL( KUidMsgTypeSMS.iUid ); CMsvEntry& serverEntry = iSmsMtm->Entry(); TMsvEntry entry( serverEntry.Entry() ); CRichText& body = iSmsMtm->Body(); // the body of the message body.Reset(); // Insert the message text gotten as input from user. body.InsertL( 0, iMessageText ); // Message will be sent immediately. entry.SetSendingState( KMsvSendStateWaiting ); entry.iDate.HomeTime(); // insert current time // Set the SMS message settings for the message. CSmsHeader& header = iSmsMtm->SmsHeader(); CSmsSettings* settings = CSmsSettings::NewL(); CleanupStack::PushL( settings ); settings->CopyL( iSmsMtm->ServiceSettings() ); // restore settings settings->SetDelivery( ESmsDeliveryImmediately ); // to be delivered immediately header.SetSmsSettingsL( *settings ); // new settings // Let's check if there is a service center address. if ( header.Message().ServiceCenterAddress().Length() == 0 ) { // No, there isn't. We assume there is at least one service center // number set and use the default service center number. CSmsSettings* serviceSettings = &( iSmsMtm->ServiceSettings() ); // Check if number of service center addresses in the list is null. if ( !serviceSettings->NumSCAddresses() ) { HBufC* text = StringLoader::LoadLC( R_SMS_SC_NBR_MISSING ); CAknWarningNote* warningNote = new ( ELeave ) CAknWarningNote; warningNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); // Remember to pop settings even if this branch is taken. CleanupStack::PopAndDestroy( settings ); return EFalse; // quit creating the message } else { // Set service center address to default. // The caller does not take ownership of the returned object. CSmsNumber* smsCenter = &( serviceSettings->SCAddress( serviceSettings->DefaultSC() ) ); header.Message().SetServiceCenterAddressL( smsCenter->Address() ); } } CleanupStack::PopAndDestroy( settings ); // Recipient number is displayed also as the recipient alias. entry.iDetails.Set( iRecipientNumber ); // Add addressee. iSmsMtm->AddAddresseeL( iRecipientNumber, entry.iDetails ); // Validate message. if ( !ValidateL() ) { return EFalse; } entry.SetVisible( ETrue ); // set message as visible entry.SetInPreparation( EFalse ); // set together with the visibility flag serverEntry.ChangeL( entry ); // commit changes iSmsMtm->SaveMessageL(); // save message TMsvSelectionOrdering selection; CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(), KMsvDraftEntryId, selection ); CleanupStack::PushL( parentEntry ); // Move message to Outbox. iOperation = parentEntry->MoveL( entry.Id(), KMsvGlobalOutBoxIndexEntryId, iStatus ); CleanupStack::PopAndDestroy( parentEntry ); iState = EWaitingForMoving; SetActive(); return ETrue; } // ----------------------------------------------------------------------------- // CSmsHandler::ValidateL() // Validate an SMS message. // ----------------------------------------------------------------------------- // TBool CSmsHandler::ValidateL() { // Empty part list to hold the result. TMsvPartList result( KMsvMessagePartNone ); // Validate message body. result = iSmsMtm->ValidateMessage( KMsvMessagePartBody ); if ( result != KMsvMessagePartNone ) { HBufC* text = StringLoader::LoadLC( R_SMS_MSG_BODY ); CAknWarningNote* warningNote = new ( ELeave ) CAknWarningNote; warningNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); return EFalse; } // Validate recipient. result = iSmsMtm->ValidateMessage( KMsvMessagePartRecipient ); if ( result != KMsvMessagePartNone ) { HBufC* text = StringLoader::LoadLC( R_SMS_RECIPIENT_NBR ); CAknWarningNote* warningNote = new ( ELeave ) CAknWarningNote; warningNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); return EFalse; } return ETrue; } // ----------------------------------------------------------------------------- // CSmsHandler::ScheduleL() // Schedule an SMS message for sending. // ----------------------------------------------------------------------------- // void CSmsHandler::ScheduleL() { CMsvEntrySelection* selection = new ( ELeave ) CMsvEntrySelection; CleanupStack::PushL( selection ); selection->AppendL( iSmsMtm->Entry().EntryId() ); // add message to selection // Add entry to task scheduler. TBuf8<1> dummyParams; // dummy parameters needed for InvokeAsyncFunctionL iOperation = iSmsMtm->InvokeAsyncFunctionL( ESmsMtmCommandScheduleCopy, *selection, dummyParams, iStatus ); CleanupStack::PopAndDestroy( selection ); iState = EWaitingForScheduling; SetActive(); } // ----------------------------------------------------------------------------- // CSmsHandler::MessageReceivedL() // Handles a received SMS message. // ----------------------------------------------------------------------------- // void CSmsHandler::MessageReceivedL( TMsvId aEntryId ) { CMsvEntry* serverEntry = iSession->GetEntryL( aEntryId ); // current entry CleanupStack::PushL( serverEntry ); TMsvEntry entry = serverEntry->Entry(); // currently handled message entry entry.SetNew( ETrue ); entry.SetUnread( ETrue ); entry.SetVisible( ETrue ); serverEntry->ChangeL( entry ); // commit changes iSmsAppUi->MessageReceived(); // let UI know we have received a message CleanupStack::PopAndDestroy( serverEntry ); HBufC* text = StringLoader::LoadLC( R_SMS_MSG_RECEIVED ); CAknInformationNote* informationNote = new ( ELeave ) CAknInformationNote; informationNote->ExecuteLD( *text ); CleanupStack::PopAndDestroy( text ); } // ----------------------------------------------------------------------------- // CSmsHandler::ViewL() // Dispalys a received SMS message. // ----------------------------------------------------------------------------- // void CSmsHandler::ViewL() { // There is an own registry for UI MTM's. iMtmUiRegistry = CMtmUiRegistry::NewL( *iSession ); // We are interested in the next unread message. TMsvId entryId( iSelection->At( iNextUnread ) ); CMsvEntry* serverEntry = iSession->GetEntryL( entryId ); CleanupStack::PushL( serverEntry ); // Create new MTM. CBaseMtm* clientMtm = iMtmRegistry->NewMtmL( serverEntry->Entry().iMtm ); CleanupStack::PushL( clientMtm ); clientMtm->SwitchCurrentEntryL( serverEntry->EntryId() ); // Check if there are more unreads messages. iNextUnread++; if ( iNextUnread < iSelection->Count() ) { iSmsAppUi->MessageReceived(); // still messages to read } else { iSmsAppUi->NoMoreUnread(); // no more messages to read } TMsvEntry entry( serverEntry->Entry() ); entry.SetNew( EFalse ); // message is no longer new entry.SetUnread( EFalse ); // message is no longer unread serverEntry->ChangeL( entry ); // commit changes CBaseMtmUi* ui = iMtmUiRegistry->NewMtmUiL( *clientMtm ); // UI MTM for SMS CleanupStack::PushL( ui ); // Display the SMS using the UI MTM. iOperation = ui->ViewL( iStatus ); CleanupStack::PopAndDestroy( 3 ); // ui, clientMtm, serverEntry SetActive(); }