email/mail/UtilsSrc/CMailMessage.cpp
branchRCL_3
changeset 27 7fdbb852d323
parent 0 72b543305e3a
equal deleted inserted replaced
26:ebe688cedc25 27:7fdbb852d323
       
     1 /*
       
     2 * Copyright (c) 2002-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  mail message class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include    "CMailMessage.h"
       
    22 #include    <MMailMessageView.h>
       
    23 #include    <MMessageLoadObserver.h>
       
    24 #include    "MailLog.h"
       
    25 #include    <miuthdr.h> // CImHeader
       
    26 #include    <miutmsg.h>
       
    27 #include    <miutconv.h>
       
    28 #include    <charconv.h>
       
    29 #include    <featmgr.h>
       
    30 #include    <MuiuOperationWait.h>
       
    31 #include 	<mmsvattachmentmanager.h>
       
    32 #include    <ErrorUI.h>
       
    33 
       
    34 // MODULE DATA STRUCTURES
       
    35 enum TLoadState
       
    36     {
       
    37     ELoadMessageBody = 1,
       
    38     EHtmlNotFound,
       
    39     ELoadAttachments,
       
    40     ELoadAttachedMessages,
       
    41     ELoadLinkedHtmlContent
       
    42     };
       
    43 
       
    44 // Constants
       
    45 enum MessageFlags
       
    46     {
       
    47     EFlagAttachment = KBit0,
       
    48     EFlagAttachedMessages = KBit1,
       
    49     EFlagStopAfterLoad = KBit2,
       
    50     EFlagHtmlError = KBit3,
       
    51     EFlagHtmlMessageCharSetOverridden = KBit4
       
    52     };
       
    53 
       
    54 // ============================ MEMBER FUNCTIONS ===============================
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CMailMessage::CMailMessage
       
    58 // C++ default constructor can NOT contain any code, that
       
    59 // might leave.
       
    60 // -----------------------------------------------------------------------------
       
    61 //
       
    62 CMailMessage::CMailMessage()
       
    63 : CActive(0), iFlags(0)
       
    64     {
       
    65     }
       
    66 
       
    67 // -----------------------------------------------------------------------------
       
    68 // CMailMessage::ConstructL
       
    69 // Symbian 2nd phase constructor can leave.
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 void CMailMessage::ConstructL(CMsvEntry& aEntry)
       
    73     {
       
    74     CActiveScheduler::Add(this);
       
    75 
       
    76     iHeader = CImHeader::NewLC();
       
    77     CleanupStack::Pop();
       
    78     iEntry = aEntry.Session().GetEntryL( aEntry.EntryId() );
       
    79 
       
    80     iMessage = CImEmailMessage::NewL(*iEntry);
       
    81     iMessageID = iEntry->EntryId();
       
    82     if (iEntry->HasStoreL())
       
    83         {
       
    84         CMsvStore* msvStore = iEntry->ReadStoreL();
       
    85         CleanupStack::PushL(msvStore);
       
    86         TRAP_IGNORE(iHeader->RestoreL(*msvStore));
       
    87         CleanupStack::PopAndDestroy(); // store
       
    88         }
       
    89 
       
    90     iGlobalParaLayer = CParaFormatLayer::NewL();
       
    91     iGlobalCharLayer = CCharFormatLayer::NewL();
       
    92 
       
    93     iBodyText = CRichText::NewL(
       
    94         iGlobalParaLayer,
       
    95         iGlobalCharLayer);
       
    96 
       
    97 	iLinkedHtmlItems = new( ELeave ) RPointerArray<
       
    98 		CLinkedHtmlItem>(5);		// CSI: 47 # approx granularity 5
       
    99 
       
   100     iAsyncWait = CMuiuOperationWait::NewLC(); //only NewLC variant exists
       
   101     CleanupStack::Pop( iAsyncWait );
       
   102     }
       
   103 
       
   104 // -----------------------------------------------------------------------------
       
   105 // CMailMessage::NewL
       
   106 // Two-phased constructor.
       
   107 // -----------------------------------------------------------------------------
       
   108 //
       
   109 EXPORT_C CMailMessage* CMailMessage::NewL(CMsvEntry& aEntry)
       
   110     {
       
   111     CMailMessage* self = new( ELeave ) CMailMessage();
       
   112     CleanupStack::PushL( self );
       
   113     self->ConstructL(aEntry);
       
   114 
       
   115     CleanupStack::Pop();
       
   116     return self;
       
   117     }
       
   118 
       
   119 
       
   120 // Destructor
       
   121 CMailMessage::~CMailMessage()
       
   122     {
       
   123     Cancel();
       
   124     delete iAsyncWait; // gets cancelled if running
       
   125     delete iHeader;
       
   126     delete iMessage;
       
   127     delete iBodyText;
       
   128     delete iGlobalParaLayer;
       
   129     delete iGlobalCharLayer;
       
   130     delete iURI;
       
   131     delete iEntry;
       
   132     if ( iLinkedHtmlItems )
       
   133         {
       
   134         iLinkedHtmlItems->ResetAndDestroy();
       
   135         delete iLinkedHtmlItems;
       
   136         }
       
   137 
       
   138    	iWaitArray.ResetAndDestroy();
       
   139     }
       
   140 
       
   141 
       
   142 EXPORT_C void CMailMessage::LoadMessageL(
       
   143     MMessageLoadObserver& aMessageObserver)
       
   144     {
       
   145     iState = ELoadMessageBody;
       
   146     iMessageObserver = &aMessageObserver;
       
   147 
       
   148     // Header is already loaded
       
   149     NotifyObserverL(EHeaderReady);
       
   150 
       
   151     if( !MessageEntry().MHTMLEmail() )
       
   152         {
       
   153         LoadBodyTextL();
       
   154         }
       
   155     else
       
   156         {
       
   157    		LoadAttachmentsL();
       
   158         }
       
   159     SetActive();
       
   160     }
       
   161 
       
   162 // -----------------------------------------------------------------------------
       
   163 // CMailMessage::LoadLinkedHtmlContentL
       
   164 // -----------------------------------------------------------------------------
       
   165 //
       
   166 EXPORT_C void CMailMessage::LoadLinkedHtmlContentL(
       
   167 	const TDesC& aBase, const TDesC& aURI)
       
   168 	{
       
   169 	LoadLinkedHTMLContentL(aBase, aURI);
       
   170 	}
       
   171 
       
   172 // -----------------------------------------------------------------------------
       
   173 // CMailMessage::HtmlCharsetIdL
       
   174 // -----------------------------------------------------------------------------
       
   175 //
       
   176 EXPORT_C TUint CMailMessage::HtmlCharsetIdL()
       
   177     {
       
   178     TUint charset = 0;
       
   179     //
       
   180     if (iMhtmlPartId != 0)
       
   181         {
       
   182         if ( iFlags & EFlagHtmlMessageCharSetOverridden )
       
   183             {
       
   184             charset = iCharacterSetId;
       
   185             }
       
   186         else
       
   187             {
       
   188             CMsvEntry* htmlEntry = iEntry->Session().GetEntryL( iMhtmlPartId );
       
   189             CleanupStack::PushL( htmlEntry );
       
   190         	charset = DoGetMimeCharsetIdL( *htmlEntry );
       
   191             CleanupStack::PopAndDestroy( htmlEntry );
       
   192             }
       
   193         }
       
   194 
       
   195 	LOG1( "CMailMessage::HtmlCharsetIdL %08x", charset );
       
   196     return charset;
       
   197     }
       
   198 
       
   199 // -----------------------------------------------------------------------------
       
   200 // CMailMessage::CharsetIdL
       
   201 // -----------------------------------------------------------------------------
       
   202 //
       
   203 EXPORT_C TUint CMailMessage::CharsetIdL()
       
   204     {
       
   205     TUint characterSetId(0);
       
   206     TBool override;
       
   207     iMessage->GetCharacterSetL( iMessageID, characterSetId, override);
       
   208 	LOG1( "CMailMessage::CharsetIdL from CImEmailMessage %08x",
       
   209 	    	characterSetId );
       
   210 	if ( characterSetId != 0 )
       
   211 	    {
       
   212 	    return characterSetId;
       
   213 	    }
       
   214 
       
   215     if( iEntry->Entry().Id() != iMessageID )
       
   216     	iEntry->SetEntryL(iMessageID);
       
   217 
       
   218    	return DoGetMimeCharsetIdL( *iEntry );
       
   219     }
       
   220 
       
   221 // -----------------------------------------------------------------------------
       
   222 // CMailMessage::ConvertToCharsetL
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 EXPORT_C void CMailMessage::ConvertToCharsetL(TUint aCharsetId)
       
   226     {
       
   227     iMessage->SetCharacterSetL( iMessageID, aCharsetId );
       
   228     }
       
   229 
       
   230 
       
   231 // -----------------------------------------------------------------------------
       
   232 // CMailMessage::AttachmentManager
       
   233 // -----------------------------------------------------------------------------
       
   234 //
       
   235 EXPORT_C MMsvAttachmentManager& CMailMessage::AttachmentManager() const
       
   236     {
       
   237     ASSERT( iState == ELoadAttachments );
       
   238 	LOG2( "CMailMessage::AttachmentManager %08x - %08x",
       
   239 	    iMessageID,
       
   240 	    iEntry->EntryId() );
       
   241     // context still in message ?
       
   242     if( iEntry->Entry().Id() != iMessageID )
       
   243     	TRAP_IGNORE( iEntry->SetEntryL(iMessageID) );
       
   244     return iMessage->AttachmentManager();
       
   245     }
       
   246 
       
   247 // -----------------------------------------------------------------------------
       
   248 // CMailMessage::LoadAttachmentsL
       
   249 // -----------------------------------------------------------------------------
       
   250 //
       
   251 EXPORT_C void CMailMessage::LoadAttachmentsL(MMessageLoadObserver& aObserver)
       
   252 	{
       
   253 	iMessageObserver = &aObserver;
       
   254 	Cancel();
       
   255 	LoadAttachmentsL();
       
   256 	iFlags |= EFlagStopAfterLoad;
       
   257 	SetActive();
       
   258 	}
       
   259 
       
   260 // -----------------------------------------------------------------------------
       
   261 // CMailMessage::LoadAttachedMessagesL
       
   262 // -----------------------------------------------------------------------------
       
   263 //
       
   264 EXPORT_C void CMailMessage::LoadAttachedMessagesL(
       
   265 	MMessageLoadObserver& aObserver)
       
   266 	{
       
   267 	iMessageObserver = &aObserver;
       
   268 	Cancel();
       
   269 	LoadAttachedMessagesL();
       
   270 	iFlags |= EFlagStopAfterLoad;
       
   271 	SetActive();
       
   272 	}
       
   273 
       
   274 // -----------------------------------------------------------------------------
       
   275 // CMailMessage::LoadHtmlContentL
       
   276 // -----------------------------------------------------------------------------
       
   277 //
       
   278 EXPORT_C void CMailMessage::LoadHtmlContentL(MMessageLoadObserver& aObserver)
       
   279 	{
       
   280 	iMessageObserver = &aObserver;
       
   281 	Cancel();
       
   282 	LoadHTMLContentL();
       
   283 	iFlags |= EFlagStopAfterLoad;
       
   284 	SetActive();
       
   285 	}
       
   286 
       
   287 // -----------------------------------------------------------------------------
       
   288 // CMailMessage::LoadLinkedHtmlContentL
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 EXPORT_C void CMailMessage::LoadLinkedHtmlContentL(
       
   292         	const TDesC& aBase,
       
   293         	const TDesC& aURI,
       
   294         	MMessageLoadObserver& aObserver )
       
   295 	{
       
   296 	iMessageObserver = &aObserver;
       
   297 	Cancel();
       
   298 	delete iURI;
       
   299 	iURI = NULL;
       
   300 	iURI = aURI.AllocL();
       
   301 
       
   302 	LoadLinkedHTMLContentL( aBase, aURI );
       
   303 	iFlags |= EFlagStopAfterLoad;
       
   304 	SetActive();
       
   305 	}
       
   306 
       
   307 // -----------------------------------------------------------------------------
       
   308 // CMailMessage::GetFileHandleL
       
   309 // -----------------------------------------------------------------------------
       
   310 //
       
   311 EXPORT_C RFile CMailMessage::GetFileHandleL( TMsvAttachmentId aId )
       
   312     {
       
   313     LOG( ">CMailMessage::GetFileHandleL" );
       
   314     Cancel();
       
   315     // Force message cancel for special cases(lost network coverage)
       
   316     if ( iMessage )
       
   317     	{
       
   318     	iMessage->Cancel();
       
   319     	}
       
   320 
       
   321     // create an array for active scheduler waits if it does not exist
       
   322     CMuiuOperationWait* wait = CMuiuOperationWait::NewLC(); //only NewLC variant exists
       
   323     // append the wait to the array
       
   324     iWaitArray.AppendL( wait );
       
   325     CleanupStack::Pop( wait );
       
   326 
       
   327     RFile handle;
       
   328 
       
   329     if ( aId == iMhtmlPartId )
       
   330         {
       
   331         // html body part
       
   332         iMessage->FindFirstHTMLPageFileHandleL( iMessageID,
       
   333                                                 wait->iStatus );
       
   334         wait->Start();
       
   335         User::LeaveIfError( wait->iStatus.Int() );
       
   336 
       
   337         User::LeaveIfError(
       
   338             iMessage->GetUniversalResourceIdentifierFileHandle(
       
   339             iMhtmlPartId, handle) );
       
   340 
       
   341         }
       
   342     else if ( IsLinkedItemL( handle, aId) )
       
   343         {
       
   344         // linked html item
       
   345         }
       
   346     else
       
   347         {
       
   348         // normal attachment
       
   349 
       
   350         //Async version of GetAttachmentsListL used here,
       
   351         //because it is quite slow operation and when there is
       
   352         //many attachments to be loaded Ui jams if synchrounous
       
   353         //method is called.
       
   354 
       
   355         iMessage->GetAttachmentsListL(
       
   356             wait->iStatus,
       
   357             iMessageID,
       
   358             CImEmailMessage::EAllAttachments,
       
   359             CImEmailMessage::EThisMessageAndEmbeddedMessages );
       
   360 
       
   361         LOG( "CMailMessage::GetFileHandleL: Starting wait" );
       
   362         wait->Start();
       
   363         LOG( "CMailMessage::GetFileHandleL: Wait finished" );
       
   364 
       
   365         User::LeaveIfError( wait->iStatus.Int() );
       
   366 
       
   367         LOG( "CMailMessage::GetFileHandleL: Status ok" );
       
   368         MMsvAttachmentManager& manager = iMessage->AttachmentManager();
       
   369         handle = manager.GetAttachmentFileL( aId );
       
   370         }
       
   371 
       
   372     // clean up the wait array for any non-active waits
       
   373     CleanupWaitArray();
       
   374 
       
   375     __ASSERT_DEBUG( handle.SubSessionHandle() != 0, User::Invariant() );
       
   376 
       
   377     LOG( "<CMailMessage::GetFileHandleL" );
       
   378     return handle;
       
   379     }
       
   380 
       
   381 // -----------------------------------------------------------------------------
       
   382 // CMailMessage::CleanupWaitArray
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 void CMailMessage::CleanupWaitArray()
       
   386 	{
       
   387 	TInt count( iWaitArray.Count() );
       
   388     // cleanup the whole array
       
   389     for( TInt i = count - 1; i >= 0; i-- )
       
   390     	{
       
   391     	CMuiuOperationWait* wait = iWaitArray[i];
       
   392     	if( !wait->IsActive() )
       
   393     		{
       
   394     		iWaitArray.Remove( i );
       
   395     		delete wait;
       
   396     		}
       
   397     	}
       
   398 	}
       
   399 
       
   400 // -----------------------------------------------------------------------------
       
   401 // CMailMessage::OverrideHtmlMessageCharset
       
   402 // -----------------------------------------------------------------------------
       
   403 //
       
   404 EXPORT_C void CMailMessage::OverrideHtmlMessageCharset( TUint aCharSet )
       
   405     {
       
   406     iCharacterSetId = aCharSet;
       
   407 
       
   408     if ( aCharSet )
       
   409         {
       
   410         iFlags |= EFlagHtmlMessageCharSetOverridden;
       
   411         }
       
   412     else
       
   413         {
       
   414         iFlags &= ~EFlagHtmlMessageCharSetOverridden;
       
   415         }
       
   416     }
       
   417 // -----------------------------------------------------------------------------
       
   418 // CMailMessage::DoCancel
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 void CMailMessage::DoCancel()
       
   422     {
       
   423     LOG1("DoCancel @ iState:%d", iState);
       
   424     if ( iMessage )
       
   425     	{
       
   426     	iMessage->Cancel();
       
   427     	}
       
   428     }
       
   429 
       
   430 // -----------------------------------------------------------------------------
       
   431 // CMailMessage::RunL
       
   432 // -----------------------------------------------------------------------------
       
   433 //
       
   434 void CMailMessage::RunL()
       
   435     {
       
   436     switch(iState)
       
   437         {
       
   438         case ELoadMessageBody:
       
   439             {
       
   440             LOG("CMailMessage::RunL @ ELoadMessageBody");
       
   441             User::LeaveIfError( iStatus.Int() );
       
   442             // Body content loaded to iBodyText
       
   443             // if HTML mail get file handle to content (iBodyText is empty)
       
   444             if( MessageEntry().MHTMLEmail() && !(iFlags & EFlagHtmlError) )
       
   445                 {
       
   446             	TInt error(KErrNone);
       
   447                 // html file handle
       
   448                 error = iMessage->
       
   449                     GetUniversalResourceIdentifierFileHandle(
       
   450                     iMhtmlPartId, iHtmlFile);
       
   451 
       
   452 	            if (error == KErrNone)
       
   453 	               	{
       
   454 	                iFlags |= EFlagAttachment;
       
   455 	               	}
       
   456 	            else
       
   457 	            	{
       
   458 	               	// Can't load HTML, so try to load plain text body
       
   459                     LOG1("CMailMessage::RunL @ Can't load HTML: %d",
       
   460             	        error);
       
   461 	               	iState = EHtmlNotFound;
       
   462 	               	iFlags |= EFlagHtmlError;
       
   463 	            	break;
       
   464 	            	}
       
   465                 }
       
   466             NotifyObserverL(EBodyTextReady);
       
   467             break;
       
   468             }
       
   469         case ELoadAttachments:
       
   470             {
       
   471             LOG("CMailMessage::RunL @ ELoadAttachments");
       
   472             // Attachment files loaded
       
   473             User::LeaveIfError( iStatus.Int() );
       
   474             NotifyObserverL(EAttachmentsReady);
       
   475             LOG("CMailMessage::RunL, NotifyObserverL returned");
       
   476             break;
       
   477             }
       
   478         case ELoadAttachedMessages:
       
   479             {
       
   480             // Attached files loaded
       
   481             User::LeaveIfError( iStatus.Int() );
       
   482             const CMsvEntrySelection& sel = iMessage->Selection();
       
   483             TInt attachedCount(sel.Count());
       
   484             LOG1("CMailMessage::RunL @ ELoadAttachedMessages %d",
       
   485             	attachedCount);
       
   486             if (attachedCount)
       
   487                 {
       
   488                 iFlags |= EFlagAttachedMessages;
       
   489                 }
       
   490 			NotifyObserverL(EAttachedMessagesReady);
       
   491             break;
       
   492             }
       
   493         case ELoadLinkedHtmlContent:
       
   494             {
       
   495             LOG("CMailMessage::RunL @ ELoadLinkedHtmlContent");
       
   496             // linked file loaded
       
   497             TInt error = iMessage->
       
   498                     GetUniversalResourceIdentifierFileHandle(
       
   499                     iLinkedfileId, iLinkedHtmlFile);
       
   500             if ( error == KErrNone )
       
   501                 {
       
   502                 CLinkedHtmlItem* htmlItem = new(ELeave) CLinkedHtmlItem(
       
   503                     *iURI, iLinkedfileId );
       
   504                 CleanupStack::PushL( htmlItem );
       
   505                 iLinkedHtmlItems->AppendL( htmlItem );
       
   506                 CleanupStack::Pop( htmlItem );
       
   507                 }
       
   508             else
       
   509                 {
       
   510                 // ignore errors. If fails linked item is not added to
       
   511                 // attachment view.
       
   512                 LOG1("CMailMessage::RunL @ ELoadLinkedHtmlContent error:%d",
       
   513                      error);
       
   514                 iLinkedHtmlFile = RFile(); // return empty handle
       
   515                 iEntry->SetEntryL( iMessageID );
       
   516                 }
       
   517 			NotifyObserverL(ELinkedFileReady);
       
   518             break;
       
   519             }
       
   520         default:
       
   521         	// all loading done. Do nothing
       
   522             break;
       
   523         }
       
   524     DoNextStateL();
       
   525     }
       
   526 
       
   527 // -----------------------------------------------------------------------------
       
   528 // CMailMessage::RunError
       
   529 // -----------------------------------------------------------------------------
       
   530 //
       
   531 TInt CMailMessage::RunError(TInt aError)
       
   532     {
       
   533     LOG2("CMailMessage::RunError @ iState: %d, aError:%d", iState, aError);
       
   534     // ActiveSheduler Panics if this returns != KErrNone
       
   535     Cancel();
       
   536     //We have to return KLeaveExit(appui's exit code), otherwise our appui is not deleted
       
   537     if(aError == KLeaveExit)
       
   538         {
       
   539         return KLeaveExit;
       
   540         }
       
   541     TRAP_IGNORE( ShowErrorNoteL( aError ) );
       
   542 
       
   543     // exit from viewer app if OOM
       
   544     if( aError == KErrNoMemory )
       
   545         {
       
   546         return KLeaveExit;
       
   547         }
       
   548 
       
   549     // Try to continue loading
       
   550     TRAP_IGNORE( DoNextStateL() );
       
   551 
       
   552     return KErrNone;
       
   553     }
       
   554 
       
   555 // -----------------------------------------------------------------------------
       
   556 // CMailMessage::DoNextStateL
       
   557 // -----------------------------------------------------------------------------
       
   558 //
       
   559 void CMailMessage::DoNextStateL()
       
   560     {
       
   561 	// Step to next state
       
   562     if ( (!(iFlags & EFlagStopAfterLoad) ||
       
   563         (iState == EHtmlNotFound))
       
   564         && NextStateL() )
       
   565         {
       
   566         SetActive();
       
   567         }
       
   568     else
       
   569         {
       
   570 		// message loaded
       
   571         NotifyObserverL(ELoadEnd);
       
   572         }
       
   573     }
       
   574 
       
   575 // -----------------------------------------------------------------------------
       
   576 // CMailMessage::DoGetMimeCharsetIdL
       
   577 // -----------------------------------------------------------------------------
       
   578 //
       
   579 TUint CMailMessage::DoGetMimeCharsetIdL( CMsvEntry& aEntry )
       
   580     {
       
   581     //Try to read the character set from two places:
       
   582     // 1) Main entry's MIME headers
       
   583     // 2) Child entrys' MIME headers
       
   584     TUint characterSetId(0);
       
   585 
       
   586     // If the message store cannot be read, abort here
       
   587     CMsvStore* store = NULL;
       
   588     TRAPD( err, store = aEntry.ReadStoreL() );
       
   589     if( err != KErrNone )
       
   590         {
       
   591         return 0;
       
   592         }
       
   593     CleanupStack::PushL(store);
       
   594 
       
   595     //------------------------------------------------
       
   596     // Option 1. Read the MIME header from main entry
       
   597     //------------------------------------------------
       
   598     if (store->IsPresentL(KUidMsgFileMimeHeader))
       
   599         {
       
   600         //Main entry's mime header
       
   601     	CImMimeHeader* mime = CImMimeHeader::NewLC();
       
   602 	    mime->RestoreL(*store);
       
   603 	    characterSetId = DetermineCharactersetIdFromMimeHeaderL( aEntry, mime );
       
   604         CleanupStack::PopAndDestroy(mime);
       
   605         }
       
   606 
       
   607     //Store is no longer needed
       
   608  	CleanupStack::PopAndDestroy(store);
       
   609 
       
   610  	//If character set is valid stop now
       
   611  	if( characterSetId )
       
   612 	 	{
       
   613 	 	return characterSetId;
       
   614 	 	}
       
   615 
       
   616      //--------------------------------------------------
       
   617     // Option 2. Read the MIME headers from child entrys'
       
   618     //---------------------------------------------------
       
   619     CMsvEntrySelection* entrySelection = iEntry->ChildrenL();
       
   620     CleanupStack::PushL(entrySelection);
       
   621 
       
   622     //Go through the children
       
   623 	TInt count = entrySelection->Count();
       
   624 	for (TInt counter = 0; counter < count; counter++)
       
   625 		{
       
   626 		//Get the child entry
       
   627 		CMsvEntry* child = iEntry->ChildEntryL((*entrySelection)[counter]);
       
   628 		CleanupStack::PushL(child);
       
   629 
       
   630 		//Read child entry store
       
   631 		CMsvStore* childStore = NULL;
       
   632 		TRAPD( err, childStore = child->ReadStoreL() );
       
   633 
       
   634 		//If error occurs in store read try the next children
       
   635 		if( err )
       
   636 			{
       
   637 			CleanupStack::PopAndDestroy(child);
       
   638 			continue;
       
   639 			}
       
   640 
       
   641 		//Read the childs MIME header if they are available
       
   642 		CleanupStack::PushL(childStore);
       
   643 		if (childStore->IsPresentL(KUidMsgFileMimeHeader))
       
   644 			{
       
   645 			CImMimeHeader* mime = CImMimeHeader::NewLC();
       
   646 			mime->RestoreL( *childStore );
       
   647 			characterSetId = DetermineCharactersetIdFromMimeHeaderL( *child, mime );
       
   648 			CleanupStack::PopAndDestroy(mime);
       
   649 			}
       
   650 		CleanupStack::PopAndDestroy(childStore);
       
   651 		CleanupStack::PopAndDestroy(child);	//This is brutal
       
   652 
       
   653 		//If we got the characterSetId set from this child we can stop
       
   654 		if( characterSetId )
       
   655 			{
       
   656 			break;
       
   657 			}
       
   658 		}
       
   659 	CleanupStack::PopAndDestroy(); // entrySelection
       
   660 
       
   661     return characterSetId;
       
   662     }
       
   663 
       
   664 // -----------------------------------------------------------------------------
       
   665 // CMailMessage::DetermineCharactersetIdFromMimeHeader
       
   666 // -----------------------------------------------------------------------------
       
   667 //
       
   668 TUint CMailMessage::DetermineCharactersetIdFromMimeHeaderL( CMsvEntry& aEntry,
       
   669 															const CImMimeHeader* aMime )
       
   670 	{
       
   671 	TUint characterSetFromMimeHeader(0);
       
   672 	TUint characterSetFromContentType(0);
       
   673 
       
   674 	//Character can sometimes be read from MimeCharset
       
   675 	characterSetFromMimeHeader = aMime->MimeCharset();
       
   676 
       
   677 	//Determine character set from ContentTypeParams
       
   678 	const CDesC8Array& array = aMime->ContentTypeParams();
       
   679     CCnvCharacterSetConverter* charconv =  CCnvCharacterSetConverter::NewLC();
       
   680     RFs& session = aEntry.Session().FileSession();
       
   681 
       
   682     for(TInt i = 0; i < array.Count() && characterSetFromContentType == 0; i++)
       
   683         {
       
   684         characterSetFromContentType = charconv->
       
   685         	ConvertStandardNameOfCharacterSetToIdentifierL( array[i], session);
       
   686         }
       
   687     CleanupStack::PopAndDestroy(); //charconv
       
   688 
       
   689     //Determine whitch one we use:
       
   690     //characterSetFromMimeHeader or characterSetFromContentType
       
   691     if( characterSetFromMimeHeader )
       
   692     	return characterSetFromMimeHeader;
       
   693     else if ( characterSetFromContentType )
       
   694     	return characterSetFromContentType;
       
   695     else
       
   696     	return 0;
       
   697 	}
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // CMailMessage::NextStateL
       
   701 // -----------------------------------------------------------------------------
       
   702 //
       
   703 TBool CMailMessage::NextStateL()
       
   704     {
       
   705     TBool retValue(ETrue);
       
   706     switch(iState)
       
   707         {
       
   708         case ELoadMessageBody:
       
   709             // load attachment next
       
   710             LoadAttachmentsL();
       
   711             break;
       
   712         case EHtmlNotFound:
       
   713         	// Html content not found, so try plain content
       
   714             LoadBodyTextL();
       
   715             break;
       
   716         case ELoadAttachments:
       
   717 			// FALLTROUGH
       
   718 			// Load Attached messages only if clien requests them.
       
   719         default:
       
   720             // "ELoadAttachedMessages" or "ELoadLinkedHtmlContent"
       
   721             // or unknown state, so we stop
       
   722             retValue = EFalse;
       
   723             break;
       
   724         }
       
   725     return retValue;
       
   726     }
       
   727 
       
   728 // -----------------------------------------------------------------------------
       
   729 // CMailMessage::LoadBodyTextL
       
   730 // -----------------------------------------------------------------------------
       
   731 //
       
   732 void CMailMessage::LoadBodyTextL()
       
   733     {
       
   734     iState = ELoadMessageBody;
       
   735 
       
   736 
       
   737     // delete the body text to avoid
       
   738     // appending the same text in different
       
   739     // character set at the end of the old text
       
   740     delete iBodyText;
       
   741     iBodyText = NULL;
       
   742     iBodyText = CRichText::NewL(
       
   743         iGlobalParaLayer,
       
   744         iGlobalCharLayer);
       
   745 
       
   746     iMessage->GetBodyTextL(iStatus,
       
   747         iMessageID,
       
   748         CImEmailMessage::EThisMessageOnly,
       
   749         *iBodyText,
       
   750         *iGlobalParaLayer,
       
   751         *iGlobalCharLayer);
       
   752 
       
   753     }
       
   754 
       
   755 // -----------------------------------------------------------------------------
       
   756 // CMailMessage::LoadHTMLContentL
       
   757 // -----------------------------------------------------------------------------
       
   758 //
       
   759 void CMailMessage::LoadHTMLContentL()
       
   760     {
       
   761     iState = ELoadMessageBody;
       
   762     iMessage->FindFirstHTMLPageFileHandleL(iMessageID, iStatus);
       
   763     }
       
   764 
       
   765 // -----------------------------------------------------------------------------
       
   766 // CMailMessage::LoadLinkedHTMLContentL
       
   767 // -----------------------------------------------------------------------------
       
   768 //
       
   769 void CMailMessage::LoadLinkedHTMLContentL(const TDesC& aBase, const TDesC& aURI)
       
   770     {
       
   771     iState = ELoadLinkedHtmlContent;
       
   772 
       
   773     iMessage->FindUniversalResourceIdentifierFileHandleL(
       
   774     	iMhtmlPartId,
       
   775     	aBase,
       
   776     	aURI,
       
   777     	iStatus);
       
   778     }
       
   779 
       
   780 // -----------------------------------------------------------------------------
       
   781 // CMailMessage::LoadAttachmentsL
       
   782 // -----------------------------------------------------------------------------
       
   783 //
       
   784 void CMailMessage::LoadAttachmentsL()
       
   785     {
       
   786     iState = ELoadAttachments;
       
   787     iMessage->GetAttachmentsListL(
       
   788         iStatus, iMessageID,
       
   789         CImEmailMessage::EAllAttachments,
       
   790         CImEmailMessage::EThisMessageAndEmbeddedMessages);
       
   791     }
       
   792 
       
   793 // -----------------------------------------------------------------------------
       
   794 // CMailMessage::LoadAttachedMessagesL
       
   795 // -----------------------------------------------------------------------------
       
   796 //
       
   797 void CMailMessage::LoadAttachedMessagesL()
       
   798     {
       
   799     iState = ELoadAttachedMessages;
       
   800     iMessage->GetMessageDigestEntriesL(iStatus, iMessageID);
       
   801     }
       
   802 
       
   803 // ----------------------------------------------------------------------------
       
   804 //  CMailMessage::NotifyObserverL()
       
   805 // ----------------------------------------------------------------------------
       
   806 //
       
   807 void CMailMessage::NotifyObserverL(TInt aState)
       
   808     {
       
   809     iMessageObserver->MessageLoadingL(aState, *this);
       
   810     }
       
   811 
       
   812 // ----------------------------------------------------------------------------
       
   813 //  CMailMessage::IsLinkedItemL()
       
   814 // ----------------------------------------------------------------------------
       
   815 //
       
   816 TBool CMailMessage::IsLinkedItemL( RFile& aHandle, TMsvAttachmentId aId )
       
   817 	{
       
   818 	TBool isLinkedItem(EFalse);
       
   819     const TInt linkedItems = iLinkedHtmlItems->Count();
       
   820     if ( linkedItems )
       
   821         {
       
   822         // linked html item?
       
   823         for( TInt index(0); index<linkedItems; ++index )
       
   824             {
       
   825             CLinkedHtmlItem* item = (*iLinkedHtmlItems)[index];
       
   826             if( item->iLinkedItemId == aId )
       
   827                 {
       
   828                 ASSERT( !iAsyncWait->IsActive() ); // nested calls illegal
       
   829                 iMessage->FindUniversalResourceIdentifierFileHandleL(
       
   830                 	iMhtmlPartId,
       
   831                 	KNullDesC(),
       
   832                 	*item->iUriAddress,
       
   833                 	iAsyncWait->iStatus );
       
   834                 iAsyncWait->Start();
       
   835                 User::LeaveIfError( iAsyncWait->iStatus.Int() );
       
   836 
       
   837                 User::LeaveIfError(
       
   838                     iMessage->GetUniversalResourceIdentifierFileHandle(
       
   839                     iLinkedfileId, aHandle) );
       
   840                 isLinkedItem = ETrue;
       
   841                 }
       
   842             }
       
   843         }
       
   844     return isLinkedItem;
       
   845 	}
       
   846 
       
   847 // ----------------------------------------------------------------------------
       
   848 //  CMailMessage::ShowErrorNoteL()
       
   849 // ----------------------------------------------------------------------------
       
   850 //
       
   851 void CMailMessage::ShowErrorNoteL( TInt aError )
       
   852     {
       
   853     CErrorUI* errorUI = CErrorUI::NewLC();
       
   854     errorUI->ShowGlobalErrorNoteL( aError ); // ignore return value
       
   855     CleanupStack::PopAndDestroy(); // errorUI
       
   856     }
       
   857 
       
   858 // End Of File