email/mail/PluginSrc/MailPlainView/MailLoadStateHtml.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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:  Loads html content
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include 	"MailLog.h"
       
    22 #include 	"MailUtils.h"
       
    23 #include    "MailLoadStateHtml.h"
       
    24 #include    "MailLoadStateInline.h"
       
    25 #include 	"MailLoadStateMachine.h"
       
    26 #include 	"MsgMailViewerHtmlConv.h"
       
    27 #include 	<MailPlainView.rsg>
       
    28 #include    <MMailAppUiInterface.h>
       
    29 #include    <CMailMessage.h>
       
    30 #include 	<StringLoader.h>
       
    31 #include 	<charconv.h>
       
    32 
       
    33 _LIT8( KStartTag, "<html>" );
       
    34 _LIT8( KHtmlHeader1, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=");
       
    35 _LIT8( KHtmlHeader2, "\">\n");
       
    36 _LIT8( KCharsetTag, "CHARSET" );
       
    37 _LIT16( KCDrive, "C:" );
       
    38 const TInt KPathNameLength( 100 );
       
    39 
       
    40 // ============================ MEMBER FUNCTIONS ===============================
       
    41 
       
    42 // load html file
       
    43 // -----------------------------------------------------------------------------
       
    44 // CLoadHtmlFile::MessageLoadingL
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 void CLoadHtmlFile::MessageLoadingL(TInt aStatus, CMailMessage& aMessage)
       
    48 	{
       
    49 	if( aStatus == CMailMessage::EBodyTextReady )
       
    50 		{
       
    51         TRAPD( err, HandleBodyTextReadyL( aMessage ) );
       
    52 
       
    53         if( err )
       
    54             {
       
    55             // Complete request and leave if error occured
       
    56             CompleteRequest( err );
       
    57             User::LeaveIfError( err );
       
    58             }
       
    59 		}
       
    60 	}
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CLoadHtmlFile::CLoadHtmlFile
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 CLoadHtmlFile::CLoadHtmlFile(
       
    67 	MMailAppUiInterface* aAppUI, MStateMachine& aStateMachine ) :
       
    68 	CActive( CActive::EPriorityStandard )
       
    69 	{
       
    70 	CActiveScheduler::Add( this );
       
    71 	iAppUI = aAppUI;
       
    72 	iStateMachine = &aStateMachine;
       
    73 	}
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CLoadHtmlFile::~CLoadHtmlFile
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CLoadHtmlFile::~CLoadHtmlFile()
       
    80 	{
       
    81 	Cancel();
       
    82 	delete iConverter;
       
    83 	}
       
    84 
       
    85 // -----------------------------------------------------------------------------
       
    86 // CLoadHtmlFile::NextStateL
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 MLoadState* CLoadHtmlFile::NextStateL()
       
    90 	{
       
    91 	return new( ELeave ) CLoadInlineImages(
       
    92 		iAppUI, *iStateMachine );
       
    93 	}
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // CLoadHtmlFile::MakeRequestL
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 void CLoadHtmlFile::MakeRequestL(
       
   100 	TRequestStatus& aStatus,
       
   101 	CMailMessage& aMessage )
       
   102 	{
       
   103 	iLoadStatus = &aStatus;
       
   104 	iMessage = &aMessage;
       
   105 	aMessage.LoadHtmlContentL( *this );
       
   106 	aStatus = KRequestPending;
       
   107 	}
       
   108 
       
   109 // -----------------------------------------------------------------------------
       
   110 // CLoadHtmlFile::HandleBodyTextReadyL
       
   111 // -----------------------------------------------------------------------------
       
   112 //
       
   113 void CLoadHtmlFile::HandleBodyTextReadyL( CMailMessage& aMessage )
       
   114     {
       
   115 	RFile handle = aMessage.HtmlContent();
       
   116 	CleanupClosePushL( handle );
       
   117 
       
   118 	if ( handle.SubSessionHandle() == 0 )
       
   119 		{
       
   120 		// if html content can not be found try to show plain text
       
   121 		// content
       
   122 		CRichText* bodyText = aMessage.MessageBody();
       
   123 		// Partial loaded or corrupted message?
       
   124 		if ( aMessage.MessageEntry().PartialDownloaded() )
       
   125 			{
       
   126 			HBufC* text = StringLoader::LoadLC(
       
   127 				R_QTN_MAIL_REST_OF_MAIL_NOT_FETCHED, CCoeEnv::Static());
       
   128 
       
   129 	        bodyText->InsertL(0, *text);
       
   130 	        CleanupStack::PopAndDestroy(); // text
       
   131 			}
       
   132 		else // Corrupted?
       
   133 			{
       
   134 			MailUtils::InformationNoteL(
       
   135 				R_MAIL_VIEWER_HTML_ERROR_DLG_TEXT );
       
   136 			}
       
   137         iAppUI->SetBodyTextL(*aMessage.MessageBody());
       
   138         CompleteRequest( KErrNone );
       
   139 		}
       
   140 	else
       
   141 		{
       
   142 		// Add html content as attachment before conversion.
       
   143 		if ( !aMessage.MessageEntry().PartialDownloaded() )
       
   144 			{
       
   145 			AddHtmlFileAttachmentAndCharsetL( aMessage, handle );
       
   146 			}
       
   147         ParseHtmlFileL( aMessage, handle );
       
   148 		}
       
   149     CleanupStack::PopAndDestroy(); // handle
       
   150     }
       
   151 
       
   152 // -----------------------------------------------------------------------------
       
   153 // CLoadHtmlFile::ShowHtmlErrorNoteIfNeededL
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 void CLoadHtmlFile::ShowHtmlErrorNoteIfNeededL( TInt aResult )
       
   157 	{
       
   158     if ( aResult == KErrNotFound )
       
   159         {
       
   160 		MailUtils::InformationNoteL( R_MAIL_VIEWER_HTML_ERROR_DLG_TEXT );
       
   161         }
       
   162     else if ( aResult == KErrCorrupt )
       
   163         {
       
   164 		MailUtils::InformationNoteL( R_MAIL_VIEWER_HTML_CORRUPTED_NOTE_TEXT );
       
   165         }
       
   166     else if ( aResult == KErrEof )
       
   167         {
       
   168         // Successfully parsed. Do nothing.
       
   169         }
       
   170     else
       
   171         {
       
   172         User::LeaveIfError( aResult );
       
   173         }
       
   174 	}
       
   175 
       
   176 // -----------------------------------------------------------------------------
       
   177 // CLoadHtmlFile::AddHtmlFileAttachmentL
       
   178 // -----------------------------------------------------------------------------
       
   179 //
       
   180 void CLoadHtmlFile::AddHtmlFileAttachmentL(
       
   181     CMailMessage& aMessage, RFile aFile )
       
   182     {
       
   183 	CMsvAttachment* htmlFileInfo = CMsvAttachment::NewL(
       
   184 		CMsvAttachment::EMsvFile );
       
   185 	CleanupStack::PushL( htmlFileInfo );
       
   186 
       
   187 	TInt htmlSize(0);
       
   188 	aFile.Size( htmlSize );
       
   189 	htmlFileInfo->SetSize( htmlSize );
       
   190 	TFileName filename;
       
   191 	User::LeaveIfError( aFile.Name( filename ) );
       
   192 	htmlFileInfo->SetAttachmentNameL( filename );
       
   193 	htmlFileInfo->SetComplete( ETrue );
       
   194 	htmlFileInfo->SetId( aMessage.MhtmlPartId() );
       
   195 
       
   196     iAppUI->AddAttachmentL( *htmlFileInfo, EFalse );
       
   197     CleanupStack::PopAndDestroy( htmlFileInfo );
       
   198     }
       
   199 
       
   200 // -----------------------------------------------------------------------------
       
   201 // CLoadHtmlFile::ParseHtmlFileL
       
   202 // -----------------------------------------------------------------------------
       
   203 //
       
   204 void CLoadHtmlFile::ParseHtmlFileL(CMailMessage& aMessage, RFile aFile )
       
   205     {
       
   206     LOG( "CLoadHtmlFile::ParseHtmlFileL" );
       
   207     LOGHANDLESIZE( aFile );
       
   208 
       
   209     // Get the charset of the html part from the message. If the message
       
   210     // thinks it knows the html charset then force the conversion of the html
       
   211     // part using the specified character set decoding.
       
   212     //
       
   213     // Otherwise, if the html message part character set is unknown, then
       
   214     // we'll let the conversion object try to identify the character set during
       
   215     // the parsing process.
       
   216     const TUint htmlCharSetId = aMessage.HtmlCharsetIdL();
       
   217     const TBool forceCharSet = ( htmlCharSetId != 0 );
       
   218 
       
   219     delete iConverter;
       
   220     iConverter = NULL;
       
   221     iConverter = CMsgMailViewerHtmlConv::NewL(
       
   222             aFile,
       
   223             htmlCharSetId,
       
   224             forceCharSet );
       
   225 
       
   226     iConverter->Convert( &iStatus );
       
   227     SetActive();
       
   228     }
       
   229 
       
   230 // -----------------------------------------------------------------------------
       
   231 // CLoadHtmlFile::RunL
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 void CLoadHtmlFile::RunL()
       
   235     {
       
   236     LOG( "CLoadHtmlFile::RunL" );
       
   237     ShowHtmlErrorNoteIfNeededL( iStatus.Int() );
       
   238 
       
   239     CRichText* bodyText = iMessage->MessageBody();
       
   240     bodyText->Reset();
       
   241     bodyText->InsertL(0, *(iConverter->GetText()));
       
   242 
       
   243     // If the conversion process successfully identified the characterset
       
   244     // of the html part, then update the message with this new charset
       
   245     // decoding value.
       
   246     if ( iConverter->AutoParsedCharSetNameAndIdentifier() )
       
   247         {
       
   248         const TUint autoParsedCharSetId = iConverter->AutoParsedCharSetIdentifier();
       
   249         iMessage->OverrideHtmlMessageCharset( autoParsedCharSetId );
       
   250         }
       
   251 
       
   252     iStateMachine->SetIdArray( iConverter->FileIdArray() );
       
   253 
       
   254     if ( iMessage->MessageEntry().PartialDownloaded() )
       
   255         {
       
   256         HBufC* text = StringLoader::LoadLC(
       
   257             R_QTN_MAIL_REST_OF_MAIL_NOT_FETCHED, CCoeEnv::Static());
       
   258 
       
   259         bodyText->InsertL(bodyText->DocumentLength(), CEditableText::ELineBreak);
       
   260 
       
   261         bodyText->InsertL(bodyText->DocumentLength(), *text);
       
   262 
       
   263         CleanupStack::PopAndDestroy(); // text
       
   264         }
       
   265 
       
   266     iAppUI->SetBodyTextL( *(iMessage->MessageBody()) );
       
   267 
       
   268     // All done
       
   269     CompleteRequest( KErrNone );
       
   270     }
       
   271 
       
   272 // -----------------------------------------------------------------------------
       
   273 // CLoadHtmlFile::RunError
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 TInt CLoadHtmlFile::RunError( TInt aError )
       
   277     {
       
   278     LOG( "CLoadHtmlFile::DoCancel" );
       
   279     CompleteRequest( aError );
       
   280     return KErrNone;
       
   281     }
       
   282 
       
   283 // -----------------------------------------------------------------------------
       
   284 // CLoadHtmlFile::DoCancel
       
   285 // -----------------------------------------------------------------------------
       
   286 //
       
   287 void CLoadHtmlFile::DoCancel()
       
   288     {
       
   289     LOG( "CLoadHtmlFile::DoCancel" );
       
   290 
       
   291     if( iConverter )
       
   292         {
       
   293         iConverter->Cancel();
       
   294         }
       
   295     }
       
   296 
       
   297 // -----------------------------------------------------------------------------
       
   298 // CLoadHtmlFile::CompleteRequest
       
   299 // -----------------------------------------------------------------------------
       
   300 //
       
   301 void CLoadHtmlFile::CompleteRequest( TInt aError )
       
   302     {
       
   303     LOG( "CLoadHtmlFile::CompleteRequest" );
       
   304     User::RequestComplete( iLoadStatus, aError );
       
   305     iAppUI->ViewMessageComplete();
       
   306     }
       
   307 
       
   308 // -----------------------------------------------------------------------------
       
   309 // CLoadHtmlFile::AddCharsetToHtmlAttachment
       
   310 // -----------------------------------------------------------------------------
       
   311 //
       
   312 void CLoadHtmlFile::AddHtmlFileAttachmentAndCharsetL( CMailMessage& aMessage, RFile& aHandle )
       
   313 	{
       
   314 	// We have to check if the html body contains information about
       
   315 	// charset used. If it does, we use original file. Otherwise
       
   316 	// we create a new html file which has charset
       
   317 	// information added
       
   318 
       
   319 	// Get charset Id and handle for the html body content
       
   320 	TUint htmlCharsetId = aMessage.HtmlCharsetIdL();
       
   321 
       
   322 	// Convert charset Id into string
       
   323 	RFs& fs = CCoeEnv::Static()->FsSession();
       
   324 	CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC();
       
   325 	HBufC8* charsetBuf = charConv->
       
   326 		ConvertCharacterSetIdentifierToStandardNameL(
       
   327 				htmlCharsetId, fs);
       
   328 	CleanupStack::PopAndDestroy( charConv ); // charConv
       
   329 	CleanupStack::PushL( charsetBuf );
       
   330 	TPtr8 charsetPtr = charsetBuf->Des();
       
   331 
       
   332 	// Calculate buffer size for charsetRowBuf and also for
       
   333 	// htmlContentBuf to avoid reallocation of memory
       
   334 	TInt bufferSize( 0 );
       
   335 	bufferSize += KHtmlHeader1().Length();
       
   336 	bufferSize += charsetBuf->Length();
       
   337 	bufferSize += KHtmlHeader2().Length();
       
   338 
       
   339 	// Read html content from the html file
       
   340 	TInt fileSize(0);
       
   341 	aHandle.Size( fileSize );
       
   342 	HBufC8* htmlContentBuf = HBufC8::NewLC( fileSize+bufferSize );
       
   343 	TPtr8 htmlContentPtr = htmlContentBuf->Des();
       
   344 	aHandle.Read( htmlContentPtr );
       
   345 	TInt i( 0 );
       
   346 	aHandle.Seek( ESeekStart, i );	// rewind the file
       
   347 
       
   348 	// Try to find strings CHARSET and <html>
       
   349 	// If the string is not found append information containing charset
       
   350 	TInt charsetFoundAt( htmlContentBuf->Find( KCharsetTag ) );
       
   351 	TInt htmlTagFoundAt( htmlContentBuf->Find( KStartTag ) );
       
   352 
       
   353 	// If CHARSET is defined in the email but it is not found from the
       
   354 	// html body part, we have to add it ourselves.
       
   355 	// Else use the original html file
       
   356 	if( charsetFoundAt <= 0
       
   357 		&& htmlTagFoundAt >= 0 )
       
   358 		{
       
   359 		// Create a new hmtl line containing character set information
       
   360 		// and append it.
       
   361 		// Create new buffer for storing charset html info row and
       
   362 		// insert it to the buffer containing html body
       
   363 		HBufC8* charsetRowBuf = HBufC8::NewLC( bufferSize );
       
   364 		TPtr8 charsetRowPtr = charsetRowBuf->Des();
       
   365 		charsetRowPtr.Append( KHtmlHeader1 );
       
   366 		charsetRowPtr.Append( charsetPtr );
       
   367 		charsetRowPtr.Append( KHtmlHeader2 );
       
   368 		htmlContentPtr.Insert( htmlTagFoundAt, charsetRowPtr );
       
   369 		CleanupStack::PopAndDestroy( charsetRowBuf );
       
   370 
       
   371 		// create mailviewer folder in c:\private
       
   372 		HBufC* pathNameBuf = HBufC::NewLC( KPathNameLength );
       
   373 		TPtr pathNamePtr = pathNameBuf->Des();
       
   374 		fs.PrivatePath( pathNamePtr );
       
   375 		pathNamePtr.Insert( 0, KCDrive );
       
   376 
       
   377 		TInt makeDir = fs.MkDir( pathNamePtr );
       
   378 		// Itīs ok if directory already exists. If other errors,
       
   379 		// use original html file
       
   380 		if( makeDir != KErrAlreadyExists && makeDir < 0 )
       
   381 			{
       
   382 			AddHtmlFileAttachmentL( aMessage, aHandle );
       
   383 			}
       
   384 		else	// continue creating new html attachment
       
   385 			{
       
   386 			// create new html attachment
       
   387 			RFile newHtmlFile;
       
   388 			HBufC* newHtmlFileNameBuf = HBufC::NewLC( KPathNameLength );
       
   389 			TPtr newHtmlFileNamePtr = newHtmlFileNameBuf->Des();
       
   390 			aHandle.Name( newHtmlFileNamePtr );
       
   391 			pathNamePtr.Append( newHtmlFileNamePtr );
       
   392 			CleanupStack::PopAndDestroy( newHtmlFileNameBuf );
       
   393 
       
   394 			TInt openResult = newHtmlFile.Replace( fs, pathNamePtr, EFileWrite );
       
   395 			CleanupClosePushL( newHtmlFile );
       
   396 			if( openResult >= KErrNone )
       
   397 				{
       
   398 				TInt writeResult = newHtmlFile.Write( 0, htmlContentPtr );
       
   399 				if( writeResult >= KErrNone )
       
   400 					{
       
   401 					AddHtmlFileAttachmentL( aMessage, newHtmlFile );
       
   402 					}
       
   403 				else	// else use original html file
       
   404 					{
       
   405 					AddHtmlFileAttachmentL( aMessage, aHandle );
       
   406 					}
       
   407 				}
       
   408 			CleanupStack::PopAndDestroy( &newHtmlFile );
       
   409 			}
       
   410 		CleanupStack::PopAndDestroy( pathNameBuf );
       
   411 		}
       
   412 	else	// charset found, use original html file
       
   413 		{
       
   414 		AddHtmlFileAttachmentL( aMessage, aHandle );
       
   415 		}
       
   416 	CleanupStack::PopAndDestroy( 2, charsetBuf );	// htmlContentBuf
       
   417 	}
       
   418 
       
   419 
       
   420 //  End of File