gdsms.cpp
上传用户:sempras
上传日期:2007-03-04
资源大小:821k
文件大小:30k
源码类别:

Symbian

开发平台:

C/C++

  1. /*
  2.         GDSMS.CPP - source file for GDSMS application
  3.         
  4. */
  5.  
  6. #include <txtrich.h>                // for CRichText
  7. #include <smscmds.h>                // for TSmsMtmCommand (asynchronous sms commands)
  8. #include <eikenv.h>                 // for CEikonEnv
  9. #include <smuthdr.h>                // for CSmsHeader
  10. #include <smsetdlg.h>               // for CSmsAddServiceCentreDialog
  11. #include <comabs.h>                 // for CCommandAbsorbingControl
  12. #include <mtclreg.h>                // for CClientMtmRegistry 
  13. #include <smutset.h>                // for CSmsMessageSettings
  14. #include "gdsms.h"                  // own definitions
  15. #include "gdsms.hrh"                // own resource header
  16. #include <gdsms.rsg>
  17. // this is the content of the message
  18. _LIT(KGDSMSTag, "GDSM");
  19. // Own constants
  20. const TUid KUidGDSMS = { 0x101F3CD9 };      // GDSMS application UID 
  21. const TInt KTagLength = 4;                  // length of our message tag
  22. const TInt KMaxTelephoneNumberLength = 30;  // maximum length for a gsm number
  23. //
  24. // CGDSMSTelNumDialog
  25. //
  26. /*
  27. -----------------------------------------------------------------------------
  28.     CGDSMSTelNumDialog::CGDSMSTelNumDialog()
  29.     C++ constructor
  30.     Return values:      None
  31. -----------------------------------------------------------------------------
  32. */
  33. CGDSMSTelNumDialog::CGDSMSTelNumDialog(TDesC& aRecipientsTelNum)
  34.     : iRecipientsTelNum(&aRecipientsTelNum)                         // Initialise data
  35.     {
  36.     }
  37. /*
  38. -----------------------------------------------------------------------------
  39.     CGDSMSTelNumDialog::PreLayoutDynInitL()
  40.     Function for doing pre layout events.
  41.     Return values:      None
  42. -----------------------------------------------------------------------------
  43. */
  44. void CGDSMSTelNumDialog::PreLayoutDynInitL()  
  45.     {
  46.     (static_cast<CEikTelephoneNumberEditor*>(Control(EGDSMSTelNumEditor)))->SetNumberL(*iRecipientsTelNum);
  47.     }
  48. /*
  49. -----------------------------------------------------------------------------
  50.     CGDSMSTelNumDialog::OkToExitL()
  51.     Function for doing on exit events.
  52.     Return values:      ETrue or EFalse
  53. -----------------------------------------------------------------------------
  54. */
  55. TBool CGDSMSTelNumDialog::OkToExitL(TInt /*aButtonId*/)             // Function for doing on exit events
  56.     {
  57.     TBuf<KMaxTelephoneNumberLength> recipientsTelNum;
  58.     (static_cast<CEikTelephoneNumberEditor*>(Control(EGDSMSTelNumEditor)))->GetNumber(recipientsTelNum);
  59.     if (recipientsTelNum.Length()==0)
  60.         {
  61.         iEikonEnv->InfoMsg(R_GDSMS_TEL_NUMBER_DIALOG);
  62.         return EFalse;
  63.         }
  64.     (static_cast<HBufC*>(iRecipientsTelNum))->Des()=recipientsTelNum; // Number is set to iRecipientsTelNum
  65.     return ETrue;
  66.     }
  67. //
  68. // CGDSMSAppView
  69. //
  70. /*
  71. -----------------------------------------------------------------------------
  72.     CGDSMSAppView::NewL()
  73.     2nd phase construction.
  74.     Return values:      CGDSMSAppView*
  75. -----------------------------------------------------------------------------
  76. */
  77. CGDSMSAppView* CGDSMSAppView::NewL(const TRect& aRect)
  78.     {
  79.     CGDSMSAppView* self=NewLC(aRect);
  80.     CleanupStack::Pop(); // self
  81.     return self;
  82.     }
  83. /*
  84. -----------------------------------------------------------------------------
  85.     CGDSMSAppView::NewLC()
  86.     2nd phase construction. Created object is put into CleanupStack
  87.     before calling ConstructL().
  88.     Return values:      CGDSMSAppView*
  89. -----------------------------------------------------------------------------
  90. */
  91. CGDSMSAppView* CGDSMSAppView::NewLC(const TRect& aRect)
  92.     {
  93.     CGDSMSAppView* self = new(ELeave) CGDSMSAppView();
  94.     CleanupStack::PushL(self);
  95.     self->ConstructL(aRect);
  96.     return self;
  97.     }
  98. /*
  99. -----------------------------------------------------------------------------
  100.     CGDSMSAppView::CGDSMSAppView()
  101.     C++ constructor
  102. -----------------------------------------------------------------------------
  103. */
  104. CGDSMSAppView::CGDSMSAppView()
  105.     {
  106.     }
  107. /*
  108. -----------------------------------------------------------------------------
  109.     CGDSMSAppView::ConstructL()
  110.     2nd phase constructor.
  111.     Return values:      CGDSMSAppView*
  112. -----------------------------------------------------------------------------
  113. */
  114. void CGDSMSAppView::ConstructL(const TRect& aRect)
  115.     {
  116.     CreateWindowL();
  117.     SetRect(aRect);
  118. ActivateL();
  119.     }
  120. /*
  121. -----------------------------------------------------------------------------
  122.     CGDSMSAppView::Draw()
  123.     Simple Draw method (only clears the application area).
  124. -----------------------------------------------------------------------------
  125. */
  126. void CGDSMSAppView::Draw(const TRect& /*aRect*/) const
  127.     {
  128.     CWindowGc& gc = SystemGc();
  129.     gc.Clear();
  130.     }
  131. //
  132. // CGDSMSAppUi
  133. //
  134. /*
  135. -----------------------------------------------------------------------------
  136.   CGDSMSAppUi::ConstructL()                          
  137.   
  138.   2nd phase constructor
  139. -----------------------------------------------------------------------------
  140. */
  141. void CGDSMSAppUi::ConstructL()
  142.     {
  143.     BaseConstructL();                                   // init this AppUi with standard values
  144.     iAppView=CGDSMSAppView::NewL(ClientRect()); 
  145.     iRecipient=HBufC::NewL(KMaxTelephoneNumberLength);  // for recipient sms number
  146.     iMsvId = NULL;                                      // MsvId for keeping track of the message server entries. 
  147.     // Create CMsvSession
  148.     iSession = CMsvSession::OpenAsyncL(*this); // new session is opened asynchronously
  149.                                                // CompleteConstructL() is called when async finishes
  150.     }
  151. /*
  152. -----------------------------------------------------------------------------
  153.     CGDSMSAppUi::~CGDSMSAppUi()
  154.     Destructor.
  155. -----------------------------------------------------------------------------
  156. */
  157. CGDSMSAppUi::~CGDSMSAppUi()
  158.     {
  159.     delete iAppView;
  160.     
  161.     delete iRecipient;
  162.     delete iMtm;
  163.     delete iMtmReg;
  164.     iMsvId = NULL;
  165.     delete iSession;    // session must be deleted last (and constructed first)
  166.     }
  167. /*
  168. -----------------------------------------------------------------------------
  169.     CGDSMSAppUi::CompleteConstructL()
  170.     Creates client MTM registry when session is ready for use. 
  171.     This completes model construction and is called after 'server
  172.     ready' event is received after async opening of CMsvSession.
  173. -----------------------------------------------------------------------------
  174. */
  175. void CGDSMSAppUi::CompleteConstructL()
  176.     {
  177.     // We get a MtmClientRegistry from our session
  178.     // this registry is used to instantiate new mtms.
  179.     iMtmReg = CClientMtmRegistry::NewL(*iSession);
  180.     // notify the user with a InfoWin
  181.     iEikonEnv->InfoWinL(_L("Construction"),_L("Server session opened."));
  182.     }
  183. /*
  184. -----------------------------------------------------------------------------
  185.     CGDSMSAppUi::HandleSessionEventL()
  186.     Handles session event observer and calls event handling functions in
  187.     observer. Note that if additional session event handlers are defined in
  188.     the session, they are called before this function (as this is the
  189.     main session observer).
  190.     The type of event is indicated by the value of aEvent. The 
  191.     interpretation of the TAny arguments depends on this type. For most 
  192.     event types, the action that is taken, for example, updating the 
  193.     display, is client-specific. All clients though should respond to 
  194.     EMsvCloseSession and EMsvServerTerminated events. 
  195. -----------------------------------------------------------------------------
  196. */
  197. void CGDSMSAppUi::HandleSessionEventL(TMsvSessionEvent aEvent, TAny* aArg1, TAny* aArg2, TAny* /*aArg3*/)
  198.     {
  199.     switch (aEvent)
  200.         {
  201.         case EMsvEntriesCreated:        // A new entry has been created in the message server
  202.             // We are interested in messages that are created in Inbox
  203.             TMsvId* entryId;
  204.             entryId = static_cast<TMsvId*>(aArg2);          // entry id from the session event
  205.             
  206.             if ( *entryId == KMsvGlobalInBoxIndexEntryId )  // new entry has been created in Inbox folder
  207.                 {
  208.                 // We take the created entries into a selection
  209.                 CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);
  210.                 // entry pointer for making changes in the actual message contexts
  211.                 CMsvEntry* entry;
  212.                 //Process each created entry, one at a time.
  213.                 for(TInt i = 0; i < entries->Count(); i++)
  214.                     {
  215.                     // Setting all messages in the selection as invisible
  216.                     entry = iSession->GetEntryL( entries->At(i) );  // this reserves memory for a new CMsvEntry
  217.                     TMsvEntry msvEntry(entry->Entry());
  218.                     msvEntry.SetVisible(EFalse);                    // set as invisible
  219.                     if( MessageReceivedL(entries->At(i)) ) // this checks the entry and handles it if it is targeted to GDSMS app   
  220.                         {
  221.                         // this is our message, set also as read
  222.                         msvEntry.SetUnread(EFalse);
  223.                         msvEntry.iMtmData3 = KUidGDSMS.iUid;        // use our app uid as an identifier
  224.                         }
  225.                     else
  226.                         {
  227.                         // message was not for us, settin it as visible again
  228.                         msvEntry.SetVisible(ETrue);
  229.                         }
  230.                     entry->ChangeL( msvEntry );                     // commit changes
  231.                     delete entry;
  232.                     }
  233.                 }
  234.             break;
  235.         case EMsvEntriesMoved:      // this event is given when message entries are moved
  236.             {
  237.             // An entry has been moved to another parent
  238.             // We are interested messages that have been moved to Sent folder
  239.             TMsvId* entryId;
  240.             entryId = static_cast<TMsvId*>(aArg2); 
  241.             if ( *entryId == KMsvSentEntryId )   // the entry has been moved into Sent folder
  242.                 {
  243.                 // We take the moved entries into a selection
  244.                 CMsvEntrySelection* entries = static_cast<CMsvEntrySelection*>(aArg1);
  245.                 //Process each created entry, one at a time.
  246.                 for(TInt i = 0; i < entries->Count(); i++)
  247.                     {
  248.                     DeleteSentEntry(entries->At(i)); // this checks the entry and deletes if it is created by GDSMS app                
  249.                     }
  250.                 }
  251.             }
  252.             break;
  253.             // This event tells us that the session has been opened
  254.         case EMsvServerReady:
  255.             CompleteConstructL();       // Construct the mtm registry & sms mtm
  256.             break;
  257.         default:
  258.             // All other events are ignored
  259.             break;
  260.         }
  261.     }
  262. /*
  263. -----------------------------------------------------------------------------
  264.     CGDSMSAppUi::HandleCommandL(TInt aCommand)
  265.     Handle the commands from CBA and menu items
  266. -----------------------------------------------------------------------------
  267. */
  268. void CGDSMSAppUi::HandleCommandL(TInt aCommand)
  269.     {
  270.     switch (aCommand)
  271.         {
  272.     case EGDSMSCmdSend:
  273.         CmdSendL();
  274.         break;
  275.     case EEikCmdExit: 
  276.         CmdExitL();
  277.         break;
  278.     default:
  279.         break;
  280.         }
  281.     }
  282. /*
  283. -----------------------------------------------------------------------------
  284.     CGDSMSAppUi::CmdSendL()
  285.     Handle send command  
  286.     
  287. -----------------------------------------------------------------------------
  288. */
  289. void CGDSMSAppUi::CmdSendL()
  290.     {
  291.     if (!InitializeCommunicationsL())
  292.         {
  293.         iEikonEnv->InfoWinL(_L("Error"),_L("Problems in initializingncommunications."));
  294.         return;
  295.         }
  296.     if (!SendMessageL())
  297.         {
  298.         iEikonEnv->InfoWinL(_L("Error"),_L("Problems in sendingnmessage."));
  299.         return;
  300.         }
  301.     }
  302. /*
  303. -----------------------------------------------------------------------------
  304.     CGDSMSAppUi::CmdExitL()
  305.     
  306.     Exit application
  307.   
  308. -----------------------------------------------------------------------------
  309. */
  310. void CGDSMSAppUi::CmdExitL()
  311.     {
  312.     DeleteMessagesFromInboxL();
  313.     Exit();
  314.     }
  315. /*
  316. -----------------------------------------------------------------------------
  317.     CGDSMSAppUi::InitializeCommunicationsL()
  318.     
  319.     Initialize a new message and ask the user for a recipient gsm number.
  320.     Return values:      ETrue or EFalse
  321. -----------------------------------------------------------------------------
  322. */
  323. TBool CGDSMSAppUi::InitializeCommunicationsL()
  324.     { 
  325.     // first the tel number
  326.     // we get it from our telNumDialog
  327.     CGDSMSTelNumDialog* telNumDialog=new(ELeave)CGDSMSTelNumDialog(*iRecipient);
  328.     if (!telNumDialog->ExecuteLD(R_GDSMS_TEL_NUMBER_DIALOG))
  329.         return EFalse;
  330.     // set up a new message
  331.     iMsvId = CreateNewMessageL();
  332.     // Set the new message to be the current entry
  333.     SetEntryL(iMsvId);
  334.     return ETrue;
  335.     }
  336. /*
  337. -----------------------------------------------------------------------------
  338.     CGDSMSAppUi::CreateNewMessageL()
  339.     Creates a new message server entry and set up default values.
  340.     Return values:      TMsvId (the id of created entry)
  341. -----------------------------------------------------------------------------
  342. */
  343. TMsvId CGDSMSAppUi::CreateNewMessageL()
  344. {
  345.     TMsvEntry newEntry;              // This represents an entry in the Message Server index
  346.     newEntry.iMtm = KUidMsgTypeSMS;                         // message type is SMS
  347.     newEntry.iType = KUidMsvMessageEntry;                   // this defines the type of the entry: message 
  348.     newEntry.iServiceId = KMsvLocalServiceIndexEntryId;     // ID of local service (containing the standard folders)
  349.     newEntry.iDate.HomeTime();                              // set the date of the entry to home time
  350.     newEntry.SetInPreparation(ETrue);                       // a flag that this message is in preparation
  351.     //----
  352.     //newEntry.iBioType = 0x1000ffff;                         // define a bio UID if sending a bio message over SMS bearer
  353.     //----
  354.     // - CMsvEntry accesses and acts upon a particular Message Server entry.
  355.     // - NewL() does not create a new entry, but simply a new object to access an existing entry.
  356.     // - It takes in as parameters the client's message server session,
  357.     //   ID of the entry to access and initial sorting order of the children of the entry. 
  358. //
  359.     CMsvEntry* entry = CMsvEntry::NewL(*iSession, KMsvDraftEntryIdValue ,TMsvSelectionOrdering());
  360.     CleanupStack::PushL(entry);
  361.     CCommandAbsorbingControl::NewLC();
  362.     CMsvOperationWait* wait = CMsvOperationWait::NewLC();
  363.     wait->Start();
  364.     // We create a new entry asynchronously...
  365.     CMsvOperation* oper = entry->CreateL(newEntry,wait->iStatus);
  366.     CleanupStack::PushL(oper);
  367.     CActiveScheduler::Start();
  368.     // ...and keep track of the progress of the create operation.
  369.     TMsvLocalOperationProgress progress = McliUtils::GetLocalProgressL(*oper);
  370.     User::LeaveIfError(progress.iError);
  371.     // Set our entry context to the created one
  372.     entry->SetEntryL(progress.iId); // operation progress contains the ID of the ceated entry
  373.     CleanupStack::PopAndDestroy(4); // entry,oper,wait, CCommandAbsorbingControl
  374.     return progress.iId;
  375. }
  376. /*
  377. -----------------------------------------------------------------------------
  378.     CGDSMSAppUi::SetEntryL(TMsvId aEntryId)
  379.     Set up current message entry.
  380.     Note: It can be useful to remember the original entry id for 
  381.           error handling.
  382. -----------------------------------------------------------------------------
  383. */
  384. void CGDSMSAppUi::SetEntryL(TMsvId aEntryId)
  385.     {
  386.     // Get the server entry from our session
  387.     CMsvEntry* entry = iSession->GetEntryL(aEntryId);
  388.     CleanupStack::PushL(entry);
  389.     
  390.     // Check if our mtm is different from the mtm set to our entry
  391.     if (iMtm == NULL || entry->Entry().iMtm != (iMtm->Entry()).Entry().iMtm)
  392.         {
  393.         // If so, we delete the old... 
  394.         delete iMtm;
  395.         iMtm = NULL;
  396.         
  397.         // ...and get a new one from the MtmRegistry
  398.         iMtm = iMtmReg->NewMtmL(entry->Entry().iMtm);
  399.         iMtm->SetCurrentEntryL(entry);  
  400.         }
  401.     else
  402.         {
  403.         // if there is no need to change our mtm,
  404.         // we only set our entry as current.
  405.         iMtm->SetCurrentEntryL(entry);
  406.         }
  407.     CleanupStack::Pop(); //entry
  408.     entry = NULL;
  409.     }
  410. /* 
  411. -----------------------------------------------------------------------------
  412.     CGDSMSAppUi::SendMessageL()
  413.     Prepares the message body and sends the message.
  414.     Return values:      ETrue or EFalse
  415. -----------------------------------------------------------------------------
  416. */
  417. TBool CGDSMSAppUi::SendMessageL()
  418.     {
  419.     TMsvEntry msvEntry = iMtm->Entry().Entry();
  420.     // We get the message body from Mtm and insert a bodytext
  421.     CRichText& mtmBody = iMtm->Body();
  422.     mtmBody.Reset();
  423.     mtmBody.InsertL(0, KGDSMSTag);   // insert our msg tag as the body text
  424.     
  425.     // set iRecipient into the Details of the entry
  426.     msvEntry.iDetails.Set(iRecipient->Des());  // set recipient info in details
  427.     msvEntry.SetInPreparation(EFalse);         // set inPreparation to false
  428.     msvEntry.SetSendingState(KMsvSendStateWaiting);   // set the sending state (immediately)
  429. msvEntry.iDate.HomeTime();                        // set time to Home Time
  430.  
  431.     // To handle the sms specifics we start using SmsMtm
  432.     CSmsClientMtm* smsMtm = STATIC_CAST(CSmsClientMtm*, iMtm);
  433.     // 
  434.     smsMtm->RestoreServiceAndSettingsL();
  435.  
  436. // CSmsHeader encapsulates data specific for sms messages,
  437.     // like service center number and options for sending.
  438.     CSmsHeader& header = smsMtm->SmsHeader();
  439.     CSmsSettings* sendOptions = CSmsSettings::NewL();
  440.     CleanupStack::PushL(sendOptions);
  441.     sendOptions->CopyL(smsMtm->ServiceSettings()); // restore existing settings
  442.     // set send options
  443.     sendOptions->SetDelivery(ESmsDeliveryImmediately);      // set to be delivered immediately
  444.     header.SetSmsSettingsL(*sendOptions);
  445. // let's check if there's sc address
  446. if (header.Message().ServiceCenterAddress().Length() == 0)
  447. {
  448. // no, there isn't. We assume there is at least one sc number set and use
  449. // the default SC number. 
  450. CSmsSettings* serviceSettings = &(smsMtm->ServiceSettings());
  451.         
  452. // if number of scaddresses in the list is null
  453.         if (!serviceSettings->NumSCAddresses())
  454.             {
  455. // here there should be a dialog in which user can add sc number
  456. iEikonEnv->InfoWinL(_L("No service center number"),_L("cannot send this one."));
  457. }
  458. else
  459. {
  460.             // set sc address to default. 
  461.             CSmsNumber* sc = 0;
  462. sc = &(serviceSettings->SCAddress(serviceSettings->DefaultSC()));
  463. header.Message().SetServiceCenterAddressL(sc->Address());
  464. }
  465. }
  466. CleanupStack::PopAndDestroy(); // send options 
  467.     
  468.     // Add our recipient to the list, takes in two TDesCs, first is real address and second is an alias
  469.     // works also without the alias parameter.
  470. smsMtm->AddAddresseeL(iRecipient->Des(),msvEntry.iDetails);
  471.     
  472.     // Next we mark our message so later on we know which
  473.     // message to delete from the Sent folder
  474.     msvEntry.iMtmData3 = KUidGDSMS.iUid;     // use our app uid as an identifier
  475.     // save message
  476.     CMsvEntry& entry = iMtm->Entry();
  477.     entry.ChangeL(msvEntry);                // make sure that we are handling the right entry
  478. smsMtm->SaveMessageL();                 // closes the message
  479.     // This moves the message entry to outbox, we'll schedule it for sending after this. 
  480.     TMsvId movedId = MoveMessageEntryL( KMsvGlobalOutBoxIndexEntryId );  // move message to outbox
  481.  
  482.     // We must create an entry selection for message copies (although now we only have one message in selection)
  483.     CMsvEntrySelection* selection = new (ELeave) CMsvEntrySelection;
  484.     CleanupStack::PushL(selection);
  485.     selection->AppendL(movedId);            // add our message to the selection
  486.     SetScheduledSendingStateL(selection);   // schedule the sending with the active scheduler
  487.     CleanupStack::PopAndDestroy(); // selection
  488.     return ETrue; // at this point the message has been sent
  489.     }
  490. /* 
  491. -----------------------------------------------------------------------------
  492.     CGDSMSAppUi::MoveMessageEntryL(TMsvId aTarget) const
  493.     Moves an entry to another parent.
  494.     Return values:      TMsvId of the moved message
  495. -----------------------------------------------------------------------------
  496. */
  497. TMsvId CGDSMSAppUi::MoveMessageEntryL( TMsvId aTarget )
  498.     {
  499. TMsvEntry msvEntry( (iMtm->Entry()).Entry() );
  500.     TMsvId id = msvEntry.Id();
  501. if (msvEntry.Parent() != aTarget)
  502. {
  503. TMsvSelectionOrdering sort;
  504. sort.SetShowInvisibleEntries(ETrue);    // we want to handle also the invisible entries
  505.         // Take a handle to the parent entry
  506. CMsvEntry* parentEntry = CMsvEntry::NewL(iMtm->Session(), msvEntry.Parent(), sort);
  507. CleanupStack::PushL(parentEntry);
  508. // Move original from the parent to the new location
  509. CCommandAbsorbingControl::NewLC();
  510. CMsvOperationWait* wait = CMsvOperationWait::NewLC();
  511. wait->Start();
  512. CMsvOperation* op = parentEntry->MoveL(msvEntry.Id(), aTarget, wait->iStatus);
  513. CleanupStack::PushL(op);
  514. CActiveScheduler::Start();  
  515. TMsvLocalOperationProgress prog=McliUtils::GetLocalProgressL(*op);
  516. User::LeaveIfError(prog.iError);
  517. id = prog.iId; // id of the moved entry
  518. CleanupStack::PopAndDestroy(4);// op, wait, parentEntry, CCommandAbsorbingControl
  519. }
  520. return id;
  521.     }
  522. /*
  523. -----------------------------------------------------------------------------
  524.     void CGDSMSAppUi::SetScheduledSendingStateL
  525.     Schedules the message to be sent through the etel server.
  526.     Return values:      none
  527. -----------------------------------------------------------------------------
  528. */
  529. void CGDSMSAppUi::SetScheduledSendingStateL(CMsvEntrySelection* aSelection)
  530.     {
  531.     
  532.     CBaseMtm* smsMtm = iMtm;
  533.     // Add entry to task scheduler
  534.     TBuf8<1> dummyParams;
  535.     CCommandAbsorbingControl::NewLC();
  536.     CMsvOperationWait* waiter = CMsvOperationWait::NewLC();
  537.     waiter->Start();
  538.     // invoking async schedule copy command on our mtm
  539.     CMsvOperation* op= smsMtm->InvokeAsyncFunctionL(
  540.             ESmsMtmCommandScheduleCopy,
  541.             *aSelection,
  542.             dummyParams,
  543.             waiter->iStatus);
  544.     CleanupStack::PushL(op);
  545.     CActiveScheduler::Start();
  546.     CleanupStack::PopAndDestroy(3); // waiter, op, CCommandAbsorbingControl
  547.     }
  548. /*
  549. -----------------------------------------------------------------------------
  550.     CGDSMSAppUi::DeleteSentEntry()
  551.     Delete our message from the Sent folder. We are double checking that
  552.     the entry we are handling is indeed in the Sent folder - AND that it
  553.     is the same message entry that wsa sent by this application.
  554.     If so, the message will be deleted from the Sent folder.
  555.     Return values:      ETrue or EFalse
  556. -----------------------------------------------------------------------------
  557. */
  558. TBool CGDSMSAppUi::DeleteSentEntry(TMsvId aEntryId)
  559.     {
  560.     // Load this entry to our mtm
  561.     SetEntryL( aEntryId ); 
  562.     TMsvEntry msvEntry( (iMtm->Entry()).Entry() );
  563.     if (msvEntry.Parent() == KMsvSentEntryId) // check again that our entry is in sent
  564. {
  565.         if (msvEntry.iMtmData3 == KUidGDSMS.iUid)    // this entry has been created by our app
  566.             {
  567.             // Taking a handle to the Sent folder...
  568.     TMsvSelectionOrdering sort;
  569.     sort.SetShowInvisibleEntries(ETrue);    // we want to handle also the invisible entries
  570.             // Take a handle to the parent entry
  571.     CMsvEntry* parentEntry = CMsvEntry::NewL(iMtm->Session(), msvEntry.Parent(), sort);
  572.     CleanupStack::PushL(parentEntry);
  573.             // here parentEntry is the Sent folder (must be so that we can call DeleteL) 
  574.     parentEntry->DeleteL(msvEntry.Id());
  575.     CleanupStack::PopAndDestroy(parentEntry);
  576.             
  577.             // information to the user
  578.             iEikonEnv->InfoMsg(_L("Message deleted in SENT folder."));
  579.             return ETrue; // entry was deleted
  580.             }
  581.         }
  582.     return EFalse; // no entries deleted
  583.     }
  584. /*
  585. -----------------------------------------------------------------------------
  586.     CGDSMSAppUi::MessageReceivedL()
  587.     Handle a new message entry that has been created on the messaging
  588.     server. This method checks if the message was targeted for this
  589.     application and then removes it from the server.
  590. -----------------------------------------------------------------------------
  591. */
  592. TBool CGDSMSAppUi::MessageReceivedL(TMsvId aEntryId)
  593.     {
  594.     TBool returnVal = EFalse;
  595.     CMsvEntry* entry = iSession->GetEntryL(aEntryId);
  596.     CleanupStack::PushL(entry);
  597.     TMsvEntry msvEntry = entry->Entry();
  598.     
  599.     // first we create a new mtm to handle this message (in case our own mtm is in use)
  600.     CBaseMtm* smsMtm = iMtmReg->NewMtmL(msvEntry.iMtm);
  601.     smsMtm->SwitchCurrentEntryL(aEntryId);
  602.     smsMtm->LoadMessageL();     // load the message
  603.     if (smsMtm->Body().Read(0,4).Compare(KGDSMSTag)==0) // message is targeted to us
  604.         {
  605.         // Now we process the message
  606.         iEikonEnv->InfoMsg(smsMtm->Body().Read(0,4)); // this will flash our message text in the upper right corner of the screen
  607.         
  608.         returnVal = ETrue;
  609.         /* As a change to the previous version of GDSMS, the message will not be deleted right
  610.            after reading it. Instead all messages that have been read by this app will be deleted
  611.            from the Inbox when this app is closed. See DeleteMessagesFromInboxL().
  612.             
  613.          */
  614.         }
  615.     // release allocated memory
  616.     delete smsMtm; 
  617.     CleanupStack::Pop(); // entry
  618.     delete entry;
  619.     return returnVal;
  620.     }
  621. /*
  622. -----------------------------------------------------------------------------
  623.     CGDSMSAppUi::DeleteMessagesFromInboxL()
  624.     This method reads the Inbox and deletes all GDSM messages that are 
  625.     invisible.
  626. -----------------------------------------------------------------------------
  627. */
  628. void CGDSMSAppUi::DeleteMessagesFromInboxL()
  629.     {
  630.     // information to the user
  631.     iEikonEnv->InfoMsg(_L("Deleting messages from Inbox."));
  632.     // then delete message from inbox, first take a handle to Inbox...
  633.     TMsvSelectionOrdering sort;
  634. sort.SetShowInvisibleEntries(ETrue);    // we want to handle also the invisible entries
  635.     // Take a handle to the Inbox entry
  636. CMsvEntry* parentEntry = CMsvEntry::NewL(*iSession, KMsvGlobalInBoxIndexEntryId, sort);
  637. CleanupStack::PushL(parentEntry);
  638.     CMsvEntrySelection* entries = parentEntry->ChildrenL();   // A selection of all the entries of the Inbox
  639.     CleanupStack::PushL(entries);
  640.     // go through all entries in the Inbox
  641.     for(TInt i = 0; i < entries->Count(); i++)
  642.         {
  643.         if( parentEntry->ChildDataL(entries->At(i)).iMtmData3 == KUidGDSMS.iUid )   // check that message is for GDSMS
  644.             {
  645.             // delete the current entry (message)
  646.         parentEntry->DeleteL(entries->At(i));
  647.             }
  648.         }
  649.     
  650.     // information to the user
  651.     iEikonEnv->InfoMsg(_L("Done."));
  652. CleanupStack::PopAndDestroy(2);   // entries, parentEntry
  653.     }
  654. //
  655. // CGDSMSDocument
  656. //
  657. /*
  658. -----------------------------------------------------------------------------
  659.     CGDSMSDocument::NewL(
  660.     2nd phase construction.
  661. -----------------------------------------------------------------------------
  662. */
  663. CGDSMSDocument* CGDSMSDocument::NewL(CEikApplication& aApp)
  664.     {
  665.     CGDSMSDocument* self = new(ELeave) CGDSMSDocument(aApp);
  666.     CleanupStack::PushL(self);
  667.     self->ConstructL();
  668.     CleanupStack::Pop(); //self.
  669.     return self;
  670.     }
  671. /*
  672. -----------------------------------------------------------------------------
  673.     CGDSMSDocument::CGDSMSDocument()
  674.     C++ constructor
  675. -----------------------------------------------------------------------------
  676. */
  677. CGDSMSDocument::CGDSMSDocument(CEikApplication& aApp)
  678.     : CEikDocument(aApp)
  679.     {
  680.     }
  681. /*
  682. -----------------------------------------------------------------------------
  683.     CGDSMSDocument::ConstructL()
  684.     2nd phase constructor.
  685. -----------------------------------------------------------------------------
  686. */
  687. void CGDSMSDocument::ConstructL()
  688.     {    
  689.     }
  690. /*
  691. -----------------------------------------------------------------------------
  692.     CGDSMSDocument::CreateAppUiL()
  693.     Create new CGDSMSAppUi object
  694.     Return values:      CEikAppUi*
  695. -----------------------------------------------------------------------------
  696. */
  697. CEikAppUi* CGDSMSDocument::CreateAppUiL()
  698.     {
  699.     return (new(ELeave) CGDSMSAppUi);
  700.     }
  701. //
  702. // CGDSMSApplication
  703. //
  704. /*
  705. -----------------------------------------------------------------------------
  706.     CGDSMSApplication::AppDllUid()
  707.     Returns application UID of GDSMS application
  708. -----------------------------------------------------------------------------
  709. */
  710. TUid CGDSMSApplication::AppDllUid() const
  711.     {
  712.     return KUidGDSMS;
  713.     }
  714. /*
  715. -----------------------------------------------------------------------------
  716.     CGDSMSApplication::CreateDocumentL()
  717.     Create new application document
  718.     Return values:      CApaDocument*
  719. -----------------------------------------------------------------------------
  720. */
  721. CApaDocument* CGDSMSApplication::CreateDocumentL()
  722.     {
  723.     return (CGDSMSDocument::NewL(*this));
  724.     }
  725. //
  726. // Functions for Application Architecture
  727. //
  728. EXPORT_C CApaApplication* NewApplication()
  729.     {
  730.     return (new CGDSMSApplication);
  731.     }
  732. //
  733. // DLL entry point
  734. //
  735. GLDEF_C TInt E32Dll(TDllReason)
  736.     {
  737.     return KErrNone;
  738.     }