examples/ForumNokia/SMSExample/Engine/src/SMSExampleMtmsEngine.cpp

00001 /*
00002  * Copyright � 2008 Nokia Corporation.
00003  */
00004 
00005 // INCLUDE FILES
00006 #include "SMSExampleMtmsEngine.h"
00007 #include "SmsEnginePanics.pan"
00008 
00009 // SYSTEM FILES
00010 #include <f32file.h>        // TParsePtrC
00011 #include <mmsclient.h>      // CMmsClientMtm
00012 #include <mtclreg.h>        // CClientMtmRegistry
00013 #include <mtmdef.h>         // KMsvMessagePartBody
00014 #include <smsclnt.h>        // CSmsClientMtm
00015 #include <smscmds.h>        // ESmsMtmCommandScheduleCopy
00016 #include <smutset.h>        // CSmsSettings
00017 #include <smuthdr.h>        // CSmsHeader
00018 #include <txtrich.h>        // CRichText
00019 #include <eikenv.h>
00020 
00021 const TInt KMessageAddressLength = 100;
00022 const TInt KMessageBodySize = 512;
00023 const TInt KArrayGranularity=10;
00024 
00025 _LIT(KSenderJohnDoe,"*Unknown*");
00026 
00027 CSMSExampleMtmsEngine* CSMSExampleMtmsEngine::NewL(
00028                                       MSMSExampleMtmsEngineObserver& aObserver)
00029     {
00030     CSMSExampleMtmsEngine* self =
00031                            new (ELeave) CSMSExampleMtmsEngine(aObserver);
00032     CleanupStack::PushL(self);
00033     self->ConstructL();
00034     CleanupStack::Pop(self);
00035     return self;
00036     }
00037 
00038 CSMSExampleMtmsEngine::CSMSExampleMtmsEngine(
00039                                       MSMSExampleMtmsEngineObserver& aObserver)
00040 : CActive(0),
00041   iObserver(aObserver),
00042   iSmsId(KMsvNullIndexEntryId)
00043     {
00044 
00045     }
00046 
00047 void CSMSExampleMtmsEngine::ConstructL()
00048     {
00049     CActiveScheduler::Add(this);
00050 
00051     // iEntrySelection encapsulates an array of entry IDs
00052     iEntrySelection = new (ELeave) CMsvEntrySelection;
00053 
00054     // Represents a channel of communication between a client thread
00055     // (Client-side MTM, User Interface MTM, or message client application)
00056     // and the Message Server thread.
00057     // Session is opened asynchorously. CreateMtmClientL() is called afterwards.
00058     // Another possibility is use OpenSyncL which is synchronous.
00059     iSession = CMsvSession::OpenAsyncL(*this);
00060     }
00061 
00062 // Creates CSmsClientMtm after session has been opened.
00063 void CSMSExampleMtmsEngine::CreateMtmClientL()
00064     {
00065     // Client-side MTM registry.
00066     iClientMtmReg = CClientMtmRegistry::NewL(*iSession);
00067 
00068     //Note: If capabilities are missing, then iSmsMtm stays null
00069     // Get the SMS Mtm client from the registry
00070     iSmsMtm = static_cast<CSmsClientMtm*>(iClientMtmReg->NewMtmL(KUidMsgTypeSMS));
00071     }
00072 
00073 CSMSExampleMtmsEngine::~CSMSExampleMtmsEngine()
00074     {
00075     Cancel();
00076     delete iMsvOper;
00077     delete iEntrySelection;
00078     delete iSmsMtm;
00079     delete iClientMtmReg;
00080     delete iSession;
00081     }
00082 
00083 void CSMSExampleMtmsEngine::DoCancel()
00084     {
00085     if (iMsvOper)
00086         {
00087         iMsvOper->Cancel();
00088         delete iMsvOper;
00089         iMsvOper = NULL;
00090         }
00091     }
00092 
00093 void CSMSExampleMtmsEngine::RunL()
00094     {
00095     iObserver.HandleMessageSentL(iStatus.Int());
00096     }
00097 
00098 // Move message to folder. Notice that the iSmsMtm points to the parent, not
00099 // to the message itself. If you move messages from inbox to drafts, those
00100 // messages cannot be edited because their complete flag is true.
00101 void CSMSExampleMtmsEngine::MoveToFolderL( TMsvId aMessageId,  TMsvId aFolder )
00102     {
00103     iSmsMtm->SwitchCurrentEntryL( aMessageId );
00104     TMsvSelectionOrdering selection;
00105     selection.SetShowInvisibleEntries(ETrue);
00106     CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(),
00107         iSmsMtm->Entry().Entry().Parent(), selection );
00108     CleanupStack::PushL(parentEntry);
00109     // Move the message
00110     parentEntry->MoveL( aMessageId, aFolder );
00111     CleanupStack::PopAndDestroy(parentEntry); // parentEntry
00112     }
00113 
00114 // Delete message from a folder. Notice that the iSmsMtm points to the parent,
00115 // not to the message itself.
00116 void CSMSExampleMtmsEngine::DeleteMessageL( TMsvId aMessageId )
00117     {
00118     iSmsMtm->SwitchCurrentEntryL( aMessageId );
00119     TMsvId parent = iSmsMtm->Entry().Entry().Parent();
00120 
00121     iSmsMtm->SwitchCurrentEntryL( parent );
00122     iSmsMtm->Entry().DeleteL( aMessageId );
00123     }
00124 
00125 // Get originator address from SmsHeader.
00126 void CSMSExampleMtmsEngine::GetMessageAddressL( TMsvId aMessageId,
00127                                                 TDes& aAddress )
00128     {
00129     iSmsMtm->SwitchCurrentEntryL( aMessageId );
00130 
00131     // Remember to load before using the SmsHeader
00132     iSmsMtm->LoadMessageL();
00133 
00134     CSmsHeader& header = iSmsMtm->SmsHeader();
00135 
00136     aAddress.Append( header.FromAddress() );
00137     // Other possibility is this: (It's little bit faster than the previous one).
00138     // aAddress.Append( iSmsMtm->Entry().Entry().iDetails );
00139     }
00140 
00141 // Get message body from entry storage (CMsvStore). CMsvStore stores whole
00142 // message, not summary information ( see GetMessageIndexBodyTextL() ).
00143 TBool CSMSExampleMtmsEngine::GetMessageL( TMsvId aMessageId, TDes& aMessage)
00144     {
00145     iSmsMtm->SwitchCurrentEntryL( aMessageId );
00146 
00147     if ( iSmsMtm->Entry().HasStoreL() )
00148         {
00149         // SMS message is stored inside Messaging store.
00150         CMsvStore* store = iSmsMtm->Entry().ReadStoreL();
00151         CleanupStack::PushL(store);
00152 
00153         if (store->HasBodyTextL())
00154             {
00155             CRichText* richText = CRichText::NewL(
00156                               CEikonEnv::Static()->SystemParaFormatLayerL(),
00157                               CEikonEnv::Static()->SystemCharFormatLayerL());
00158             richText->Reset();
00159             CleanupStack::PushL(richText);
00160 
00161             // Get the SMS body text.
00162             store->RestoreBodyTextL(*richText);
00163             const TInt length = richText->DocumentLength();
00164             TBuf<KMessageBodySize> message;
00165 
00166             // Check length because message is read to limited size TBuf.
00167             if ( length >= KMessageBodySize )
00168                 {
00169                 message.Append( richText->Read(0, KMessageBodySize -1) );
00170                 }
00171             else
00172                 {
00173                 message.Append( richText->Read(0, length) );
00174                 }
00175 
00176             aMessage.Append( message );
00177 
00178             CleanupStack::PopAndDestroy(richText);
00179             }
00180         CleanupStack::PopAndDestroy(store);
00181         }
00182     else
00183         {
00184         return EFalse;
00185         }
00186 
00187     return ETrue;
00188     }
00189 
00190 // Get beginning of message's body. Index entry is just a summary of the whole
00191 // message.
00192 TBool CSMSExampleMtmsEngine::GetMessageIndexBodyTextL( TMsvId aMessageId,
00193                                                        TDes& aMessage)
00194     {
00195     iSmsMtm->SwitchCurrentEntryL( aMessageId );
00196 
00197     aMessage.Append(iSmsMtm->Entry().Entry().iDescription );
00198     return ETrue;
00199     }
00200 
00201 
00202 // Copy message to another folder.
00203 void CSMSExampleMtmsEngine::CopyMessageL( TMsvId aMessageId, TMsvId aFolder )
00204     {
00205     iSmsMtm->SwitchCurrentEntryL( aMessageId );
00206     TMsvSelectionOrdering selection;
00207     selection.SetShowInvisibleEntries(ETrue);
00208     CMsvEntry* parentEntry = CMsvEntry::NewL( iSmsMtm->Session(),
00209         iSmsMtm->Entry().Entry().Parent(), selection );
00210     CleanupStack::PushL(parentEntry);
00211     // iSmsMtm points to the parent
00212     parentEntry->CopyL( aMessageId, aFolder );
00213     CleanupStack::PopAndDestroy(); // parentEntry
00214     }
00215 
00216 // ids of messages that has been got using ListMessagesL
00217 RArray<TMsvId>* CSMSExampleMtmsEngine::GetMessageIds()
00218     {
00219     return iIdArray;
00220     }
00221 
00222 
00223 // Get all folder's children which are SMS messages.
00224 // Note that the folder can contain .sis files which have to be filtered out.
00225 // IdArray is made here because it makes finding the SMS easier later on.
00226 void CSMSExampleMtmsEngine::GetFolderSMSMessageInformationL(
00227                                                 TMsvId aFolderID,
00228                                                 CDesCArrayFlat*& aAddresses,
00229                                                 CDesCArrayFlat*& aMessages )
00230     {
00231 
00232     iSmsMtm->SwitchCurrentEntryL( aFolderID );
00233     CMsvEntry& entry = iSmsMtm->Entry();
00234 
00235     // Remember to delete this entry after no longer needed!
00236     // Only intrested in messages. Filter out service etries.
00237     CMsvEntrySelection* entries = entry.ChildrenWithMtmL(KUidMsgTypeSMS);
00238 
00239     CDesCArrayFlat* arrayAddr =
00240                         new (ELeave) CDesCArrayFlat( KArrayGranularity );
00241     CDesCArrayFlat* arrayMsgBody =
00242                         new (ELeave) CDesCArrayFlat( KArrayGranularity );
00243 
00244     iIdArray = new (ELeave) RArray<TMsvId>;
00245 
00246     for (TInt i = 0; i < entries->Count(); i++ )
00247         {
00248         TBuf<KMessageBodySize> body;
00249         TBuf<KMessageAddressLength> address;
00250 
00251         // Append only SMS messages, .sis files etc. are disregarded.
00252         // Take only beginning of SMS body, because listbox only shows
00253         // beginning of message.
00254         if ( GetMessageIndexBodyTextL( (*entries)[i], body ) ) // SMS body
00255             {
00256             iIdArray->Append( (*entries)[i] );
00257             arrayMsgBody->AppendL ( body );
00258 
00259             // Recipient address
00260             //If done an own messafe to the drafts with out a address then failes
00261             TRAPD(err, GetMessageAddressL( (*entries)[i], address ) );
00262             if( err == KErrNone)
00263                 arrayAddr->AppendL ( address );
00264             else
00265                 arrayAddr->AppendL ( KSenderJohnDoe );
00266             }
00267         }
00268 
00269     // Delete entries. This is your responsibility.
00270     entries->Reset();
00271     delete entries;
00272     entries = 0;
00273 
00274     aAddresses = arrayAddr; // address array
00275     aMessages = arrayMsgBody; // msg body array
00276     }
00277 
00278 // Tells when the session has been opened
00279 void CSMSExampleMtmsEngine::HandleSessionEventL(TMsvSessionEvent aEvent,
00280                                                 TAny* /*aArg1*/,
00281                                                 TAny* /*aArg2*/,
00282                                                 TAny* /*aArg3*/)
00283     {
00284     switch (aEvent)
00285         {
00286         // This event tells us that the session has been opened
00287         case EMsvServerReady:
00288             CreateMtmClientL();
00289             break;
00290 
00291         default:
00292             // do nothing
00293             break;
00294         }
00295     }

Generated by  doxygen 1.6.2