/*
* 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: 48 %
*
*/
// SYSTEM INCLUDES
#include "emailtrace.h"
#include <AknUtils.h>
#include <freestyleemailui.mbg>
#include <FreestyleEmailUi.rsg>
#include <StringLoader.h>
#include <AknBidiTextUtils.h>
//<cmail>
#include "fstextviewer.h"
#include "fsrichtext.h"
#include "CFSMailMessagePart.h"
#include "CFSMailClient.h"
#include "CFSMailCommon.h"
//</cmail>
#include <txtfrmat.h>
// <cmail> SF
#include <alf/alftextvisual.h>
// </cmail>
//<cmail> Platform layout changes
#include <aknlayoutscalable_apps.cdl.h>
#include <layoutmetadata.cdl.h>
//</cmail> Platform layout changes
// for fonts
#include <AknFontAccess.h>
#include <AknLayoutFont.h>
// <cmail> separator line
#include <w32std.h>
#include <coecntrl.h>
// </cmail> 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
// -----------------------------------------------------------------------------
// <cmail>
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();
}
// </cmail>
// -----------------------------------------------------------------------------
// 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 );
// <cmail> separator line
AppendSeparatorLineL();
// </cmail> 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;
// <cmail> 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_navi_follow_up,
EMbmFreestyleemailuiQgn_indi_navi_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_navi_follow_up_complete,
EMbmFreestyleemailuiQgn_indi_navi_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.
// <cmail> Platform layout change
//newIconSize.iHeight = newIconSize.iHeight * 3 / 4;
// </cmail> 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;
// <cmail> 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;
// </cmail> separator line
default:
{
User::Leave( KErrNotSupported );
}
break;
}
// </cmail>
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<CPicture>( 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<CFSMailAddress>& addressArray = iMessage->GetToRecipients();
emailAddress = addressArray[aCurrentHotSpot.iDisplayNameArrayIndex]->GetEmailAddress().AllocLC();
}
else if( aCurrentHotSpot.iType == ETypeCcAddressDisplayName )
{
RPointerArray<CFSMailAddress>& addressArray = iMessage->GetCCRecipients();
emailAddress = addressArray[aCurrentHotSpot.iDisplayNameArrayIndex]->GetEmailAddress().AllocLC();
}
else if( aCurrentHotSpot.iType == ETypeBccAddressDisplayName )
{
RPointerArray<CFSMailAddress>& 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
// -----------------------------------------------------------------------------
//<cmail>
HBufC* CFSEmailUiMailViewerRichText::ClipHeaderInfoToFitLC( const TDesC& aText, TBool aIsDisplayName )
{
FUNC_LOG;
// Clip to fit in available amouth of pixels
const CAknLayoutFont* textNameFont = GetCorrectFontL( EViewerFontHotspotNormal );
// <cmail> Platform layout change
TInt textWidthInPixels = HeaderIndentedTextAreaWidth( EFalse );
// </cmail> 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;
}
//</cmail>
// -----------------------------------------------------------------------------
// 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?
// <cmail> 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();
}
}
// </cmail> 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<CFSMailAddress>& 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<CFSMailAddress>* 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<TPtrC>* wrappedArray = new (ELeave) CArrayFixFlat<TPtrC>( maxSubjectLines );
CleanupStack::PushL( wrappedArray );
CArrayFixFlat<TInt>* lineWidthArray = new (ELeave) CArrayFixFlat<TInt>( maxSubjectLines );
CleanupStack::PushL( lineWidthArray );
for ( TInt i = 0 ; i < maxSubjectLines ; ++i )
{
lineWidthArray->AppendL( subjectWidthInPixels );
}
//<cmail>
const CAknLayoutFont* subjectFont = GetCorrectFontL( EViewerFontText );
AknTextUtils::WrapToArrayAndClipL( subjectPtr, *lineWidthArray, *subjectFont, *wrappedArray );
//</cmail>
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<CFSMailMessagePart> 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.
//<cmail>
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 );
}
//</cmail>
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<CAlfAnchorLayout*>( 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 );
// <cmail> 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() );
// </cmail> 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();
//<cmail>
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 );
//</cmail>
// 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 );
// <cmail>
// insert found data to member variable iHotSpotData
const CArrayFixFlat<CFindItemEngine::SFoundItem>* itemArray = hotspotSearch->ItemArray();
TInt itemCount = hotspotSearch->ItemCount();
for ( TInt i = 0; i < itemCount; i++ )
{
CFindItemEngine::SFoundItem* foundItem = const_cast<CFindItemEngine::SFoundItem*> ( &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 ) );
}
}
// </cmail>
CleanupStack::PopAndDestroy( hotspotSearch );
}
//<cmail>
// -----------------------------------------------------------------------------
// 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];
}
*/
//</cmail>
// -----------------------------------------------------------------------------
// 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:
{
// <cmail>
//returnedColor = iAppUi.LayoutHandler()->ViewerTitleFontHeight();
returnedColor = iAppUi.LayoutHandler()->ViewerTitleTextColor();
// </cmail>
}
break;
case EViewerFontText:
default:
{
returnedColor = iAppUi.LayoutHandler()->ViewerTextTextColor();
}
break;
}
return returnedColor;
}
//<cmail> 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();
}
//</cmail>
// -----------------------------------------------------------------------------
// 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 );
//<cmail>
const CAknLayoutFont* newFont = GetCorrectFontL( aFontType );
TRgb fontColor = SkinFontColorByType( aFontType );
TFontUnderline underline = EUnderlineOff;
if ( aFontType == EViewerFontHotspotNormal )
{
underline = EUnderlineOn;
}
ApplyFontToTextL( newFont, aPosition, aText.Length(), fontColor, underline );
//</cmail>
}
//<cmail>
// -----------------------------------------------------------------------------
// 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 );
}
//</cmail>
// -----------------------------------------------------------------------------
// 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
//<cmail>
const CAknLayoutFont* newFont = GetCorrectFontL( EViewerFontText );
TRgb fontColor = SkinFontColorByType( EViewerFontHotspotNormal );
TFontUnderline underline = EUnderlineOn;
ApplyFontToTextL( newFont, aBodyHotSpotData.iStartPos + iHeaderLength,
aBodyHotSpotData.iLength, fontColor, underline );
//</cmail>
}
// <cmail> 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;
}
// </cmail> separator line
// End of the file