examples/ForumNokia/InternetEmail/src/InternetEmailEngine.cpp

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

Generated by  doxygen 1.6.2