examples/ForumNokia/InternetEmail/src/InternetEmailEngine.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 
00031 #include "InternetEmailEngine.h"
00032 
00033 
00034 // ================= MEMBER FUNCTIONS =======================
00035 //
00036 
00037 // -------------------------------------------------
00038 // CInternetEmailEngine* CInternetEmailEngine::NewL(
00039 //      MInternetEmailEngineObserver& aObserver )
00040 //  static creation
00041 // --------------------------------------------------
00042 //
00043 CInternetEmailEngine* CInternetEmailEngine::NewL( MInternetEmailEngineObserver& aObserver )
00044     {
00045     CInternetEmailEngine* engine=new(ELeave) CInternetEmailEngine( aObserver );
00046     CleanupStack::PushL(engine);
00047     engine->ConstructL();
00048     CleanupStack::Pop(engine);
00049     return engine;
00050     }
00051 
00052 // ------------------------------------------------------------------
00053 // CInternetEmailEngine::CInternetEmailEngine(
00054 //      MInternetEmailEngineObserver& aObserver )
00055 //      : CActive(CActive::EPriorityStandard), iObserver( aObserver )
00056 //  actual constructor. Creates ao with standard prioritory
00057 // ------------------------------------------------------------------
00058 //
00059 CInternetEmailEngine::CInternetEmailEngine( MInternetEmailEngineObserver& aObserver )
00060     : CActive(CActive::EPriorityStandard), iObserver( aObserver )
00061     {
00062     // add this object to the active scheduler
00063     CActiveScheduler::Add(this);
00064     }
00065 
00066 // ---------------------------------------------
00067 // CInternetEmailEngine::~CInternetEmailEngine()
00068 // Frees reserved resources
00069 // ---------------------------------------------
00070 //
00071 CInternetEmailEngine::~CInternetEmailEngine()
00072     {
00073     if( IsActive() )
00074         {
00075         Cancel();
00076         }
00077     if(iMsvOp)
00078         {
00079         iMsvOp->Cancel();
00080         }
00081     delete iMsvOp;
00082     iMsvOp = NULL;
00083 
00084     delete iEntry;
00085     iEntry = NULL;
00086 
00087     delete iMtm;
00088     iMtm = NULL;
00089 
00090     delete iRemoteEntries;
00091     iRemoteEntries = NULL;
00092 
00093     delete iUiReg;
00094     iUiReg = NULL;
00095 
00096     delete iClientReg;
00097     iClientReg = NULL;
00098 
00099     delete iMsvSession; //Session must be deleted last
00100     iMsvSession = NULL;
00101     }
00102 
00103 // ----------------------------------
00104 // CInternetEmailEngine::ConstructL()
00105 //  EPOC two phased constructor
00106 // ----------------------------------
00107 //
00108 void CInternetEmailEngine::ConstructL()
00109     {
00110     // create and open a session towards messaging
00111     // the open operation is asynchronous and HandleSessionEventL
00112     // will be called when the open is complete
00113     iMsvSession=CMsvSession::OpenAsyncL(*this);
00114 
00115     // Default protocol values
00116     iProtocolType=EProtocolNULL;
00117     iProtocolUid=KUidMsgTypeSMTP;
00118     iIsProtocolSet=EFalse;
00119     iHasImapInbox=EFalse;
00120 
00121     //for message handling
00122     iServiceId=KMsvRootIndexEntryId;
00123     iId=KMsvRootIndexEntryId;
00124     iRemoteEntries = new(ELeave) CMsvEntrySelection();
00125 
00126     // other member initalization
00127     iState=EInitialising;
00128     }
00129 
00130 // ------------------------------------------
00131 // CInternetEmailEngine::CompleteConstructL()
00132 //  Called when MsvServer session is ready
00133 // ------------------------------------------
00134 //
00135 void CInternetEmailEngine::CompleteConstructL()
00136     {
00137     iClientReg = CClientMtmRegistry::NewL( *iMsvSession );
00138     iUiReg = CMtmUiRegistry::NewL( *iMsvSession );
00139     }
00140 
00141 // --------------------------------------------------------
00142 // void CInternetEmailEngine::RunL()
00143 //  The main statemachine
00144 //
00145 //  Cornerstone i of this module.
00146 // --------------------------------------------------------
00147 //
00148 void CInternetEmailEngine::RunL()
00149     {
00150 
00151     TBuf8<1> null;
00152 
00153     switch( iState ) // separation between states
00154         {
00155 
00156         // ------------------------------------
00157         //  STATE: EConnecting
00158         //   usually opens internet connection
00159         // ------------------------------------
00160         case EConnecting:
00161             {
00162 
00163             if( iProtocolType==EProtocolPop3 )
00164                 {
00165                 MailCommandL(KPOP3MTMConnect, null);
00166                 }
00167             else
00168                 {
00169                 //As KIMAP4MTMConnect, but, after connection to
00170                 //the IMAP service, starts a background synchronisation.
00171                 //The call completes when the connection occurs
00172                 //and the synchronisation starts.
00173                 MailCommandL(KIMAP4MTMConnectAndSynchronise, null);
00174                 }
00175 
00176             iState=EFetching;
00177             SetActive(); //returns to active scheduler which waits for our request
00178             }
00179             break;
00180 
00181         // ------------------------------------
00182         //  STATE: EFetching
00183         //   handles the remote mail fetch
00184         // ------------------------------------
00185         case EFetching:
00186             {
00187 
00188             // SEPARATION BETWEEN IMAP AND POP
00189             if( iProtocolType==EProtocolPop3 )
00190                 {
00191                 TImPop3GetMailInfo Pop3GetMailInfo; // setup a mail info buffer
00192                 // setting iMaxEmailSize to KMaxTUint tells messaging to get the headers only
00193                 Pop3GetMailInfo.iMaxEmailSize = KMaxTUint;
00194                 // setup which service to download the messages from
00195                 Pop3GetMailInfo.iDestinationFolder = iServiceId;
00196                 // package up the information
00197                 TPckgBuf<TImPop3GetMailInfo> package(Pop3GetMailInfo);
00198                 // execute a pop3 copy mail command
00199                 MailCommandL(KPOP3MTMCopyAllMailWhenAlreadyConnected,package);
00200                 }
00201             else
00202                 {
00203                 //Completes (with KErrNone) only when the background synchronisation
00204                 //has finished. It is used to ensure that no UI-initiated
00205                 //folder syncing is performed during the background synchronisation.
00206                 MailCommandL(KIMAP4MTMWaitForBackground,null);
00207                 }
00208 
00209             iState=EDisconnecting;
00210             SetActive(); //returns to active scheduler which waits for our request
00211             }
00212             break;
00213 
00214         // ------------------------------------
00215         //  STATE: EDisconnecting
00216         //   Disconnects from remote mailbox
00217         //   note: state only for pop as
00218         //   it is only offline mode protocol
00219         // ------------------------------------
00220         case EDisconnecting:
00221             {
00222             // SEPARATION BETWEEN IMAP AND POP
00223             if( iProtocolType==EProtocolPop3 )
00224                 {
00225                 MailCommandL(KPOP3MTMDisconnect,null); // execute a disconnect from service command
00226                 }
00227             else
00228                 {
00229                 //Cancels any operations in progress
00230                 //and sends logout messages to server.
00231                 //As long as the background synchronisation,
00232                 //this will also run any pending delete operations queued while offline.
00233                 MailCommandL(KIMAP4MTMDisconnect,null);
00234                 }
00235 
00236             iState=EDone;
00237             SetActive();
00238             }
00239             break;
00240 
00241         // ------------------------------------
00242         //  STATE: EDone
00243         //   Returns our machine to ready state
00244         // ------------------------------------
00245         case EDone:
00246             {
00247             UpdateRemoteCountL(); // updates model and informs observers
00248             iState = EReady;
00249             if(iMsvOp)
00250                 {
00251                 iMsvOp->Cancel();
00252                 }
00253             delete iMsvOp;
00254             iMsvOp=NULL;
00255             }
00256             break;
00257 
00258         // ------------------------------------
00259         //  STATE: ECanceling
00260         //   waits for mailcommands to cancel
00261         // ------------------------------------
00262         case ECanceling:
00263             {
00264             UpdateRemoteCountL(); // updates model and informs observers
00265             iState= EReady;
00266             delete iMsvOp;
00267             iMsvOp=NULL;
00268             }
00269             break;
00270 
00271         default:
00272             //EReady is default, EInitialising, EReadyButNeedsProtocol
00273             //handled elsewhere
00274             break;
00275         }
00276     }
00277 
00278 // ----------------------------------------------------------------------------
00279 // void CInternetEmailEngine::MailCommandL( const TInt aCommand,TDes8& aParams)
00280 //  Excecutes asynchronous calls for both protocols. Note the specific
00281 //  aSelection and aParams given to InvokeAsyncFunctionL (and later to
00282 //  TransferCommandL) define the functioncall.
00283 //
00284 //  Cornerstone ii of this module.
00285 // ----------------------------------------------------------------------------
00286 void CInternetEmailEngine::MailCommandL( const TInt aCommand, TDes8& aParams)
00287     {
00288     // make sure iServiceId is a remote type service
00289     if( iServiceId != KMsvLocalServiceIndexEntryId )
00290         {
00291         iRemoteEntries->Reset();
00292         iRemoteEntries->AppendL(iServiceId); //aSelection[0] is used in many mtm commands
00293 
00294         // get the msventry for the service id
00295         CMsvEntry* service = iMsvSession->GetEntryL(iServiceId);
00296         CleanupStack::PushL(service);
00297 
00298         // make sure the mtm for the service is of approriate type
00299         if(service->Entry().iMtm == iProtocolUid)
00300             {
00301             // delete and reset any outstanding operation
00302             if(iMsvOp)
00303                 {
00304                 iMsvOp->Cancel();
00305                 }
00306             delete iMsvOp;
00307             iMsvOp=NULL;
00308             iMsvOp=iMtm->InvokeAsyncFunctionL(aCommand,*iRemoteEntries,aParams/*ptr*/,iStatus);
00309             if( iStatus != KRequestPending )
00310                 {
00311                 User::Leave( iStatus.Int() ); //leave if error
00312                 }
00313             }
00314         CleanupStack::PopAndDestroy(service);
00315         }
00316     else
00317         {
00318         User::Leave(KErrNotFound);
00319         }
00320     }
00321 
00322 // -----------------------------------------------------------------------
00323 // void CInternetEmailEngine::HandleSessionEventL(TMsvSessionEvent aEvent,
00324 //      TAny* /*aArg1*/,TAny* /*aArg2*/,TAny* /*aArg3*/ )
00325 //  Messaging callback from MMsvSessionObserver
00326 //
00327 //  Cornerstone iii of this module.
00328 // -----------------------------------------------------------------------
00329 void CInternetEmailEngine::HandleSessionEventL(TMsvSessionEvent aEvent,
00330     TAny* /*aArg1*/,TAny* /*aArg2*/,TAny* /*aArg3*/ )
00331     {
00332     switch(aEvent)
00333         {
00334          // the messaging server is ready
00335         case MMsvSessionObserver::EMsvServerReady:
00336             {
00337             // ---------------------------------------------
00338             //  STATE: EInitialising
00339             //   Completes constructs and changes state when
00340             //   MsvServer session is ready
00341             // ---------------------------------------------
00342             if(iState==EInitialising)
00343                 {
00344                 iState=EReadyButNeedsProtocol;
00345                 CompleteConstructL();
00346                 }
00347             }
00348             break;
00349 
00350         case MMsvSessionObserver::EMsvEntriesCreated:
00351         case MMsvSessionObserver::EMsvEntriesChanged:
00352         case MMsvSessionObserver::EMsvEntriesDeleted:
00353         case MMsvSessionObserver::EMsvEntriesMoved:
00354             //note: we could notify observers here to redraw if entry
00355             //would be approriate type and we would need more robust ui
00356         case MMsvSessionObserver::EMsvMtmGroupInstalled:
00357         case MMsvSessionObserver::EMsvMtmGroupDeInstalled:
00358         case MMsvSessionObserver::EMsvGeneralError:
00359         case MMsvSessionObserver::EMsvServerFailedToStart:
00360         case MMsvSessionObserver::EMsvCorruptedIndexRebuilt:
00361         case MMsvSessionObserver::EMsvCloseSession:
00362         case MMsvSessionObserver::EMsvServerTerminated:
00363         case MMsvSessionObserver::EMsvMediaChanged:
00364         case MMsvSessionObserver::EMsvMediaUnavailable:
00365         case MMsvSessionObserver::EMsvMediaAvailable:
00366         case MMsvSessionObserver::EMsvMediaIncorrect:
00367         case MMsvSessionObserver::EMsvCorruptedIndexRebuilding:
00368             break;
00369         }
00370     }
00371 
00372 // ---------------------------------------------------------------
00373 // void CInternetEmailEngine::DisplayMessageL( const TMsvId &aId )
00374 //  here we use the generic mtm ui (view) architecture
00375 //  and its views and dialogs to display messages in standard way.
00376 //
00377 //  cornerstone iv: of this module.
00378 // ---------------------------------------------------------------
00379 //
00380 void CInternetEmailEngine::DisplayMessageL( const TMsvId &aId )
00381     {
00382     // 1. construct the client MTM
00383     TMsvEntry indexEntry;
00384     TMsvId serviceId;
00385     User::LeaveIfError( iMsvSession->GetEntry(aId, serviceId, indexEntry));
00386     CBaseMtm* mtm = iClientReg->NewMtmL(indexEntry.iMtm);
00387     CleanupStack::PushL(mtm);
00388 
00389     // 2. construct the user interface MTM
00390     CBaseMtmUi* uiMtm = iUiReg->NewMtmUiL(*mtm);
00391     CleanupStack::PushL(uiMtm);
00392 
00393     // 3. display the message
00394     uiMtm->BaseMtm().SwitchCurrentEntryL(indexEntry.Id());
00395     CMsvOperationWait* waiter=CMsvOperationWait::NewLC();
00396     waiter->Start(); //we use synchronous waiter
00397     CMsvOperation* op = uiMtm->OpenL(waiter->iStatus); //the main "async-sync" call
00398     CleanupStack::PushL(op);
00399     CActiveScheduler::Start(); //notice! nested active scheduler for modal operation
00400 
00401     // 4. cleanup for example even members
00402     CleanupStack::PopAndDestroy(4); // op,waiter, mtm, uimtm
00403     }
00404 
00405 
00406 // ---------------------------------------------
00407 // void CInternetEmailEngine::CancelOperation()
00408 //  public interface method for user initiated
00409 //  cancelling of email operations.
00410 // ---------------------------------------------
00411 //
00412 void CInternetEmailEngine::CancelOperation()
00413     {
00414     iState= ECanceling; //we switch state and wait for op to cancel
00415 
00416     if( iMsvOp )
00417         {
00418         iMsvOp->Cancel(); //iStatus now KErrCancel (-3)
00419         }
00420     }
00421 
00422 // ---------------------------------------------
00423 // void CInternetEmailEngine::DoCancel()
00424 //  framework cancel method, no implemented here
00425 // ---------------------------------------------
00426 //
00427 void CInternetEmailEngine::DoCancel()
00428     {
00429     // no implementation required
00430     }
00431 
00432 // -------------------------------------------------------
00433 // TInt CInternetEmailEngine::RunError( const TInt aError)
00434 //  simply return error value
00435 // -------------------------------------------------------
00436 //
00437 TInt CInternetEmailEngine::RunError( const TInt aError)
00438     {
00439     return aError;
00440     }
00441 
00442 // -------------------------------------
00443 // void CInternetEmailEngine::LoadMtmL()
00444 //  common helper to load mtm context
00445 // -------------------------------------
00446 //
00447 void CInternetEmailEngine::LoadMtmL()
00448     {
00449     if(iId == KMsvRootIndexEntryId)
00450         {
00451         User::Leave(KErrNotFound);
00452         }
00453 
00454     TMsvEntry tmp;
00455     User::LeaveIfError(iMsvSession->GetEntry(iId,iServiceId,tmp));
00456     iMtm =InstantiateClientMtmL(iServiceId,iProtocolUid);
00457     }
00458 
00459 // ------------------------------------------------------
00460 // CBaseMtm* CInternetEmailEngine::InstantiateClientMtmL(
00461 //  TMsvId aService, const TUid aType)
00462 //  Helper to load either imap/pop mtm using base class
00463 // ------------------------------------------------------
00464 //
00465 CBaseMtm* CInternetEmailEngine::InstantiateClientMtmL(TMsvId aService, const TUid aType)
00466     {
00467     // create a client mtm
00468     CBaseMtm* newMtm = iClientReg->NewMtmL(aType);
00469     CleanupStack::PushL(newMtm);
00470     // get the entry associated with the given servive ID
00471     CMsvEntry* entry = iMsvSession->GetEntryL(aService);
00472     CleanupStack::PushL(entry);
00473     // set the entry as the current entry
00474     // mtm takes ownership of the entry
00475     newMtm->SetCurrentEntryL(entry);
00476     CleanupStack::Pop(2); //newMtm, entry
00477     return newMtm;
00478     }
00479 
00480 // -------------------------------------------------------------------
00481 // void CInternetEmailEngine::Queue()
00482 // SetActive() or complete our own status.
00483 // this allows the active scheduler chance to
00484 // service other active objects before return back to our RunL
00485 // -------------------------------------------------------------------
00486 //
00487 void CInternetEmailEngine::Queue()
00488     {
00489     if(!IsActive())
00490         {
00491         SetActive();
00492         }
00493 
00494     TRequestStatus* st= &iStatus;
00495     User::RequestComplete(st,KErrNone);
00496     }
00497 
00498 // -----------------------------------------------------------------
00499 // TBool CInternetEmailEngine::CheckIfExistsL( const TInt typeenum )
00500 //  returns ETrue if given type protocol type exists
00501 // -----------------------------------------------------------------
00502 //
00503 TBool CInternetEmailEngine::CheckIfExistsL( const TInt aTypeEnum )
00504     {
00505     TUid temp = ( aTypeEnum == EProtocolImap4 ) ? KUidMsgTypeIMAP4 : KUidMsgTypePOP3;
00506     TMsvId id=FindServiceL(temp);
00507     return ( id == KMsvRootIndexEntryId ) ? EFalse : ETrue;
00508     }
00509 
00510 
00511 // ---------------------------------------------------------------
00512 // TPtrC CInternetEmailEngine::RemoteEmailTextL(const TInt aIndex)
00513 //      Get the subject of the email from message header
00514 // ---------------------------------------------------------------
00515 //
00516 TPtrC CInternetEmailEngine::RemoteEmailTextL( const TInt aIndex )
00517     {
00518     if( iState == ECanceling )
00519         {
00520         User::Leave( KErrCancel );
00521         }
00522 
00523     TMsvId entryId=(*iRemoteEntries)[aIndex];
00524     if(iEntry==NULL || iEntry->Entry().Id()!=entryId)
00525         {
00526         delete iEntry;
00527         iEntry=NULL;
00528         iEntry=iMsvSession->GetEntryL(entryId);
00529         }
00530     return iEntry->Entry().iDescription;
00531     }
00532 
00533 // ------------------------------------------------------------------
00534 // TPtrC CInternetEmailEngine::RemoteEmailSenderL( const TInt aIndex)
00535 //      Get the sender of the email from message header
00536 // ------------------------------------------------------------------
00537 //
00538 TPtrC CInternetEmailEngine::RemoteEmailSenderL( const TInt aIndex )
00539     {
00540     if( iState == ECanceling )
00541         {
00542         User::Leave( KErrCancel );
00543         }
00544 
00545     TMsvId entryId=(*iRemoteEntries)[aIndex];
00546     if(iEntry==NULL || iEntry->Entry().Id()!=entryId)
00547         {
00548         delete iEntry;
00549         iEntry=NULL;
00550         iEntry=iMsvSession->GetEntryL(entryId);
00551         }
00552     return iEntry->Entry().iDetails;
00553     }
00554 
00555 // ---------------------------------------------
00556 // TInt CInternetEmailEngine::RemoteEmailCount()
00557 //      get the email count as integer
00558 // ---------------------------------------------
00559 //
00560 TInt CInternetEmailEngine::RemoteEmailCount()
00561     {
00562     return iRemoteCount;
00563     }
00564 
00565 // ------------------------------------------------------------------
00566 // void CInternetEmailEngine::RemoteOpenEmailL( TInt aIndex )
00567 //  open remote email. may cause system to go online to retrieve mail
00568 // ------------------------------------------------------------------
00569 //
00570 void CInternetEmailEngine::RemoteOpenEmailL( TInt aIndex )
00571     {
00572     TMsvId entryId=(*iRemoteEntries)[aIndex];
00573     if(aIndex<0 || aIndex>=iRemoteCount)
00574         {
00575         User::Leave(KErrGeneral);
00576         }
00577     iState=EReady;
00578     DisplayMessageL(entryId);
00579     }
00580 
00581 // --------------------------------------------------------
00582 // void CInternetEmailEngine::RemoteFetchL()
00583 //  enters connect state and queues own request accordingly
00584 // --------------------------------------------------------
00585 //
00586 void CInternetEmailEngine::RemoteFetchL()
00587     {
00588     iState=EConnecting;
00589     Queue();
00590     }
00591 
00592 // ---------------------------------------------------------
00593 // CMsvEntrySelection* CInternetEmailEngine::UpdateEntriesL(
00594 //      const TMsvId& aServiceId)
00595 //  updates the message entries for viewing
00596 // ---------------------------------------------------------
00597 //
00598 CMsvEntrySelection* CInternetEmailEngine::UpdateEntriesL(
00599     const TMsvId& aServiceId)
00600     {
00601     CMsvEntry* entry=iMsvSession->GetEntryL(aServiceId); // get the entry
00602     CleanupStack::PushL(entry);
00603     CMsvEntrySelection* entries=entry->ChildrenL(); // get the entry's children
00604     CleanupStack::PopAndDestroy(entry);
00605     return entries;
00606     }
00607 
00608 // -----------------------------------------------
00609 // void CInternetEmailEngine::UpdateRemoteCountL()
00610 //  update the remote mail count
00611 //
00612 //  Note: only method where observers are notified
00613 // -----------------------------------------------
00614 //
00615 void CInternetEmailEngine::UpdateRemoteCountL()
00616     {
00617     // reset the remote mail count and entries
00618     iRemoteCount=0;
00619     delete iRemoteEntries;
00620     iRemoteEntries=NULL;
00621 
00622     // SEPARATION BETWEEN IMAP AND POP
00623     if( iProtocolType == EProtocolImap4 && !iHasImapInbox )
00624         {
00625         iId=FindFolderThenServiceL(iProtocolUid); //leaves with KErrFound if still no folder set
00626         }
00627 
00628     // get the current entries. Note that iId is normally a remote
00629     // mailbox for pop and first folder( inbox ) for imap. which is
00630     // why we have to check if folders are already sync if protocol
00631     // is imap, so we wont draw the screen with wrong parent and output
00632     // folders to the listbox and not the message entries we want to.
00633     iRemoteEntries=UpdateEntriesL(iId);
00634 
00635 
00636     // if the nunber has changed then inform the observers
00637     if(iRemoteEntries->Count()!=iRemoteCount)
00638         {
00639         iRemoteCount=iRemoteEntries->Count();
00640         iObserver.HandleEngineChangedEventL(ERemoteCountChanged);
00641         }
00642     }
00643 
00644 // -------------------------------------------
00645 // TBool CInternetEmailEngine::IsProtocolSet()
00646 //  returns ETrue if protocol is set
00647 // -------------------------------------------
00648 //
00649 TBool CInternetEmailEngine::IsProtocolSet()
00650     {
00651     return iIsProtocolSet;
00652     }
00653 
00654 // ----------------------------------------------------
00655 // TBool CInternetEmailEngine::IsEngineReady()
00656 //  returns ETrue if server is ready thus engine is too
00657 // ----------------------------------------------------
00658 //
00659 TBool CInternetEmailEngine::IsEngineReady()
00660     {
00661     return (iClientReg!=NULL)?(ETrue):(EFalse);
00662     }
00663 
00664 // --------------------------------------------------------------
00665 // void CInternetEmailEngine::SetProtocolL( const TInt aType )
00666 //  sets protocol and loads mtm context for given protocol.
00667 //  note that the structure of mailbox is fundamentally different
00668 //  between simple POP and better IMAP. IMAP has folders like
00669 //  inbox under the service entry so we must the pick different
00670 //  nesting level with IMAP than with POP.
00671 // --------------------------------------------------------------
00672 //
00673 void CInternetEmailEngine::SetProtocolL( const TInt aType )
00674     {
00675     iProtocolType=aType;
00676     iProtocolUid=(iProtocolType==EProtocolPop3)?KUidMsgTypePOP3:KUidMsgTypeIMAP4;
00677     iIsProtocolSet=ETrue;
00678     iState=EReady;
00679     iId=FindServiceL(iProtocolUid);
00680     LoadMtmL();
00681 
00682     if( iProtocolType!=EProtocolPop3) //Note IMAP has folders!
00683         {
00684         TRAPD( err, iId=FindFolderThenServiceL(iProtocolUid));
00685         if( err != KErrNone )
00686             {
00687             //now we know we have fresh imap service without any folders
00688             return;
00689             }
00690         }
00691 
00692     UpdateRemoteCountL(); //we draw the message entries if any
00693 
00694 
00695     }
00696 
00697 
00698 
00699 // --------------------------------------------------------------
00700 // TMsvId CInternetEmailEngine::FindServiceL(TUid aType)
00701 //  find the message id of a service given a UID
00702 //  this function will return the first service id for given type
00703 // --------------------------------------------------------------
00704 //
00705 TMsvId CInternetEmailEngine::FindServiceL(TUid aType)
00706     {
00707     // select the root index to start the search
00708     CMsvEntry* currentEntry = iMsvSession->GetEntryL(KMsvRootIndexEntryId);
00709     CleanupStack::PushL(currentEntry);
00710 
00711     // don't sort the entries
00712     currentEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvNoGrouping,EMsvSortByNone, ETrue));
00713 
00714     TMsvId rc = KMsvRootIndexEntryId;
00715    TInt count=currentEntry->Count();
00716     // loop for every child entry of the root index
00717     for(TInt i = 0;i<count;i++)
00718         {
00719         const TMsvEntry& child = (*currentEntry)[i];
00720 
00721         // is the current child the same type as the type we are looking for ?
00722         if (child.iMtm == aType)
00723             {
00724             rc=child.Id();
00725             break;
00726             }
00727         }//for
00728 
00729     CleanupStack::PopAndDestroy(currentEntry);
00730     // return the service id of the type if found.
00731     // otherwise return the root index
00732     return rc;
00733     }
00734 
00735 // ---------------------------------------------------------------
00736 // TMsvId CInternetEmailEngine::FindFolderThenServiceL(TUid aType)
00737 //  this function will return the first folder of first
00738 //  service of given type or if it doesnt exist then
00739 //  this function will leave with KErrNotFound as most of
00740 //  the usage sitations couldnt handle mailbox instead of
00741 //  folder.
00742 // ----------------------------------------------------------------
00743 //
00744 TMsvId CInternetEmailEngine::FindFolderThenServiceL(TUid aType)
00745     {
00746 
00747     // select the root index to start the search
00748     CMsvEntry* currentEntry = iMsvSession->GetEntryL(KMsvRootIndexEntryId);
00749     CleanupStack::PushL(currentEntry);
00750 
00751     // don't sort the entries
00752     currentEntry->SetSortTypeL(TMsvSelectionOrdering(KMsvNoGrouping,EMsvSortByNone, ETrue));
00753 
00754     TMsvId rc = KMsvRootIndexEntryId;
00755     TInt count=currentEntry->Count();
00756     // loop for every child entry of the root index
00757     for(TInt i = 0;i<count;i++)
00758         {
00759         const TMsvEntry& child = (*currentEntry)[i];
00760 
00761         // is the current child the same type as the type we are looking for ?
00762         if (child.iMtm == aType)
00763             {
00764             // selects first entry as index entry
00765             CMsvEntry* firstEntry = iMsvSession->GetEntryL(child.Id());
00766             CleanupStack::PushL(firstEntry);
00767             TInt innercount=firstEntry->Count();
00768             if( innercount )
00769                 { //if has childs == folders take first
00770                 const TMsvEntry& folder = (*firstEntry)[0];
00771                 rc=folder.Id();
00772                 iHasImapInbox=ETrue;
00773                 }
00774             else
00775                 {
00776                 iHasImapInbox=EFalse;
00777                 }
00778             CleanupStack::PopAndDestroy(firstEntry);
00779             break;
00780             }
00781         }//for
00782 
00783     CleanupStack::PopAndDestroy(currentEntry);
00784 
00785     if( !iHasImapInbox )
00786         {
00787         User::Leave( KErrNotFound );
00788         }
00789 
00790     // return the service id of the type if found.
00791     return rc;
00792     }
00793 
00794 // End of File

Generated by  doxygen 1.6.2