idlehomescreen/xmluicontroller/src/imagetransactionelement.cpp
changeset 0 f72a12da539e
child 2 08c6ee43b396
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluicontroller/src/imagetransactionelement.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,496 @@
+/*
+* Copyright (c) 2005-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:  Image transaction element
+*
+*/
+
+
+#include "xnbitmap.h"
+#include "xnnewsticker.h"
+#include "xntype.h"
+#include "xnmenu.h"
+#include "xnmenuadapter.h"
+#include "xnuiengineappif.h"
+
+#include <imageconversion.h>
+#include <gulicon.h>
+
+#include "imagetransactionelement.h"
+#include "xmluicontrollerpanic.h"
+#include "aixmluiutils.h"
+#include "xnuiengineappif.h"
+
+using namespace AiXmlUiController;
+using namespace XnImageInterface;
+using namespace ContentAccess;
+
+namespace AiXmlUiController
+    {
+
+TBool IsNodeVisible( CXnNodeAppIf& aNode )
+    {
+    CXnProperty* propVisibility = aNode.GetPropertyL( XnPropertyNames::style::common::KVisibility );;
+
+    if( propVisibility )
+        {
+        const TDesC8& visibility = propVisibility->StringValue();
+
+        if( visibility == XnPropertyNames::style::common::visibility::KHidden )
+            {
+            return EFalse;
+            }    
+        }
+
+    CXnProperty* propDisplay = aNode.GetPropertyL( XnPropertyNames::style::common::KDisplay );
+
+    if( propDisplay )
+        {
+        const TDesC8& display = propDisplay->StringValue();
+
+        if( display == XnPropertyNames::style::common::display::KNone )
+            {
+            return EFalse;
+            }
+        }
+
+    CXnProperty* propDisabled = aNode.GetPropertyL( XnPropertyNames::common::KDisabled );
+
+    if( propDisabled )
+        {
+        const TDesC8& disabled = propDisabled->StringValue();
+
+        if( disabled == XnPropertyNames::KTrue )
+            {
+            return EFalse;
+            }
+        }
+    return ETrue;
+    }
+/**
+ * Uses CImageDecoder to decode images asynchronously.
+ * When decoding is done, it tries to find target and set
+ * image into element. Destroys itself at end of RunL method.
+ */
+class CKamikazeImageDecoder: public CActive
+    {
+public:
+    static CKamikazeImageDecoder* NewL(
+            RFile& aFile, const TDesC8& aNodeId, 
+            const TDesC8& aNodeNs, TXnUiEngineAppIf& aUiEngine);
+    ~CKamikazeImageDecoder();
+public:
+    /**
+     * Start decoding and forget instance. 
+     * Destroyes itself.
+     */
+    void DecodeLD();
+private:
+    // from CActive
+    void DoCancel();
+    void RunL();
+private:    
+    void ConstructL(RFile& aFile, const TDesC8& aNodeId,const TDesC8& aNodeNs);
+    CKamikazeImageDecoder(TXnUiEngineAppIf& aUiEngine);
+    void SetImageL();
+private:
+    /**
+     * Image decoder. Own.
+     */
+    CImageDecoder* iDecoder;
+    /**
+     * Target node id
+     */
+    HBufC8* iNodeId;
+    /**
+     * Target node namespace
+     */
+    HBufC8* iNodeNs;
+    /**
+     * Provides services to find target
+     */
+    TXnUiEngineAppIf& iUiEngine;
+    /**
+     * Icon. Own.
+     */
+    CGulIcon* iIcon;
+    };
+
+CKamikazeImageDecoder* CKamikazeImageDecoder::NewL(
+    RFile& aFile, 
+    const TDesC8& aNodeId,
+    const TDesC8& aNodeNs,
+    TXnUiEngineAppIf& aUiEngine)
+    {
+    CKamikazeImageDecoder* p = new (ELeave)CKamikazeImageDecoder(aUiEngine);
+    CleanupStack::PushL(p);
+    p->ConstructL(aFile,aNodeId,aNodeNs);
+    CleanupStack::Pop(p);
+    return p;
+    }
+
+CKamikazeImageDecoder::CKamikazeImageDecoder(TXnUiEngineAppIf& aUiEngine):
+    CActive(CActive::EPriorityStandard ), iUiEngine(aUiEngine)
+    {
+    CActiveScheduler::Add( this );
+    }
+
+CKamikazeImageDecoder::~CKamikazeImageDecoder()
+    {
+    Cancel();
+    delete iDecoder;
+    delete iNodeId;
+    delete iNodeNs;
+    delete iIcon;
+    }
+
+void CKamikazeImageDecoder::ConstructL(
+    RFile& aFile, 
+    const TDesC8& aNodeId, 
+    const TDesC8& aNodeNs)
+    {
+    // Create new decoder for file
+    iDecoder = CImageDecoder::FileNewL( aFile, EView );
+    iNodeId = aNodeId.AllocL();
+    iNodeNs = aNodeNs.AllocL();
+    iIcon = CGulIcon::NewL();
+    }
+
+void CKamikazeImageDecoder::DecodeLD()
+    {
+    TFrameInfo frameInfo = iDecoder->FrameInfo(0);
+    CFbsBitmap* bitmap = new( ELeave ) CFbsBitmap;
+    iIcon->SetBitmap( bitmap );
+    
+    User::LeaveIfError( bitmap->Create( frameInfo.iOverallSizeInPixels,
+                        frameInfo.iFrameDisplayMode ) );
+    
+    CFbsBitmap* mask(0);
+    if ( frameInfo.iFlags & TFrameInfo::ETransparencyPossible )
+        {
+        mask = new( ELeave ) CFbsBitmap;
+        iIcon->SetMask( mask );
+        User::LeaveIfError( mask->Create( frameInfo.iOverallSizeInPixels,
+                                          ( ( frameInfo.iFlags & TFrameInfo::EAlphaChannel )
+                                          ? EGray256 : EGray2 ) ) );
+        }
+    
+    if(iIcon->Mask())
+        {
+        iDecoder->Convert( &iStatus, *bitmap, *mask );
+        }
+    else
+        {
+        iDecoder->Convert( &iStatus, *bitmap );
+        }
+    SetActive();
+    }
+
+void CKamikazeImageDecoder::DoCancel()
+    {
+    iDecoder->Cancel();
+    }
+
+void CKamikazeImageDecoder::SetImageL()
+    {
+     
+    // Find target
+    CXnNodeAppIf* node = iUiEngine.FindNodeByIdL(*iNodeId,*iNodeNs);
+    if(!node)
+        {
+        return;
+        }
+        
+    const TDesC8& type = node->Type()->Type();
+    
+    if ( type == XnImageInterface::MXnImageInterface::Type() )
+        {
+        MXnImageInterface* imageIntr = NULL;
+        if ( !XnComponentInterface::MakeInterfaceL( imageIntr, *node ) )
+            {
+            return;
+            }
+        // Set new bitmaps. Ownership is transferred to MXnImageInterface
+        iIcon->SetBitmapsOwnedExternally( ETrue );
+        imageIntr->SetContentBitmaps( iIcon->Bitmap(), iIcon->Mask() );
+      
+        }
+    else if ( type == XnNewstickerInterface::MXnNewstickerInterface::Type() )
+        {
+        XnNewstickerInterface::MXnNewstickerInterface* newsTicker = NULL;
+        XnComponentInterface::MakeInterfaceL( newsTicker, *node );
+        LeaveIfNull( newsTicker, KErrNotSupported );
+        
+        User::LeaveIfError( newsTicker->SetSeparatorImageL( iIcon ) );
+        // Ownership of icon transferred to newsticker
+        iIcon = NULL;
+        }
+    // Menu softkey icons
+    else if ( ( ( type == KXnMenuItem || type == KXnMenu ) &&
+                IsNodeVisible( *node ) ) ||
+              type == XnPropertyNames::softkey::KNodeName )
+        {
+        CXnNodeAppIf* menuBar = node->ParentL();
+        
+        XnMenuInterface::MXnMenuInterface::TSoftKeyPosition softkeyPosition = 
+            XnMenuInterface::MXnMenuInterface::ELeft;
+                    
+        CXnProperty* property = 
+            node->GetPropertyL( XnPropertyNames::softkey::KTypeAttribute );     
+        if ( property && property->StringValue() == XnPropertyNames::softkey::type::KRight )
+            {
+            softkeyPosition = XnMenuInterface::MXnMenuInterface::ERight;
+            }
+        else if ( property && property->StringValue() == XnPropertyNames::softkey::type::KLeft )
+            {
+            softkeyPosition = XnMenuInterface::MXnMenuInterface::ELeft;
+            }
+        else  // Image can be published only to RSK or LSK
+            {
+            return;
+            }
+            
+        XnMenuInterface::MXnMenuInterface* menuIf = NULL;
+        
+        XnComponentInterface::MakeInterfaceL( menuIf, *menuBar );
+        if ( menuIf )
+            {
+            // Use black mask and preserver aspect ratio
+           
+            menuIf->SetSoftKeyImageL( iIcon->Bitmap(), 
+                                          iIcon->Mask(), 
+                                          softkeyPosition, 
+                                          node,
+                                          ETrue, 
+                                          ETrue ); 
+            iIcon->SetBitmapsOwnedExternally( ETrue );
+            }
+        if( menuBar )
+            {
+            iUiEngine.RefreshMenuL();
+            }
+        }
+        
+    }
+
+void CKamikazeImageDecoder::RunL()
+    {
+    CleanupStack::PushL(this);
+    if(iStatus == KErrNone)
+        {
+        SetImageL();
+        iUiEngine.RenderUIL();
+        }
+    CleanupStack::PopAndDestroy(this);
+    }
+     
+// ======== MEMBER FUNCTIONS ========
+
+CImageTransactionElement::CImageTransactionElement(
+                                AiUtility::CContentPriorityMap& aContentPriorityMap)
+    : CTransactionElement(aContentPriorityMap)
+    {
+    }
+
+CImageTransactionElement* CImageTransactionElement::NewL(
+                                AiUtility::CContentPriorityMap& aContentPriorityMap)
+    {
+    CImageTransactionElement* self = new( ELeave ) CImageTransactionElement(
+                                                            aContentPriorityMap );
+    return self;
+    }
+
+CImageTransactionElement::~CImageTransactionElement()
+    {
+    delete iNewIcon;
+    delete iImageDecoder;
+    }
+
+void CImageTransactionElement::InitializeL( CXnNodeAppIf& aTarget,
+                                            CGulIcon* aIcon )
+    {
+    CheckTypeL( aTarget );
+    
+    LeaveIfNull( aIcon, KErrArgument );
+    
+    SetTarget( aTarget );
+    iNewIcon = aIcon;
+    }
+
+void CImageTransactionElement::InitializeL( CXnNodeAppIf& aTarget,
+                                            RFile& aFile )
+    {
+    CheckTypeL( aTarget );
+   
+    const TDesC8* nodeId = &KNullDesC8;
+    
+    CXnProperty* property = aTarget.GetPropertyL(XnPropertyNames::common::KId);
+    if(property)
+        {
+        nodeId = &property->StringValue();
+        }
+    if ( iImageDecoder )
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+    iImageDecoder = CKamikazeImageDecoder::NewL(
+                        aFile,*nodeId,aTarget.Namespace(),*aTarget.UiEngineL()); 
+    
+    SetTarget( aTarget );
+    }
+
+
+void CImageTransactionElement::UpdateDataL()
+    {
+    if ( iImageDecoder )
+        {
+        iImageDecoder->DecodeLD();
+        iImageDecoder = NULL; // self destroy
+        }
+    else
+        {
+        __ASSERT_DEBUG( iNewIcon, Panic( EBitmapNull ) );
+    
+        const TDesC8& type = LeaveIfNull( Target().Type(), KErrNotSupported )->Type();
+        
+        if ( type == XnImageInterface::MXnImageInterface::Type() )
+            {
+            MXnImageInterface* imageIntr = NULL;
+            if ( !XnComponentInterface::MakeInterfaceL( imageIntr, Target() ) )
+                {
+                User::Leave( KErrNotSupported );
+                }
+            // Set new bitmaps. Ownership is transferred to MXnImageInterface
+            iNewIcon->SetBitmapsOwnedExternally( ETrue );
+            imageIntr->SetContentBitmaps( iNewIcon->Bitmap(), iNewIcon->Mask() );
+            }
+        else if ( type == XnNewstickerInterface::MXnNewstickerInterface::Type() )
+            {
+            XnNewstickerInterface::MXnNewstickerInterface* newsTicker = NULL;
+            XnComponentInterface::MakeInterfaceL( newsTicker, Target() );
+            LeaveIfNull( newsTicker, KErrNotSupported );
+            
+            User::LeaveIfError( newsTicker->SetSeparatorImageL( iNewIcon ) );
+            
+            // Ownership of icon transferred to newsticker
+            
+            iNewIcon = NULL;
+            }
+        // Menu softkey icons
+        else if ( ( ( type == KXnMenuItem || type == KXnMenu ) &&
+                    IsNodeVisible( Target() ) ) ||
+                  type == XnPropertyNames::softkey::KNodeName )
+            {
+            CXnNodeAppIf* menuBar = Target().ParentL();
+            
+            XnMenuInterface::MXnMenuInterface::TSoftKeyPosition softkeyPosition = 
+                XnMenuInterface::MXnMenuInterface::ELeft;
+                        
+            CXnProperty* property = 
+                Target().GetPropertyL( XnPropertyNames::softkey::KTypeAttribute );     
+            if ( property && property->StringValue() == XnPropertyNames::softkey::type::KRight )
+                {
+                softkeyPosition = XnMenuInterface::MXnMenuInterface::ERight;
+                }
+            else if ( property && property->StringValue() == XnPropertyNames::softkey::type::KLeft )
+                {
+                softkeyPosition = XnMenuInterface::MXnMenuInterface::ELeft;
+                }
+            else  // Image can be published only to RSK or LSK
+                {
+                delete iNewIcon;
+                iNewIcon = NULL;            
+                User::Leave( KErrNotSupported );
+                }
+                
+            XnMenuInterface::MXnMenuInterface* menuIf = NULL;
+            
+            XnComponentInterface::MakeInterfaceL( menuIf, *menuBar );
+            if ( menuIf )
+                {
+                // Use black mask and preserver aspect ratio
+                TRAPD(err,
+                    menuIf->SetSoftKeyImageL( iNewIcon->Bitmap(), 
+                                              iNewIcon->Mask(), 
+                                              softkeyPosition, 
+                                              &Target(),
+                                              ETrue, 
+                                              ETrue ) 
+                );
+                // Menuinterface takes ownership
+                if ( err == KErrNone )
+                    {
+                    iNewIcon->SetBitmapsOwnedExternally( ETrue );
+                    }
+                if( menuBar )
+                    {
+                    menuBar->UiEngineL()->RefreshMenuL();
+                    }
+                }
+            }
+        else
+            {
+            User::Leave( KErrNotSupported );
+            }
+        }
+    
+    delete iNewIcon;
+    iNewIcon = NULL;
+    
+    UpdateContentPriorityL();
+    }
+
+void CImageTransactionElement::Reset()
+    {
+    if ( iImageDecoder )
+        {
+        delete iImageDecoder;
+        iImageDecoder = NULL;
+        }
+    
+    CTransactionElement::Reset();
+
+    delete iNewIcon;
+    iNewIcon = NULL;
+    }
+
+TBool CImageTransactionElement::IsSupported( CXnNodeAppIf& aTarget )
+    {
+    // Get type info
+    CXnType* typeInfo = aTarget.Type();
+    
+    if ( !typeInfo )
+        {
+        return EFalse;
+        }
+    
+    const TDesC8& type = typeInfo->Type();
+    
+    // image element and newsticker supported
+    return ( type == XnImageInterface::MXnImageInterface::Type() ||
+             type == XnNewstickerInterface::MXnNewstickerInterface::Type() ||
+             type == XnMenuInterface::MXnMenuInterface::Type() ||
+             type == KXnMenuItem ||
+             type == KXnMenu ||
+             type == XnPropertyNames::softkey::KNodeName );
+    }
+
+void CImageTransactionElement::CheckTypeL( CXnNodeAppIf& aTarget )
+    {
+    if ( !IsSupported( aTarget ) )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    }
+} // ns