emailuis/uicomponents/src/fstextviewermarkfacility.cpp
changeset 0 8466d47a6819
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/uicomponents/src/fstextviewermarkfacility.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,430 @@
+/*
+* 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:  Responsible for marking capabilities
+*
+*/
+
+
+//<cmail> removed __FS_ALFRED_SUPPORT flag
+//#include <fsconfig.h>
+//</cmail> removed __FS_ALFRED_SUPPORT flag
+// <cmail> SF
+#include "emailtrace.h"
+#include <alf/alfanchorlayout.h>
+#include <alf/alfcontrol.h>
+#include <alf/alftextvisual.h>
+#include <alf/alfimagevisual.h>
+#include <alf/alfborderbrush.h>
+#include <alf/alfbrusharray.h>
+// </cmail>
+
+#include "fstextviewermarkfacility.h"
+#include "fstextviewerskindata.h"
+
+
+// ---------------------------------------------------------------------------
+// NewL
+// ---------------------------------------------------------------------------
+CFsTextViewerMarkFacility* CFsTextViewerMarkFacility::NewL( 
+        CAlfLayout* aLayout, 
+        CAlfControl* aControl, 
+        CFsTextViewerVisualizerData* aNavigator,
+        CFsTextViewerSkinData* aSkinData )
+    {
+    FUNC_LOG;
+    CFsTextViewerMarkFacility* self = new (ELeave) CFsTextViewerMarkFacility( 
+            aLayout, 
+            aControl, 
+            aNavigator, 
+            aSkinData );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// ~CFsTextViewerMarkFacility
+// ---------------------------------------------------------------------------
+CFsTextViewerMarkFacility::~CFsTextViewerMarkFacility()
+    {
+    FUNC_LOG;
+    if ( iLayout )
+        {
+        iLayout->RemoveAndDestroyAllD();
+        }
+
+    if ( iBorder )
+        {
+        delete iBorder;
+        }
+    
+    iVisuals.Close();
+    }
+
+// ---------------------------------------------------------------------------
+// SetHeadOffset
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::SetHeadOffsetL( TInt aHead )
+    {
+    FUNC_LOG;
+    iHead = aHead;
+    TInt visualIndex = iNavigator->Find( iHead );
+    
+    TInt begin = iNavigator->GetVisStartOffset( visualIndex );
+    TInt end = iNavigator->GetVisEndOffset( visualIndex );
+
+    CAlfVisual* visual = CreateMarkVisualL( 
+            iNavigator->GetVisual( visualIndex ), 
+            begin,
+            end );
+    }
+
+// ---------------------------------------------------------------------------
+// SetTailOffset
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::SetTailOffsetL( TInt /* aTail */ )
+    {
+    FUNC_LOG;
+
+    }
+
+// ---------------------------------------------------------------------------
+// FollowCursor
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::FollowCursorL()
+    {
+    FUNC_LOG;
+    if ( iHead < iNavigator->GetCursorCharOffset() )
+        {
+        iTail = iNavigator->FindPrevChar();
+        }
+    else if ( iHead > iNavigator->GetCursorCharOffset() )
+        {
+        iTail = iNavigator->GetCursorCharOffset();
+        }
+    else
+        {
+        iTail = iHead;
+        }
+
+    TInt visualIndex = iNavigator->Find( iTail );
+    
+    TInt begin = iNavigator->GetVisStartOffset( visualIndex );
+    TInt end = iNavigator->GetVisEndOffset( visualIndex );
+    CAlfVisual* visual = NULL;
+    
+    visual = Find( iTail );
+
+    if ( !visual )
+        {
+        visual = CreateMarkVisualL( 
+            iNavigator->GetVisual( visualIndex ), 
+            begin,
+            end );
+        }
+
+    CAlfImageVisual* imageVisual( dynamic_cast<CAlfImageVisual*>( visual ) );
+    CAlfTextVisual* textVisual( dynamic_cast<CAlfTextVisual*>( visual ) );
+    if ( imageVisual )
+        {
+        UpdateImageVisualL( visual, iNavigator->GetVisual( visualIndex ) );
+        }
+    else if ( textVisual )
+        {
+        if ( iHead == iNavigator->GetCursorCharOffset() )
+            {
+            begin = LocalVisOffset( iHead );
+            end = LocalVisOffset( iHead );
+            }
+        else if ( iTail >= iHead )
+            {
+            begin = IsHeadVisual( iTail ) ? LocalVisOffset( iHead ) : 0;
+            end = LocalVisOffset( iTail ) + 1;
+            }
+        else if ( iTail < iHead )
+            {
+            begin = LocalVisOffset( iTail );
+            end = IsHeadVisual( iTail ) 
+                ? LocalVisOffset( iHead ) 
+                : VisualLength( visual );
+            }
+
+        UpdateTextVisualL( 
+                visual, 
+                iNavigator->GetVisual( visualIndex ), 
+                begin, 
+                end );
+        }
+
+    DeleteUnused();
+    }
+
+// ---------------------------------------------------------------------------
+// SetLayout
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::SetLayout( CAlfLayout* aLayout )
+    {
+    FUNC_LOG;
+    iLayout = aLayout;
+    iVisuals.Reset();
+    }
+
+// ---------------------------------------------------------------------------
+// GetRange
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::GetRange( TInt& aBegin, TInt& aEnd ) const
+    {
+    FUNC_LOG;
+    aBegin = iHead;
+    aEnd = iTail;
+    }
+
+// ---------------------------------------------------------------------------
+// CreateMarkVisualL
+// ---------------------------------------------------------------------------
+CAlfVisual* CFsTextViewerMarkFacility::CreateMarkVisualL( 
+        CAlfVisual* aVisual, 
+        TInt aBegin, 
+        TInt aEnd )
+    {
+    FUNC_LOG;
+    CAlfImageVisual* imageVisual( dynamic_cast<CAlfImageVisual*>( aVisual ) );
+    CAlfTextVisual* textVisual( dynamic_cast<CAlfTextVisual*>( aVisual ) );
+    TFsRangedVisual visual;
+
+    visual.iStart = aBegin;
+    visual.iEnd = aEnd;
+
+    if ( imageVisual )
+        {
+        visual.iVisual = CAlfImageVisual::AddNewL( *iControl, iLayout );
+        }
+    else if ( textVisual )
+        {
+        visual.iVisual = CAlfTextVisual::AddNewL( *iControl, iLayout );
+        static_cast<CAlfTextVisual*>(visual.iVisual)->SetStyle( 
+                EAlfTextStyleNormal, 
+                EAlfBackgroundTypeLight );
+        static_cast<CAlfTextVisual*>(visual.iVisual)->EnableShadow( EFalse );
+        static_cast<CAlfTextVisual*>(visual.iVisual)->SetAlign( 
+                EAlfAlignHLeft, 
+                EAlfAlignVBottom );
+        static_cast<CAlfTextVisual*>(visual.iVisual)->SetColor( 
+                iSkinData->iMarkedTextColor );
+        static_cast<CAlfTextVisual*>(visual.iVisual)->SetTextStyle(
+                static_cast<CAlfTextVisual*>(aVisual)->Style() );
+        visual.iVisual->SetClipping();
+        }
+
+    visual.iVisual->EnableBrushesL();
+    visual.iVisual->Brushes()->AppendL( iBorder, EAlfDoesNotHaveOwnership );
+    
+    iVisuals.AppendL( visual );
+
+    return visual.iVisual;
+    }
+
+// ---------------------------------------------------------------------------
+// UpdateImageVisualL
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::UpdateImageVisualL( 
+        CAlfVisual* aVisual, 
+        CAlfVisual* aBaseVisual )
+    {
+    FUNC_LOG;
+    TRect markRect = aBaseVisual->DisplayRectTarget();
+    aVisual->SetRect( markRect );
+    }
+
+// ---------------------------------------------------------------------------
+// UpdateTextVisualL
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::UpdateTextVisualL( CAlfVisual* aVisual, 
+                                    CAlfVisual* aBaseVisual, 
+                                    TInt aBegin, TInt aEnd )
+    {
+    FUNC_LOG;
+    CAlfTextVisual* visual = static_cast<CAlfTextVisual*>(aBaseVisual);
+    CAlfTextVisual* targetVisual = static_cast<CAlfTextVisual*>(aVisual);
+    TRect markRect = visual->SubstringExtents( aBegin, aEnd );
+    markRect.Move( visual->DisplayRectTarget().iTl );
+    
+    HBufC* text = visual->Text().AllocL();
+    targetVisual->SetTextL( text->Mid( aBegin, aEnd - aBegin ) );
+    targetVisual->SetRect( markRect );
+    delete text;
+    }
+
+// ---------------------------------------------------------------------------
+// ConstructL
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::ConstructL()
+    {
+    FUNC_LOG;
+    iBorder = CAlfBorderBrush::NewL( iControl->Env(), 1, 1, 0, 0  );
+    iBorder->SetColor( KRgbBlack );
+    iBorder->SetOpacity( .55f );
+    }
+
+// ---------------------------------------------------------------------------
+// CFsTextViewerMarkFacility
+// ---------------------------------------------------------------------------
+CFsTextViewerMarkFacility::CFsTextViewerMarkFacility( 
+        CAlfLayout* aLayout, 
+        CAlfControl* aControl,
+        CFsTextViewerVisualizerData* aNavigator,
+        CFsTextViewerSkinData* aSkinData )
+    {
+    FUNC_LOG;
+    iLayout = aLayout;
+    iControl = aControl;
+    iNavigator = aNavigator;
+    iSkinData = aSkinData;
+    }
+
+// ---------------------------------------------------------------------------
+// VisualLength
+// ---------------------------------------------------------------------------
+TInt CFsTextViewerMarkFacility::VisualLength( CAlfVisual* aVisual )
+    {
+    FUNC_LOG;
+    TInt retVal = KErrNone;
+    for ( TInt i = 0; i < iVisuals.Count(); ++i )
+        {
+        if ( iVisuals[i].iVisual == aVisual )
+            {
+            retVal = iVisuals[i].iEnd - iVisuals[i].iStart + 1;
+            }
+        }
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// Find
+// ---------------------------------------------------------------------------
+TInt CFsTextViewerMarkFacility::Find( CAlfVisual* aVisual )
+    {
+    FUNC_LOG;
+    TInt retVal = KErrNone;
+    for ( TInt i = 0; i < iVisuals.Count(); ++i )
+        {
+        if ( iVisuals[i].iVisual == aVisual )
+            {
+            retVal = i;
+            }
+        }
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// Find
+// ---------------------------------------------------------------------------
+CAlfVisual* CFsTextViewerMarkFacility::Find( TInt aOffset )
+    {
+    FUNC_LOG;
+    CAlfVisual* retVal = NULL;
+
+    for ( TInt i = 0; i < iVisuals.Count(); ++i )
+        {
+        if ( aOffset >= iVisuals[i].iStart && aOffset <= iVisuals[i].iEnd )
+            {
+            retVal = iVisuals[i].iVisual;
+            }
+        }
+
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// Find
+// ---------------------------------------------------------------------------
+TInt CFsTextViewerMarkFacility::FindIndex( TInt aOffset )
+    {
+    FUNC_LOG;
+    TInt retVal = -1;
+
+    for ( TInt i = 0; i < iVisuals.Count(); ++i )
+        {
+        if ( aOffset >= iVisuals[i].iStart && aOffset <= iVisuals[i].iEnd )
+            {
+            retVal = i;
+            }
+        }
+
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// LocalVisOffset
+// ---------------------------------------------------------------------------
+TInt CFsTextViewerMarkFacility::LocalVisOffset( TInt aGlobalOffset )
+    {
+    FUNC_LOG;
+    TInt retVal = -1;
+    TInt start = 
+        iNavigator->GetVisStartOffset( iNavigator->Find( aGlobalOffset ) );
+    retVal = aGlobalOffset - start;
+
+    return retVal;
+    }
+
+// ---------------------------------------------------------------------------
+// DeleteUnused
+// ---------------------------------------------------------------------------
+void CFsTextViewerMarkFacility::DeleteUnused()
+    {
+    FUNC_LOG;
+    TInt begin = Min( iHead, iTail );
+    TInt end = Max( iHead, iTail );
+    for ( TInt i = 0; i < iVisuals.Count(); ++i )
+        {
+        if ( ( iVisuals[i].iStart >= begin 
+                   && iVisuals[i].iStart <= end ) 
+             || ( iVisuals[i].iEnd >= begin 
+                   && iVisuals[i].iEnd <= end ) 
+             || ( iVisuals[i].iStart <= begin 
+                   && iVisuals[i].iEnd >= begin ) )
+            {
+            
+            }
+        else
+            {
+            iVisuals[i].iVisual->RemoveAndDestroyAllD();
+                iVisuals.Remove( i );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// IsHeadVisual
+// ---------------------------------------------------------------------------
+TBool CFsTextViewerMarkFacility::IsHeadVisual( TInt aGlobalOffset )
+    {
+    FUNC_LOG;
+    TBool retVal = EFalse;
+
+    TInt headIndex = FindIndex( iHead );
+    
+    if ( headIndex >= 0 
+            && headIndex < iVisuals.Count()
+            && aGlobalOffset <= iVisuals[headIndex].iEnd 
+            && aGlobalOffset >= iVisuals[headIndex].iStart )
+        {
+        retVal = ETrue;
+        }
+
+    return retVal;
+    }
+