messagingappbase/msgeditor/viewsrc/MsgXhtmlBodyControl.cpp
changeset 0 72b543305e3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingappbase/msgeditor/viewsrc/MsgXhtmlBodyControl.cpp	Thu Dec 17 08:44:11 2009 +0200
@@ -0,0 +1,434 @@
+/*
+* 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:  MsgXhtmlBodyControl implementation
+*
+*/
+
+
+
+// ========== INCLUDE FILES ================================
+
+#include <AknUtils.h>
+#include <AknsUtils.h>
+#include <applayout.cdl.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <ItemFinder.h>
+
+#include "MsgEditorCommon.h"
+#include "MsgXhtmlBodyControl.h"
+#include "MsgBodyControlEditor.h"
+#include "MsgEditorPanic.h"
+
+// ========== EXTERNAL DATA STRUCTURES =====================
+
+// ========== EXTERNAL FUNCTION PROTOTYPES =================
+
+// ========== CONSTANTS ====================================
+
+#ifdef RD_MSG_XHTML_SUPPORT 
+_LIT( KWwwUrlAddress, "www." );
+_LIT( KSchemeAddress, ":" );
+#endif
+
+// ========== MACROS =======================================
+
+// ========== LOCAL CONSTANTS AND MACROS ===================
+#ifdef RD_MSG_XHTML_SUPPORT 
+const TInt KObserverArrayGranularity = 2;
+#endif
+
+// ========== MODULE DATA STRUCTURES =======================
+
+// ========== LOCAL FUNCTION PROTOTYPES ====================
+
+// ========== LOCAL FUNCTIONS ==============================
+
+// ========== MEMBER FUNCTIONS =============================
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::CMsgXhtmlBodyControl
+//
+// Constructor.
+// ---------------------------------------------------------
+//
+CMsgXhtmlBodyControl::CMsgXhtmlBodyControl( MMsgBaseControlObserver& aBaseControlObserver ) : 
+    CMsgBodyControl( aBaseControlObserver )
+    {
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::~CMsgXhtmlBodyControl
+//
+// Destructor.
+// ---------------------------------------------------------
+//
+CMsgXhtmlBodyControl::~CMsgXhtmlBodyControl()
+    {
+    delete iObservers;
+#ifdef RD_MSG_XHTML_SUPPORT 
+    delete iParser;
+#endif
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::NewL
+//
+// Factory method that creates this control.
+// ---------------------------------------------------------
+//
+EXPORT_C CMsgXhtmlBodyControl* CMsgXhtmlBodyControl::NewL( CMsgEditorView& aParent,
+                                                           MMsgAsyncControlObserver* aObserver )
+    {
+    CMsgXhtmlBodyControl* self = new ( ELeave ) CMsgXhtmlBodyControl( aParent );
+    self->SetMopParent( &aParent );
+    
+    CleanupStack::PushL( self );
+    self->ConstructL( aObserver );
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::ConstructL
+// ---------------------------------------------------------
+//
+#ifdef RD_MSG_XHTML_SUPPORT 
+void CMsgXhtmlBodyControl::ConstructL( MMsgAsyncControlObserver* aObserver )
+    {
+    CMsgBodyControl::ConstructL();
+    
+    SetControlType( EMsgXhtmlBodyControl );
+    SetPlainTextMode( EFalse );
+    
+    iObservers = new( ELeave ) CArrayPtrFlat<MMsgAsyncControlObserver>( KObserverArrayGranularity );
+    
+    iParser = CXhtmlParser::NewL( this );
+
+    ResolveLayout();
+    
+    if ( aObserver )
+        {
+        iObservers->AppendL( aObserver );
+        }
+    }
+#else
+void CMsgXhtmlBodyControl::ConstructL( MMsgAsyncControlObserver* /*aObserver*/ )
+    {
+    User::Leave( KErrNotSupported );
+    }
+#endif
+
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::LoadL
+// ---------------------------------------------------------
+//
+#ifdef RD_MSG_XHTML_SUPPORT 
+void CMsgXhtmlBodyControl::LoadL( RFile& aFileHandle )
+    {
+    RFile fileHandle;
+    fileHandle.Duplicate( aFileHandle );
+    
+    iParser->CreateDomL( fileHandle ); // Takes ownership
+
+    SetState( EMsgAsyncControlStateOpening );
+    }
+#else
+void CMsgXhtmlBodyControl::LoadL( RFile& /*aFileHandle*/ )
+    {
+    }
+#endif
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::Cancel
+// ---------------------------------------------------------
+//
+#ifdef RD_MSG_XHTML_SUPPORT 
+void CMsgXhtmlBodyControl::Cancel()
+    {
+    if ( iState == EMsgAsyncControlStateOpening )
+        {
+        iParser->Cancel();
+        SetState( EMsgAsyncControlStateIdle );
+        }
+    }
+#else
+void CMsgXhtmlBodyControl::Cancel()
+    {
+    }
+#endif
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::Close
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::Close()
+    {
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::State
+// ---------------------------------------------------------
+//
+TMsgAsyncControlState CMsgXhtmlBodyControl::State() const
+    {
+    return iState;
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::Error
+// ---------------------------------------------------------
+//
+TInt CMsgXhtmlBodyControl::Error() const
+    {
+    return iError;
+    }
+        
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::AddObserverL
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::AddObserverL( MMsgAsyncControlObserver& aObserver )
+    {
+    iObservers->AppendL( &aObserver );
+    }
+        
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::RemoveObserver
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::RemoveObserver( MMsgAsyncControlObserver& aObserver )
+    {
+    for ( TInt current = 0; current < iObservers->Count(); current++ )
+        {
+        if ( iObservers->At( current ) == &aObserver )
+            {
+            iObservers->Delete( current );
+            break;
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::ParseCompleteL
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::ParseCompleteL()
+    {
+    ParseXhtmlL();
+    
+    if ( iState ==  EMsgAsyncControlStateOpening )
+        {
+        SetState( EMsgAsyncControlStateReady );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::ParseError
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::ParseError( TInt aError )
+    {
+    iError = aError;
+    SetState( EMsgAsyncControlStateError );
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::HandleResourceChange
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::HandleResourceChange( TInt aType )
+    {
+    CMsgBodyControl::HandleResourceChange( aType );
+        
+	if ( aType == KEikDynamicLayoutVariantSwitch )
+        {
+        ResolveLayout();
+        
+        if ( iState == EMsgAsyncControlStateReady )
+            {
+            TRAPD( error, ParseXhtmlL() );
+            if ( error != KErrNone )
+                {
+                ParseError( error );
+                }
+            }
+        }
+    
+    for ( TInt current = 0; current < iObservers->Count(); current++ )
+        {
+        iObservers->At( current )->MsgAsyncControlResourceChanged( *this, aType );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::SetState
+// ---------------------------------------------------------
+//
+void CMsgXhtmlBodyControl::SetState( TMsgAsyncControlState  aState )
+    {
+    TMsgAsyncControlState oldState = iState;
+    iState = aState;
+    
+    for ( TInt current = 0; current < iObservers->Count(); current++ )
+        {
+        iObservers->At( current )->MsgAsyncControlStateChanged( *this, iState, oldState );
+        }
+    }
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::ResolveLayout
+// ---------------------------------------------------------
+//
+#ifdef RD_MSG_XHTML_SUPPORT 
+void CMsgXhtmlBodyControl::ResolveLayout()
+    {
+    TAknLayoutRect msgTextPane;
+    msgTextPane.LayoutRect( MsgEditorCommons::MsgDataPane(),
+                            AknLayoutScalable_Apps::msg_text_pane( 0 ) );
+                            
+    TAknLayoutRect msgBodyPane;
+    msgBodyPane.LayoutRect( msgTextPane.Rect(),
+                            AknLayoutScalable_Apps::msg_body_pane() );
+    
+    TAknLayoutText normalTextLayout;
+    normalTextLayout.LayoutText( msgBodyPane.Rect(),
+                                 AknLayoutScalable_Apps::msg_body_pane_t1( 0 ) );
+
+    TAknLayoutText largeTextLayout;
+    largeTextLayout.LayoutText( msgBodyPane.Rect(),
+                                AknLayoutScalable_Apps::msg_body_pane_t1( 2 ) );
+
+    TAknLayoutText smallTextLayout;
+    smallTextLayout.LayoutText( msgBodyPane.Rect(),
+                                AknLayoutScalable_Apps::msg_body_pane_t1( 3 ) );
+
+    
+    TRgb textColor = normalTextLayout.Color();
+    if ( AknsUtils::AvkonSkinEnabled() )
+        {
+        AknsUtils::GetCachedColor( AknsUtils::SkinInstance(),
+                                   textColor,
+                                   KAknsIIDQsnTextColors,
+                                   EAknsCIQsnTextColorsCG6 );
+        
+        }
+        
+    iParser->SetDefaultTextColor( textColor );
+    iParser->SetFonts( largeTextLayout.Font(),
+                       normalTextLayout.Font(),
+                       smallTextLayout.Font(),
+                       normalTextLayout.Font() );   
+    }
+#else
+void CMsgXhtmlBodyControl::ResolveLayout()
+    {
+    }
+#endif                      
+
+// ---------------------------------------------------------
+// CMsgXhtmlBodyControl::ParseXhtmlL
+// ---------------------------------------------------------
+//
+#ifdef RD_MSG_XHTML_SUPPORT 
+void CMsgXhtmlBodyControl::ParseXhtmlL()
+    {
+    CRichText& text = TextContent();
+    text.Reset();
+    
+    iParser->SetMode( IsPlainTextMode(), IsPlainTextMode() );
+    
+    iParser->ParseL( text );
+        
+    CItemFinder* autoFinder = ItemFinder();
+    
+    TInt linkCount = iParser->HyperLinkCount();
+    
+    if ( autoFinder && linkCount > 0 )
+        {
+        CArrayPtrFlat<CItemFinder::CFindItemExt>* linkArray = 
+                new( ELeave ) CArrayPtrFlat<CItemFinder::CFindItemExt>( linkCount );
+        CleanupStack::PushL( TCleanupItem( CleanupLinkArray, linkArray ) );
+        
+        TInt startPos( 0 );
+        TInt endPos( 0 );
+        TPtrC address;
+        
+        for( TInt current = 0; current < linkCount; current++ )
+            {
+            User::LeaveIfError( iParser->HyperLink( current, startPos, endPos, address ) );
+            
+            CItemFinder::CFindItemExt* findItem = new( ELeave ) CItemFinder::CFindItemExt();
+            CleanupStack::PushL( findItem );
+            
+            findItem->iItemType = CItemFinder::ENoneSelected;
+            
+            if ( address.Length() >= KWwwUrlAddress().Length() &&
+                 address.Left( KWwwUrlAddress().Length() ).MatchF( KWwwUrlAddress ) != KErrNotFound )
+                {
+                findItem->iItemType = CItemFinder::EUrlAddress;    
+                }
+            else if ( address.Length() >= KSchemeAddress().Length() &&
+                      address.FindF( KSchemeAddress() ) != KErrNotFound )
+                {
+                findItem->iItemType = CItemFinder::EUriScheme;
+                }
+            
+            if ( findItem->iItemType != CItemFinder::ENoneSelected )
+                {
+                findItem->iItemDescriptor = address.AllocL();
+                findItem->iStart = startPos;
+                findItem->iEnd = endPos;
+        
+                linkArray->AppendL( findItem );
+                CleanupStack::Pop( findItem );
+                }
+            else
+                {
+                CleanupStack::PopAndDestroy( findItem );
+                }
+            };
+        
+        User::LeaveIfError( autoFinder->SetExternalLinks( linkArray ) );
+        CleanupStack::PopAndDestroy( linkArray );
+        }
+    
+    Editor().SetAmountToFormatL( ETrue );
+    }
+#else
+void CMsgXhtmlBodyControl::ParseXhtmlL()
+    {
+    }
+#endif
+
+// ----------------------------------------------------
+// CMsgXhtmlBodyControl::CleanupLinkArray
+// ----------------------------------------------------
+//
+#ifdef RD_MSG_XHTML_SUPPORT 
+void CMsgXhtmlBodyControl::CleanupLinkArray( TAny* aArray )
+    {
+    CArrayPtrFlat<CItemFinder::CFindItemExt>* linkArray = static_cast<CArrayPtrFlat<CItemFinder::CFindItemExt>*>( aArray );
+    
+    linkArray->ResetAndDestroy();
+    delete linkArray;
+    }
+#else
+void CMsgXhtmlBodyControl::CleanupLinkArray( TAny* aArray )
+    {
+    }
+#endif
+
+//  End of File