diff -r 000000000000 -r 8466d47a6819 emailuis/emailui/src/FreestyleEmailUiMailViewerRichText.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailuis/emailui/src/FreestyleEmailUiMailViewerRichText.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,2267 @@ +/* +* Copyright (c) 2007 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: FreestyleEmailUi mail viewer rich text implementation +* Version : %version: 47 % +* +*/ + + +// SYSTEM INCLUDES +#include "emailtrace.h" +#include +#include +#include +#include +#include +// +#include "fstextviewer.h" +#include "fsrichtext.h" +#include "CFSMailMessagePart.h" +#include "CFSMailClient.h" +#include "CFSMailCommon.h" +// +#include +// SF +#include +// +// Platform layout changes +#include +#include +// Platform layout changes + +// for fonts +#include +#include + +// separator line +#include +#include +// separator line + +// INTERNAL INCLUDES +#include "FreestyleEmailUiMailViewerRichText.h" +#include "FreestyleEmailUiAppui.h" +#include "FreestyleEmailUiConstants.h" +#include "FreestyleEmailUiLiterals.h" +#include "FreestyleEmailUiFileSystemInfo.h" +#include "FreestyleEmailUi.hrh" +#include "FreestyleEmailUiTextureManager.h" +#include "FreestyleEmailUiUtilities.h" +#include "FreestyleEmailUiLayoutHandler.h" +#include "FreestyleEmailUiMailViewerConstants.h" +#include "ncsconstants.h" // for KSentLineDateAndTimeSeparatorText + + +// CONST VALUES +static const TInt KHotspotHighlightOn = 1; +// Max hotspot count is a maximum number of hotspots allowed to be placed into +// fs_generic text viewer component. +static const TInt KMaxHotspotCount = 300; + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::NewL +// ----------------------------------------------------------------------------- +CFSEmailUiMailViewerRichText* CFSEmailUiMailViewerRichText::NewL( + CFreestyleEmailUiAppUi& aAppUi ) + { + FUNC_LOG; + CFSEmailUiMailViewerRichText* self = + CFSEmailUiMailViewerRichText::NewLC( aAppUi ); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::NewLC +// ----------------------------------------------------------------------------- +CFSEmailUiMailViewerRichText* CFSEmailUiMailViewerRichText::NewLC( + CFreestyleEmailUiAppUi& aAppUi ) + { + FUNC_LOG; + CFSEmailUiMailViewerRichText* self = + new (ELeave) CFSEmailUiMailViewerRichText( aAppUi ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::ConstructL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::ConstructL() + { + FUNC_LOG; + + CEikonEnv* env = CEikonEnv::Static(); + iViewerRichText = CFsRichText::NewL( env->SystemParaFormatLayerL(), + env->SystemCharFormatLayerL() ); + + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CFSEmailUiMailViewerRichText +// ----------------------------------------------------------------------------- +CFSEmailUiMailViewerRichText::CFSEmailUiMailViewerRichText( + CFreestyleEmailUiAppUi& aAppUi ) + : iAppUi( aAppUi ) + { + FUNC_LOG; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::~CFSEmailUiMailViewerRichText +// ----------------------------------------------------------------------------- +CFSEmailUiMailViewerRichText::~CFSEmailUiMailViewerRichText() + { + FUNC_LOG; + delete iViewerRichText; + + iFontsArray.ResetAndDestroy(); + + iViewerHeadingHotSpotData.Reset(); + iBodyTextHotSpotData.Reset(); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SetHotspotByIndexL +// ----------------------------------------------------------------------------- +// +void CFSEmailUiMailViewerRichText::SetHotspotByIndexL( TInt aIndex ) + { + FUNC_LOG; + /*TInt headingHotspotCount = iViewerHeadingHotSpotData.Count(); + TInt bodyHotspotCount = iBodyTextHotSpotData.Count(); + + if ( iTextViewer ) + { + if ( aIndex < headingHotspotCount ) + { + iTextViewer->FocusLineL( iViewerHeadingHotSpotData[aIndex].iHotspotLine , EFalse ); + iTextViewer->SetCurrentHotspotByOrderL( aIndex ); + } + else if ( (aIndex - headingHotspotCount) < bodyHotspotCount ) + { + iTextViewer->FocusLineL( iViewerHeadingHotSpotData[headingHotspotCount - 1].iHotspotLine , ETrue ); + iTextViewer->SetCurrentHotspotByOrderL( headingHotspotCount - 1 ); + } + }*/ + // Remove the if/elseif contents above and replace them with the commented line below, once it becomes available in fs_generic + iTextViewer->SetCurrentHotspotByOrderL( aIndex, ETrue ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentHotspotIndexL +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::CurrentHotspotIndexL() + { + FUNC_LOG; + /*TInt hotspotIndex(0); + + if ( iTextViewer ) + { + TInt start(0); + TInt end(0); + TInt headingHotspotCount = iViewerHeadingHotSpotData.Count(); + TInt bodyHotspotCount = iBodyTextHotSpotData.Count(); + TBool foundHotspot = EFalse; + + iTextViewer->GetCurrentHotspotL( start, end ); + + if ( headingHotspotCount > 0 ) + { + TInt headingHotspotEnd = iViewerHeadingHotSpotData[ headingHotspotCount-1 ].iEnd; + if ( start < headingHotspotEnd ) + { + for ( TInt i = 0; i < headingHotspotCount; ++i) + { + if ( iViewerHeadingHotSpotData[i].iStart == start ) + { + foundHotspot = ETrue; + hotspotIndex = i; + break; + } + } + } + } + + if ( !foundHotspot ) + { + for ( TInt i = 0; i < bodyHotspotCount; ++i) + { + if ( iBodyTextHotSpotData[i].iStartPos + iHeaderLength == start ) + { + hotspotIndex = i + headingHotspotCount; + break; + } + } + } + } + + return hotspotIndex;*/ + + return iTextViewer->GetCurrentHotspotByOrder(); + } +// + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::EmailStatusIconLine +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::EmailStatusIconLine() + { + FUNC_LOG; + return iEmailStatusIconLine; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::FollowupIconLine +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::FollowupIconLine() + { + FUNC_LOG; + return iFollowupIconLine; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::RefreshRichTextL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::RefreshRichTextL( CFsTextViewer& aTextViewer, + CFSMailMessage& aMessage, + CFSMailBox& aMailBox ) + { + FUNC_LOG; + + Reset(); + + // Save new pointers + iTextViewer = &aTextViewer; + iMessage = &aMessage; + iMailBox = &aMailBox; + + // Reconstruct the whole rich text + // line by line according to information found from current message + AppendFromLineL( *iMessage, iHeaderLineInfo ); + AppendRecipientLinesL( *iMessage, iHeaderLineInfo, EViewerRecipientTypeTo ); + AppendRecipientLinesL( *iMessage, iHeaderLineInfo, EViewerRecipientTypeCc ); + + // show bcc field only if opened from sent folder + TFSMailMsgId currentMessageFolderId = iMessage->GetFolderId(); + CFSMailFolder* currentFolder = NULL; + + TRAP_IGNORE( currentFolder = iAppUi.GetMailClient()->GetFolderByUidL( + iMessage->GetMailBoxId(), currentMessageFolderId ) ); + + CleanupStack::PushL( currentFolder ); + if ( currentFolder && currentFolder->GetFolderType() == EFSSentFolder ) + { + AppendRecipientLinesL( *iMessage, iHeaderLineInfo, EViewerRecipientTypeBcc ); + } + CleanupStack::PopAndDestroy( currentFolder ); + + AppendSentLineL( *iMessage, iHeaderLineInfo ); + + AppendSubjectLinesL( *iMessage, iHeaderLineInfo ); + AppendHtmlTextLineL( *iMessage, iHeaderLineInfo ); + AppendAttachmentLinesL( *iMessage, iHeaderLineInfo ); + + // Append little bit of vertical space before the header area ends. + InsertTransparentSpacingIconL( EBottomMostSpace ); + + // separator line + AppendSeparatorLineL(); + // separator line + + // Add the upmost space also just before the body text. + InsertTransparentSpacingIconL( ETopMostSpace ); + + // Save the total header lenght in characters + iHeaderLength = iViewerRichText->DocumentLength(); + + // Add body text + AppendInitialBodytextLinesL( *iMessage ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::Reset +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::Reset() + { + FUNC_LOG; + + // reset all the data + iTextViewer = NULL; + iMessage = NULL; + iMailBox = NULL; + + iViewerRichText->Reset(); + iViewerHeadingHotSpotData.Reset(); + iBodyTextHotSpotData.Reset(); + iStatusLayout = NULL; + iStatusVisual = NULL; + + iHeaderLength = 0; + iHeaderLineInfo.iHeaderLineCount = 0; + iHeaderLineInfo.iToLineCount = 0; + iHeaderLineInfo.iCcLineCount = 0; + iHeaderLineInfo.iSubjectLineCount = 0; + + iAttachmentHotSpotIndex = KErrNotFound; + iViewHtmlHotSpotIndex = KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::RichText +// ----------------------------------------------------------------------------- +CFsRichText& CFSEmailUiMailViewerRichText::RichText() + { + FUNC_LOG; + return *iViewerRichText; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SentTextLine +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::SentTextLine() const + { + FUNC_LOG; + return iSentTextLine; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SubjectTextLine +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::SubjectTextLine() const + { + FUNC_LOG; + return iSubjectTextLine; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AttachmentTextLine +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::AttachmentTextLine() const + { + FUNC_LOG; + TInt line = KErrNotFound; + if ( iAttachmentHotSpotIndex >= 0 && + iAttachmentHotSpotIndex < iViewerHeadingHotSpotData.Count() ) + { + line = iViewerHeadingHotSpotData[ iAttachmentHotSpotIndex ].iHotspotLine; + } + return line; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::ViewHtmlTextLine +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::ViewHtmlTextLine() const + { + FUNC_LOG; + TInt line = KErrNotFound; + if ( iViewHtmlHotSpotIndex >= 0 && + iViewHtmlHotSpotIndex < iViewerHeadingHotSpotData.Count() ) + { + line = iViewerHeadingHotSpotData[ iViewHtmlHotSpotIndex ].iHotspotLine; + } + return line; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::HeaderLengthInCharacters +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::HeaderLengthInCharacters() const + { + FUNC_LOG; + return iHeaderLength; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::UpdateIconL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::UpdateIconL( TViewerIconType aViewerIconType ) + { + FUNC_LOG; + TInt place = 0; + +// icons changed + + CFbsBitmap* imageImage = NULL; + CFbsBitmap* mask = NULL; + TSize newIconSize = iAppUi.LayoutHandler()->ViewerIconSize(); + TFileName iconFile; + TFsEmailUiUtility::GetFullIconFileNameL( iconFile ); + // Load right icon according to type + // Email status and follow up icons have their fixed places. + // Spacing and indentation icons are always appended to the end of the rich text and + // they are always transparent. + switch ( aViewerIconType ) + { + case EViewerEmailStatus: + { + TFSEmailUiTextures textureId = TFsEmailUiUtility::GetMsgIconTextureId( iMessage ); + iAppUi.FsTextureManager()->ProvideBitmapL( textureId, imageImage, mask ); + place = iEmailStatusIconPlace; + } + break; + case EViewerIconFollowUp: + { + AknsUtils::CreateColorIconL( + AknsUtils::SkinInstance(), + KAknsIIDNone, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG7, + imageImage, + mask, + iconFile, + EMbmFreestyleemailuiQgn_indi_cmail_viewer_follow_up, + EMbmFreestyleemailuiQgn_indi_cmail_viewer_follow_up_mask, + KRgbBlack ); + AknIconUtils::DisableCompression( imageImage ); + AknIconUtils::DisableCompression( mask ); + place = iFollowupIconPlace; + } + break; + case EViewerIconFollowUpComplete: + { + AknsUtils::CreateColorIconL( + AknsUtils::SkinInstance(), + KAknsIIDNone, + KAknsIIDQsnIconColors, + EAknsCIQsnIconColorsCG7, + imageImage, + mask, + iconFile, + EMbmFreestyleemailuiQgn_indi_cmail_viewer_follow_up_complete, + EMbmFreestyleemailuiQgn_indi_cmail_viewer_follow_up_complete_mask, + KRgbBlack ); + AknIconUtils::DisableCompression( imageImage ); + AknIconUtils::DisableCompression( mask ); + place = iFollowupIconPlace; + } + break; + case EViewerIconFollowUpNone: + { + AknIconUtils::CreateIconL( imageImage, mask, iconFile, + EMbmFreestyleemailuiQgn_graf_cmail_blank, + EMbmFreestyleemailuiQgn_graf_cmail_blank_mask ); + AknIconUtils::DisableCompression( imageImage ); + AknIconUtils::DisableCompression( mask ); + place = iFollowupIconPlace; + } + break; + case EViewerAttachment: + { + AknIconUtils::CreateIconL( imageImage, mask, iconFile, + EMbmFreestyleemailuiQgn_indi_cmail_attachment, + EMbmFreestyleemailuiQgn_indi_cmail_attachment_mask ); + AknIconUtils::DisableCompression( imageImage ); + AknIconUtils::DisableCompression( mask ); + place = iAttachmentIconPlace; + // Make the attachment icon a bit smaller than other icons. Shrink only the height: + // when aspect ratio is preserved, the shrinked image will be centered within the standard width icon. + // Platform layout change + //newIconSize.iHeight = newIconSize.iHeight * 3 / 4; + // Platform layout change + } + break; + case EViewerIconIndentation: + { + AknIconUtils::CreateIconL( imageImage, mask, iconFile, + EMbmFreestyleemailuiQgn_graf_cmail_blank, + EMbmFreestyleemailuiQgn_graf_cmail_blank_mask ); + AknIconUtils::DisableCompression( imageImage ); + AknIconUtils::DisableCompression( mask ); + place = iViewerRichText->DocumentLength(); + } + break; + case EViewerIconSpacing: + { + AknIconUtils::CreateIconL( imageImage, mask, iconFile, + EMbmFreestyleemailuiQgn_graf_cmail_blank, + EMbmFreestyleemailuiQgn_graf_cmail_blank_mask ); + AknIconUtils::DisableCompression( imageImage ); + AknIconUtils::DisableCompression( mask ); + place = iViewerRichText->DocumentLength(); + // for spacing icon iCurrentSpacingIconSize need to be calculated beforehand + // and set properly + newIconSize = iCurrentSpacingIconSize; + } + break; + // separator line + case EViewerIconSeparatorLine: + { + TRgb colorToFetch = iAppUi.LayoutHandler()->SeparatorLineColor(); + TSize lineSize = iAppUi.LayoutHandler()->SeparatorGraphicSizeInThisResolution(); + TInt KMyTempHigh = lineSize.iHeight; + // Graphic elments width is too large for these rich text classes + // and thus we have to calculate proper width by ourself. + TInt KMyTempWidth = SeparatorLineWidth(); + + // create a bitmap to be used off-screen + CFbsBitmap* offScreenBitmap = new (ELeave) CFbsBitmap(); + User::LeaveIfError(offScreenBitmap->Create(TSize(KMyTempWidth,KMyTempHigh), + iAppUi.DisplayMode())); + CleanupStack::PushL(offScreenBitmap); + + mask = new (ELeave) CFbsBitmap(); + CleanupStack::PushL(mask); + + // create an off-screen device and context + CGraphicsContext* bitmapContext=NULL; + CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(offScreenBitmap); + CleanupStack::PushL(bitmapDevice); + User::LeaveIfError(bitmapDevice->CreateContext(bitmapContext)); + CleanupStack::PushL(bitmapContext); + + TRect rect(0,0,KMyTempWidth,KMyTempHigh); + bitmapContext->SetBrushColor(colorToFetch); + bitmapContext->SetBrushStyle(CGraphicsContext::ESolidBrush); + bitmapContext->SetPenColor(colorToFetch); + bitmapContext->DrawRect(rect); + + imageImage = offScreenBitmap; + AknIconUtils::DisableCompression( imageImage ); + place = iViewerRichText->DocumentLength(); + newIconSize = TSize( KMyTempWidth,KMyTempHigh); + // cleanup + CleanupStack::PopAndDestroy(2); + CleanupStack::Pop(2); + } + break; + // separator line + default: + { + User::Leave( KErrNotSupported ); + } + break; + } +// + + AknIconUtils::SetSize( imageImage, newIconSize, EAspectRatioPreserved ); + AknIconUtils::SetSize( mask, newIconSize, EAspectRatioPreserved ); + + // Create picture object, which takes ownership of bitmaps + CleanupStack::PushL( imageImage ); + CleanupStack::PushL( mask ); + CMyPicture* picture = new ( ELeave ) CMyPicture( newIconSize, *imageImage, *mask ); + CleanupStack::Pop( mask ); + CleanupStack::Pop( imageImage ); + + CleanupStack::PushL( picture ); + + // remove old picture if there is one. + if ( place < iViewerRichText->DocumentLength() ) + { + iViewerRichText->DeleteL( place, 1 ); + } + + // Insert header object to the right spot + TPictureHeader header; + header.iPicture = TSwizzle( picture ); + CleanupStack::Pop( picture ); // The following call will always take the ownership of the picture pointed in the header. Not only when succesful. + iViewerRichText->InsertL( place, header ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::FindCurrentHeaderHotSpotL +// ----------------------------------------------------------------------------- +TBool CFSEmailUiMailViewerRichText::FindCurrentHeaderHotSpotL( SViewerHeadingHotSpotData& aCurrentHotSpot ) const + { + FUNC_LOG; + TBool foundHotSpot = EFalse; + TInt start(0); + TInt end(0); + if ( iTextViewer ) + { + iTextViewer->GetCurrentHotspotL( start, end ); + TInt headingHotSpotCount = iViewerHeadingHotSpotData.Count(); + if ( headingHotSpotCount > 0 ) + { + TInt headingHotspotEnd = iViewerHeadingHotSpotData[ headingHotSpotCount-1 ].iEnd; + if ( start < headingHotspotEnd ) + { + for ( TInt i = 0 ; i < headingHotSpotCount ; i++ ) + { + if ( iViewerHeadingHotSpotData[ i ].iStart == start ) + { + aCurrentHotSpot = iViewerHeadingHotSpotData[ i ]; + foundHotSpot = ETrue; + break; + } + } + } + } + } + return foundHotSpot; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::FindCurrentBodyHotSpotL +// ----------------------------------------------------------------------------- +TBool CFSEmailUiMailViewerRichText::FindCurrentBodyHotSpotL( CFindItemEngine::SFoundItem& aCurrentHotSpot ) const + { + FUNC_LOG; + TBool foundHotSpot = EFalse; + TInt start(0); + TInt end(0); + if ( iTextViewer ) + { + iTextViewer->GetCurrentHotspotL( start, end ); + for ( TInt a = 0 ; a < iBodyTextHotSpotData.Count() ; a++ ) + { + if ( start == iBodyTextHotSpotData[a].iStartPos + iHeaderLength ) + { + aCurrentHotSpot = iBodyTextHotSpotData[a]; + foundHotSpot = ETrue; + break; + } + } + } + return foundHotSpot; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::FindCurrentHotSpotL +// ----------------------------------------------------------------------------- +THotspotType CFSEmailUiMailViewerRichText::FindCurrentHotSpotL( + SViewerHeadingHotSpotData& aHeaderHotspot, + CFindItemEngine::SFoundItem& aBodyHotspot ) const + { + FUNC_LOG; + THotspotType retVal = ENoHotspot; + if ( FindCurrentHeaderHotSpotL( aHeaderHotspot ) ) + { + retVal = EHeaderHotspot; + } + else if ( FindCurrentBodyHotSpotL( aBodyHotspot ) ) + { + retVal = EBodyHotspot; + } + return retVal; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::GetHotspotTextLC, heading hotspots +// ----------------------------------------------------------------------------- +HBufC* CFSEmailUiMailViewerRichText::GetHotspotTextLC( + const SViewerHeadingHotSpotData& aHotSpot ) const + { + FUNC_LOG; + TInt hotspotTextLength = aHotSpot.iEnd - aHotSpot.iStart; + if ( aHotSpot.iEnd == aHotSpot.iStart ) // check for special case + { + hotspotTextLength = 1; + } + + return GetHotspotTextLC( aHotSpot.iStart, hotspotTextLength ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::GetHotspotTextLC, body text hotspots +// ----------------------------------------------------------------------------- +HBufC* CFSEmailUiMailViewerRichText::GetHotspotTextLC( + const CFindItemEngine::SFoundItem& /*aHotSpot*/ ) const + { + FUNC_LOG; + HBufC* hotspotText = iTextViewer->GetCurrentHotspotTextL(); + CleanupStack::PushL( hotspotText ); + return hotspotText; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::GetEmailAddressLC +// ----------------------------------------------------------------------------- +HBufC* CFSEmailUiMailViewerRichText::GetEmailAddressLC( + const SViewerHeadingHotSpotData& aCurrentHotSpot ) const + { + FUNC_LOG; + HBufC* emailAddress = NULL; + if( aCurrentHotSpot.iType == ETypeFromAddressDisplayName ) + { + CFSMailAddress* mailAddressObject = iMessage->GetSender(); + emailAddress = mailAddressObject->GetEmailAddress().AllocLC(); + } + else if( aCurrentHotSpot.iType == ETypeToAddressDisplayName ) + { + RPointerArray& addressArray = iMessage->GetToRecipients(); + emailAddress = addressArray[aCurrentHotSpot.iDisplayNameArrayIndex]->GetEmailAddress().AllocLC(); + } + else if( aCurrentHotSpot.iType == ETypeCcAddressDisplayName ) + { + RPointerArray& addressArray = iMessage->GetCCRecipients(); + emailAddress = addressArray[aCurrentHotSpot.iDisplayNameArrayIndex]->GetEmailAddress().AllocLC(); + } + else if( aCurrentHotSpot.iType == ETypeBccAddressDisplayName ) + { + RPointerArray& addressArray = iMessage->GetBCCRecipients(); + emailAddress = addressArray[aCurrentHotSpot.iDisplayNameArrayIndex]->GetEmailAddress().AllocLC(); + } + else if( aCurrentHotSpot.iType == ETypeEmailAddress ) + { + emailAddress = GetHotspotTextLC( aCurrentHotSpot ); + } + else + { + User::Leave( KErrNotSupported ); + } + return emailAddress; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::GetHeaderHotspotEmailAddressLC +// ----------------------------------------------------------------------------- +HBufC* CFSEmailUiMailViewerRichText::GetHeaderHotspotEmailAddressLC( + const SViewerHeadingHotSpotData& aCurrentHeaderHotSpotData ) const + { + FUNC_LOG; + return GetEmailAddressLC( aCurrentHeaderHotSpotData ); + } + + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendRecipientIndetationL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendRecipientIndetationL() + { + FUNC_LOG; + // add transparent indentation icon here, to get right indentation in pixels + UpdateIconL( EViewerIconIndentation ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendNewLineL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendNewLineL() + { + FUNC_LOG; + AppendFormattedTextL( KLineFeed, EViewerFontText ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendSpaceL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendSpaceL() + { + FUNC_LOG; + AppendFormattedTextL( KSpace, EViewerFontText ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::ClipHeaderInfoToFitLC +// ----------------------------------------------------------------------------- +// +HBufC* CFSEmailUiMailViewerRichText::ClipHeaderInfoToFitLC( const TDesC& aText, TBool aIsDisplayName ) + { + FUNC_LOG; + // Clip to fit in available amouth of pixels + const CAknLayoutFont* textNameFont = GetCorrectFontL( EViewerFontHotspotNormal ); + // Platform layout change + TInt textWidthInPixels = HeaderIndentedTextAreaWidth( EFalse ); + // Platform layout change + // create new descriptor for the clipped text. + HBufC* textBuffer = aText.AllocLC(); + // Drop out unwanted characters from display name such as <> and "" + if ( aIsDisplayName && textBuffer ) + { + TFsEmailUiUtility::StripDisplayName( *textBuffer ); + textWidthInPixels -= iAppUi.LayoutHandler()->ViewerIconSize().iWidth; + } + TPtr textBufferModDes = textBuffer->Des(); + AknTextUtils::ClipToFit( textBufferModDes, *textNameFont, textWidthInPixels ); + return textBuffer; + } +// + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::HeaderIndentedTextAreaWidth +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::HeaderIndentedTextAreaWidth( const TBool aAddExtra ) const + { + FUNC_LOG; + // For some reason, the ratioanally calculated text width seems to be a bit + // wider than the width where GenericTextViewer does line wrapping. Reserve + // some extra pixels to overcome this. Maybe there is some difference in + // the ways the text width is calculated? + // Platform layout change + //const TInt KExtraPixels = 10; + TInt extraPixels( 10 ); + if ( aAddExtra ) + { + const CAknLayoutFont* newFont = NULL; + TRAP_IGNORE( newFont = GetCorrectFontL( EViewerFontText ) ); + if ( newFont ) + { + TOpenFontMetrics fontMetrics; + newFont->GetFontMetrics( fontMetrics ); + extraPixels = fontMetrics.MaxWidth(); + } + } + // Platform layout change + + TRect screenRect = iTextViewer->GetControl()->DisplayArea(); + + TInt recipientIndenInpixels = iAppUi.LayoutHandler()->ViewerIndentationIconSize().iWidth; + TInt scrollBarBreadth = CEikScrollBar::DefaultScrollBarBreadth(); + + // Calculate space left for actual text + TInt rightMargin = iAppUi.LayoutHandler()->ViewerRightMarginInPixels() + scrollBarBreadth; + TInt leftMargin = iAppUi.LayoutHandler()->ViewerLeftMarginInPixels(); + TInt textWidthInPixels = screenRect.iBr.iX - recipientIndenInpixels - rightMargin - leftMargin - extraPixels; + + return textWidthInPixels; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendFromLineL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendFromLineL( CFSMailMessage& aMessagePtr, + SMailMsgHeaderInfo& aHeaderInfo ) + { + FUNC_LOG; + + // Add the upmost space before the header information + InsertTransparentSpacingIconL( ETopMostSpace ); + + CFSMailAddress* fromAddress = aMessagePtr.GetSender(); + if ( fromAddress ) + { + // Append "from:" text + HBufC* fromHeadingText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_FROM ); + AppendFormattedTextL( *fromHeadingText, EViewerFontTitle ); + CleanupStack::PopAndDestroy( fromHeadingText ); + + // Append new line + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + + AppendRecipientIndetationL(); + + TDesC* displayName = &fromAddress->GetDisplayName(); + TDesC* emailAddrs = &fromAddress->GetEmailAddress(); + if ( displayName && displayName->Length() != 0 ) + { + HBufC* clippedDisplayName = ClipHeaderInfoToFitLC( *displayName, ETrue ); + + // Append display name and hotspot + InsertHotspotTextAndFontL( *clippedDisplayName ); + + // Add hotspot information to rich text and hotspot data to header hotspots array + TInt hotSpotLength = clippedDisplayName->Length(); + iViewerRichText->SetHotSpotL( iRichTextDocumentLength, hotSpotLength, KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + hsData.iType = ETypeFromAddressDisplayName; + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength + hotSpotLength; + hsData.iDisplayNameArrayIndex = 0; + hsData.iHotspotLine = aHeaderInfo.iHeaderLineCount; + iViewerHeadingHotSpotData.Append( hsData ); + + CleanupStack::PopAndDestroy( clippedDisplayName ); + + // Append new line + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + else if ( emailAddrs && emailAddrs->Length() != 0 ) + { + // clip emailAddress to fit in one line. + HBufC* clippedDisplayName = ClipHeaderInfoToFitLC( *displayName, ETrue ); + + // Append email address and hotspot + InsertHotspotTextAndFontL( *clippedDisplayName ); + TInt hotSpotLength = clippedDisplayName->Length(); + iViewerRichText->SetHotSpotL(iRichTextDocumentLength, hotSpotLength, KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + hsData.iType = ETypeEmailAddress; + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength + hotSpotLength; + hsData.iDisplayNameArrayIndex = 0; + hsData.iHotspotLine = aHeaderInfo.iHeaderLineCount; + iViewerHeadingHotSpotData.Append( hsData ); + + CleanupStack::PopAndDestroy( clippedDisplayName ); + + // Append new line + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + } + } + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendRecipientsL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendRecipientsL( + const RPointerArray& aRecipientArray, SMailMsgHeaderInfo& aHeaderInfo, + TViewerRecipientType aRecipientType ) + { + FUNC_LOG; + + TInt showAddresses(0); + TInt recipientCount = aRecipientArray.Count(); + TInt maxRecipientCount = iAppUi.LayoutHandler()->ViewerMaxRecipientLineCount(); + + if ( recipientCount <= maxRecipientCount ) + { + // All recipients fit to screen + showAddresses = recipientCount; + } + else + { + // Reserve space for additional recipients count + showAddresses = maxRecipientCount - 1; + } + + for ( TInt i = 0; i < showAddresses; i++ ) + { + iRichTextDocumentLength = iViewerRichText->DocumentLength(); + TDesC* displayName = &( aRecipientArray[i]->GetDisplayName() ); + TDesC* emailAddrs = &( aRecipientArray[i]->GetEmailAddress() ); + if ( displayName && displayName->Length() != 0 ) + { + AppendRecipientIndetationL(); + + HBufC* clippedDisplayName = ClipHeaderInfoToFitLC( *displayName, ETrue ); + + // Append display name and set hotspot data + InsertHotspotTextAndFontL( *clippedDisplayName ); + + iViewerRichText->SetHotSpotL( iRichTextDocumentLength, clippedDisplayName->Length(), KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + switch ( aRecipientType ) + { + case EViewerRecipientTypeCc: + hsData.iType = ETypeCcAddressDisplayName; + break; + case EViewerRecipientTypeBcc: + hsData.iType = ETypeBccAddressDisplayName; + break; + case EViewerRecipientTypeTo: + default: + hsData.iType = ETypeToAddressDisplayName; + break; + } + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength + clippedDisplayName->Length(); + hsData.iDisplayNameArrayIndex = i; + hsData.iHotspotLine = aHeaderInfo.iHeaderLineCount; + iViewerHeadingHotSpotData.Append( hsData ); + + CleanupStack::PopAndDestroy( clippedDisplayName ); + + // Append new line + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + else if ( emailAddrs && emailAddrs->Length() != 0 ) + { + AppendRecipientIndetationL(); + + // clip emailAddress to fit in one line. + HBufC* clippedDisplayName = ClipHeaderInfoToFitLC( *displayName, ETrue ); + + // Append email address name and set hotspot data + InsertHotspotTextAndFontL( *clippedDisplayName ); + iViewerRichText->SetHotSpotL( iRichTextDocumentLength, clippedDisplayName->Length(), KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + hsData.iType = ETypeEmailAddress; + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength + clippedDisplayName->Length(); + hsData.iHotspotLine = aHeaderInfo.iHeaderLineCount; + iViewerHeadingHotSpotData.Append( hsData ); + + CleanupStack::PopAndDestroy( clippedDisplayName ); + + // Append new line + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + } + if ( recipientCount > showAddresses ) + { + InsertTransparentSpacingIconL( EHeaderInfoSpace ); + + AppendRecipientIndetationL(); + + HBufC* nMoreRecipientsText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_N_MORE_RECIPIENTS, recipientCount ); + // Append n more recipients address name and set hotspot data + InsertHotspotTextAndFontL( *nMoreRecipientsText ); + iViewerRichText->SetHotSpotL(iRichTextDocumentLength, nMoreRecipientsText->Length(), KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + switch ( aRecipientType ) + { + case EViewerRecipientTypeCc: + hsData.iType = ETypeCcNMoreRecipients; + break; + case EViewerRecipientTypeBcc: + hsData.iType = ETypeBccNMoreRecipients; + break; + case EViewerRecipientTypeTo: + default: + hsData.iType = ETypeToNMoreRecipients; + break; + } + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength+nMoreRecipientsText->Length(); + hsData.iHotspotLine = aHeaderInfo.iHeaderLineCount; + iViewerHeadingHotSpotData.Append( hsData ); + // Append new line + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + CleanupStack::PopAndDestroy( nMoreRecipientsText ); + } + } + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendRecipientLinesL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendRecipientLinesL( CFSMailMessage& aMessagePtr, + SMailMsgHeaderInfo& aHeaderInfo, TViewerRecipientType aRecipientType ) + { + FUNC_LOG; + + RPointerArray* mailAddressArray = NULL; + HBufC* headingText = NULL; + switch ( aRecipientType ) + { + case EViewerRecipientTypeTo: + { + mailAddressArray = &aMessagePtr.GetToRecipients(); // ownership is not transfered. + headingText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_TO ); + } + break; + case EViewerRecipientTypeCc: + { + mailAddressArray = &aMessagePtr.GetCCRecipients(); // ownership is not transfered. + headingText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_CC ); + } + break; + case EViewerRecipientTypeBcc: + { + mailAddressArray = &aMessagePtr.GetBCCRecipients(); // ownership is not transfered. + headingText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_BCC ); + } + break; + default: + { + // nothing here. + } + break; + } + + if ( mailAddressArray && mailAddressArray->Count() ) + { + // Add vertical empty space between last recipient and new heading info text + InsertTransparentSpacingIconL( EHeaderInfoSpace ); + + AppendFormattedTextL( *headingText, EViewerFontTitle ); + + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + + // Append the recipients + AppendRecipientsL( *mailAddressArray, aHeaderInfo, aRecipientType ); + } + + // cleanup if heading text was created + if ( headingText ) + { + CleanupStack::PopAndDestroy( headingText ); + } + + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendSentLineL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendSentLineL( CFSMailMessage& aMessagePtr, + SMailMsgHeaderInfo& aHeaderInfo ) + { + FUNC_LOG; + + InsertTransparentSpacingIconL( EHeaderInfoSpace ); + + // Save "Sent ..." text line number for initial focus setting + iSentTextLine = aHeaderInfo.iHeaderLineCount; + + HBufC* dateText = TFsEmailUiUtility::DateTextFromMsgLC( &aMessagePtr ); + HBufC* timeText = TFsEmailUiUtility::TimeTextFromMsgLC( &aMessagePtr ); + HBufC* sentHeadingText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_SENT ); + HBufC* combinedSentText = sentHeadingText->ReAllocL( sentHeadingText->Length() + KSpace().Length() + + dateText->Length() + + KSentLineDateAndTimeSeparatorText().Length() + + timeText->Length() ); + CleanupStack::Pop( sentHeadingText ); + CleanupStack::PushL( combinedSentText ); + TPtr combinedSentTextPtr = combinedSentText->Des(); + combinedSentTextPtr.Append( KSpace ); + combinedSentTextPtr.Append( *dateText ); + combinedSentTextPtr.Append( KSentLineDateAndTimeSeparatorText ); + combinedSentTextPtr.Append( *timeText ); + + AppendFormattedTextL( *combinedSentText, EViewerFontSent ); + + CleanupStack::PopAndDestroy( combinedSentText ); + CleanupStack::PopAndDestroy( timeText ); + CleanupStack::PopAndDestroy( dateText ); + + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendSubjectLinesL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendSubjectLinesL( CFSMailMessage& aMessagePtr, + SMailMsgHeaderInfo& aHeaderInfo ) + { + FUNC_LOG; + InsertTransparentSpacingIconL( EHeaderInfoSpace ); + + // "Subject:" text + HBufC* subjectHeadingText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_SUBJECT ); + AppendFormattedTextL( *subjectHeadingText, EViewerFontTitle ); + CleanupStack::PopAndDestroy( subjectHeadingText ); + + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + + // Save "subject:" text line number for initial focus setting + iSubjectTextLine = aHeaderInfo.iHeaderLineCount; + + TInt subjectLineCount = 0; + + // Get the subject text to modifyable buffer because truncation may be needed. + // Use "no subject" text if not available. + HBufC* subjectBuf = TFsEmailUiUtility::CreateSubjectTextLC( &aMessagePtr ); + TPtr subjectPtr = subjectBuf->Des(); + + // Wrap and clip to maximum number of lines + TInt subjectWidthInPixels = HeaderIndentedTextAreaWidth(); + TInt maxSubjectLines = iAppUi.LayoutHandler()->ViewerMaxSubjectLineCount(); + CArrayFixFlat* wrappedArray = new (ELeave) CArrayFixFlat( maxSubjectLines ); + CleanupStack::PushL( wrappedArray ); + CArrayFixFlat* lineWidthArray = new (ELeave) CArrayFixFlat( maxSubjectLines ); + CleanupStack::PushL( lineWidthArray ); + for ( TInt i = 0 ; i < maxSubjectLines ; ++i ) + { + lineWidthArray->AppendL( subjectWidthInPixels ); + } + // + const CAknLayoutFont* subjectFont = GetCorrectFontL( EViewerFontText ); + + AknTextUtils::WrapToArrayAndClipL( subjectPtr, *lineWidthArray, *subjectFont, *wrappedArray ); + // + subjectLineCount = wrappedArray->Count(); + + TInt i = 1; // indicating current subject line, starting as 1 = first line, 2 = second line + for( ; i <= subjectLineCount ; i++ ) + { + // Rest of the lines have no preceeding icon, just indentation + AppendRecipientIndetationL(); + + TPtrC temp = (*wrappedArray)[i-1]; + AppendFormattedTextL( temp, EViewerFontText ); + + // add line break + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + aHeaderInfo.iSubjectLineCount++; + } + + CleanupStack::PopAndDestroy( lineWidthArray ); + CleanupStack::PopAndDestroy( wrappedArray ); + CleanupStack::PopAndDestroy( subjectBuf ); + } + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendMessageIconL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendMessageIconL() + { + FUNC_LOG; + // append embedded icon. + iEmailStatusIconPlace = iViewerRichText->DocumentLength(); + iEmailStatusIconLine = iHeaderLineInfo.iHeaderLineCount; + UpdateIconL( EViewerEmailStatus ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendFollowUpIconL +// ----------------------------------------------------------------------------- +TBool CFSEmailUiMailViewerRichText::AppendFollowUpIconL( CFSMailMessage& aMessagePtr ) + { + FUNC_LOG; + TBool added = EFalse; + + if ( TFsEmailUiUtility::IsFollowUpSupported( *iMailBox ) ) + { + iFollowupIconPlace = iViewerRichText->DocumentLength(); + iFollowupIconLine = iHeaderLineInfo.iHeaderLineCount; + if ( aMessagePtr.IsFlagSet( EFSMsgFlag_FollowUpComplete ) ) + { + UpdateIconL( EViewerIconFollowUpComplete ); + } + else if ( aMessagePtr.IsFlagSet( EFSMsgFlag_FollowUp ) ) + { + UpdateIconL( EViewerIconFollowUp ); + } + else + { + UpdateIconL( EViewerIconFollowUpNone ); + } + added = ETrue; + } + + return added; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendAttachmentIconL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendAttachmentIconL() + { + FUNC_LOG; + // append embedded icon. + iAttachmentIconPlace = iViewerRichText->DocumentLength(); + UpdateIconL( EViewerAttachment ); + + InsertSpaceAfterIconL(); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendAttachmentLinesL +// Append attachement(s) line to the rich text. +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendAttachmentLinesL( CFSMailMessage& aMessagePtr, SMailMsgHeaderInfo& aHeaderInfo ) + { + FUNC_LOG; + if ( aMessagePtr.IsFlagSet( EFSMsgFlag_Attachments ) ) + { + // get attachments and count + RPointerArray attachments; + CleanupResetAndDestroyClosePushL( attachments ); + aMessagePtr.AttachmentListL( attachments ); + TInt attachmentsCount = attachments.Count(); + HBufC* attachmentText = NULL; + if ( attachmentsCount == 1 ) + { + TDesC& attachmentName = attachments[0]->AttachmentNameL(); + TUint attachmentSize = attachments[0]->ContentSize(); // bytes + + // create size text including the unit and preceeding space character + HBufC* sizeWithUnit = TFsEmailUiUtility::CreateSizeDescLC( attachmentSize ); + HBufC* sizeText = HBufC::NewL( sizeWithUnit->Length()+1 ); + sizeText->Des().Append( ' ' ); + sizeText->Des().Append( *sizeWithUnit ); + CleanupStack::PopAndDestroy( sizeWithUnit ); + CleanupStack::PushL( sizeText ); + + // clip attachment name to fit in one line so that size information has enough space too. + // + const CAknLayoutFont* attachmentFont = GetCorrectFontL( EViewerFontHotspotNormal ); + + TInt attachmentTextWidthInPixels = HeaderIndentedTextAreaWidth(); + TInt sizeTextInPixels = attachmentFont->TextWidthInPixels( *sizeText ); + TInt pixelsLeftForAttachmentName = attachmentTextWidthInPixels - sizeTextInPixels; + + // safe check if the size information is too wide for some reason. + if ( pixelsLeftForAttachmentName < 0 ) + { + attachmentText = HBufC::NewL( attachmentName.Length() + sizeText->Length() ); + attachmentText->Des().Append( attachmentName ); + attachmentText->Des().Append( *sizeText ); + TPtr attachmentTextBufferModDes = attachmentText->Des(); + AknTextUtils::ClipToFit( attachmentTextBufferModDes, *attachmentFont, attachmentTextWidthInPixels ); + } + else + { // normal case + HBufC* attacmentNameBuffer = attachmentName.AllocLC(); + TPtr attachmentNameBufferModDes = attacmentNameBuffer->Des(); + AknTextUtils::ClipToFit( attachmentNameBufferModDes, *attachmentFont, pixelsLeftForAttachmentName ); + + attachmentText = HBufC::NewL( attacmentNameBuffer->Length() + sizeText->Length() ); + attachmentText->Des().Append( *attacmentNameBuffer ); + attachmentText->Des().Append( *sizeText ); + CleanupStack::PopAndDestroy( attacmentNameBuffer ); + } + CleanupStack::PopAndDestroy( sizeText ); + } + // + else if ( attachmentsCount > 1 ) + { + TInt totalSize = 0; + for( TInt i = 0; i < attachmentsCount ; i++ ) + { + totalSize += attachments[i]->ContentSize(); + } + HBufC* sizeText = TFsEmailUiUtility::CreateSizeDescLC( totalSize ); + attachmentText = StringLoader::LoadL( R_FSE_VIEWER_ATTACHMENTS_TEXT_WITH_SIZE, + *sizeText, attachmentsCount ); + CleanupStack::PopAndDestroy( sizeText ); + } + + // Append attachment line to rich text if there was attachments + if ( attachmentText ) + { + CleanupStack::PushL( attachmentText ); + + InsertTransparentSpacingIconL( EHeaderInfoSpace ); + + AppendAttachmentIconL(); + + InsertHotspotTextAndFontL( *attachmentText ); + iViewerRichText->SetHotSpotL( iRichTextDocumentLength, attachmentText->Length(), KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + if ( attachmentsCount == 1 ) + { + hsData.iType = ETypeAttachment; + } + else + { + hsData.iType = ETypeAttachments; + } + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength + attachmentText->Length(); + hsData.iHotspotLine = aHeaderInfo.iHeaderLineCount; + iAttachmentHotSpotIndex = iViewerHeadingHotSpotData.Count(); + iViewerHeadingHotSpotData.Append( hsData ); + CleanupStack::PopAndDestroy( attachmentText ); + + // Append new lines + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + CleanupStack::PopAndDestroy( &attachments ); + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendHtmlTextLineL +// Appends "View as HTML" selection hotspot to the rich text if message has HTML text part +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendHtmlTextLineL( CFSMailMessage& aMessagePtr, SMailMsgHeaderInfo& aHeaderInfo ) + { + FUNC_LOG; + + CFSMailMessagePart* htmlBodyPart = aMessagePtr.HtmlBodyPartL(); + if ( htmlBodyPart ) + { + CleanupStack::PushL( htmlBodyPart ); + + // Add just a little bit of vertical space before the next lines + InsertTransparentSpacingIconL( EHeaderInfoSpace ); + + // Indent the "View as HTML" link + AppendRecipientIndetationL(); + + HBufC* htmlLineText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_HTML ); + HBufC* clippedHtmlLine = ClipHeaderInfoToFitLC( *htmlLineText, EFalse ); + + InsertHotspotTextAndFontL( *clippedHtmlLine ); + iViewerRichText->SetHotSpotL( iRichTextDocumentLength, clippedHtmlLine->Length(), KHotspotHighlightOn ); + SViewerHeadingHotSpotData hsData; + hsData.iType = ETypeHtml; + hsData.iStart = iRichTextDocumentLength; + hsData.iEnd = iRichTextDocumentLength + htmlLineText->Length(); + hsData.iHotspotLine = iHeaderLineInfo.iHeaderLineCount; + iViewHtmlHotSpotIndex = iViewerHeadingHotSpotData.Count(); + iViewerHeadingHotSpotData.Append( hsData ); + + CleanupStack::PopAndDestroy( clippedHtmlLine ); + CleanupStack::PopAndDestroy( htmlLineText ); + CleanupStack::PopAndDestroy( htmlBodyPart ); + + // Append one line feed plus little extra vertical space + AppendNewLineL(); + aHeaderInfo.iHeaderLineCount++; + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendInitialBodytextLinesL +// Append body text which is found from the message to the end of the rich text. +// If plain text body part is not found, tries to convert body from html part +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendInitialBodytextLinesL( CFSMailMessage& aMessagePtr ) + { + FUNC_LOG; + CFSMailMessagePart* plainTextBodyPart = aMessagePtr.PlainTextBodyPartL(); + + if ( plainTextBodyPart ) + { + CleanupStack::PushL( plainTextBodyPart ); + + TInt fetchedSize = plainTextBodyPart->FetchedContentSize(); + if ( fetchedSize > 0 ) + { + // Limit displayed plain text body size to KPlainTextLimitationInBytes + // currently set to 150K characters of text that should be more than enough for mobile email + TInt bufSize = Min( fetchedSize, KPlainTextLimitationInChars ); + HBufC* plainTextData16 = HBufC::NewLC( bufSize ); + + TPtr pointer = plainTextData16->Des(); + plainTextBodyPart->GetContentToBufferL( pointer, 0 ); + + // Store body length + iBodyLength = plainTextData16->Length(); + + // append everything we have now + AppendFormattedTextL( *plainTextData16, EViewerFontText ); + + // Append hotspot data for content + iBodyTextHotSpotData.Reset(); + FindBodyTextHotSpotsL( *plainTextData16 ); + CleanupStack::PopAndDestroy( plainTextData16 ); + // Make sure that text viewer is not filled with more than max + // number of hotspot count + TInt hotspotCount = iBodyTextHotSpotData.Count(); + if ( hotspotCount > KMaxHotspotCount ) + { + hotspotCount = KMaxHotspotCount; + } + for ( TInt i=0; i < hotspotCount; i++ ) + { + AddBodyHotsSpotWithTextFormatingL( iBodyTextHotSpotData[i] ); + } + } + CleanupStack::PopAndDestroy( plainTextBodyPart ); + } + else + { + CFSMailMessagePart* htmlBodyPart = aMessagePtr.HtmlBodyPartL(); + if ( htmlBodyPart ) + { + CleanupStack::PushL( htmlBodyPart ); + + TInt fetchedBodySize = htmlBodyPart->FetchedContentSize(); + TInt wholeContentSize = htmlBodyPart->ContentSize(); + if ( fetchedBodySize == wholeContentSize ) + { + HBufC* htmlData = HBufC::NewLC( fetchedBodySize ); + TPtr pointer = htmlData->Des(); + htmlBodyPart->GetContentToBufferL( pointer, 0 ); + HBufC* txtData = TFsEmailUiUtility::ConvertHtmlToTxtL( *htmlData ); + CleanupStack::PopAndDestroy( htmlData ); + CleanupStack::PushL( txtData ); + + // User large fixed maximum amount of characters to append. + // In normal cases all text is included. + TPtrC truncatedText = txtData->Left( KPlainTextLimitationInChars ); + iBodyLength = truncatedText.Length(); + AppendFormattedTextL( truncatedText, EViewerFontText ); + // Append hotspot data for content + iBodyTextHotSpotData.Reset(); + FindBodyTextHotSpotsL( truncatedText ); + CleanupStack::PopAndDestroy( txtData ); + // Make sure that text viewer is not filled with more than max + // number of hotspot count + TInt hotspotCount = iBodyTextHotSpotData.Count(); + if ( hotspotCount > KMaxHotspotCount ) + { + hotspotCount = KMaxHotspotCount; + } + for ( TInt i=0; i < hotspotCount; i++ ) + { + AddBodyHotsSpotWithTextFormatingL( iBodyTextHotSpotData[i] ); + } + } + + CleanupStack::PopAndDestroy( htmlBodyPart ); + } + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendFetchedBodytextLinesL +// Append rest of the body text replacing "Fetching more text" +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendFetchedBodytextLinesL( CFSMailMessage& aMessagePtr ) + { + FUNC_LOG; + TInt startBodyPoint = iBodyLength; + CFSMailMessagePart* plainTextBodyPart = aMessagePtr.PlainTextBodyPartL(); + if ( plainTextBodyPart ) + { + CleanupStack::PushL( plainTextBodyPart ); + // Fetching More text is not required any more + SetEmptyStatusLayoutTextL(); + + // Limit the whole data reading to KPlainTextLimitationInChars, usually this is more than + // enough for mobile email client + TInt fetchedSize = plainTextBodyPart->FetchedContentSize(); + TInt bufSize = Min( fetchedSize, KPlainTextLimitationInChars ); + HBufC* plainTextData16 = HBufC::NewLC( bufSize ); + + // Get more fetched content to buffer + TPtr pointer = plainTextData16->Des(); + plainTextBodyPart->GetContentToBufferL( pointer, 0 ); + + // Store body length + iBodyLength = plainTextData16->Length(); + + // Safety check required by POP protocol. Sometimes iBodyLength changes + // when message has been fetched. Following is added to prevent crashes related to that. + if ( startBodyPoint > iBodyLength ) + { + startBodyPoint = iBodyLength; + } + + // Insert rest of the body text after previously added body text + TPtrC restOfThePlainText = plainTextData16->Mid( startBodyPoint ); + InsertFormattedTextL( restOfThePlainText, EViewerFontText, + iHeaderLength + startBodyPoint ); + + // Find hotspots from the added body text + TInt previousBodyHotspotCount = iBodyTextHotSpotData.Count(); + FindBodyTextHotSpotsL( restOfThePlainText ); + // Make sure that text viewer is not filled with more than max + // number of hotspot count + TInt hotspotCount = iBodyTextHotSpotData.Count(); + if ( hotspotCount > KMaxHotspotCount ) + { + hotspotCount = KMaxHotspotCount; + } + for ( TInt i = previousBodyHotspotCount; i < hotspotCount; i++ ) + { + iBodyTextHotSpotData[i].iStartPos += startBodyPoint; + AddBodyHotsSpotWithTextFormatingL( iBodyTextHotSpotData[i] ); + } + + iTextViewer->ReloadTextL(); + CleanupStack::PopAndDestroy( plainTextData16 ); + CleanupStack::PopAndDestroy( plainTextBodyPart ); + } + + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CreateStatusLayoutL +// Creates status layout to display fetching more text. +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::CreateStatusLayoutL( TBool aSetEmptyContents /*= ETrue*/ ) + { + FUNC_LOG; + // ensure not created twice + if ( !iStatusVisual && iTextViewer ) + { + iStatusLayout = static_cast( iTextViewer->GetStatusLayout() ); + CAlfControl* textViewerControl = iTextViewer->GetControl(); + iStatusVisual = CAlfTextVisual::AddNewL( *textViewerControl, iStatusLayout ); + iStatusVisual->EnableShadow( EFalse ); + iStatusVisual->SetColor( iAppUi.LayoutHandler()->ViewerBodyTextColor() ); + + TAlfTimedValue statusVisualOpacity; + statusVisualOpacity.SetValueNow ( 1 ); + iStatusVisual->SetOpacity( statusVisualOpacity ); + + // Platform layout change + /*iStatusVisual->SetTextStyle( iAppUi.LayoutHandler()->FSTextStyleFromIdL( EFSFontTypeSmallBold )->Id() );*/ + iStatusVisual->SetTextStyle( iAppUi.LayoutHandler()->FSTextStyleFromLayoutL( AknLayoutScalable_Apps::list_single_cmail_header_caption_pane_t1() ).Id() ); + // Platform layout change + iStatusVisual->SetAlign( EAlfAlignHCenter, EAlfAlignVTop ); + + if ( aSetEmptyContents ) + { + SetEmptyStatusLayoutTextL(); + } + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendFetchingMoreTextL +// metdod for updating the animated text while rest of the message is been fetched +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendFetchingMoreTextL() + { + FUNC_LOG; + // Create status layout if it doesn't exist yet + CreateStatusLayoutL( EFalse ); + + // add fetching content text with current animation + HBufC* fetchingContentText = StringLoader::LoadLC( R_FREESTYLE_EMAIL_UI_VIEWER_FETCHING_CONTENT_TEXT ); + + // create buffer for "Fetching more text" and dots animation + HBufC* newDes = HBufC::NewLC( fetchingContentText->Length() + KTotalNumberOfLines + KTotalNumberOfLines); + TPtr des = newDes->Des(); + + // add KTotalNumberOfLines always at the beginning + for( TInt i = 0 ; i < KTotalNumberOfLines / KNumberOfLines ; i++ ) + { + des.Append( KThreeLines ); + } + + // append fething text + des.Append( *fetchingContentText ); + + // add dots according to current ellipsis count + for( TInt i = 0 ; i < iCurrentEllipsisCount ; i++ ) + { + des.Append( KThreeLines ); + } + + // ellipses count counter going through 0,1,2,3,0,1,2,3,0,... sequence + if( iCurrentEllipsisCount >= KTotalNumberOfLines / KNumberOfLines ) + { + iCurrentEllipsisCount = 0; + } + else + { + iCurrentEllipsisCount++; + } + + // just in case, try clipping the text if it doesn't fit in one line for some reason. + TRect screenRect = iTextViewer->GetControl()->DisplayArea(); + // + const CAknLayoutFont* bodyTextFont = GetCorrectFontL( EViewerFontBody ); + TInt rightMargin = iAppUi.LayoutHandler()->ViewerRightMarginInPixels(); + TInt leftMargin = iAppUi.LayoutHandler()->ViewerLeftMarginInPixels(); + TInt pixelsToFit = screenRect.iBr.iX - rightMargin - leftMargin; + AknTextUtils::ClipToFit( des, *bodyTextFont, pixelsToFit ); + // + + // Assign the text to status layout. + iStatusVisual->SetTextL( *newDes ); + iStatusLayout->SetClipping( EFalse ); + TSize statusSize = iStatusVisual->TextExtents(); + iStatusLayout->SetSize( statusSize ); + iStatusVisual->SetRect( TRect( TPoint( 0, 0 ), statusSize ) ); + iTextViewer->UpdateStatusLayout(); + + CleanupStack::PopAndDestroy( newDes ); + CleanupStack::PopAndDestroy( fetchingContentText ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SetEmptyStatusLayoutTextL +// The text in status layout is updated to contain only a couple of line feeds. +// This ensures, that the whole body can be scrolled visible also when the +// attachment downloading popup is shown in the bottom. +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::SetEmptyStatusLayoutTextL() + { + FUNC_LOG; + _LIT( KEmptyStatusText, "\n " ); + if ( iStatusVisual && iStatusLayout && iTextViewer ) + { + iStatusVisual->SetTextL( KEmptyStatusText ); + iStatusLayout->SetClipping( EFalse ); + TSize statusSize = iStatusVisual->TextExtents(); + iStatusLayout->SetSize( statusSize ); + iStatusVisual->SetRect( TRect( TPoint( 0, 0 ), statusSize ) ); + iTextViewer->UpdateStatusLayout(); + } + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SetHotspotHighlightedColorL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::SetHotspotHighlightedColorL( TInt aStartIndx, TInt aLenght, TBool aHighlight ) + { + FUNC_LOG; + TCharFormat charFormat; + TCharFormatMask charFormatMask; + if ( aHighlight ) + { + charFormat.iFontPresentation.iTextColor = SkinFontColorByType( EViewerFontHotspotHighLighted ); + } + else + { + charFormat.iFontPresentation.iTextColor = SkinFontColorByType( EViewerFontHotspotNormal ); + } + + charFormatMask.SetAttrib( EAttColor ); + iViewerRichText->ApplyCharFormatL( charFormat, charFormatMask, aStartIndx, aLenght ); + iTextViewer->ReloadTextL(); + } + +// --------------------------------------------------------------------------- +// Getter for the index of the attachment hotspot +// --------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::AttachmentHotSpotIndex() const + { + FUNC_LOG; + return iAttachmentHotSpotIndex; + } + +// --------------------------------------------------------------------------- +// Getter for the index of the View HTML hotspot +// --------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::ViewHtmlHotSpotIndex() const + { + FUNC_LOG; + return iViewHtmlHotSpotIndex; + } + +// --------------------------------------------------------------------------- +// Helper function for getting hotspot text from rich text data +// --------------------------------------------------------------------------- +HBufC* CFSEmailUiMailViewerRichText::GetHotspotTextLC( TInt aStartPos, + TInt aLength ) const + { + FUNC_LOG; + __ASSERT_DEBUG( aStartPos >= 0, User::Invariant() ); + __ASSERT_DEBUG( aLength > 0, User::Invariant() ); + + HBufC* des = HBufC::NewLC( aLength ); + + // Hotspot text is retrived in a loop, because the CPlainText::Read + // method may return only part of the requested text + TInt documentLength = iViewerRichText->DocumentLength(); + while ( aLength > 0 && aStartPos < documentLength ) + { + TPtrC text = iViewerRichText->Read( aStartPos, aLength ); + des->Des().Append( text ); + aLength -= text.Length(); + aStartPos += text.Length(); + } + + return des; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::FindBodyTextHotSpotsL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::FindBodyTextHotSpotsL( const TDesC& aBodyContent ) + { + FUNC_LOG; + // Use s60 find item engine to find hotspots from the body text + CFindItemEngine* hotspotSearch = CFindItemEngine::NewL + ( + aBodyContent, + // define wanted + (CFindItemEngine::TFindItemSearchCase) + (CFindItemEngine::EFindItemSearchMailAddressBin | + CFindItemEngine::EFindItemSearchPhoneNumberBin | + CFindItemEngine::EFindItemSearchURLBin | + CFindItemEngine::EFindItemSearchScheme ) + ); + CleanupStack::PushL( hotspotSearch ); + + // + // insert found data to member variable iHotSpotData + const CArrayFixFlat* itemArray = hotspotSearch->ItemArray(); + TInt itemCount = hotspotSearch->ItemCount(); + for ( TInt i = 0; i < itemCount; i++ ) + { + CFindItemEngine::SFoundItem* foundItem = const_cast ( &itemArray->At( i ) ); + TBool foundSameHotspotTwice = EFalse; + // Check if same hotspot is found twice. This may happen when both flags + // EFindItemSearchScheme and EFindItemSearchURLBin are ON for search request. + for ( TInt j = i + 1; j < itemCount; j++ ) + { + if ( foundItem->iStartPos == itemArray->At( j ).iStartPos ) + { + foundSameHotspotTwice = ETrue; + break; + } + } + if ( !foundSameHotspotTwice ) + { + // At this phase hotspot is one character too early + // Change it to right place. If FindItemEngine implementation + // will change then following line must be removed. + //foundItem->iStartPos++; + iBodyTextHotSpotData.AppendL( itemArray->At( i ) ); + } + } + // + + CleanupStack::PopAndDestroy( hotspotSearch ); + } + + +// +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::GetCorrectFontL +// ----------------------------------------------------------------------------- +const CAknLayoutFont* CFSEmailUiMailViewerRichText::GetCorrectFontL( TViewerFontType aFontType ) const + { + FUNC_LOG; + /* + EViewerFontTitle = 0, + EViewerFontText, + EViewerFontBody, + EViewerFontHotspotNormal, + EViewerFontHotspotHighLighted, + EViewerFontSent, + EViewerFontIndentation + */ + const CAknLayoutFont* font = NULL; + + switch ( aFontType ) + { + case EViewerFontTitle: + case EViewerFontSent: + { + font = CurrentTitleFontL(); + } + break; + case EViewerFontText: + case EViewerFontBody: + case EViewerFontHotspotNormal: + case EViewerFontHotspotHighLighted: + case EViewerFontIndentation: + default: + { + font = CurrentTextFontL(); + } + break; + } + + if (NULL == font) + User::Leave(KErrGeneral); + + return font; + + } + +/* +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::ReConstructFontArrayL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::ReConstructFontArrayL() + { + FUNC_LOG; + iFontsArray.ResetAndDestroy(); + + // append title font + CAknLayoutFont* titleFont = CurrentTitleFontLC(); + iFontsArray.AppendL( titleFont ); + CleanupStack::Pop( titleFont ); + + // append text font + CAknLayoutFont* textFont = CurrentTextFontLC(); + iFontsArray.AppendL( textFont ); + CleanupStack::Pop( textFont ); + + // append body font + CAknLayoutFont* bodyFont = CurrentTextFontLC(); + iFontsArray.AppendL( bodyFont ); + CleanupStack::Pop( bodyFont ); + + // append not highlighted hotspot font + CAknLayoutFont* normalHotspotFont = CurrentTextFontLC(); + iFontsArray.AppendL( normalHotspotFont ); + CleanupStack::Pop( normalHotspotFont ); + + // append highlighted hotspot font + CAknLayoutFont* highLightedHotspotFont = CurrentTextFontLC(); + iFontsArray.AppendL( highLightedHotspotFont ); + CleanupStack::Pop( highLightedHotspotFont ); + + // append sent line font + CAknLayoutFont* sentLineFont = CurrentSentTextFontLC(); + iFontsArray.AppendL( sentLineFont ); + CleanupStack::Pop( sentLineFont ); + + // append indentation font + CAknLayoutFont* indentationFont = CurrentTextFontLC(); + iFontsArray.AppendL( indentationFont ); + CleanupStack::Pop( indentationFont ); + } +*/ + +/* +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::FontFromFontArray +// ----------------------------------------------------------------------------- +CAknLayoutFont& CFSEmailUiMailViewerRichText::FontFromFontArray( TViewerFontType aFontType ) const + { + FUNC_LOG; + return *iFontsArray[aFontType]; + } +*/ +// + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SkinFontColorByType +// ----------------------------------------------------------------------------- +TRgb CFSEmailUiMailViewerRichText::SkinFontColorByType( TViewerFontType aFontType ) + { + FUNC_LOG; + TRgb returnedColor; + switch ( aFontType ) + { + case EViewerFontTitle: + { + returnedColor = iAppUi.LayoutHandler()->ViewerTitleTextColor(); + } + break; + case EViewerFontBody: + { + returnedColor = iAppUi.LayoutHandler()->ViewerBodyTextColor(); + } + break; + case EViewerFontHotspotNormal: + { + returnedColor = iAppUi.LayoutHandler()->ViewerNormalHotspotTextColor(); + } + break; + case EViewerFontHotspotHighLighted: + { + returnedColor = iAppUi.LayoutHandler()->ViewerHighlightedHotspotTextColor(); + } + break; + case EViewerFontSent: + { + // + //returnedColor = iAppUi.LayoutHandler()->ViewerTitleFontHeight(); + returnedColor = iAppUi.LayoutHandler()->ViewerTitleTextColor(); + // + } + break; + case EViewerFontText: + default: + { + returnedColor = iAppUi.LayoutHandler()->ViewerTextTextColor(); + } + break; + } + return returnedColor; + } + +// LAYOUT CHANGES + +/* +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentTitleFontLC +// ----------------------------------------------------------------------------- +CAknLayoutFont* CFSEmailUiMailViewerRichText::CurrentTitleFontLC() + { + FUNC_LOG; + TAknLogicalFontId logicalFontId = iAppUi.LayoutHandler()->ViewerTitleFontAknLogicalFontId(); + TAknFontSpecification spec( logicalFontId ); + TInt heightInPixels = iAppUi.LayoutHandler()->ViewerTitleFontHeight(); + spec.SetTextPaneHeight( heightInPixels ); + CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice(); + CAknLayoutFont* font = AknFontAccess::CreateLayoutFontFromSpecificationL( *dev, spec ); + CleanupStack::PushL( font ); + return font; + } +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentTextFontLC +// ----------------------------------------------------------------------------- +CAknLayoutFont* CFSEmailUiMailViewerRichText::CurrentTextFontLC() + { + FUNC_LOG; + TAknLogicalFontId logicalFontId = iAppUi.LayoutHandler()->ViewerTextFontAknLogicalFontId(); + TAknFontSpecification spec( logicalFontId ); + TInt heightInPixels = iAppUi.LayoutHandler()->ViewerTextFontHeight(); + spec.SetTextPaneHeight( heightInPixels ); + CWsScreenDevice* dev = CCoeEnv::Static()->ScreenDevice(); + CAknLayoutFont* font = AknFontAccess::CreateLayoutFontFromSpecificationL( *dev, spec ); + CleanupStack::PushL( font ); + return font; + } +*/ + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentTitleFontL +// ----------------------------------------------------------------------------- +const CAknLayoutFont* CFSEmailUiMailViewerRichText::CurrentTitleFontL() const + { + FUNC_LOG; + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect); + + TAknLayoutRect cmailPaneRect; + cmailPaneRect.LayoutRect(mainPaneRect, AknLayoutScalable_Apps::list_cmail_pane()); + + TAknLayoutRect labelRect; + labelRect.LayoutRect(cmailPaneRect.Rect(), AknLayoutScalable_Apps::list_single_cmail_header_caption_pane()); + + TAknLayoutText layoutText; + layoutText.LayoutText(labelRect.Rect(), AknLayoutScalable_Apps::list_single_cmail_header_caption_pane_t1()); + + const CAknLayoutFont* font = CAknLayoutFont::AsCAknLayoutFontOrNull( layoutText.Font() ); + + //All fonts must be loaded properly? Leave if something is failing. + if(NULL == font) + User::Leave(KErrGeneral); + + return font; + + } + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentTextFontL +// ----------------------------------------------------------------------------- +const CAknLayoutFont* CFSEmailUiMailViewerRichText::CurrentTextFontL() const + { + FUNC_LOG; + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect); + + TAknLayoutRect cmailPaneRect; + cmailPaneRect.LayoutRect(mainPaneRect, AknLayoutScalable_Apps::list_cmail_pane()); + + //Using variety 0 -> 1 row line by default + TAknLayoutRect labelRect; + labelRect.LayoutRect(cmailPaneRect.Rect(), AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0 )); + + TAknLayoutText layoutText; + layoutText.LayoutText(labelRect.Rect(), AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1( 0 )); + + const CAknLayoutFont* font = CAknLayoutFont::AsCAknLayoutFontOrNull( layoutText.Font() ); + + //All fonts must be loaded properly? Leave if something is failing. + if(NULL == font) + User::Leave(KErrGeneral); + + return font; + + } + + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentSentTextFontLC +// ----------------------------------------------------------------------------- +const CAknLayoutFont* CFSEmailUiMailViewerRichText::CurrentSentTextFontL() const + { + return CurrentTitleFontL(); + } +// + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::CurrentSpacingHeight +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::CurrentSpacingHeight( TViewerSpacingIconType aSpacingIconType ) const + { + FUNC_LOG; + TInt heightInPixels = 0; + switch( aSpacingIconType ) + { + case ETopMostSpace: + { + heightInPixels = iAppUi.LayoutHandler()->ViewerTopMostSpaceHeight(); + } + break; + case ERecipientSpace: + { + heightInPixels = iAppUi.LayoutHandler()->ViewerRecipientSpaceHeight(); + } + break; + case EHeaderInfoSpace: + { + heightInPixels = iAppUi.LayoutHandler()->ViewerHeaderInfoSpaceHeight(); + } + break; + case EBottomMostSpace: + { + heightInPixels = iAppUi.LayoutHandler()->ViewerBottomMostSpaceHeight(); + } + break; + } + return heightInPixels; + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::InsertTransparentSpacingIconL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::InsertTransparentSpacingIconL( TViewerSpacingIconType aSpacingIconType ) + { + FUNC_LOG; + TInt currentSpace = CurrentSpacingHeight( aSpacingIconType ); + TInt fontSide = 0; + switch ( aSpacingIconType ) + { + case ETopMostSpace: + case EBottomMostSpace: + { + TInt currentTextHeight = iAppUi.LayoutHandler()->ViewerTitleFontHeight(); + fontSide = currentSpace - currentTextHeight; + } + break; + case ERecipientSpace: + { + TInt currentTextHeight = iAppUi.LayoutHandler()->ViewerTextFontHeight(); + fontSide = currentSpace - currentTextHeight; + } + break; + case EHeaderInfoSpace: + { + TInt currentTextHeight = iAppUi.LayoutHandler()->ViewerTitleFontHeight(); + fontSide = currentSpace - currentTextHeight; + } + break; + } + iCurrentSpacingIconSize.SetSize( fontSide, fontSide ); + + UpdateIconL( EViewerIconSpacing ); + + // Add extra space before line ending so that we can modify the line height + AppendSpaceL(); + + AppendNewLineL(); + iHeaderLineInfo.iHeaderLineCount++; + + // to make the icon need less space. + TCharFormat charFormat; + TCharFormatMask charFormatMask; + charFormat.iFontSpec.iHeight = CEikonEnv::Static()->ScreenDevice()->VerticalPixelsToTwips( fontSide ); + charFormat.iFontPresentation.iUnderline = EUnderlineOff; + charFormatMask.SetAttrib( EAttFontHeight ); + charFormatMask.SetAttrib( EAttFontUnderline ); + iViewerRichText->ApplyCharFormatL( charFormat, charFormatMask, iViewerRichText->DocumentLength() - 3, 3 ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::InsertSpaceAfterIconL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::InsertSpaceAfterIconL() + { + FUNC_LOG; + TInt spaceInPixels = iAppUi.LayoutHandler()->ViewerPixelsBetweenMsgStatusIconAndSubject(); + iCurrentSpacingIconSize.SetSize( spaceInPixels, spaceInPixels ); + UpdateIconL( EViewerIconSpacing ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::InsertHotspotTextAndFontL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::InsertHotspotTextAndFontL( const TDesC& aText ) + { + FUNC_LOG; + AppendFormattedTextL( aText, EViewerFontHotspotNormal ); + } + +// ----------------------------------------------------------------------------- +// Appends formatted text to the rich text +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendFormattedTextL( const TDesC& aText, + TViewerFontType aFontType ) + { + FUNC_LOG; + iRichTextDocumentLength = iViewerRichText->DocumentLength(); + InsertFormattedTextL( aText, aFontType, iRichTextDocumentLength ); + } + +// ----------------------------------------------------------------------------- +// Inserts formatted text to the rich text +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::InsertFormattedTextL( const TDesC& aText, + TViewerFontType aFontType, TInt aPosition ) + { + FUNC_LOG; + ASSERT( aPosition >= 0 ); + ASSERT( aPosition <= iViewerRichText->DocumentLength() ); + + // Insert text at given position + iViewerRichText->InsertL( aPosition, aText ); + + // + const CAknLayoutFont* newFont = GetCorrectFontL( aFontType ); + + TRgb fontColor = SkinFontColorByType( aFontType ); + TFontUnderline underline = EUnderlineOff; + if ( aFontType == EViewerFontHotspotNormal ) + { + underline = EUnderlineOn; + } + + ApplyFontToTextL( newFont, aPosition, aText.Length(), fontColor, underline ); + // + } + +// + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::ApplyFontToTextL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::ApplyFontToTextL( const CAknLayoutFont* aFont, + TInt aStartInx, + TInt aLength, + TRgb& aColor, + TFontUnderline aUnderline ) + { + FUNC_LOG; + TCharFormat charFormat; + TCharFormatMask charFormatMask; + charFormat.iFontSpec = aFont->FontSpecInTwips(); + // Applies antialiasing for all text in mail viewer. + charFormat.iFontSpec.iFontStyle.SetBitmapType( EAntiAliasedGlyphBitmap ); + charFormat.iFontPresentation.iTextColor = aColor; + charFormat.iFontPresentation.iUnderline = aUnderline; + charFormatMask.SetAll(); + iViewerRichText->ApplyCharFormatL( charFormat, charFormatMask, aStartInx, aLength ); + } +// + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AddBodyHotsSpotWithTextFormatingL +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AddBodyHotsSpotWithTextFormatingL( const CFindItemEngine::SFoundItem& aBodyHotSpotData ) + { + FUNC_LOG; + iViewerRichText->SetHotSpotL( aBodyHotSpotData.iStartPos + iHeaderLength, + aBodyHotSpotData.iLength, KHotspotHighlightOn ); + + // add underlining and right color the the hotspots + // + const CAknLayoutFont* newFont = GetCorrectFontL( EViewerFontText ); + TRgb fontColor = SkinFontColorByType( EViewerFontHotspotNormal ); + + TFontUnderline underline = EUnderlineOn; + ApplyFontToTextL( newFont, aBodyHotSpotData.iStartPos + iHeaderLength, + aBodyHotSpotData.iLength, fontColor, underline ); + // + + } + +// separator line + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::AppendSeparatorLineL +// Append attachement(s) line to the rich text. +// ----------------------------------------------------------------------------- +void CFSEmailUiMailViewerRichText::AppendSeparatorLineL() + { + FUNC_LOG; + UpdateIconL( EViewerIconSeparatorLine ); + } + +// ----------------------------------------------------------------------------- +// CFSEmailUiMailViewerRichText::SeparatorLineWidth +// ----------------------------------------------------------------------------- +TInt CFSEmailUiMailViewerRichText::SeparatorLineWidth() const + { + FUNC_LOG; + // For some reason, the ratioanally calculated text width seems to be a bit + // wider than the width where GenericTextViewer does line wrapping. Reserve + // some extra pixels to overcome this. Maybe there is some difference in + // the ways the text width is calculated? + const TInt KExtraPixels( 10 ); + + TRect screenRect = iTextViewer->GetControl()->DisplayArea(); + TInt scrollBarBreadth = CEikScrollBar::DefaultScrollBarBreadth(); + + // Calculate space left for actual text + TInt rightMargin = iAppUi.LayoutHandler()->ViewerRightMarginInPixels() + scrollBarBreadth; + TInt leftMargin = iAppUi.LayoutHandler()->ViewerLeftMarginInPixels(); + TInt widthInPixels = screenRect.iBr.iX - rightMargin - leftMargin - KExtraPixels; + + return widthInPixels; + } + +// separator line + +// End of the file +