diff -r 000000000000 -r 8466d47a6819 emailuis/uicomponents/src/fstextviewervisualizer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailuis/uicomponents/src/fstextviewervisualizer.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,2223 @@ +/* +* 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: Implementation of class CFsTextViewerVisualizer +* +*/ + + +// +//#include +#include "emailtrace.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// +#include +#include +//start screen saver +#include +#include +//end screen saver +#include "fsscrollbarset.h" +#include "fsalfscrollbarlayout.h" +#include "fstextviewercoordinator.h" +#include "fstextviewervisualizer.h" +#include "fstextviewercontrol.h" +#include "fstextparser.h" +#include "fsrichtext.h" +#include "fsrichtexttext.h" +#include "fsrichtextsmiley.h" +#include "fsrichtextpicture.h" +#include "fssmileydictionary.h" +#include "fssmileyparser.h" +#include "fstexture.h" +#include "fstextstylemanager.h" +#include "fstextviewervisualizerdata.h" +#include "fstextviewerselectsmanager.h" +#include "fstextviewermarkfacility.h" +#include "fstextviewerskindata.h" +#include "fstextviewerwatermark.h" +#include "fstextviewervisualizer.h" +#include "fstextviewervisualizersettings.h" +#include "fstextureloader.h" +#include "fstextviewerlayouter.h" +#include "fslayoutmanager.h" + +const TInt KMinLettersInNewLine = 3; + +// --------------------------------------------------------------------------- +// TFsTextureObserver::FsTextureEvent +// --------------------------------------------------------------------------- +void TFsTextureObserver::FsTextureEvent( + const TFsTextureEvent& /*aEventType*/, + CFsTexture& /*aTexture*/) + { + FUNC_LOG; + + } + +// --------------------------------------------------------------------------- +// NewL +// --------------------------------------------------------------------------- +CFsTextViewerVisualizer* CFsTextViewerVisualizer::NewL( + CFsTextViewerControl& aControl, + CFsRichText* aRichText, + CFsSmileyDictionary* aSmDict, + CFsTextViewerVisualizerSettings* aSettings ) + { + FUNC_LOG; + CFsTextViewerVisualizer* self = + new (ELeave) CFsTextViewerVisualizer( aSettings ); + CleanupStack::PushL( self ); + self->ConstructL( aControl, aRichText, aSmDict ); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// ~CFsTextViewerVisualizer +// --------------------------------------------------------------------------- +CFsTextViewerVisualizer::~CFsTextViewerVisualizer() + { + FUNC_LOG; + delete iBorder; + iBorder = NULL; + + delete iParser; + iParser = NULL; + + delete iTextureLoader; + iTextureLoader = NULL; + + delete iHelper; + iHelper = NULL; + + delete iLayouter; + iLayouter = NULL; + + delete iNavigator; + iNavigator = NULL; + + delete iSelector; + iSelector = NULL; + + delete iMarkFacility; + iMarkFacility = NULL; + + delete iTextStyleManager; + iTextStyleManager = NULL; + + delete iSkinData; + iSkinData = NULL; + + delete iBackgroundBrush; + iBackgroundBrush = NULL; + + delete iScrollbar; + iScrollbar = NULL; + } + +// --------------------------------------------------------------------------- +// ScrollUpL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ScrollUpL( TInt aOffset /*=EUseDefaultScrollOffset*/, TInt aTime ) + { + FUNC_LOG; + + iRootLayout->SetFlag( EAlfVisualFlagFreezeLayout ); + TInt effectiveOffset = iLineOffset; + if ( aOffset > EUseDefaultScrollOffset ) + { + iLineOffset = aOffset; + } + else + { + if ( iLineOffset > iScrollingOffset ) + { + iLineOffset -= iScrollingOffset; + } + else + { + iLineOffset = 0; + } + } + effectiveOffset -= iLineOffset; + iEffectiveOffset.SetTarget( iLineOffset, aTime != EUseDefaultScrollTime + ? aTime + : iScrollingDelay ); + iNavigator->ScrollAllL( effectiveOffset, aTime != EUseDefaultScrollTime + ? aTime + : iScrollingDelay, iContentLayout ); + + if ( iBackgroundLayout ) + { + TAlfTimedPoint offset; + offset.iY.SetTarget( iLineOffset, aTime != EUseDefaultScrollTime + ? aTime + : iScrollingDelay ); + iBackgroundLayout->SetScrollOffset( offset ); + } + + if ( iMarkingLayout ) + { + for ( TInt i = 0; i < iMarkingLayout->Count(); ++i ) + { + iMarkingLayout->Visual( i ). + Move( TPoint( 0, effectiveOffset ), aTime > EUseDefaultScrollTime + ? aTime + : iScrollingDelay ); + } + } + if ( iCursor ) + { + iCursor->Move( TPoint( 0, effectiveOffset ), iScrollingDelay ); + } + + iRootLayout->ClearFlag( EAlfVisualFlagFreezeLayout ); + + UpdateScrollbarL(); + } + +// --------------------------------------------------------------------------- +// ScrollDownL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ScrollDownL( TInt aOffset /*=EUseDefaultScrollOffset*/, TInt aTime ) + { + FUNC_LOG; + + iRootLayout->SetFlag( EAlfVisualFlagFreezeLayout ); + TAlfRealRect layoutSize = iContentLayout->DisplayRect(); + TInt effectiveOffset = iLineOffset; + TInt maxLineOffset = iTotalHeight - layoutSize.iBr.iY; + + // If offset given, use it. Otherwise scroll one page down. + if ( aOffset > EUseDefaultScrollOffset ) + { + iLineOffset = aOffset; + } + else + { + if ( iLineOffset + iScrollingOffset <= maxLineOffset ) + { + iLineOffset += iScrollingOffset; + } + else + { + iLineOffset = maxLineOffset; + } + } + effectiveOffset -= iLineOffset; + + iNavigator->ScrollAllL( + effectiveOffset, aTime > EUseDefaultScrollTime + ? aTime + : iScrollingDelay, iContentLayout ); + iEffectiveOffset.SetTarget( iLineOffset, aTime > EUseDefaultScrollTime + ? aTime + : iScrollingDelay ); + if ( iBackgroundLayout ) + { +// TAlfTimedPoint offset( iBackgroundLayout->ScrollOffset() ); + TAlfTimedPoint offset; + offset.iY.SetTarget( iLineOffset, aTime > EUseDefaultScrollTime + ? aTime + : iScrollingDelay ); + iBackgroundLayout->SetScrollOffset( offset ); + } + + if ( iMarkingLayout ) + { + for ( TInt i = 0; i < iMarkingLayout->Count(); ++i ) + { + iMarkingLayout->Visual( i ). + Move( TPoint( 0, effectiveOffset ), aTime > + EUseDefaultScrollTime ? + aTime : iScrollingDelay ); + } + } + if ( iCursor ) + { + iCursor->Move( TPoint( 0, effectiveOffset ), iScrollingDelay ); + } + UpdateScrollbarL(); + + iRootLayout->ClearFlag( EAlfVisualFlagFreezeLayout ); + } + +// --------------------------------------------------------------------------- +// PageUpL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::PageUpL( TInt aTime ) + { + FUNC_LOG; + ScrollUpL( iLineOffset - iContentSize.iHeight, aTime ); + } + +// --------------------------------------------------------------------------- +// PageDownL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::PageDownL( TInt aTime ) + { + FUNC_LOG; + if ( iLineOffset + iContentSize.iHeight + > iTotalHeight - iContentSize.iHeight ) + { + ScrollDownL( iTotalHeight - iContentSize.iHeight, aTime ); + } + else + { + ScrollDownL( iLineOffset + iContentSize.iHeight, aTime ); + } + } + +// --------------------------------------------------------------------------- +// NextVisibleHotspot +// --------------------------------------------------------------------------- +TBool CFsTextViewerVisualizer::NextVisibleHotspotL( TBool& aChanged ) + { + FUNC_LOG; + TBool retVal = EFalse; + + retVal = iSelector->MoveNextL( aChanged ); + + return retVal; + } + +// --------------------------------------------------------------------------- +// PrevVisibleHotspot +// --------------------------------------------------------------------------- +TBool CFsTextViewerVisualizer::PrevVisibleHotspotL( TBool& aChanged ) + { + FUNC_LOG; + TBool retVal = EFalse; + + retVal = iSelector->MovePrevL( aChanged ); + + return retVal; + } + +// --------------------------------------------------------------------------- +// MoveLeft +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::MoveLeftL() + { + FUNC_LOG; + iNavigator->MoveToPrevCharL(); + + DrawCursorL( iCursorDelay ); + } + +// --------------------------------------------------------------------------- +// MoveRight +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::MoveRightL() + { + FUNC_LOG; + iNavigator->MoveToNextCharL(); + + DrawCursorL( iCursorDelay ); + } + +// --------------------------------------------------------------------------- +// MoveDownL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::MoveDownL() + { + FUNC_LOG; + if ( iNavigator->GetCursorLine() == iTotalLines ) + { + return; + } + TBool goOn = ETrue; + + TInt currentX = iNavigator->GetCursorRectL().iTl.iX; + TInt currentY = iNavigator->GetCursorRectL().iTl.iY; + + while ( goOn ) + { + if ( !iNavigator->MoveToNextCharL() ) + { + goOn = EFalse; + } + DrawMarkL(); + if ( iNavigator->GetCursorRectL().iTl.iX <= currentX ) + { + goOn = EFalse; + } + } + + TInt currentX2 = iNavigator->GetCursorRectL().iTl.iX; + currentY = iNavigator->GetCursorRectL().iTl.iY; + + goOn = ETrue; + while ( goOn ) + { + currentX2 = iNavigator->GetCursorRectL().iTl.iX; + + if ( !iNavigator->MoveToNextCharL() ) + { + goOn = EFalse; + } + + DrawMarkL(); + + if ( iNavigator->GetCursorRectL().iTl.iX >= currentX || + iNavigator->GetCursorRectL().iTl.iX <= currentX2 ) + { + iNavigator->MoveToPrevCharL(); + DrawMarkL(); + goOn = EFalse; + } + } + + DrawCursorL( iCursorDelay ); + } + +// --------------------------------------------------------------------------- +// MoveUpL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::MoveUpL() + { + FUNC_LOG; + if ( iNavigator->GetCursorLine() == 1 ) + { + return; + } + TBool goOn = ETrue; + + TInt currentX = iNavigator->GetCursorRectL().iTl.iX; + TInt currentY = iNavigator->GetCursorRectL().iTl.iY; + + while ( goOn ) + { + if ( !iNavigator->MoveToPrevCharL() ) + { + goOn = EFalse; + } + DrawMarkL(); + if ( iNavigator->GetCursorRectL().iTl.iY < currentY ) + { + goOn = EFalse; + } + } + + TInt currentX2 = iNavigator->GetCursorRectL().iTl.iX; + currentY = iNavigator->GetCursorRectL().iTl.iY; + + goOn = ETrue; + while ( goOn ) + { + currentX2 = iNavigator->GetCursorRectL().iTl.iX; + + if ( !iNavigator->MoveToPrevCharL() ) + { + goOn = EFalse; + } + DrawMarkL(); + if ( iNavigator->GetCursorRectL().iTl.iX <= currentX || + iNavigator->GetCursorRectL().iTl.iX >= currentX2 ) + { + iNavigator->MoveToNextCharL(); + DrawMarkL(); + goOn = EFalse; + } + } + + DrawCursorL( iCursorDelay ); + } + +// --------------------------------------------------------------------------- +// EnableMark +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::EnableMarkL( TBool aEnabled ) + { + FUNC_LOG; + iMark = aEnabled; + if ( iMark ) + { + if ( iMarkingLayout ) + { + iMarkingLayout->RemoveAndDestroyAllD(); + } + iMarkingLayout = CAlfLayout::AddNewL( *iControl, iRootLayout ); + iMarkFacility->SetLayout( iMarkingLayout ); + iMarkFacility->SetHeadOffsetL( iNavigator->GetCursorCharOffset() ); + } + } + +// --------------------------------------------------------------------------- +// SwitchMark +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SwitchMarkL() + { + FUNC_LOG; + iMark = !iMark; + if ( iMark ) + { + if ( iMarkingLayout ) + { + iMarkingLayout->RemoveAndDestroyAllD(); + } + iMarkingLayout = CAlfLayout::AddNewL( *iControl, iRootLayout ); + iMarkingLayout->SetSize( iContentSize ); + iMarkFacility->SetLayout( iMarkingLayout ); + iMarkFacility->SetHeadOffsetL( iNavigator->GetCursorCharOffset() ); + } + } + +// --------------------------------------------------------------------------- +// MarkEnabled +// --------------------------------------------------------------------------- +TBool CFsTextViewerVisualizer::MarkEnabled() + { + FUNC_LOG; + return iMark; + } + +// --------------------------------------------------------------------------- +// ExpandL +// --------------------------------------------------------------------------- +CAlfLayout* CFsTextViewerVisualizer::ExpandL( + TInt aId, + TInt aStart, + CAlfVisual* aVisual ) + { + FUNC_LOG; + iContentLayout->SetFlag( EAlfVisualFlagFreezeLayout ); + TInt brY = aVisual->DisplayRectTarget().iBr.iY + iContentLayout->ScrollOffset().IntValueNow().iY; + TInt posY = aVisual->Pos().Target().iY; + TInt posX = aVisual->Pos().Target().iX; + iParser->SetExpandStatusL( aId, ETrue ); + CAlfAnchorLayout* expandLayout = + CAlfAnchorLayout::AddNewL( *iControl, iContentLayout ); + + expandLayout->SetFlag( EAlfVisualFlagManualLayout ); + expandLayout->SetClipping(); + TInt end = iParser->GetEndIndexOfExpandAreaL( aId ); + TSize layoutSize = LayoutVisualsL( expandLayout, aStart, end ); + iNavigator->UpdateLinesNumbers(); + iTotalLines = iNavigator->GetTotalLines(); + iSelector->DimAllL(); + + iTotalHeight += layoutSize.iHeight; + + expandLayout->SetPos( TPoint( 0, brY ) ); + expandLayout->SetSize( TSize( 0, 0 ), 0 ); + expandLayout->SetSize( layoutSize, iSettings->iExpandDelay ); + + iNavigator->Sort(); + + iNavigator->ScrollFromCharL( end, layoutSize.iHeight, iSettings->iExpandDelay, iContentLayout ); // leaving + + if ( iNavigator->GetCursorCharOffset() >= end ) + { + TRect target = iCursor->DisplayRectTarget(); + target.Move( 0, layoutSize.iHeight ); + iCursor->SetRect( target, iSettings->iExpandDelay ); + } + + UpdateScrollbarL(); + TFsVisRange range; + range.iStart = aStart; + range.iEnd = end; + iNavigator->AppendLayoutL( + static_cast( expandLayout ), range ); + iContentLayout->ClearFlag( EAlfVisualFlagFreezeLayout ); + return expandLayout; + } + +// --------------------------------------------------------------------------- +// ExpandExisting +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ExpandExistingL( + CAlfLayout* aLayout, + TSize aTargetSize, TInt aId ) + { + FUNC_LOG; + TSize layoutSize = aTargetSize; + TInt end = iParser->GetEndIndexOfExpandAreaL( aId ); + + aLayout->SetSize( aTargetSize, iSettings->iExpandDelay ); + + iNavigator->ScrollFromCharL( end, layoutSize.iHeight, iSettings->iExpandDelay, iContentLayout ); // leaving + + for ( TInt i = 0; i < aLayout->Count(); ++i ) + { + iNavigator->EnableVisual( &aLayout->Visual( i ) ); + } + + if ( iNavigator->GetCursorCharOffset() >= end ) + { + TRect target = iCursor->DisplayRectTarget(); + target.Move( 0, layoutSize.iHeight ); + iCursor->SetRect( target, iSettings->iExpandDelay ); + } + + iTotalHeight += layoutSize.iHeight; + + iNavigator->Sort(); + + UpdateScrollbarL(); + + iNavigator->UpdateLinesNumbers(); + iTotalLines = iNavigator->GetTotalLines(); + + RefreshPartBgsL(); + } + +// --------------------------------------------------------------------------- +// Collapse +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::CollapseL( CAlfLayout* aLayout, TInt aId ) + { + FUNC_LOG; + TRect target = aLayout->DisplayRectTarget(); + + TInt start = iParser->GetStartIndexOfExpandAreaL( aId ); + TInt end = iParser->GetEndIndexOfExpandAreaL( aId ); + TInt caption = iParser->GetBodyIndexOfExpandAreaL ( aId ); + + TSize layoutSize = TSize( + aLayout->Size().Target().iX, + aLayout->Size().Target().iY ); + + aLayout->SetSize( TSize( 0, 0 ) ); + + iNavigator->ScrollFromCharL( end, layoutSize.iHeight * -1, iSettings->iExpandDelay, iContentLayout );// leaving + + for ( TInt i = 0; i < aLayout->Count(); ++i ) + { + iNavigator->EnableVisual( &aLayout->Visual( i ), EFalse ); + } + + if ( iNavigator->GetCursorCharOffset() >= start + && iNavigator->GetCursorCharOffset() <= end ) + { + iNavigator->MoveToPrevCharL(); + iNavigator->MoveToNextCharL(); + DrawCursorL( iSettings->iExpandDelay ); + } + else if ( iNavigator->GetCursorCharOffset() > end ) + { + target = iCursor->DisplayRectTarget(); + target.Move( 0, -1 * layoutSize.iHeight ); + iCursor->SetRect( target, iSettings->iExpandDelay ); + } + + iTotalHeight -= layoutSize.iHeight; + + iNavigator->Sort(); + + RefreshPartBgsL(); + + iNavigator->UpdateLinesNumbers(); + iTotalLines = iNavigator->GetTotalLines(); + + UpdateScrollbarL(); + } + +// --------------------------------------------------------------------------- +// LayoutVisualsL +// --------------------------------------------------------------------------- +TSize CFsTextViewerVisualizer::LayoutVisualsL( + CAlfLayout* aLayout, + TInt aStart, + TInt aEnd ) + { + FUNC_LOG; + TInt backupLineOffset = iLayouter->GetCurrentLineOffset(); + iLayouter->SetCurrentLineOffset( 0 ); + iParser->SetParsingPosition( aStart + 10 ); + TInt currentEnd = 0; + + TBidiText::TDirectionality direction; + TBidiText::TDirectionality lastDirection; + + if ( iSettings->iMirroring ) + { + direction = TBidiText::ERightToLeft; + } + else + { + direction = TBidiText::ELeftToRight; + } + lastDirection = direction; + + MFsRichTextObject* object = NULL; + iLayouter->ConstructLineL( 1 ); + while ( iParser->IsNextObject() && currentEnd <= aEnd ) + { + if ( object ) + { + delete object; + object = NULL; + } + object = iParser->GetNextObjectL(); + currentEnd = object->GetEndOfObject(); + if ( object->GetType() == MFsRichTextObject::EFsNewLine ) + { + TCharFormat charFormat; + TCharFormatMask charFormatMask; + iCFsRichText->GetSpecificCharFormat( charFormat, charFormatMask, object->GetBeginOfObject() ); + TInt styleId; + styleId = iTextStyleManager->GetStyleIDL( charFormat ); + CFont* font; + User::LeaveIfNull( iScreenDev ); + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( styleId ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( font, fontSpec ) ); + TInt height; + height = font->HeightInPixels(); + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + + iLayouter->ConstructLineL( height ); + lastDirection = direction; + } + else + { + if ( ( object->GetType() == MFsRichTextObject::EFsText + || object->GetType() == MFsRichTextObject::EFsSmiley ) + && static_cast(object)->GetTextDirection() != direction + && lastDirection != direction ) + { + iLayouter->InsertObjectL( object, aLayout, iParser, EFalse ); + } + else + { + iLayouter->AppendObjectL( object, aLayout, iParser, EFalse ); + } + if ( object->GetType() == MFsRichTextObject::EFsText ) + { + lastDirection = static_cast(object)->GetTextDirection(); + } + } + } + + iLayouter->ConstructLineL(); + + if ( object ) + { + delete object; + object = NULL; + } + + iNavigator->ScrollAllL( 0, 0, iContentLayout ); + + TSize retVal; + retVal = TSize( iContentLayout->Size().Target().iX, iLayouter->GetCurrentLineOffset() ); + iLayouter->SetCurrentLineOffset( backupLineOffset ); + return retVal; + } + +// --------------------------------------------------------------------------- +// Navigator +// --------------------------------------------------------------------------- +CFsTextViewerVisualizerData* CFsTextViewerVisualizer::Navigator() + { + FUNC_LOG; + return iNavigator; + } + +// --------------------------------------------------------------------------- +// Parser +// --------------------------------------------------------------------------- +CFsTextParser* CFsTextViewerVisualizer::Parser() + { + FUNC_LOG; + return iParser; + } + +// --------------------------------------------------------------------------- +// Clicked +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ClickedL() + { + FUNC_LOG; + iSelector->ClickedL(); + } + +TBool CFsTextViewerVisualizer::SmileysEnabled() + { + FUNC_LOG; + return iSmileyEnabled; + } + +// --------------------------------------------------------------------------- +// IsHotspotHighlighted +// --------------------------------------------------------------------------- +TBool CFsTextViewerVisualizer::IsHotspotHighlighted() + { + FUNC_LOG; + return iSelector->IsHotspotHighlighted(); + } + +// --------------------------------------------------------------------------- +// EnableSmileys +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::EnableSmileys( TBool aStatus ) + { + FUNC_LOG; + iSmileyEnabled = aStatus; + } + +// --------------------------------------------------------------------------- +// SetScrollOffsetInPx +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetScrollOffsetInPx( TInt aPxOffset ) + { + FUNC_LOG; + iScrollingOffset = aPxOffset; + } + +// --------------------------------------------------------------------------- +// SetScrollOffsetInLines +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetScrollOffsetInLines( TInt aLineOffset ) + { + FUNC_LOG; + TInt lineHeight = iControl->Env().TextStyleManager().TextStyle( + EAlfTextStyleNormal )->TextSizeInPixels(); + iScrollingOffset = aLineOffset * lineHeight; + } + +// --------------------------------------------------------------------------- +// SetSmileySize +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetSmileySize( TSize aSize ) + { + FUNC_LOG; + iParser->SetSizeOfSmile( aSize ); + } + +// --------------------------------------------------------------------------- +// SetScrollDelay +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetScrollDelay( TInt aDelay ) + { + FUNC_LOG; + iScrollingDelay = aDelay; + } + +// --------------------------------------------------------------------------- +// SetCursorDelay +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetCursorDelay( TInt aDelay ) + { + FUNC_LOG; + iCursorDelay = aDelay; + } + +// --------------------------------------------------------------------------- +// Reset +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::Reset() + { + FUNC_LOG; + iLineOffset = 0; + + delete iSkinData; + iSkinData = NULL; + + delete iLayouter; + iLayouter = NULL; + + delete iBorder; + iBorder = NULL; + + delete iHelper; + iHelper = NULL; + + delete iNavigator; + iNavigator = NULL; + + delete iSelector; + iSelector = NULL; + + delete iMarkFacility; + iMarkFacility = NULL; + + delete iScrollbar; + iScrollbar = NULL; + } + +// --------------------------------------------------------------------------- +// ReloadL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ReloadL() + { + FUNC_LOG; + TInt currentLength = iCFsRichText->DocumentLength(); + + TInt lastCursorPosition = 0; + + if( iCursor ) + { + lastCursorPosition = iNavigator->GetCursorCharOffset(); + } + + if ( iRichTextLength == currentLength ) + { + Reset(); + iParser->ParseTextL(); + iParser->SetParsingPosition( 0 ); + ConstructSelfL( iCFsRichText, iSmileyDict, EFalse ); + ConstructVisualsL(); + iNavigator->Sort(); + iSelector->DimAllL(); + iRichTextLength = currentLength; + } + else + { + iParser->ParseTextL(); + iParser->SetParsingPosition( iRichTextLength ); + iRichTextLength = currentLength; + + ConstructVisualsL( EFalse ); + iNavigator->UpdateLinesNumbers(); + iNavigator->Sort(); + } + UpdateScrollbarL(); + + if ( !iCursor ) + { + iCursor = CAlfImageVisual::AddNewL( *iControl, iRootLayout ); + iCursor->SetFlag( EAlfVisualFlagManualLayout ); + iCursor->EnableBrushesL(); + iCursor->Brushes()->AppendL( iBorder, EAlfDoesNotHaveOwnership ); + iCursor->SetRect( TRect( 0, 0, 0, 0 ) ); + + while ( lastCursorPosition > iNavigator->GetCursorCharOffset() ) + { + iNavigator->MoveToNextCharL(); + } + + DrawCursorL(0); + } + } + +// --------------------------------------------------------------------------- +// GetMarkedRange +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::GetMarkedRange( TInt& aBegin, TInt& aEnd ) + { + FUNC_LOG; + TInt begin = 0; + TInt end = 0; + iMarkFacility->GetRange( begin, end ); + aBegin = begin; + aEnd = end; + } + +// --------------------------------------------------------------------------- +// GetHotspotRange +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::GetHotspotRangeL( TInt& aBegin, TInt& aEnd ) + { + FUNC_LOG; + TInt id = iSelector->GetCurrentSelectId(); + + if ( 0 <= id ) + { + aBegin = iParser->GetStartIndexOfHotSpotAreaL( id, ETrue ); + aEnd = iParser->GetEndIndexOfHotSpotAreaL( id, ETrue ); + } + else + { + aBegin = 0; + aEnd = 0; + } + } + +// --------------------------------------------------------------------------- +// CalculateSizeL +// --------------------------------------------------------------------------- +TSize CFsTextViewerVisualizer::CalculateSizeL( MFsRichTextObject* aObject ) + { + FUNC_LOG; + TSize retVal; + + switch ( aObject->GetType() ) + { + case MFsRichTextObject::EFsText: + { + CFont* font; + User::LeaveIfNull(iScreenDev); + + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( + static_cast( aObject )->GetStyleId() + ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( font, fontSpec ) ); + + retVal = TSize( + font->TextWidthInPixels( + static_cast(aObject)->GetText() ), + font->FontMaxHeight() ); + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + break; + } + case MFsRichTextObject::EFsTexture: + { + retVal = static_cast + (aObject)->GetTextureSize(); + break; + } + case MFsRichTextObject::EFsSmiley: + { + if ( iSmileyEnabled ) + { + retVal = static_cast + (aObject)->GetPictureObject()->GetTextureSize(); + } + else + { + CFont* font; + CFsRichTextText* object = + static_cast + (aObject)->GetTextObject(); + User::LeaveIfNull(iScreenDev); + + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( + object->GetStyleId() ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( font, fontSpec ) ); + + retVal = TSize( + font->TextWidthInPixels( object->GetText() ), + font->FontMaxHeight() ); + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + break; + } + } + default: + { + break; + } + } + + return retVal; + } + +// --------------------------------------------------------------------------- +// CalculateWidthL +// --------------------------------------------------------------------------- +TInt CFsTextViewerVisualizer::CalculateWidthL( + const TDesC& aText, + TInt aTextStyleId ) + { + FUNC_LOG; + TInt retVal; + + CFont* font; + User::LeaveIfNull( iScreenDev ); + + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( aTextStyleId ) ); + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( + font, + TFontSpec( *typeface, textStyle->TextSizeInTwips() ) ) ); + + retVal = font->TextWidthInPixels( aText ); + + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + + return retVal; + } + +// --------------------------------------------------------------------------- +// SetWatermark +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetWatermarkL( + CFsTextViewerWatermark* aWatermark ) + { + FUNC_LOG; + iWatermark = aWatermark; + if ( iRootLayout ) + { + iRootLayout->SetFlag( EAlfVisualFlagManualLayout ); + iWatermarkVisual = CAlfImageVisual::AddNewL( *iControl, iRootLayout ); + iWatermarkVisual->SetFlag( EAlfVisualFlagManualLayout ); + iWatermarkVisual->SetImage( TAlfImage( iWatermark->Texture() ) ); + iWatermarkVisual->SetScaleMode( CAlfImageVisual::EScaleFit ); + iWatermarkVisual->SetSize( TSize( + iWatermark->Rect().Height(), + iWatermark->Rect().Width() ) ); + iWatermarkVisual->SetPos( iWatermark->Rect().iTl ); + iWatermarkVisual->SetOpacity( iWatermark->Opacity() ); + iContentLayout->MoveToFront(); + } + } + + +// --------------------------------------------------------------------------- +// RootLayout +// --------------------------------------------------------------------------- +CAlfLayout* CFsTextViewerVisualizer::RootLayout() + { + FUNC_LOG; + return iRootLayout; + } + +// --------------------------------------------------------------------------- +// SetBackgroundColor +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetBackgroundColorL( const TRgb& aColor ) + { + FUNC_LOG; + if ( iBackgroundBrush ) + { + for ( TInt i = 0; i < iRootLayout->Brushes()->Count(); ++i ) + { + if ( &iRootLayout->Brushes()->At( i ) == iBackgroundBrush ) + { + iRootLayout->Brushes()->Remove( i ); + } + } + delete iBackgroundBrush; + iBackgroundBrush = NULL; + } + iBackgroundBrush = CAlfGradientBrush::NewL( *iEnv ); + CAlfGradientBrush* brush = + static_cast( iBackgroundBrush ); + brush->SetLayer( EAlfBrushLayerBackground ); + brush->SetColor( aColor ); + brush->SetOpacity( iSettings->iBackgroundOpacity ); + iRootLayout->EnableBrushesL(); + iRootLayout->Brushes()->AppendL( brush, EAlfDoesNotHaveOwnership ); + } + +// --------------------------------------------------------------------------- +// SetBackgroundImage +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetBackgroundImageL( CAlfTexture& aTexture ) + { + FUNC_LOG; + if ( iBackgroundBrush ) + { + for ( TInt i = 0; i < iRootLayout->Brushes()->Count(); ++i ) + { + if ( &iRootLayout->Brushes()->At( i ) == iBackgroundBrush ) + { + iRootLayout->Brushes()->Remove( i ); + } + } + delete iBackgroundBrush; + iBackgroundBrush = NULL; + } + iBackgroundBrush = CAlfImageBrush::NewL( *iEnv, TAlfImage( aTexture ) ); + iBackgroundBrush->SetLayer( EAlfBrushLayerBackground ); + iBackgroundBrush->SetOpacity( iSettings->iBackgroundOpacity ); + iRootLayout->EnableBrushesL(); + iRootLayout->Brushes()->AppendL( + iBackgroundBrush, + EAlfDoesNotHaveOwnership ); + } + +// --------------------------------------------------------------------------- +// SetBackgroundOpacity +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetBackgroundOpacity() + { + FUNC_LOG; + if ( iBackgroundBrush ) + { + iBackgroundBrush->SetOpacity( iSettings->iBackgroundOpacity ); + } + } + +// --------------------------------------------------------------------------- +// RefreshPartBgs +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::RefreshPartBgsL() + { + FUNC_LOG; + iNavigator->ResetBgArray(); + if ( iIsLayouted ) + { + RedrawPartBgsL(); + } + } + +// --------------------------------------------------------------------------- +// RedrawPartBgs +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::RedrawPartBgsL() + { + FUNC_LOG; + for ( TInt i = 0; i < iSettings->iPartBgs.Count(); ++i ) + { + TFsPartBgVisual background; + background.iRect.iTl = + iNavigator->GetVisualPos( iSettings->iPartBgs[i].iStart ).iTl; + background.iRect.iBr + = iNavigator->GetVisualPos( iSettings->iPartBgs[i].iEnd ).iBr; + background.iRect.iTl.iX = 0; + background.iRect.iBr.iX = + iDisplaySize.iWidth + + iSettings->iLeftMargin + + iSettings->iRightMargin; + background.iVisual = STATIC_CAST(CAlfVisual*, iControl->AppendVisualL(EAlfVisualTypeVisual,iBackgroundLayout)); + background.iVisual->EnableBrushesL(); + background.iVisual->Brushes()->AppendL( + iSettings->iPartBgs[i].iBrush, + EAlfDoesNotHaveOwnership ); + background.iVisual->SetRect( background.iRect ); + iNavigator->AppendBgL( background ); + } + } + +// --------------------------------------------------------------------------- +// Control +// --------------------------------------------------------------------------- +CAlfControl* CFsTextViewerVisualizer::Control() + { + FUNC_LOG; + return iControl; + } + +// --------------------------------------------------------------------------- +// StackLayout +// --------------------------------------------------------------------------- +CAlfLayout* CFsTextViewerVisualizer::StackLayout() + { + FUNC_LOG; + return iRootLayout; + } + +// --------------------------------------------------------------------------- +// BackgroundLayout +// --------------------------------------------------------------------------- +CAlfLayout* CFsTextViewerVisualizer::BackgroundLayout() + { + FUNC_LOG; + return iBackgroundLayout; + } + +// --------------------------------------------------------------------------- +// RemoveEndLines +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::RemoveEndLinesL( TInt aLines ) + { + FUNC_LOG; + TInt cutCharIndex = iNavigator->RemoveFromLineL( + iTotalLines - aLines + 1, + iHelper ); + + iNavigator->Sort(); + iNavigator->UpdateLinesNumbers(); + iTotalLines = iNavigator->GetTotalLines(); + iTotalHeight = iNavigator->GetTotalHeight(); + iLayouter->SetPosition( iTotalLines, iTotalHeight ); + UpdateScrollbarL(); + + iCFsRichText->DeleteL( + cutCharIndex, + iCFsRichText->DocumentLength() - cutCharIndex ); + iRichTextLength = iCFsRichText->DocumentLength(); + + delete iParser; + iParser = NULL; + + iParser = CFsTextParser::NewL( + *iCFsRichText, + iControl->Env(), + iTextureLoader ); + iParser->SetSizeOfSmile( TSize( 20,20 ) ); + iParser->SetTextStylemanager(iTextStyleManager); + + iNavigator->SetParser( iParser ); + + if ( iSmileyDict ) + { + CFsSmileyParser* smParser = CFsSmileyParser::NewL(); + smParser->SetSmileyDictionary( iSmileyDict ); + iParser->SetSmileyParser(smParser); + } + + iParser->ParseTextL(); + + if ( iCursor ) + { + DrawCursorL( 0 ); + } + } + +// --------------------------------------------------------------------------- +// ReplaceTextL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ReplaceTextL( + CFsRichText* aRichText, + CFsSmileyDictionary* aSmDict ) + { + FUNC_LOG; + if ( 0 == aRichText->DocumentLength() ) + { + return; + } + + TInt lineOffset = iLineOffset; + + Reset(); + + delete iParser; + iParser = NULL; + + iCFsRichText = aRichText; + _LIT(oneSpace, " "); + + aRichText->InsertL( aRichText->DocumentLength() , oneSpace ); + iLineOffset = 0; + ConstructSelfL( aRichText, aSmDict ? aSmDict : iSmileyDict ); + iParser->ParseTextL(); + iRichTextLength = aRichText->DocumentLength(); + + ConstructVisualsL(); + iNavigator->Sort(); + iSelector->DimAllL(); + + if ( lineOffset > iTotalHeight - iContentSize.iHeight ) + { + lineOffset = iTotalHeight - iContentSize.iHeight; + } + ScrollUpL( lineOffset, 0 ); + } + +// --------------------------------------------------------------------------- +// FocusLineL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::FocusLineL( TInt aLine, TBool aShowAsFirstLine ) + { + FUNC_LOG; + + TInt totalLines = iNavigator->GetTotalLines(); + + if( aLine > totalLines ) + { + aLine = totalLines; + } + + TInt firstVisible = iNavigator->GetFirstVisible()->iLineNumber; + TInt lastVisible = iNavigator->GetLastVisible()->iLineNumber; + + TInt targetLineOffset = iNavigator->GetLineOffset( aLine ); + + if ( aShowAsFirstLine && aLine <= lastVisible && aLine >= firstVisible ) + { + if ( iLineOffset + + targetLineOffset + > iTotalHeight - iContentSize.iHeight ) + { + ScrollDownL( iTotalHeight - iContentSize.iHeight, 0 ); + } + else + { + ScrollDownL( iLineOffset + + targetLineOffset, + 0 ); + } + } + else if ( aLine == 1 ) + { + ScrollUpL( 1, 0 ); + } + else if ( aLine > lastVisible ) + { + if ( iLineOffset + + targetLineOffset + > iTotalHeight - iContentSize.iHeight ) + { + ScrollDownL( iTotalHeight - iContentSize.iHeight, 0 ); + } + else + { + ScrollDownL( + iLineOffset + + targetLineOffset, 0 ); + } + } + else if ( aLine < firstVisible ) + { + ScrollUpL( + iLineOffset + + targetLineOffset, 0 ); + } + + iNavigator->FindAndHighlightHotspotL( aLine ); + } + +// --------------------------------------------------------------------------- +// UpdateDisplaySize +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::UpdateDisplaySize() + { + FUNC_LOG; + + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect ); + iDisplaySize = mainPaneRect.Size(); + + // Submit iContentLayout's size as display size for external classes, as + // it's the actual area where viewer content is drawn (excluding e.g. + // scroll bar area), so that's what should be used in most cases. + iContentSize = iContentLayout->Size().IntTarget().AsSize(); + + // Set helper display size before subtracting the margins, as helper + // takes account also the margins in it's own calculations + iHelper->SetSize( iContentSize ); + iHelper->SetLeftMargin( iSettings->iLeftMargin ); + iHelper->SetRightMargin( iSettings->iRightMargin ); + + iContentSize.iWidth -= iSettings->iLeftMargin; + iContentSize.iWidth -= iSettings->iRightMargin; + + iLayouter->SetDisplaySize( iContentSize ); + iLayouter->SetMargins( iSettings->iLeftMargin, iSettings->iRightMargin ); + iNavigator->SetScreenHeight( iContentSize.iHeight ); + } + +// --------------------------------------------------------------------------- +// ReloadPicturesL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ReloadPicturesL( TInt aLine ) + { + FUNC_LOG; + iParser->ParseTextL(); + iNavigator->ReloadPicturesL( aLine ); + } + +// --------------------------------------------------------------------------- +// GetVisibleFocusedHotspotLine +// --------------------------------------------------------------------------- +TBool CFsTextViewerVisualizer::GetVisibleFocusedHotspotLine( + TInt& aLineNum ) const + { + FUNC_LOG; + TBool retVal = EFalse; + + if ( iSelector->IsCurrentHotspotVisible() ) + { + aLineNum = iSelector->GetCurrentHotspotLine() + 1; + retVal = ETrue; + } + + return retVal; + } + +// --------------------------------------------------------------------------- +// SetCurrentHotspotByOrderL +// --------------------------------------------------------------------------- +// +void CFsTextViewerVisualizer::SetCurrentHotspotByOrderL( TInt aIndex, TBool aFocusLine ) + { + FUNC_LOG; + + iSelector->SelectByIndexL( aIndex ); + if (aFocusLine) + { + FocusLineL(iSelector->GetCurrentHotspotLine(), EFalse); + iSelector->SelectByIndexL( aIndex ); + } + } +// + +// --------------------------------------------------------------------------- +// SetCurrentHotspotByCharL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::SetCurrentHotspotByCharL( TInt aIndex ) + { + FUNC_LOG; + if ( aIndex >= 0 ) + { + iSelector->SelectByCharL( aIndex ); + } + } + +// --------------------------------------------------------------------------- +// GetStatusLayout +// --------------------------------------------------------------------------- +CAlfLayout* CFsTextViewerVisualizer::GetStatusLayout() + { + FUNC_LOG; + return iStatusLineLayout; + } + +// --------------------------------------------------------------------------- +// UpdateStatusLayout +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::UpdateStatusLayout() + { + FUNC_LOG; + if ( !iStatusLineLayout ) + { + // + TRAPD( err, iStatusLineLayout = CAlfAnchorLayout::AddNewL( *iControl, iContentLayout ) ); // Modified + if ( err != KErrNone ) + { + return; // debug printing of error + } + // + iStatusLineLayout->SetClipping( ETrue ); + iStatusLineLayout->SetSize( TSize( 0, 0 ) ); + iStatusLineLayout->SetFlag( EAlfVisualFlagManualLayout ); + } + iNavigator->SetStatusLineLayout( iStatusLineLayout ); + iTotalHeight = iNavigator->GetTotalHeight(); + // + TRAP_IGNORE( iNavigator->ScrollAllL( 0, 0, iContentLayout ) ); + // + } + +// --------------------------------------------------------------------------- +// RemoveStatusLayout +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::RemoveStatusLayout() + { + FUNC_LOG; + iStatusLineLayout->RemoveAndDestroyAllD(); + // + TRAPD( err, iStatusLineLayout = CAlfAnchorLayout::AddNewL( *iControl, iContentLayout ) ); // Modified + if ( err != KErrNone ) + { + return; //debug printing of error + } + // + + iStatusLineLayout->SetClipping( ETrue ); + iStatusLineLayout->SetSize( TSize( 0, 0 ) ); + iStatusLineLayout->SetFlag( EAlfVisualFlagManualLayout ); + + iNavigator->SetStatusLineLayout( iStatusLineLayout ); + iTotalHeight = iNavigator->GetTotalHeight(); + // + TRAP_IGNORE( iNavigator->ScrollAllL( 0, 0, iContentLayout ) ); + // + } + +// --------------------------------------------------------------------------- +// GetCurrentHotspotTextL +// --------------------------------------------------------------------------- +HBufC* CFsTextViewerVisualizer::GetCurrentHotspotTextL() + { + FUNC_LOG; + HBufC* retVal = NULL; + + TInt id = iSelector->GetCurrentSelectId(); + TInt begin = 0; + TInt end = 0; + + if ( 0 <= id ) + { + begin = iParser->GetStartIndexOfHotSpotAreaL( id, EFalse ); + end = iParser->GetEndIndexOfHotSpotAreaL( id, EFalse ); + } + + if ( begin >= 0 && end >= begin ) + { + retVal = iParser->GetTextL( begin, end ); + } + + return retVal; + } + +// +TInt CFsTextViewerVisualizer::GetCurrentHotspotByOrder() + { + return iSelector->GetCurrentSelectedIndex(); + } +// + +CAknDoubleSpanScrollBar* CFsTextViewerVisualizer::GetScrollBar() + { + return iScrollbar; + } + +// --------------------------------------------------------------------------- +// ConstructL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ConstructL( + CFsTextViewerControl& aControl, + CFsRichText* aRichText, + CFsSmileyDictionary* aSmDict ) + { + FUNC_LOG; + iControl = &aControl; + iEnv = &iControl->Env(); + + InitDefaultsL(); + + if ( 0 == aRichText->DocumentLength() ) + { + return; + } + iCFsRichText = aRichText; + + _LIT(oneSpace, " "); + aRichText->InsertL( aRichText->DocumentLength() , oneSpace ); + + ConstructSelfL( aRichText, aSmDict ); + iParser->ParseTextL(); + iRichTextLength = aRichText->DocumentLength(); + + ConstructVisualsL(); + iNavigator->Sort(); + iSelector->DimAllL(); + } + +// --------------------------------------------------------------------------- +// CFsTextViewerVisualizer +// --------------------------------------------------------------------------- +CFsTextViewerVisualizer::CFsTextViewerVisualizer( + CFsTextViewerVisualizerSettings* aSettings ) + : iSettings( aSettings ), + iIsLayouted( EFalse ) + { + FUNC_LOG; + } + +// --------------------------------------------------------------------------- +// ConstructVisualsL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ConstructVisualsL( + TBool aRefreshBg ) + { + const TInt KDisableScreensaver = 1; + const TInt KEnableScreensaver = 0; + + //screen saver off + User::ResetInactivityTime(); + TInt error=RProperty::Set(KPSUidScreenSaver,KScreenSaverAllowScreenSaver,KDisableScreensaver); + //end + FUNC_LOG; + UpdateDisplaySize(); + iLayouter->EnableSmileys( iSmileyEnabled ); + + MFsRichTextObject* object = NULL; + + while ( iParser->IsNextObject() ) + { + if ( object ) + { + delete object; + object = NULL; + } + object = iParser->GetNextObjectL(); + if( !object ) continue; + iLayouter->ChangeDirection( iParser->GetParagraphDirection( object->GetBeginOfObject() ) ); + if ( iLayouter->IsNewLine() ) + { + if ( object->GetType() == MFsRichTextObject::EFsText ) + { + if ( static_cast(object)->GetTextDirection() == TBidiText::ERightToLeft ) + { + iLayouter->SetDirection( TBidiText::ERightToLeft ); + } + } + } + + if ( object->GetType() == MFsRichTextObject::EFsNewLine ) + { + TCharFormat charFormat; + TCharFormatMask charFormatMask; + iCFsRichText->GetSpecificCharFormat( charFormat, charFormatMask, object->GetBeginOfObject() ); + TInt styleId; + styleId = iTextStyleManager->GetStyleIDL( charFormat ); + CFont* font; + User::LeaveIfNull( iScreenDev ); + CAlfTextStyle* textStyle( + iEnv->TextStyleManager().TextStyle( styleId ) ); + + HBufC* typeface( textStyle->TypefaceNameL() ); + CleanupStack::PushL( typeface ); + TFontSpec fontSpec( *typeface, textStyle->TextSizeInTwips() ); + + User::LeaveIfError( + iScreenDev->GetNearestFontInTwips( font, fontSpec ) ); + TInt height; + height = font->HeightInPixels(); + iScreenDev->ReleaseFont( font ); + CleanupStack::PopAndDestroy( typeface ); + + iLayouter->ConstructLineL( height ); + } + else + { + iLayouter->AppendObjectL( object, iContentLayout, iParser ); + } + } + + iLayouter->ConstructLineL(); + + if ( object ) + { + delete object; + object = NULL; + } + + iNavigator->ScrollAllL( 0, 0, iContentLayout ); + iNavigator->RegisterHotspotsL(); + iTotalHeight = iNavigator->GetTotalHeight(); + iTotalLines = iLayouter->Lines(); + iIsLayouted = ETrue; + + if ( aRefreshBg ) + { + RefreshPartBgsL(); + } + //screen saver on + error=RProperty::Set(KPSUidScreenSaver,KScreenSaverAllowScreenSaver,KEnableScreensaver); + //end + } + + +// --------------------------------------------------------------------------- +// PrepareRangedVisL +// --------------------------------------------------------------------------- +TFsRangedVisual CFsTextViewerVisualizer::PrepareRangedVisL( + MFsRichTextObject* aObject, CAlfLayout* aLayout ) + { + FUNC_LOG; + TFsRangedVisual retVal; + retVal.iVisual = NULL; + retVal.iHotspot = EFalse; + retVal.iEmbed = EFalse; + + switch ( aObject->GetType() ) + { + case MFsRichTextObject::EFsText: + { + retVal.iStart = aObject->GetBeginOfObject(); + retVal.iEnd = aObject->GetEndOfObject(); + retVal.iIsActive = ETrue; + retVal.iLayout = aLayout; + retVal.iIsText = ETrue; + retVal.iTextColor = + static_cast(aObject)->GetTextColor(); + break; + } + case MFsRichTextObject::EFsTexture: + { + retVal.iStart = aObject->GetBeginOfObject(); + retVal.iEnd = aObject->GetEndOfObject(); + retVal.iIsActive = ETrue; + retVal.iLayout = aLayout; + retVal.iIsText = EFalse; + break; + } + case MFsRichTextObject::EFsSmiley: + { + if ( iSmileyEnabled ) + { + retVal.iStart = aObject->GetBeginOfObject(); + retVal.iEnd = aObject->GetEndOfObject(); + retVal.iIsActive = ETrue; + retVal.iLayout = aLayout; + retVal.iIsText = EFalse; + } + else + { + retVal.iStart = aObject->GetBeginOfObject(); + retVal.iEnd = aObject->GetEndOfObject(); + retVal.iIsActive = ETrue; + retVal.iLayout = aLayout; + retVal.iIsText = ETrue; + } + break; + } + case MFsRichTextObject::EFsNewLine: + { + break; + } + default: + { + break; + } + } + + if ( retVal.iIsActive ) + { + if ( aObject->GetEmbeded() && aLayout == iContentLayout ) + { + retVal.iId = aObject->GetIdOfEmbeded(); + retVal.iEmbed = ETrue; + } + if ( aObject->GetHotSpot() ) + { + retVal.iHotspotType = aObject->GetTypeOfHotSpot(); + retVal.iId = aObject->GetIdOfHotSpot(); + retVal.iHotspot = ETrue; + } + } + + return retVal; + } + +// --------------------------------------------------------------------------- +// DrawCursor +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::DrawCursorL( TInt aTime ) + { + FUNC_LOG; + if ( !iCursor ) + { + iCursor = CAlfImageVisual::AddNewL( *iControl, iRootLayout ); + iCursor->SetFlag( EAlfVisualFlagManualLayout ); + iCursor->EnableBrushesL(); + iCursor->Brushes()->AppendL( iBorder, EAlfDoesNotHaveOwnership ); + iCursor->SetRect( TRect( 0, 0, 0, 0 ) ); + } + + if ( iMark ) + { + DrawMarkL( aTime ); + } + + TRect target = iNavigator->GetCursorRectL(); + target.iBr.iX = target.iTl.iX; + + iCursor->SetRect( target, aTime ); + + if ( target.iTl.iY < 0 ) + { + ScrollUpL( iLineOffset + target.iTl.iY, 0 ); + } + else if ( target.iBr.iY > iContentSize.iHeight ) + { + ScrollDownL( iLineOffset + target.iBr.iY - iContentSize.iHeight, 0 ); + } + } + +// --------------------------------------------------------------------------- +// DrawMark +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::DrawMarkL( TInt /* aTime */ ) + { + FUNC_LOG; + if ( iMark ) + { + iMarkFacility->FollowCursorL(); + } + } + +// --------------------------------------------------------------------------- +// InitDefaultsL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::InitDefaultsL() + { + FUNC_LOG; + iScrollingOffset = iSettings->iScrollingOffset; + iCursorDelay = iSettings->iCursorDelay; + iScrollingDelay = iSettings->iScrollingDelay; + iExpandDelay = iSettings->iExpandDelay; + iMark = EFalse; + iCursorEnabled = ETrue; + iSmileyEnabled = ETrue; + iLineOffset = 0; + iSmileyDict = NULL; + } + +// --------------------------------------------------------------------------- +// ConstructSelfL +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::ConstructSelfL( + CFsRichText* aRichText, + CFsSmileyDictionary* aSmDict, + TBool aNew ) + { + FUNC_LOG; + iSkinData = CFsTextViewerSkinData::NewL(); + + iBorder = CAlfBorderBrush::NewL( *iEnv, 1, 1, 0, 0 ); + iBorder->SetColor( iSkinData->iCursorColor ); + + iRootLayout = CAlfDeckLayout::AddNewL( *iControl ); + iRootLayout->SetFlag( EAlfVisualChanged ); + + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect ); + iDisplaySize = mainPaneRect.Size(); + + iRootLayout->SetSize( iDisplaySize ); + iRootLayout->SetFlag( EAlfVisualFlagManualLayout ); + + if ( iBackgroundBrush ) + { + iRootLayout->EnableBrushesL(); + iRootLayout->Brushes()->AppendL( + iBackgroundBrush, + EAlfDoesNotHaveOwnership ); + } + + if ( iWatermark ) + { + if ( iWatermarkVisual ) + { + iWatermarkVisual->RemoveAndDestroyAllD(); + } + SetWatermarkL( iWatermark ); + } + + iBackgroundLayout = CAlfLayout::AddNewL( *iControl, iRootLayout ); + iBackgroundLayout->SetFlag( EAlfVisualFlagManualLayout ); + iBackgroundLayout->SetClipping( EFalse ); + iBackgroundLayout->SetSize( iDisplaySize ); + iBackgroundLayout->EnableScrollingL(); + + iComponentLayout =CAlfGridLayout::AddNewL(*iControl, + 1, 1, iRootLayout); + iComponentLayout->SetClipping(ETrue); + iComponentLayout->EnableBrushesL(); + iComponentLayout->UpdateChildrenLayout(); + + iContentLayout = CAlfAnchorLayout::AddNewL( *iControl, iComponentLayout ); + iContentLayout->MoveToFront(); + iContentLayout->EnableScrollingL(); + iContentLayout->SetClipping( EFalse ); + + iStatusLineLayout = CAlfAnchorLayout::AddNewL( *iControl, iContentLayout ); + iStatusLineLayout->SetClipping( ETrue ); + iStatusLineLayout->SetSize( TSize( 0, 0 ) ); + iStatusLineLayout->SetFlag( EAlfVisualFlagManualLayout ); + + iScrollbarVisibility = EFsScrollbarAuto; + + iScrollbar = new (ELeave) CAknDoubleSpanScrollBar(0); + iScrollbar->ConstructL(ETrue, iControl, 0, CEikScrollBar::EVertical, 0 ); + + TInt pageHeight = iContentLayout->Size().IntTarget().iY; + + iScrollbarModel.SetScrollSpan( pageHeight ); + iScrollbarModel.SetWindowSize( pageHeight ); + iScrollbarModel.SetFocusPosition( 0 ); + + iScrollbar->MakeVisible( EFalse ); + iScrollbarVisible = EFalse; + iScrollbar->SetModelL( &iScrollbarModel ); + + iDummyScrollbar = CAlfImageVisual::AddNewL( *iControl ); + iComponentLayout->Append( iDummyScrollbar ); + + SetColumnsL( ETrue ); + + if ( aNew ) + { + if ( !iTextStyleManager ) + { + iTextStyleManager = CFsTextStyleManager::NewL( + iControl->Env().TextStyleManager() ); + } + + iTextureLoader = CFsTextureLoader::NewL( + iControl->Env().TextureManager(), + iFsTextureObserver ); + + iParser = CFsTextParser::NewL( + *aRichText, + iControl->Env(), + iTextureLoader ); + iParser->SetSizeOfSmile( TSize( 20,20 ) ); + iParser->SetTextStylemanager( iTextStyleManager ); + + if ( aSmDict ) + { + CFsSmileyParser* smParser = CFsSmileyParser::NewL(); + smParser->SetSmileyDictionary( aSmDict ); + iParser->SetSmileyParser(smParser); + iSmileyDict = aSmDict; + } + } + + iHelper = CFsTextViewerCoordinator::NewL(); + + iSelector = CFsTextViewerSelectsManager::NewL( this ); + + iNavigator = CFsTextViewerVisualizerData::NewL( + iControl, + iParser, + iSelector ); + iNavigator->SetScreenHeight( iDisplaySize.iHeight ); + iNavigator->SetStatusLineLayout( iStatusLineLayout ); + + iMarkFacility = CFsTextViewerMarkFacility::NewL( + iMarkingLayout, + iControl, + iNavigator, + iSkinData ); + + iLayouter = CFsTextViewerLayouter::NewL( iEnv ); + iLayouter->SetNavigator( iNavigator ); + iLayouter->SetHelper( iHelper ); + iLayouter->SetMargins( iSettings->iLeftMargin, iSettings->iRightMargin ); + iLayouter->iVisualizer = this; + iLayouter->iControl = iControl; + + iScreenDev = CCoeEnv::Static()->ScreenDevice(); + iEffectiveOffset.SetTarget( 0, 0 ); + + UpdateDisplaySize(); + } + +// --------------------------------------------------------------------------- +// FindMaxLength +// --------------------------------------------------------------------------- +TInt CFsTextViewerVisualizer::FindMaxLengthL( CAlfVisual* aVisual ) + { + FUNC_LOG; + CAlfTextVisual* visual = static_cast(aVisual); + TInt retVal = visual->Text().Length(); + TInt length = visual->Text().Length(); + TInt maxWidth = iContentSize.iWidth; + TInt width = visual->Size().Target().iX; + + while ( width >= maxWidth ) + { + width = visual->SubstringExtents( 0, --retVal ).Width(); + } + + if ( length - retVal < KMinLettersInNewLine ) + { + retVal -= KMinLettersInNewLine - ( length - retVal ); + } + + return retVal; + } + +// --------------------------------------------------------------------------- +// FindMaxLength +// --------------------------------------------------------------------------- +TInt CFsTextViewerVisualizer::FindMaxLengthL( MFsRichTextObject* aObject ) + { + FUNC_LOG; + const TDesC& text = static_cast(aObject)->GetText(); + TInt retVal = text.Length(); + TInt length = text.Length(); + TInt maxWidth = iContentSize.iWidth; + TInt textStyle = static_cast(aObject)->GetStyleId(); + TInt width = CalculateWidthL( + text.Left( length ), + textStyle ); + + + while ( width >= maxWidth ) + { + width = CalculateWidthL( + text.Left( --retVal ), + textStyle ); + } + + if ( length - retVal < KMinLettersInNewLine ) + { + retVal -= KMinLettersInNewLine - ( length - retVal ); + } + + return retVal; + } + +// --------------------------------------------------------------------------- +// Updates scrollbar +// --------------------------------------------------------------------------- +void CFsTextViewerVisualizer::UpdateScrollbarL() + { + FUNC_LOG; + + // If scroll event handling is ongoing, it means that user is dragging the + // scroll bar. In this case the scroll bar is updating itself + // automatically, so we don't need to do anything here. + if( iControl->IsScrollEventHandlingOngoing() ) + { + return; + } + + // --------------------------------------------------------------------------- + // Updates scrollbar + // --------------------------------------------------------------------------- + // + iScrollbarPos = iContentLayout->ScrollOffset().IntTarget().iY; + TInt pageHeight = iContentLayout->Size().IntTarget().iY; + + TFsScrollbarVisibility visibility = iScrollbarVisibility; + + TBool showScrollbar( EFalse ); + + if ( visibility == EFsScrollbarAuto ) + { + if ( iTotalHeight < pageHeight ) + { + showScrollbar = EFalse; + } + else + { + showScrollbar = ETrue; + } + } + else if ( visibility == EFsScrollbarShowAlways ) + { + showScrollbar = ETrue; + } + else // EFsScrollbarHideAlways + { + showScrollbar = EFalse; + } + + TInt firstVisible = iNavigator->GetFirstVisible()->iLineNumber; + TInt firstVisibleOffset = iNavigator->GetLineOffset( firstVisible ); + + iScrollbarModel.SetScrollSpan( Max( iTotalHeight, pageHeight ) ); + iScrollbarModel.SetWindowSize( pageHeight ); + iScrollbarModel.SetFocusPosition( iLineOffset ); + + iScrollbar->SetModelL(&iScrollbarModel); + + if ( (showScrollbar != iScrollbarVisible) || + ((iComponentLayout->ColumnCount() > 1) && !showScrollbar) ) + { + SetColumnsL( showScrollbar ); + + iScrollbarVisible = showScrollbar; + } + + // Layout sizes might have changed, so update the new sizes + UpdateDisplaySize(); + + iScrollbar->MakeVisible( iScrollbarVisible ); + iScrollbar->DrawNow(); + } + +void CFsTextViewerVisualizer::SetColumnsL( TBool aShowScrollBar ) + { + TRect mainPaneRect; + AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect); + + TRect listRect = iRootLayout->DisplayRectTarget(); + listRect.Move(mainPaneRect.iTl); + + if (aShowScrollBar) + { + TRect scrollPane, listPane; + + CFsLayoutManager::LayoutMetricsRect( + listRect, + CFsLayoutManager::EFsLmSpFsScrollPane, + scrollPane); + CFsLayoutManager::LayoutMetricsRect( + listRect, + CFsLayoutManager::EFsLmMainSpFsListPane, + listPane); + + iScrollbar->SetRect(scrollPane); + RArray columns; + if (CFsLayoutManager::IsMirrored()) + { + columns.Append(scrollPane.Width()); + columns.Append(listPane.Width()); + } + else + { + columns.Append(listPane.Width()); + columns.Append(scrollPane.Width()); + } + iComponentLayout->SetColumnsL(columns); + columns.Close(); + if (CFsLayoutManager::IsMirrored()) + { + iComponentLayout->SetFlag(EAlfVisualFlagFreezeLayout); + iComponentLayout->Reorder(*iDummyScrollbar, 0, 0); + iComponentLayout->ClearFlag(EAlfVisualFlagFreezeLayout); + } + } + else + { + RArray columns; + columns.Append(listRect.Width()); + iComponentLayout->SetColumnsL(columns); + columns.Close(); + if (CFsLayoutManager::IsMirrored()) + { + iComponentLayout->SetFlag(EAlfVisualFlagFreezeLayout); + iComponentLayout->Reorder(*iContentLayout, 0, 0); + iComponentLayout->ClearFlag(EAlfVisualFlagFreezeLayout); + } + } + iComponentLayout->UpdateChildrenLayout(0); + } + +// --------------------------------------------------------------------------- +// Handle visibility change +// --------------------------------------------------------------------------- +// +void CFsTextViewerVisualizer::NotifyControlVisibilityChange( TBool aIsVisible ) + { + if ( aIsVisible ) + { + TRAP_IGNORE( UpdateScrollbarL() ); + } + else + { + iScrollbar->MakeVisible( aIsVisible ); + iScrollbarVisible = aIsVisible; + } + } + +TInt CFsTextViewerVisualizer::GetTotalHeight() + { + return iTotalHeight; + } + +TInt CFsTextViewerVisualizer::GetViewTopPosition() + { + return iLineOffset; + } + +TPoint CFsTextViewerVisualizer::GetViewCenterPosition() + { + TInt x = iContentSize.iWidth / 2; + TInt y = GetViewTopPosition() + ( iContentSize.iHeight / 2 ); + return TPoint( x, y ); + }