diff -r 000000000000 -r 72b543305e3a email/mail/PluginSrc/MailPlainView/MailLoadStateHtml.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/mail/PluginSrc/MailPlainView/MailLoadStateHtml.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,420 @@ +/* +* Copyright (c) 2002-2004 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: Loads html content +* +*/ + + + +// INCLUDE FILES +#include "MailLog.h" +#include "MailUtils.h" +#include "MailLoadStateHtml.h" +#include "MailLoadStateInline.h" +#include "MailLoadStateMachine.h" +#include "MsgMailViewerHtmlConv.h" +#include +#include +#include +#include +#include + +_LIT8( KStartTag, "" ); +_LIT8( KHtmlHeader1, "\n"); +_LIT8( KCharsetTag, "CHARSET" ); +_LIT16( KCDrive, "C:" ); +const TInt KPathNameLength( 100 ); + +// ============================ MEMBER FUNCTIONS =============================== + +// load html file +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::MessageLoadingL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::MessageLoadingL(TInt aStatus, CMailMessage& aMessage) + { + if( aStatus == CMailMessage::EBodyTextReady ) + { + TRAPD( err, HandleBodyTextReadyL( aMessage ) ); + + if( err ) + { + // Complete request and leave if error occured + CompleteRequest( err ); + User::LeaveIfError( err ); + } + } + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::CLoadHtmlFile +// ----------------------------------------------------------------------------- +// +CLoadHtmlFile::CLoadHtmlFile( + MMailAppUiInterface* aAppUI, MStateMachine& aStateMachine ) : + CActive( CActive::EPriorityStandard ) + { + CActiveScheduler::Add( this ); + iAppUI = aAppUI; + iStateMachine = &aStateMachine; + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::~CLoadHtmlFile +// ----------------------------------------------------------------------------- +// +CLoadHtmlFile::~CLoadHtmlFile() + { + Cancel(); + delete iConverter; + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::NextStateL +// ----------------------------------------------------------------------------- +// +MLoadState* CLoadHtmlFile::NextStateL() + { + return new( ELeave ) CLoadInlineImages( + iAppUI, *iStateMachine ); + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::MakeRequestL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::MakeRequestL( + TRequestStatus& aStatus, + CMailMessage& aMessage ) + { + iLoadStatus = &aStatus; + iMessage = &aMessage; + aMessage.LoadHtmlContentL( *this ); + aStatus = KRequestPending; + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::HandleBodyTextReadyL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::HandleBodyTextReadyL( CMailMessage& aMessage ) + { + RFile handle = aMessage.HtmlContent(); + CleanupClosePushL( handle ); + + if ( handle.SubSessionHandle() == 0 ) + { + // if html content can not be found try to show plain text + // content + CRichText* bodyText = aMessage.MessageBody(); + // Partial loaded or corrupted message? + if ( aMessage.MessageEntry().PartialDownloaded() ) + { + HBufC* text = StringLoader::LoadLC( + R_QTN_MAIL_REST_OF_MAIL_NOT_FETCHED, CCoeEnv::Static()); + + bodyText->InsertL(0, *text); + CleanupStack::PopAndDestroy(); // text + } + else // Corrupted? + { + MailUtils::InformationNoteL( + R_MAIL_VIEWER_HTML_ERROR_DLG_TEXT ); + } + iAppUI->SetBodyTextL(*aMessage.MessageBody()); + CompleteRequest( KErrNone ); + } + else + { + // Add html content as attachment before conversion. + if ( !aMessage.MessageEntry().PartialDownloaded() ) + { + AddHtmlFileAttachmentAndCharsetL( aMessage, handle ); + } + ParseHtmlFileL( aMessage, handle ); + } + CleanupStack::PopAndDestroy(); // handle + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::ShowHtmlErrorNoteIfNeededL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::ShowHtmlErrorNoteIfNeededL( TInt aResult ) + { + if ( aResult == KErrNotFound ) + { + MailUtils::InformationNoteL( R_MAIL_VIEWER_HTML_ERROR_DLG_TEXT ); + } + else if ( aResult == KErrCorrupt ) + { + MailUtils::InformationNoteL( R_MAIL_VIEWER_HTML_CORRUPTED_NOTE_TEXT ); + } + else if ( aResult == KErrEof ) + { + // Successfully parsed. Do nothing. + } + else + { + User::LeaveIfError( aResult ); + } + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::AddHtmlFileAttachmentL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::AddHtmlFileAttachmentL( + CMailMessage& aMessage, RFile aFile ) + { + CMsvAttachment* htmlFileInfo = CMsvAttachment::NewL( + CMsvAttachment::EMsvFile ); + CleanupStack::PushL( htmlFileInfo ); + + TInt htmlSize(0); + aFile.Size( htmlSize ); + htmlFileInfo->SetSize( htmlSize ); + TFileName filename; + User::LeaveIfError( aFile.Name( filename ) ); + htmlFileInfo->SetAttachmentNameL( filename ); + htmlFileInfo->SetComplete( ETrue ); + htmlFileInfo->SetId( aMessage.MhtmlPartId() ); + + iAppUI->AddAttachmentL( *htmlFileInfo, EFalse ); + CleanupStack::PopAndDestroy( htmlFileInfo ); + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::ParseHtmlFileL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::ParseHtmlFileL(CMailMessage& aMessage, RFile aFile ) + { + LOG( "CLoadHtmlFile::ParseHtmlFileL" ); + LOGHANDLESIZE( aFile ); + + // Get the charset of the html part from the message. If the message + // thinks it knows the html charset then force the conversion of the html + // part using the specified character set decoding. + // + // Otherwise, if the html message part character set is unknown, then + // we'll let the conversion object try to identify the character set during + // the parsing process. + const TUint htmlCharSetId = aMessage.HtmlCharsetIdL(); + const TBool forceCharSet = ( htmlCharSetId != 0 ); + + delete iConverter; + iConverter = NULL; + iConverter = CMsgMailViewerHtmlConv::NewL( + aFile, + htmlCharSetId, + forceCharSet ); + + iConverter->Convert( &iStatus ); + SetActive(); + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::RunL +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::RunL() + { + LOG( "CLoadHtmlFile::RunL" ); + ShowHtmlErrorNoteIfNeededL( iStatus.Int() ); + + CRichText* bodyText = iMessage->MessageBody(); + bodyText->Reset(); + bodyText->InsertL(0, *(iConverter->GetText())); + + // If the conversion process successfully identified the characterset + // of the html part, then update the message with this new charset + // decoding value. + if ( iConverter->AutoParsedCharSetNameAndIdentifier() ) + { + const TUint autoParsedCharSetId = iConverter->AutoParsedCharSetIdentifier(); + iMessage->OverrideHtmlMessageCharset( autoParsedCharSetId ); + } + + iStateMachine->SetIdArray( iConverter->FileIdArray() ); + + if ( iMessage->MessageEntry().PartialDownloaded() ) + { + HBufC* text = StringLoader::LoadLC( + R_QTN_MAIL_REST_OF_MAIL_NOT_FETCHED, CCoeEnv::Static()); + + bodyText->InsertL(bodyText->DocumentLength(), CEditableText::ELineBreak); + + bodyText->InsertL(bodyText->DocumentLength(), *text); + + CleanupStack::PopAndDestroy(); // text + } + + iAppUI->SetBodyTextL( *(iMessage->MessageBody()) ); + + // All done + CompleteRequest( KErrNone ); + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::RunError +// ----------------------------------------------------------------------------- +// +TInt CLoadHtmlFile::RunError( TInt aError ) + { + LOG( "CLoadHtmlFile::DoCancel" ); + CompleteRequest( aError ); + return KErrNone; + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::DoCancel +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::DoCancel() + { + LOG( "CLoadHtmlFile::DoCancel" ); + + if( iConverter ) + { + iConverter->Cancel(); + } + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::CompleteRequest +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::CompleteRequest( TInt aError ) + { + LOG( "CLoadHtmlFile::CompleteRequest" ); + User::RequestComplete( iLoadStatus, aError ); + iAppUI->ViewMessageComplete(); + } + +// ----------------------------------------------------------------------------- +// CLoadHtmlFile::AddCharsetToHtmlAttachment +// ----------------------------------------------------------------------------- +// +void CLoadHtmlFile::AddHtmlFileAttachmentAndCharsetL( CMailMessage& aMessage, RFile& aHandle ) + { + // We have to check if the html body contains information about + // charset used. If it does, we use original file. Otherwise + // we create a new html file which has charset + // information added + + // Get charset Id and handle for the html body content + TUint htmlCharsetId = aMessage.HtmlCharsetIdL(); + + // Convert charset Id into string + RFs& fs = CCoeEnv::Static()->FsSession(); + CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC(); + HBufC8* charsetBuf = charConv-> + ConvertCharacterSetIdentifierToStandardNameL( + htmlCharsetId, fs); + CleanupStack::PopAndDestroy( charConv ); // charConv + CleanupStack::PushL( charsetBuf ); + TPtr8 charsetPtr = charsetBuf->Des(); + + // Calculate buffer size for charsetRowBuf and also for + // htmlContentBuf to avoid reallocation of memory + TInt bufferSize( 0 ); + bufferSize += KHtmlHeader1().Length(); + bufferSize += charsetBuf->Length(); + bufferSize += KHtmlHeader2().Length(); + + // Read html content from the html file + TInt fileSize(0); + aHandle.Size( fileSize ); + HBufC8* htmlContentBuf = HBufC8::NewLC( fileSize+bufferSize ); + TPtr8 htmlContentPtr = htmlContentBuf->Des(); + aHandle.Read( htmlContentPtr ); + TInt i( 0 ); + aHandle.Seek( ESeekStart, i ); // rewind the file + + // Try to find strings CHARSET and + // If the string is not found append information containing charset + TInt charsetFoundAt( htmlContentBuf->Find( KCharsetTag ) ); + TInt htmlTagFoundAt( htmlContentBuf->Find( KStartTag ) ); + + // If CHARSET is defined in the email but it is not found from the + // html body part, we have to add it ourselves. + // Else use the original html file + if( charsetFoundAt <= 0 + && htmlTagFoundAt >= 0 ) + { + // Create a new hmtl line containing character set information + // and append it. + // Create new buffer for storing charset html info row and + // insert it to the buffer containing html body + HBufC8* charsetRowBuf = HBufC8::NewLC( bufferSize ); + TPtr8 charsetRowPtr = charsetRowBuf->Des(); + charsetRowPtr.Append( KHtmlHeader1 ); + charsetRowPtr.Append( charsetPtr ); + charsetRowPtr.Append( KHtmlHeader2 ); + htmlContentPtr.Insert( htmlTagFoundAt, charsetRowPtr ); + CleanupStack::PopAndDestroy( charsetRowBuf ); + + // create mailviewer folder in c:\private + HBufC* pathNameBuf = HBufC::NewLC( KPathNameLength ); + TPtr pathNamePtr = pathNameBuf->Des(); + fs.PrivatePath( pathNamePtr ); + pathNamePtr.Insert( 0, KCDrive ); + + TInt makeDir = fs.MkDir( pathNamePtr ); + // Itīs ok if directory already exists. If other errors, + // use original html file + if( makeDir != KErrAlreadyExists && makeDir < 0 ) + { + AddHtmlFileAttachmentL( aMessage, aHandle ); + } + else // continue creating new html attachment + { + // create new html attachment + RFile newHtmlFile; + HBufC* newHtmlFileNameBuf = HBufC::NewLC( KPathNameLength ); + TPtr newHtmlFileNamePtr = newHtmlFileNameBuf->Des(); + aHandle.Name( newHtmlFileNamePtr ); + pathNamePtr.Append( newHtmlFileNamePtr ); + CleanupStack::PopAndDestroy( newHtmlFileNameBuf ); + + TInt openResult = newHtmlFile.Replace( fs, pathNamePtr, EFileWrite ); + CleanupClosePushL( newHtmlFile ); + if( openResult >= KErrNone ) + { + TInt writeResult = newHtmlFile.Write( 0, htmlContentPtr ); + if( writeResult >= KErrNone ) + { + AddHtmlFileAttachmentL( aMessage, newHtmlFile ); + } + else // else use original html file + { + AddHtmlFileAttachmentL( aMessage, aHandle ); + } + } + CleanupStack::PopAndDestroy( &newHtmlFile ); + } + CleanupStack::PopAndDestroy( pathNameBuf ); + } + else // charset found, use original html file + { + AddHtmlFileAttachmentL( aMessage, aHandle ); + } + CleanupStack::PopAndDestroy( 2, charsetBuf ); // htmlContentBuf + } + + +// End of File