emailuis/emailui/src/ncsutility.cpp
branchRCL_3
changeset 64 3533d4323edc
child 70 968773a0b6ef
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/emailui/src/ncsutility.cpp	Wed Sep 01 12:28:57 2010 +0100
@@ -0,0 +1,1222 @@
+/*
+* 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: utility class definition
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "emailtrace.h"
+#include <StringLoader.h>
+#include <AknsUtils.h>
+#include <AknUtils.h>
+#include <AknsSkinInstance.h>
+#include <aknbutton.h>
+#include <eikedwin.h>
+#include <FreestyleEmailUi.rsg>
+#include <RPbkViewResourceFile.h>
+#include <CPbkContactEngine.h>
+#include <CPbkMultipleEntryFetchDlg.h>
+#include <CPbkContactItem.h>
+#include <AknIconUtils.h>
+#include <eikimage.h>
+#include <fbs.h>
+#include <flogger.h>
+#include <aknenv.h> // CAknEnv
+
+#include "cfsmailbox.h"
+#include "cfsmailclient.h"
+#include "cfsmailaddress.h"
+
+#include <aknlayoutscalable_apps.cdl.h>
+#include <layoutmetadata.cdl.h>
+#include <AknLayoutFont.h>
+
+#include "ncsutility.h"
+#include "ncsemailaddressobject.h"
+#include "ncsconstants.h"
+#include "FSDelayedLoader.h"
+#include "FreestyleEmailUiUtilities.h"
+#include "FreestyleEmailUiLayoutData.h"
+
+// CONSTANTS
+const TInt KFSUtilityMinColorValue = 0;
+const TInt KFSUtilityMaxColorValue = 255;
+const TInt KFSUtilityThresholdColorValue = 200;
+const TInt KFSUtilityThresholdColorMiddleValue = 127;
+
+// ========================= MEMBER FUNCTIONS ==================================
+
+
+// -----------------------------------------------------------------------------
+// NcsUtility::CompleteRelativePathL()
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::CompleteRelativePathL( 
+        const TDesC& aRelativePath, TPtr& aAbsolutePath )
+    {
+    FUNC_LOG;
+
+    // + 2 is for drive letter and ":"
+    if( aAbsolutePath.MaxLength() < aRelativePath.Length() + 2 )
+        {
+        User::Leave( KErrArgument );
+        }
+
+    TFileName path;
+    path.Copy( aRelativePath );
+    TInt err = CompleteWithAppPath( path );
+    User::LeaveIfError( err );
+
+    aAbsolutePath.Copy( path );
+
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::GenerateFromLineToMessageBodyL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* NcsUtility::GenerateFromLineToMessageBodyL( 
+        const RPointerArray<CNcsEmailAddressObject>& aFromArray )
+    {
+    FUNC_LOG;
+
+    HBufC* buf = DoGenerateAddressLineToMessageBodyL( 
+            R_NCS_ENGINE_EMAIL_FROM, aFromArray );
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::GenerateSentLineToMessageBodyL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* NcsUtility::GenerateSentLineToMessageBodyL( CFSMailMessage& aMessage )
+    {
+    FUNC_LOG;
+
+    HBufC* dateText = TFsEmailUiUtility::DateTextFromMsgLC( &aMessage );
+    HBufC* timeText = TFsEmailUiUtility::TimeTextFromMsgLC( &aMessage );
+    HBufC* sent = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_SENT );
+
+    HBufC* buf = HBufC::NewL( sent->Length() +
+                              KSpace().Length() +
+                              dateText->Length() +
+                              KSentLineDateAndTimeSeparatorText().Length() +
+                              timeText->Length() );
+    TPtr ptr = buf->Des();
+    ptr.Append( *sent );
+    ptr.Append( KSpace );
+    ptr.Append( *dateText );
+    ptr.Append( KSentLineDateAndTimeSeparatorText );
+    ptr.Append( *timeText );
+
+    CleanupStack::PopAndDestroy( sent );
+    CleanupStack::PopAndDestroy( timeText );
+    CleanupStack::PopAndDestroy( dateText );
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::GenerateAddressLineToMessageBodyL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* NcsUtility::GenerateAddressLineToMessageBodyL(
+    RPointerArray<CNcsEmailAddressObject>& aToArray, TRecipientType aType )
+    {
+    FUNC_LOG;
+
+    // figure out the recipient type dependent text
+    TInt labelResource = R_NCS_ENGINE_EMAIL_TO;
+    if ( aType == ERecipientTypeCc )
+        {
+        labelResource = R_NCS_ENGINE_EMAIL_CC;
+        }
+
+    HBufC* buf = DoGenerateAddressLineToMessageBodyL( labelResource, aToArray );
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::DoGenerateAddressLineToMessageBodyL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* NcsUtility::DoGenerateAddressLineToMessageBodyL( TInt aLabelResourceId,
+        const RPointerArray<CNcsEmailAddressObject>& aAddressArray )
+    {
+    FUNC_LOG;
+
+    // load label string (e.g. "From:", "To:", "Cc:")
+    HBufC* label = StringLoader::LoadLC( aLabelResourceId );
+
+    // calculate how large buffer do we need for the whole line
+    TInt bufLength = label->Length();
+    TInt count = aAddressArray.Count();
+    for ( TInt i = 0; i < count; i++ )
+        {
+        CNcsEmailAddressObject* obj = aAddressArray[i];
+        const TDesC& dispName = obj->DisplayName();
+        // use display name if it is available, otherwise email address
+        if ( dispName.Length() > 0 )
+            {
+            bufLength += dispName.Length();
+            }
+        else
+            {
+            bufLength += obj->EmailAddress().Length();
+            }
+        if ( i < ( count - 1 ) )
+            {
+            bufLength += KEmailAddressSeparator().Length();
+            bufLength += KSpace().Length();
+            }
+        }
+
+    // allocate buffer to contain the whole text
+    HBufC* buf = HBufC::NewL( bufLength );
+    TPtr ptr = buf->Des();
+
+    // add label
+    ptr.Append( *label );
+    CleanupStack::PopAndDestroy( label );
+
+    // append each address into our text buffer
+    for ( TInt i = 0; i < count; i++ )
+        {
+        CNcsEmailAddressObject* obj = aAddressArray[i];
+        const TDesC& dispName = obj->DisplayName();
+        // use display name if it is available, otherwise email address
+        if ( dispName.Length() > 0 )
+            {
+            ptr.Append( dispName );
+            }
+        else
+            {
+            ptr.Append( obj->EmailAddress() );
+            }
+        if ( i < ( count - 1 ) )
+            {
+            ptr.Append( KEmailAddressSeparator );
+            ptr.Append( KSpace );
+            }
+        }
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::GenerateSubjectLineToMessageBodyL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* NcsUtility::GenerateSubjectLineToMessageBodyL( const TDesC& aSubject )
+    {
+    FUNC_LOG;
+
+    // load "Subject:" string
+    HBufC* subjectLabel = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_SUBJECT );
+
+    // allocate buffer for the text
+    HBufC* buf = HBufC::NewL( subjectLabel->Length() + aSubject.Length() );
+    TPtr ptr = buf->Des();
+    ptr.Append( *subjectLabel );
+    ptr.Append( aSubject );
+
+    CleanupStack::PopAndDestroy( subjectLabel );
+
+    return buf;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::CreateNcsAddressL()
+//
+// -----------------------------------------------------------------------------
+//
+CNcsEmailAddressObject* NcsUtility::CreateNcsAddressL( 
+        const CFSMailAddress& aFsAddress )
+    {
+    FUNC_LOG;
+
+    CNcsEmailAddressObject* address = CNcsEmailAddressObject::NewL( ETrue );
+    CleanupStack::PushL( address );
+    // temporary ugly code because email API can return references to null
+    TDesC& a = aFsAddress.GetEmailAddress();
+    if ( &a )
+        {
+        address->SetEmailAddressL( a );
+        }
+    TDesC& name = aFsAddress.GetDisplayName();
+    if ( &name )
+        {
+        address->SetDisplayNameL( name );
+        }
+
+    CleanupStack::Pop( address );
+
+    return address;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::CreateFsAddressL()
+// Caller takes the ownership of the returned address object
+// -----------------------------------------------------------------------------
+//
+CFSMailAddress* NcsUtility::CreateFsAddressL( 
+        const CNcsEmailAddressObject& aNcsAddress )
+    {
+    FUNC_LOG;
+
+    CFSMailAddress* address = CFSMailAddress::NewL();
+    address->SetEmailAddress( aNcsAddress.EmailAddress() );
+    address->SetDisplayName( aNcsAddress.DisplayName() );
+
+    return address;
+    }
+
+
+// -----------------------------------------------------------------------------
+// NcsUtility::FormatSubjectLineL()
+//
+// -----------------------------------------------------------------------------
+//
+HBufC* NcsUtility::FormatSubjectLineL( 
+        const TDesC& aNewSubjectLine, const TDesC& aPrefix )
+    {
+    FUNC_LOG;
+       
+        HBufC* formattedSubjectLine = aNewSubjectLine.AllocLC();
+        HBufC* prefix = aPrefix.AllocLC();
+        TPtr formattedSubjectLinePtr = formattedSubjectLine->Des();
+        TPtr prefixPtr = prefix->Des();
+        prefixPtr.Trim();
+        
+        TInt subjectLineLength = formattedSubjectLinePtr.Length();
+        TInt length = subjectLineLength;
+        TInt prefixLength = prefixPtr.Length();
+        HBufC* fwdPrefix = StringLoader::LoadLC( R_NCS_ENGINE_EMAIL_FORWARD_PREFIX );
+        TPtr fwdPrt = fwdPrefix->Des();
+        TInt fwdLength = fwdPrt.Length();
+        fwdPrt.Trim();
+        
+          for(TInt index = formattedSubjectLinePtr.FindC( prefixPtr ); index != KErrNotFound ; index = formattedSubjectLinePtr.FindC( prefixPtr ))
+            {
+                formattedSubjectLinePtr = formattedSubjectLinePtr.RightTPtr( length );
+                length = formattedSubjectLinePtr.Length() - index - prefixLength;
+            }
+           formattedSubjectLinePtr.Trim();
+           
+           for(TInt index = formattedSubjectLinePtr.FindC( fwdPrt) ; index != KErrNotFound  ; index = formattedSubjectLinePtr.FindC( fwdPrt ))
+              {
+                   formattedSubjectLinePtr = formattedSubjectLinePtr.RightTPtr( length );
+                   length = formattedSubjectLinePtr.Length() - index - fwdLength;
+              }
+
+           formattedSubjectLinePtr.Trim();
+        
+        
+        HBufC* finalSubject = HBufC::NewL( formattedSubjectLinePtr.Length() + prefixPtr.Length() + KSpace().Length()  );
+        TPtr ptr = finalSubject->Des();
+        if ( AknLayoutUtils::LayoutMirrored() )
+            {
+            ptr.Append( formattedSubjectLinePtr );
+            ptr.Append( KSpace );
+            ptr.Append( prefixPtr );        
+            
+            }
+        else
+            {
+            ptr.Append( prefixPtr );
+            ptr.Append( KSpace );
+            ptr.Append( formattedSubjectLinePtr );
+        
+            }
+        CleanupStack::PopAndDestroy( fwdPrefix );
+        CleanupStack::PopAndDestroy( prefix );
+        CleanupStack::PopAndDestroy( formattedSubjectLine );
+
+        return finalSubject;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ConvertAddressArrayL()
+//
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::ConvertAddressArrayL( 
+        const RPointerArray<CFSMailAddress>& aSrc, 
+        RPointerArray<CNcsEmailAddressObject>& aDst )
+    {
+    FUNC_LOG;
+
+    for ( TInt i=0; i<aSrc.Count(); i++ )
+        {
+        CNcsEmailAddressObject* ncsRecipient = 
+            NcsUtility::CreateNcsAddressL( *aSrc[i] );
+        CleanupStack::PushL( ncsRecipient );
+        aDst.AppendL( ncsRecipient );
+        CleanupStack::Pop( ncsRecipient );
+        }
+
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ConvertAddressArrayL()
+// Caller takes the ownership of address objects pointoed in the array aDst.
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::ConvertAddressArrayL( 
+        const RPointerArray<CNcsEmailAddressObject>& aSrc, 
+        RPointerArray<CFSMailAddress>& aDst )
+    {
+    FUNC_LOG;
+
+    for ( TInt i=0; i<aSrc.Count(); i++ )
+        {
+        CFSMailAddress* fsRecipient = 
+            NcsUtility::CreateFsAddressL( *aSrc[i] );
+        CleanupStack::PushL( fsRecipient );
+        aDst.AppendL( fsRecipient );
+        CleanupStack::Pop( fsRecipient );
+        }
+
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LoadScalableIconL()
+//
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LoadScalableIconL( 
+        const TDesC& aMifRelativeFileName, TInt aImgId, 
+        TInt aMaskId, CEikImage*& aIcon, 
+        CFbsBitmap*& aImage, CFbsBitmap*& aMask )
+    {
+    FUNC_LOG;
+
+    HBufC* buf = HBufC::NewLC( KMaxFileName );
+    TPtr ptr = buf->Des();
+    NcsUtility::CompleteRelativePathL( aMifRelativeFileName, ptr );
+
+    AknIconUtils::CreateIconL( aImage,
+                               aMask,
+                               ptr,
+                               aImgId,
+                               aMaskId );
+
+    TSize size;
+    AknIconUtils::GetContentDimensions( aImage, size );
+    AknIconUtils::SetSize( aImage, size );
+
+    aIcon = new ( ELeave ) CEikImage;
+    aIcon->SetNewBitmaps( aImage, aMask );
+    aIcon->SetPictureOwnedExternally( ETrue );
+
+    CleanupStack::PopAndDestroy( buf );
+
+    }
+
+
+// -----------------------------------------------------------------------------
+// NcsUtility::DebugLog
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::DebugLog( TRefByValue<const TDesC> aFmt, ... )
+    {
+    FUNC_LOG;
+    _LIT( KDebugDir, "FreestyleEmailUi" );
+    _LIT( KDebugLog, "log.txt" );
+
+    VA_LIST args;
+    VA_START( args, aFmt );
+    RFileLogger::WriteFormat( KDebugDir,
+                              KDebugLog,
+                              EFileLoggingModeAppend,
+                              aFmt,
+                              args );
+    VA_END( args );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::IsEqualAddressArray
+// -----------------------------------------------------------------------------
+//
+TBool NcsUtility::IsEqualAddressArray( 
+        const RPointerArray<CFSMailAddress>& aAddresses1,
+        const RPointerArray<CFSMailAddress>& aAddresses2 )
+    {
+    FUNC_LOG;
+
+    if ( aAddresses1.Count() != aAddresses2.Count() )
+        {
+        return EFalse;
+        }
+    for ( TInt i=0; i<aAddresses1.Count(); i++ )
+        {
+        if ( aAddresses1[i]->GetEmailAddress().Compare( 
+                aAddresses2[i]->GetEmailAddress() ) != 0 )
+            {
+            return EFalse;
+            }
+        if ( aAddresses1[i]->GetDisplayName().Compare( 
+                aAddresses2[i]->GetDisplayName() ) != 0 )
+            {
+            return EFalse;
+            }
+        }
+
+    return ETrue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// NcsUtility::Measures
+// -----------------------------------------------------------------------------
+//
+TNcsMeasures NcsUtility::Measures()
+    {
+    FUNC_LOG;
+
+    TNcsMeasures ms;
+
+    TAknUiZoom zoomLevel = EAknUiZoomNormal;
+    CAknEnv::Static()->GetCurrentGlobalUiZoom( zoomLevel );
+    switch ( zoomLevel )
+        {
+        case EAknUiZoomNormal: case EAknUiZoomAutomatic:
+            {
+            ms.iAifHeight = KAifHeight;
+            ms.iAifLabelMarginVertical = KAifLabelMarginVertical;
+            ms.iAifEditorMarginVertical = KAifEditorMarginVertical;
+            ms.iAifEditorHeight = KAifEditorHeight;
+            ms.iSubjectExtraHeightBottom = KSubjectExtraHeightBottom;
+            ms.iAttachmentExtraHeightBottom = KAttachmentExtraHeightBottom;
+            ms.iIconMarginPriorityVertical = KIconMarginPriorityVertical;
+            ms.iIconMarginFollowUpVertical = KIconMarginFollowUpVertical;
+            ms.iIconMarginAttachmentVertical = KIconMarginAttachmentVertical;
+            ms.iLabelFontHeightPx = KLabelFontHeightPx;
+            ms.iEditorFontHeightPx = KEditorFontHeightPx;
+            }
+            break;
+        case EAknUiZoomSmall: case EAknUiZoomVerySmall:
+            {
+            ms.iAifHeight = KAifHeightSmall;
+            ms.iAifLabelMarginVertical = KAifLabelMarginVerticalSmall;
+            ms.iAifEditorMarginVertical = KAifEditorMarginVerticalSmall;
+            ms.iAifEditorHeight = KAifEditorHeightSmall;
+            ms.iSubjectExtraHeightBottom = KSubjectExtraHeightBottomSmall;
+            ms.iAttachmentExtraHeightBottom = 
+                KAttachmentExtraHeightBottomSmall;
+            ms.iIconMarginPriorityVertical = KIconMarginPriorityVerticalSmall;
+            ms.iIconMarginFollowUpVertical = KIconMarginFollowUpVerticalSmall;
+            ms.iIconMarginAttachmentVertical = 
+                KIconMarginAttachmentVerticalSmall;
+            ms.iLabelFontHeightPx = KLabelFontHeightPxSmall;
+            ms.iEditorFontHeightPx = KEditorFontHeightPxSmall;
+            }
+            break;
+        case EAknUiZoomLarge: case EAknUiZoomVeryLarge:
+            {
+            ms.iAifHeight = KAifHeightLarge;
+            ms.iAifLabelMarginVertical = KAifLabelMarginVerticalLarge;
+            ms.iAifEditorMarginVertical = KAifEditorMarginVerticalLarge;
+            ms.iAifEditorHeight = KAifEditorHeightLarge;
+            ms.iSubjectExtraHeightBottom = KSubjectExtraHeightBottomLarge;
+            ms.iAttachmentExtraHeightBottom = 
+                KAttachmentExtraHeightBottomLarge;
+            ms.iIconMarginPriorityVertical = KIconMarginPriorityVerticalLarge;
+            ms.iIconMarginFollowUpVertical = KIconMarginFollowUpVerticalLarge;
+            ms.iIconMarginAttachmentVertical = 
+                KIconMarginAttachmentVerticalLarge;
+            ms.iLabelFontHeightPx = KLabelFontHeightPxLarge;
+            ms.iEditorFontHeightPx = KEditorFontHeightPxLarge;
+            }
+            break;
+        }
+
+    return ms;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::GetNearestFontL
+// -----------------------------------------------------------------------------
+//
+CFont* NcsUtility::GetNearestFontL( TInt aLogicalFontId, TInt aHeightPixels )
+    {
+    FUNC_LOG;
+
+    // Base the font on logical font passed to us
+    const CFont* logicalFont = AknLayoutUtils::FontFromId( aLogicalFontId );
+    // Note: This font is owned by the application's system font array (where
+    // it is likely already to have been created) and does not need to be
+    // released. It can just go out of scope.
+
+    // Extract font information
+    TFontSpec fontSpec = logicalFont->FontSpecInTwips();
+
+    // Desired height, weight, and posture
+    CWsScreenDevice& screenDev = *( CEikonEnv::Static()->ScreenDevice() );
+    fontSpec.iHeight = screenDev.VerticalPixelsToTwips( aHeightPixels );
+    fontSpec.iFontStyle.SetStrokeWeight( EStrokeWeightNormal );
+    fontSpec.iFontStyle.SetPosture( EPostureUpright );
+
+    // Obtain new font
+    CFont* font;
+
+    TInt err = screenDev.GetNearestFontInTwips( font, fontSpec );
+    User::LeaveIfError( err );
+
+    return font;
+    // Font is now usable. Must be released before application
+    // exit using CWsScreenDevice::ReleaseFont()
+    }
+
+// <cmail> Platform layout change
+// -----------------------------------------------------------------------------
+// NcsUtility::GetLayoutFont
+// -----------------------------------------------------------------------------
+//
+const CFont* NcsUtility::GetLayoutFont(
+        const TRect& aParent, TNcsLayoutFont aUsage )
+    {
+    FUNC_LOG;
+    TAknLayoutText layoutText;
+    switch (aUsage)
+        {
+        case ENcsHeaderCaptionFont:
+            {
+            layoutText.LayoutText(aParent, AknLayoutScalable_Apps::list_single_cmail_header_caption_pane_t1());
+            break;
+            }
+        case ENcsHeaderDetailFont:
+            {
+            layoutText.LayoutText(aParent, AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1(0));
+            break;
+            }
+        case ENcsBodytextFont:
+            {
+            layoutText.LayoutText(aParent, AknLayoutScalable_Apps::list_cmail_body_pane_t1());
+            break;
+            }
+        }
+    return layoutText.Font();
+    }
+// </cmail>
+
+// -----------------------------------------------------------------------------
+// NcsUtility::IsEditReplyForwardQuoteSupported
+// -----------------------------------------------------------------------------
+//
+TBool NcsUtility::IsReplyForwardQuoteReadOnly( const CFSMailBox& aMailBox )
+    {
+    FUNC_LOG;
+    TBool r = aMailBox.HasCapability( EFSMBoxCapaReadOnlySmartQuote );
+    return r;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::FindFirstPrintableCharIndex
+// -----------------------------------------------------------------------------
+//
+TInt NcsUtility::FindFirstPrintableCharIndex( const TDesC& aText )
+    {
+    FUNC_LOG;
+    for ( TInt i=0; i<aText.Length(); i++ )
+        {
+        TChar c = aText[i];
+        if ( c.IsGraph() )
+            {
+            return i;
+            }
+        else
+            {
+            continue;
+            }
+        }
+    return KErrNotFound;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ConvertCharacters
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::ConvertCharacters( TDes& aBuffer, TUint16 aFrom, TUint16 aTo )
+    {
+    FUNC_LOG;
+    for ( TInt i=0; i<aBuffer.Length(); i++ )
+        {
+        if ( aBuffer[i] == aFrom )
+            {
+            aBuffer[i] = aTo;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ConvertLineEndingsL
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::ConvertLineEndingsL( HBufC*& aBuffer )
+    {
+    FUNC_LOG;
+    // find line ending positions
+    RArray<TInt> positions;
+    CleanupClosePushL( positions );
+    for ( TInt i=0; i<aBuffer->Length(); i++ )
+        {
+        if ( (*aBuffer)[i] == (TInt32)CEditableText::EParagraphDelimiter )
+            {
+            positions.Append( i );
+            }
+        }
+
+    // case when there are no line endings can be early exited
+    if ( positions.Count() <= 0 )
+        {
+        CleanupStack::PopAndDestroy( &positions );
+        return;
+        }
+
+    // we need to do the conversion
+    // initialize
+    const TChar KCR = 0x0D;
+    const TChar KLF = 0x0A;
+    TInt startPos = 0;
+    TInt length = 0;
+
+    // create destination buffer
+    HBufC* newBuffer = HBufC::NewL( aBuffer->Length() + positions.Count() * 2 );
+    TPtr dstPtr = newBuffer->Des();
+
+    // do the conversion
+    for ( TInt i=0; i<positions.Count(); i++ )
+        {
+        // copy text, no line ending
+        length = positions[i] - startPos;
+        TPtrC16 srcPtr = aBuffer->Mid( startPos, length );
+        dstPtr.Append( srcPtr );
+        startPos = positions[i] + 1;
+        // append line ending
+        dstPtr.Append( KCR );
+        dstPtr.Append( KLF );
+        }
+    // handle the text piece after last line ending if there is such
+    const TInt lastPos = positions[ positions.Count() - 1 ];
+    const TInt high = aBuffer->Length() - 1;
+    if ( lastPos < high )
+        {
+        const TInt start = lastPos + 1;
+        TPtrC16 srcPtr = aBuffer->Mid( start, aBuffer->Length() - start );
+        dstPtr.Append( srcPtr );
+        }
+    // delete old buffer and give pointer to new one
+    delete aBuffer;
+    aBuffer = newBuffer;
+    CleanupStack::PopAndDestroy( &positions );
+    }
+
+ // -----------------------------------------------------------------------------
+// NcsUtility::DeleteMessage
+// -----------------------------------------------------------------------------
+//
+TInt NcsUtility::DeleteMessage( CFSMailClient& aMailClient,
+        const TFSMailMsgId& aMailBoxId,
+        const TFSMailMsgId& aFolderId,
+        const TFSMailMsgId& aMsgId )
+    {
+    FUNC_LOG;
+    RArray<TFSMailMsgId> msgIds;
+    TInt error = msgIds.Append( aMsgId );
+    if ( error == KErrNone )
+        {
+        TRAP( error, aMailClient.DeleteMessagesByUidL( aMailBoxId, aFolderId,
+            msgIds ) );
+        }
+    msgIds.Close();
+    return error;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::HeaderCaptionPaneRect
+// -----------------------------------------------------------------------------
+//
+TRect NcsUtility::HeaderCaptionPaneRect( const TRect& aParent )
+    {
+    FUNC_LOG;
+    TAknLayoutRect headerCaptionPaneRect;
+    headerCaptionPaneRect.LayoutRect( aParent, AknLayoutScalable_Apps::list_single_cmail_header_caption_pane() );
+    return headerCaptionPaneRect.Rect();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::HeaderDetailPaneRect
+// -----------------------------------------------------------------------------
+//
+TRect NcsUtility::HeaderDetailPaneRect( 
+        const TRect& aParent, const TInt aRows, TBool aSameRow )
+    {
+    FUNC_LOG;
+    const TInt variety( aRows == 1 ? 0 : 1 );
+    TAknLayoutRect headerDetailPaneRect;
+    headerDetailPaneRect.LayoutRect( aParent, AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( variety ) );
+    TRect result( headerDetailPaneRect.Rect() );
+    if (!aSameRow)
+        {
+        result.Move( 0, HeaderCaptionPaneRect( aParent ).Height() );
+        }
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::HeaderDetailIconRect
+// -----------------------------------------------------------------------------
+//
+TRect NcsUtility::HeaderDetailIconRect( 
+        const TRect& aParent, const TInt aRows, const THeaderDetailIcon aIcon )
+    {
+    FUNC_LOG;
+    const TInt variety( aRows == 1 ? 0 : 1 );
+    TAknLayoutRect headerIconRect;
+    headerIconRect.LayoutRect( aParent,
+            aIcon == EIconFront ?
+                AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_g1( variety ) :
+                AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_g2( variety ) );
+    // Offset detail rect by header caption pane height
+    TRect result( headerIconRect.Rect() );
+    //result.Move( 0, HeaderCaptionPaneRect( aParent ).Height() );
+    return result;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ListscrollPaneRect
+// -----------------------------------------------------------------------------
+TRect NcsUtility::ListscrollPaneRect()
+    {
+    FUNC_LOG;
+    TRect mainPaneRect;
+    AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
+    TAknLayoutRect listRect;
+    listRect.LayoutRect( mainPaneRect, AknLayoutScalable_Apps::main_sp_fs_listscroll_pane_te() );
+    return listRect.Rect();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ListCmailPaneRect
+// -----------------------------------------------------------------------------
+//
+TRect NcsUtility::ListCmailPaneRect( const TRect& aParent )
+    {
+    FUNC_LOG;
+    TAknLayoutRect listCmailPaneRect;
+    listCmailPaneRect.LayoutRect( aParent, AknLayoutScalable_Apps::list_cmail_pane() );
+    return listCmailPaneRect.Rect();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ListCmailScrollbarRect
+// -----------------------------------------------------------------------------
+//
+TRect NcsUtility::ListCmailScrollbarRect( const TRect& aParent )
+    {
+    FUNC_LOG;
+    TAknLayoutRect listCmailPaneRect;
+    listCmailPaneRect.LayoutRect( aParent, AknLayoutScalable_Apps::sp_fs_scroll_pane_cp03() );
+    return listCmailPaneRect.Rect();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::SeparatorSizeInThisResolution
+//
+// Returns size of empty space between header and message body
+// -----------------------------------------------------------------------------
+//
+TSize NcsUtility::SeparatorSizeInThisResolution()
+    {
+    FUNC_LOG;
+
+    TRect mainPaneRect;
+    AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect);
+
+    TAknLayoutRect listRect;
+    listRect.LayoutRect(mainPaneRect, AknLayoutScalable_Apps::list_cmail_pane());
+
+    TAknLayoutRect bodyRect;
+    bodyRect.LayoutRect(listRect.Rect(), AknLayoutScalable_Apps::list_cmail_body_pane());
+
+    TRect rect( bodyRect.Rect() );
+    rect.Shrink( 0, bodyRect.Rect().Height() / 4 );
+    return rect.Size();
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// NcsUtility::SeparatorLineColor
+// -----------------------------------------------------------------------------
+//
+TRgb NcsUtility::SeparatorLineColor()
+    {
+    FUNC_LOG;
+    MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+    TRgb rgb;
+    if (AknsUtils::GetCachedColor( skin, rgb,
+            KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG6) != KErrNone )
+        {
+        rgb = KRgbBlack;
+        }
+
+    return rgb;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ComposerLeftMarginInPixels
+//
+// Left margin value for additional graphics in composer view
+// -----------------------------------------------------------------------------
+//
+TInt NcsUtility::ComposerLeftMarginInPixels( const TRect& aParent )
+    {
+    FUNC_LOG;
+    const TRect cmailPaneRect( ListCmailPaneRect( aParent ) );
+    TAknLayoutRect layoutRect;
+    layoutRect.LayoutRect( cmailPaneRect, AknLayoutScalable_Apps::list_single_cmail_header_caption_pane() );
+    TAknLayoutText captionTextRect;
+    captionTextRect.LayoutText( layoutRect.Rect(), AknLayoutScalable_Apps::list_single_cmail_header_caption_pane_t1() );
+    return Abs( cmailPaneRect.iTl.iX - captionTextRect.TextRect().iTl.iX );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ComposerRightMarginInPixels
+//
+// Right margin value for additional graphics in composer view
+// -----------------------------------------------------------------------------
+//
+TInt NcsUtility::ComposerRightMarginInPixels( const TRect& aParent )
+    {
+    FUNC_LOG;
+    const TRect cmailPaneRect( ListCmailPaneRect( aParent ) );
+    TAknLayoutRect layoutRect;
+    layoutRect.LayoutRect( cmailPaneRect, AknLayoutScalable_Apps::list_single_cmail_header_caption_pane() );
+    TAknLayoutText captionTextRect;
+    captionTextRect.LayoutText( layoutRect.Rect(), AknLayoutScalable_Apps::list_single_cmail_header_caption_pane_t1() );
+    return Abs( cmailPaneRect.iBr.iX - captionTextRect.TextRect().iBr.iX );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::ListCmailBodyPaneRect
+// -----------------------------------------------------------------------------
+//
+TRect NcsUtility::ListCmailBodyPaneRect( const TRect& aParent )
+    {
+    FUNC_LOG;
+    TAknLayoutRect listCmailBodyRect;
+    listCmailBodyRect.LayoutRect( aParent, AknLayoutScalable_Apps::list_cmail_body_pane() );
+    return listCmailBodyRect.Rect();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutCaptionLabel
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutCaptionLabel( CEikLabel* aLabel, const TRect& aParentRect )
+    {
+    FUNC_LOG;
+    AknLayoutUtils::LayoutLabel( 
+            aLabel, NcsUtility::HeaderCaptionPaneRect( aParentRect ), 
+            AknLayoutScalable_Apps::list_single_cmail_header_caption_pane_t1().LayoutLine() );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutCaptionLabel
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutCaptionButton( 
+        CAknButton* aButton, const TRect& aParentRect)
+    {
+    FUNC_LOG;
+    TAknLayoutText layoutText;
+    
+    const TInt labelVariety = 2;
+    TAknTextComponentLayout textComponentLayout;
+    TAknLayoutRect layoutRect;
+    TRect rect;
+    
+    TInt fontId;
+    TInt topMargin;
+    TInt bottomMargin;
+    
+    // Getting editor's top and bottom margin from its layout
+    textComponentLayout = 
+        AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1(
+            KHeaderDetailTextPaneVariety );
+    fontId = textComponentLayout.LayoutLine().FontId();
+    
+    TAknTextDecorationMetrics metrics( fontId );
+    metrics.GetTopAndBottomMargins( topMargin, bottomMargin );
+    
+    layoutRect.LayoutRect(
+        HeaderDetailPaneRect( aParentRect, 1, ETrue ),
+        AknLayoutScalable_Apps::bg_button_pane_cp12() );
+    
+    textComponentLayout = 
+        AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t2( 
+                labelVariety );
+    layoutText.LayoutText(
+        HeaderDetailPaneRect( aParentRect, 1, ETrue ),
+        textComponentLayout.LayoutLine() );
+    
+    rect = layoutRect.Rect();
+    rect.iTl.iY -= topMargin + bottomMargin;
+    
+    aButton->SetRect( rect );
+    aButton->SetTextFont( layoutText.Font() );
+    aButton->SetTextHorizontalAlignment( layoutText.Align() );
+    TMargins8 margs( 0, 0, 5, 0 );
+    aButton->SetMargins( margs );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutDetailLabel
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutDetailLabel( 
+        CEikLabel* aLabel, const TRect& aParentRect, TInt aRow)
+    {
+    FUNC_LOG;
+    TRect rect( NcsUtility::HeaderDetailPaneRect( aParentRect, 1, ETrue ) );
+    rect.Move( 0, aRow*rect.Height() );
+    AknLayoutUtils::LayoutLabel( aLabel, rect, AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1( 0 ).LayoutLine() );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutDetailEdwin
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutDetailEdwin( 
+        CEikEdwin* aEdwin, const TRect& aParentRect, 
+        const TInt aLineCount, const TBool aBackIcon )
+    {
+    FUNC_LOG;
+    TAknMultiLineTextLayout edwinLayout;
+    const TInt textPaneVariety( aBackIcon ? 1 : 3 );
+    TAknTextComponentLayout textLayout( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1( textPaneVariety ) );
+    RArray< TAknTextComponentLayout > edwinLayoutLines;
+    TAknTextComponentLayout textRowLayout;
+    TAknWindowComponentLayout headerDetailPane( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0, 0, 0 ) );
+    for ( TInt line = 0; line < aLineCount; line++ )
+        {
+        textRowLayout = TAknWindowComponentLayout::ComposeText( TAknWindowComponentLayout::MultiLineY( headerDetailPane, line, 0 ), textLayout );
+        edwinLayoutLines.Append( textRowLayout );
+        }
+    AknLayoutUtils::LayoutEdwin( aEdwin, NcsUtility::HeaderDetailPaneRect( aParentRect, aLineCount ), TAknTextComponentLayout::Multiline( edwinLayoutLines ) );
+    edwinLayoutLines.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutDetailEdwin
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutDetailEdwinTouch( 
+        CEikEdwin* aEdwin, const TRect& aParentRect,
+        const TInt aLineCount, const TBool /*aBackIcon*/  )
+    {
+    FUNC_LOG;
+    TAknMultiLineTextLayout edwinLayout;
+    TAknTextComponentLayout textLayout( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane_t1( KHeaderDetailTextPaneVariety ) );
+    RArray< TAknTextComponentLayout > edwinLayoutLines;
+    TAknTextComponentLayout textRowLayout;
+    TAknWindowComponentLayout headerDetailPane( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0, 0, 0 ) );
+    for ( TInt line = 0; line < aLineCount; line++ )
+        {
+        textRowLayout = TAknWindowComponentLayout::ComposeText( TAknWindowComponentLayout::MultiLineY( headerDetailPane, line, 0 ), textLayout );
+        edwinLayoutLines.Append( textRowLayout );
+        }
+    AknLayoutUtils::LayoutEdwin( aEdwin, NcsUtility::HeaderDetailPaneRect( aParentRect, aLineCount, ETrue ), TAknTextComponentLayout::Multiline( edwinLayoutLines ) );
+    edwinLayoutLines.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::HeaderControlPosition
+// -----------------------------------------------------------------------------
+//
+TPoint NcsUtility::HeaderControlPosition( 
+        const TRect& aParentRect, const TInt aCurrentLine )
+    {
+    FUNC_LOG;
+    TAknLayoutRect detailPane;
+    TAknWindowComponentLayout headerDetailPane( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0, 0, 0 ) );
+    detailPane.LayoutRect( aParentRect, TAknWindowComponentLayout::MultiLineY( headerDetailPane, aCurrentLine, 0 ) );
+    return detailPane.Rect().iTl;
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutHeaderControl
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutHeaderControl( 
+        CCoeControl* aControl, const TRect& aParentRect, 
+        const TInt aCurrentLine, const TInt aNumberOfLines )
+    {
+    FUNC_LOG;
+    TAknLayoutRect detailPane;
+    TAknWindowComponentLayout headerDetailPane( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0, 0, 0 ) );
+    detailPane.LayoutRect( aParentRect, TAknWindowComponentLayout::MultiLineY( headerDetailPane, aCurrentLine, 0 ) );
+    TRect rect( detailPane.Rect() );
+    rect.SetHeight( rect.Height() * aNumberOfLines );
+    aControl->SetRect( rect );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::LayoutBodyEdwin
+// -----------------------------------------------------------------------------
+//
+void NcsUtility::LayoutBodyEdwin( 
+        CEikEdwin* aEdwin, const TRect& aParentRect, const TInt aCurrentLine, 
+        const TInt aNumberOfLines, TInt& aSeparatorYPosition )
+    {
+    FUNC_LOG;
+    TAknMultiLineTextLayout edwinLayout;
+    TAknTextComponentLayout textLayout( AknLayoutScalable_Apps::list_cmail_body_pane_t1() );
+    RArray< TAknTextComponentLayout > edwinLayoutLines;
+    TAknTextComponentLayout textRowLayout;
+    TAknWindowComponentLayout headerCaptionPane( AknLayoutScalable_Apps::list_single_cmail_header_caption_pane( 0, 0, 0 ) );
+    TInt lines = Max( aNumberOfLines, 2 );
+    for ( TInt line = 0; line < lines; line++ )
+        {
+        textRowLayout = TAknWindowComponentLayout::ComposeText( TAknWindowComponentLayout::MultiLineY( headerCaptionPane, line, 0 ), textLayout );
+        edwinLayoutLines.Append( textRowLayout );
+        }
+    TAknLayoutRect bodyPane;
+    bodyPane.LayoutRect( aParentRect, AknLayoutScalable_Apps::list_cmail_body_pane() );
+    TRect bodyRect( bodyPane.Rect() );
+    TAknLayoutRect detailPane;
+    TAknWindowComponentLayout headerDetailPane( AknLayoutScalable_Apps::list_single_cmail_header_detail_pane( 0, 0, 0 ) );
+    detailPane.LayoutRect( aParentRect, TAknWindowComponentLayout::MultiLineY( headerDetailPane, aCurrentLine, 0 ) );
+    bodyRect = TRect( detailPane.Rect().iTl, bodyRect.Size() );
+    aSeparatorYPosition = bodyRect.iTl.iY;
+    // Since layout doesn't specify enough space between separator line
+    // and editor, we add some space manually
+    TInt deltaMove = NcsUtility::SeparatorSizeInThisResolution().iHeight;
+    bodyRect.Move( 0, deltaMove );
+    AknLayoutUtils::LayoutEdwin( aEdwin, bodyRect, TAknTextComponentLayout::Multiline( edwinLayoutLines ), EAknsCIQsnTextColorsCG6 );
+    edwinLayoutLines.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::CalculateSeparatorLineSecondaryColor
+//
+// Calculates secondary color value based on the start value. Useful for
+// gradient drawing.
+// @param aDegree = color change coefficient
+// -----------------------------------------------------------------------------
+//
+TRgb NcsUtility::CalculateSeparatorLineSecondaryColor( TInt aDegree,
+                                                       TRgb /*aStartColor*/ )
+    {
+    TRgb secondaryColor;
+    TInt redValue;
+    TInt greenValue;
+    TInt blueValue;
+    TRgb startColor = SeparatorLineColor();
+    if( startColor.Red() > KFSUtilityThresholdColorValue &&
+            startColor.Green() > KFSUtilityThresholdColorValue &&
+            startColor.Blue() > KFSUtilityThresholdColorValue )
+        {
+        //Original color is bright, so let's make secondary color darker
+        redValue = startColor.Red() - ( startColor.Red() / aDegree );
+        greenValue = startColor.Green() - ( startColor.Green() / aDegree );
+        blueValue = startColor.Blue() - ( startColor.Blue() / aDegree );
+        }
+    else
+        {
+        //Original color is dark, so let's make secondary color brighter
+        //Checking how bright original color is
+        if( startColor.Red() < KFSUtilityThresholdColorMiddleValue &&
+                startColor.Green() < KFSUtilityThresholdColorMiddleValue &&
+                startColor.Blue() < KFSUtilityThresholdColorMiddleValue )
+            {
+            // Calculating new values from the unoccupied color space
+            redValue = startColor.Red() + ( (
+                    KFSUtilityMaxColorValue - startColor.Red() ) / aDegree );
+            greenValue = startColor.Green() + ( (
+                    KFSUtilityMaxColorValue - startColor.Green() ) / aDegree );
+            blueValue = startColor.Blue() + ( (
+                    KFSUtilityMaxColorValue - startColor.Blue() ) / aDegree );
+            }
+        else
+            {
+            // Calculating new values from the occupied color space
+            redValue = startColor.Red() + ( startColor.Red() / aDegree );
+            greenValue = startColor.Green() + ( startColor.Green() / aDegree );
+            blueValue = startColor.Blue() + ( startColor.Blue() / aDegree );
+            }
+        }
+
+    if ( redValue > KFSUtilityMaxColorValue )
+        {
+        redValue = KFSUtilityMaxColorValue;
+        }
+    if ( greenValue > KFSUtilityMaxColorValue )
+        {
+        greenValue = KFSUtilityMaxColorValue;
+        }
+    if ( blueValue > KFSUtilityMaxColorValue )
+        {
+        blueValue = KFSUtilityMaxColorValue;
+        }
+    return TRgb( redValue , greenValue, blueValue );
+    }
+
+// -----------------------------------------------------------------------------
+// NcsUtility::CalculateMsgBodyLineColor
+//
+// Calculates line color to be used in message body. Calculated color is darker than
+// given base color.
+// @param aDegree = color darkening coefficient
+// @param aBaseColor = base color to be used in calculation
+// -----------------------------------------------------------------------------
+//
+TRgb NcsUtility::CalculateMsgBodyLineColor( TInt aDegree,
+                                            TRgb aBaseColor )
+    {
+    TInt redValue = aBaseColor.Red() - ( aBaseColor.Red() / aDegree );
+    TInt greenValue = aBaseColor.Green() - ( aBaseColor.Green() / aDegree );
+    TInt blueValue = aBaseColor.Blue() - ( aBaseColor.Blue() / aDegree );
+
+    if ( redValue < KFSUtilityMinColorValue )
+        {
+        redValue = KFSUtilityMinColorValue;
+        }
+    if ( greenValue < KFSUtilityMinColorValue )
+        {
+        greenValue = KFSUtilityMinColorValue;
+        }
+    if ( blueValue < KFSUtilityMinColorValue )
+        {
+        blueValue = KFSUtilityMinColorValue;
+        }
+
+    return TRgb( redValue , greenValue, blueValue );
+    }
+
+//End of file
+