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

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

Generated by  doxygen 1.6.2