idlehomescreen/xmluirendering/uiengine/src/xnpropertylist.cpp
changeset 0 f72a12da539e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluirendering/uiengine/src/xnpropertylist.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,397 @@
+/*
+* Copyright (c) 2002-2004 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:  Xuikon property list
+*
+*/
+
+//  INCLUDES
+#include "xnpropertylist.h"
+#include "xnproperty.h"
+#include "xnproperty.h"
+#include "xnpropertycomparator.h"
+#include "xncomparator.h"
+#include "xnmap.h"
+#include "xndomproperty.h"
+#include "xndompropertyvalue.h"
+#include "xnpanic.h"
+
+// LOCAL CONSTANTS AND MACROS
+_LIT8( KPseudoClassFocus, "focus" );
+_LIT8( KPseudoClassPassiveFocus, "passivefocus" );
+_LIT8( KPseudoClassHold, "hold" );
+_LIT8( KPseudoClassHover, "hover" );
+_LIT8( KPseudoClassLink, "link" );
+_LIT8( KPseudoClassVisited, "visited" );
+_LIT8( KPseudoClassActive, "active" );
+_LIT8( KPseudoClassEdit, "edit" );
+_LIT8( KPseudoClassPressedDown, "presseddown" );
+
+// LOCAL FUNCTION PROTOTYPES
+static const TDesC8& PseudoClassName(
+    CXnDomProperty::TPseudoClass aPseudoClass );
+static CXnDomProperty::TPseudoClass PseudoClassFromName(
+    const TDesC8& aName );
+static TInt FindPseudoClass(
+    const RArray< CXnDomProperty::TPseudoClass >& aArray,
+    const TDesC8& aPseudoClass );
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// PseudoClassName
+// -----------------------------------------------------------------------------
+//
+static const TDesC8& PseudoClassName( CXnDomProperty::TPseudoClass aPseudoClass )
+    {
+    switch ( aPseudoClass )
+        {
+        case CXnDomProperty::EFocus:
+            return KPseudoClassFocus;
+        case CXnDomProperty::EPassiveFocus:
+            return KPseudoClassPassiveFocus;
+        case CXnDomProperty::EHold:
+            return KPseudoClassHold;
+        case CXnDomProperty::EHover:
+            return KPseudoClassHover;
+        case CXnDomProperty::ELink:
+            return KPseudoClassLink;
+        case CXnDomProperty::EVisited:
+            return KPseudoClassVisited;
+        case CXnDomProperty::EActive:
+            return KPseudoClassActive;
+        case CXnDomProperty::EEdit:
+            return KPseudoClassEdit;
+        case CXnDomProperty::EPressedDown:
+            return KPseudoClassPressedDown;
+        default:
+            return KNullDesC8;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// PseudoClassFromName
+// -----------------------------------------------------------------------------
+//
+static CXnDomProperty::TPseudoClass PseudoClassFromName( const TDesC8& aName )
+    {
+    if ( aName == KPseudoClassFocus )
+        {
+        return CXnDomProperty::EFocus;
+        }
+    else if ( aName == KPseudoClassPassiveFocus )
+        {
+        return CXnDomProperty::EPassiveFocus;
+        }
+    else if ( aName == KPseudoClassHold )
+        {
+        return CXnDomProperty::EHold;
+        }
+    else if ( aName == KPseudoClassHover )
+        {
+        return CXnDomProperty::EHover;
+        }
+    else if ( aName == KPseudoClassLink )
+        {
+        return CXnDomProperty::ELink;
+        }
+    else if ( aName == KPseudoClassVisited )
+        {
+        return CXnDomProperty::EVisited;
+        }
+    else if ( aName == KPseudoClassActive )
+        {
+        return CXnDomProperty::EActive;
+        }
+    else if ( aName == KPseudoClassEdit )
+        {
+        return CXnDomProperty::EEdit;
+        }
+    else if ( aName == KPseudoClassPressedDown )
+        {
+        return CXnDomProperty::EPressedDown;
+        }
+    return CXnDomProperty::ENone;
+    }
+
+// -----------------------------------------------------------------------------
+// FindPseudoClass
+// -----------------------------------------------------------------------------
+//
+static TInt FindPseudoClass(
+    const RArray< CXnDomProperty::TPseudoClass >& aArray,
+    const TDesC8& aPseudoClass )
+    {
+    for ( TInt i = aArray.Count() - 1; i >= 0; --i )
+        {
+        CXnDomProperty::TPseudoClass item = aArray[i];
+        if ( PseudoClassName( item ) == aPseudoClass )
+            {
+            return i;
+            }
+        }
+    return KErrNotFound;
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::NewL()
+// -----------------------------------------------------------------------------
+//
+CXnPropertyList* CXnPropertyList::NewL()
+    {
+    CXnPropertyList* self = new ( ELeave ) CXnPropertyList;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();//self
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::~CXnPropertyList()
+// -----------------------------------------------------------------------------
+//
+CXnPropertyList::~CXnPropertyList()
+    {
+    delete iMap;
+
+    iCurrentPseudoClasses.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::CXnPropertyList()
+// -----------------------------------------------------------------------------
+//
+CXnPropertyList::CXnPropertyList()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::ConstructL()
+// -----------------------------------------------------------------------------
+//
+void CXnPropertyList::ConstructL()
+    {
+    iMap = CXnMap::NewL( new ( ELeave ) TXnPropertyComparator );
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::SetPropertyL
+// Set a property.
+// -----------------------------------------------------------------------------
+//
+void CXnPropertyList::SetPropertyL( CXnProperty* aProperty )
+    {
+    CXnPropertyKey key;
+    key.iString = &( aProperty->Property()->Name() );
+    key.iPseudoClass = aProperty->Property()->PseudoClass();
+
+    CXnProperty* tmp = static_cast< CXnProperty* >( iMap->Get( key ) );
+    if ( tmp == aProperty )
+        {
+        return;
+        }
+    TBool replaced = EFalse;
+    for ( TInt i = ( iMap->Container() ).Count() - 1; i >= 0; --i )
+        {
+        tmp = static_cast< CXnProperty* >( ( iMap->Container() )[i] );
+        if ( aProperty->Property()->PseudoClass() == CXnDomProperty::ENone )
+            {
+            const TDesC8& tmpName = tmp->Property()->Name();
+            const TDesC8& propertyName = aProperty->Property()->Name();
+            if ( tmpName == propertyName )
+                {
+                if ( tmp->Property()->PseudoClass() != CXnDomProperty::ENone )
+                    {
+                    TBool pseudoMatch = EFalse;
+                    for ( TInt j = iCurrentPseudoClasses.Count() - 1; j >= 0; --j )
+                        {
+                        CXnDomProperty::TPseudoClass pseudoClass =
+                            iCurrentPseudoClasses[j];
+                        if ( tmp->Property()->PseudoClass() == pseudoClass )
+                            {
+                            pseudoMatch = ETrue;
+                            break;
+                            }
+                        }
+                    if ( !pseudoMatch )
+                        {
+                        continue;
+                        }
+                    CXnProperty* newProperty = aProperty->CloneL();
+                    CleanupStack::PushL( newProperty );
+                    newProperty->Property()->SetPseudoClass(
+                        tmp->Property()->PseudoClass() );
+                    // add new object
+                    if ( ( iMap->Container()).Append( newProperty ) != KErrNone )
+                        {
+                        User::Leave( KXnErrAddingProperyToListFailed );
+                        }
+                    CleanupStack::Pop( newProperty );
+                    }
+                if ( ( iMap->Container() ).Append( aProperty )!= KErrNone )
+                    {
+                    User::Leave( KXnErrAddingProperyToListFailed_2 );
+                    }
+                replaced = ETrue;
+                // remove old object
+                delete tmp;
+                ( iMap->Container() ).Remove( i );
+                }
+            }
+        else
+            {
+            const TDesC8& tmpName = tmp->Property()->Name();
+            const TDesC8& propertyName = aProperty->Property()->Name();
+            if ( tmp->Property()->PseudoClass() != CXnDomProperty::ENone &&
+                 tmp->Property()->PseudoClass() == aProperty->Property()->PseudoClass() &&
+                 tmpName == propertyName )
+                {
+                if ( ( iMap->Container() ).Append( aProperty )!= KErrNone )
+                    {
+                    User::Leave( KXnErrAddingProperyToListFailed_3 );
+                    }
+                replaced = ETrue;
+                // remove old object
+                delete tmp;
+                ( iMap->Container() ).Remove( i );
+                }
+            }
+        }
+    if ( replaced )
+        {
+        return;
+        }
+    if ( aProperty->Property()->PseudoClass() != CXnDomProperty::ENone )
+        {
+        for ( TInt i = iCurrentPseudoClasses.Count() - 1; i >= 0; --i )
+            {
+            CXnDomProperty::TPseudoClass pseudoClass = iCurrentPseudoClasses[i];
+            CXnProperty* newProperty = aProperty->CloneL();
+            CleanupStack::PushL( newProperty );
+            newProperty->Property()->SetPseudoClass( pseudoClass );
+            // add new object
+            User::LeaveIfError( ( iMap->Container() ).Append( newProperty ) );
+            if ( ( iMap->Container() ).Append( newProperty )!= KErrNone )
+                {
+                User::Leave( KXnErrAddingProperyToListFailed_4 );
+                }
+            CleanupStack::Pop( newProperty );
+            }
+        }
+    if ( ( iMap->Container() ).Append( aProperty )!= KErrNone )
+        {
+        User::Leave( KXnErrAddingProperyToListFailed_5 );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::GetProperty
+// Gets a property.
+// -----------------------------------------------------------------------------
+//
+CXnProperty* CXnPropertyList::GetProperty( const TDesC8& aKey ) const
+    {
+    CXnPropertyKey key;
+    key.iString = &aKey;
+    for ( TInt i = iCurrentPseudoClasses.Count() - 1; i >= 0; --i )
+        {
+        key.iPseudoClass = iCurrentPseudoClasses[i];
+        CXnProperty* property = static_cast< CXnProperty* >( iMap->Get( key ) );
+        if ( property )
+            {
+            return property;
+            }
+        }
+
+    key.iPseudoClass = CXnDomProperty::ENone;
+    CXnProperty* property = static_cast< CXnProperty* >( iMap->Get( key ) );
+    if ( property )
+        {
+        return property;
+        }
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::SetPseudoClassL
+// Set a pseudoclass
+// -----------------------------------------------------------------------------
+//
+TBool CXnPropertyList::SetStateL( const TDesC8& aState )
+    {
+    if ( FindPseudoClass( iCurrentPseudoClasses, aState ) < 0 )
+        {
+        User::LeaveIfError( iCurrentPseudoClasses.Append(
+            PseudoClassFromName( aState ) ) );
+        return ETrue;
+        }
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::IsStateSet
+// Check whether a state is set or not
+// -----------------------------------------------------------------------------
+//
+TBool CXnPropertyList::IsStateSet( const TDesC8& aState )
+    {
+    if ( FindPseudoClass( iCurrentPseudoClasses, aState ) < 0 )
+        {
+        return EFalse;
+        }
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::UnsetPseudoClass
+// Unset a pseudoclass
+// -----------------------------------------------------------------------------
+//
+TBool CXnPropertyList::UnsetState( const TDesC8& aState )
+    {
+    TInt index = FindPseudoClass( iCurrentPseudoClasses, aState );
+    if ( index < 0 )
+        {
+        return EFalse;
+        }
+    iCurrentPseudoClasses.Remove( index );
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnPropertyList::CloneL
+// Clone the list
+// -----------------------------------------------------------------------------
+//
+CXnPropertyList* CXnPropertyList::CloneL()
+    {
+    CXnPropertyList* clone = CXnPropertyList::NewL();
+    CleanupStack::PushL( clone );
+    TInt count = iCurrentPseudoClasses.Count();
+    for ( TInt i = 0; i < count; ++i )
+        {
+        User::LeaveIfError( clone->iCurrentPseudoClasses.Append(
+            iCurrentPseudoClasses[i] ) );
+        }
+    clone->iMap = CXnMap::NewL( new ( ELeave ) TXnPropertyComparator );
+    count = iMap->Container().Count();
+    for ( TInt i = 0; i < count; ++i )
+        {
+        User::LeaveIfError( clone->iMap->Container().Append(
+            static_cast< CXnProperty* >( iMap->Container()[i] )->CloneL() ) );
+        }
+    CleanupStack::Pop( clone );
+    return clone;
+    }