/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_extensions.hxx"
#include "genericpropertyhandler.hxx"
#include "formmetadata.hxx"
#include "handlerhelper.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
#include <com/sun/star/reflection/XEnumTypeDescription.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/inspection/PropertyControlType.hpp>
#include <com/sun/star/inspection/XHyperlinkControl.hpp>
#include <com/sun/star/awt/XActionListener.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
/** === end UNO includes === **/
#include <tools/debug.hxx>
#include <comphelper/extract.hxx>

#include <algorithm>

//------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_GenericPropertyHandler()
{
	::pcr::OAutoRegistration< ::pcr::GenericPropertyHandler > aAutoRegistration;
}

//........................................................................
namespace pcr
{
//........................................................................

    using namespace ::com::sun::star::uno;
    using namespace ::com::sun::star::beans;
    using namespace ::com::sun::star::script;
    using namespace ::com::sun::star::frame;
    using namespace ::com::sun::star::lang;
    using namespace ::com::sun::star::util;
    using namespace ::com::sun::star::container;
    using namespace ::com::sun::star::reflection;
    using namespace ::com::sun::star::inspection;
    using ::com::sun::star::awt::XActionListener;
    using ::com::sun::star::awt::ActionEvent;

    //====================================================================
	//= EnumRepresentation
	//====================================================================
    class EnumRepresentation : public IPropertyEnumRepresentation
    {
    private:
        oslInterlockedCount                 m_refCount;
        Reference< XEnumTypeDescription >   m_xTypeDescription;
        Type                                m_aEnumType;

    public:
        EnumRepresentation( const Reference< XComponentContext >& _rxContext, const Type& _rEnumType );

        // IPropertyEnumRepresentation implementation
        virtual ::std::vector< ::rtl::OUString >
                                    SAL_CALL getDescriptions() const;
        virtual void                SAL_CALL getValueFromDescription( const ::rtl::OUString& _rDescription, ::com::sun::star::uno::Any& _out_rValue ) const;
        virtual ::rtl::OUString     SAL_CALL getDescriptionForValue( const ::com::sun::star::uno::Any& _rEnumValue ) const;

        // IReference implementation
        virtual oslInterlockedCount SAL_CALL acquire();
        virtual oslInterlockedCount SAL_CALL release();

    private:
        void            impl_getValues( Sequence< sal_Int32 >& _out_rValues ) const;

    private:
        EnumRepresentation();                                       // never implemented
        EnumRepresentation( const EnumRepresentation& );            // never implemented
        EnumRepresentation& operator=( const EnumRepresentation& ); // never implemented
    };

	//--------------------------------------------------------------------
    EnumRepresentation::EnumRepresentation( const Reference< XComponentContext >& _rxContext, const Type& _rEnumType )
        :m_refCount( 0 )
        ,m_aEnumType( _rEnumType )
    {
        try
        {
            if ( _rxContext.is() )
            {
                Reference< XHierarchicalNameAccess > xTypeDescProv(
                    _rxContext->getValueByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) ) ),
                    UNO_QUERY_THROW );

                m_xTypeDescription = Reference< XEnumTypeDescription >( xTypeDescProv->getByHierarchicalName( m_aEnumType.getTypeName() ), UNO_QUERY_THROW );
            }
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "EnumRepresentation::EnumRepresentation: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    ::std::vector< ::rtl::OUString > EnumRepresentation::getDescriptions() const
    {
        Sequence< ::rtl::OUString > aNames;
        try
        {
            if ( m_xTypeDescription.is() )
                aNames = m_xTypeDescription->getEnumNames();
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "EnumRepresentation::getDescriptions: caught an exception!" );
        }

        return ::std::vector< ::rtl::OUString >( aNames.getConstArray(), aNames.getConstArray() + aNames.getLength() );
    }

    //--------------------------------------------------------------------
    void EnumRepresentation::impl_getValues( Sequence< sal_Int32 >& _out_rValues ) const
    {
        _out_rValues.realloc( 0 );
        try
        {
            if  ( m_xTypeDescription.is() )
                _out_rValues = m_xTypeDescription->getEnumValues();
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "EnumRepresentation::impl_getValues: caught an exception!" );
        }
    }

    //--------------------------------------------------------------------
    void EnumRepresentation::getValueFromDescription( const ::rtl::OUString& _rDescription, Any& _out_rValue ) const
    {
        ::std::vector< ::rtl::OUString > aDescriptions( getDescriptions() );

        sal_Int32 index = ::std::find( aDescriptions.begin(), aDescriptions.end(),
            _rDescription ) - aDescriptions.begin();

        Sequence< sal_Int32 > aValues;
        impl_getValues( aValues );

        if ( ( index >= 0 ) && ( index < aValues.getLength() ) )
            _out_rValue = ::cppu::int2enum( aValues[ index ], m_aEnumType );
        else
        {
            DBG_ERROR( "EnumRepresentation::getValueFromDescription: cannot convert!" );
            _out_rValue.clear();
        }
    }

    //--------------------------------------------------------------------
    ::rtl::OUString EnumRepresentation::getDescriptionForValue( const Any& _rEnumValue ) const
    {
        ::rtl::OUString sDescription;

        sal_Int32 nAsInt = 0;
        OSL_VERIFY( ::cppu::enum2int( nAsInt, _rEnumValue ) );

        Sequence< sal_Int32 > aValues;
        impl_getValues( aValues );

        sal_Int32 index = ::std::find( aValues.getConstArray(), aValues.getConstArray() + aValues.getLength(),
            nAsInt ) - aValues.getConstArray();

        ::std::vector< ::rtl::OUString > aDescriptions( getDescriptions() );
        if ( ( index >= 0 ) && ( index < (sal_Int32)aDescriptions.size() ) )
            sDescription = aDescriptions[ index ];
        else
        {
             DBG_ERROR( "EnumRepresentation::getDescriptionForValue: cannot convert!" );
        }
        return sDescription;
    }

    //--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL EnumRepresentation::acquire()
    {
        return osl_incrementInterlockedCount( &m_refCount );
    }

    //--------------------------------------------------------------------
    oslInterlockedCount SAL_CALL EnumRepresentation::release()
    {
        if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
        {
           delete this;
           return 0;
        }
        return m_refCount;
    }

    //====================================================================
	//= UrlClickHandler
	//====================================================================
    typedef ::cppu::WeakImplHelper1 <   XActionListener
                                    >   UrlClickHandler_Base;
    class UrlClickHandler : public UrlClickHandler_Base
    {
        ComponentContext    m_aContext;
    public:
        UrlClickHandler( const ComponentContext& _rContext, const Reference< XHyperlinkControl >& _rxControl );

    protected:
        ~UrlClickHandler();

        // XActionListener
        virtual void SAL_CALL actionPerformed( const ActionEvent& rEvent ) throw (RuntimeException);

        // XEventListener
        virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);

    protected:
        void impl_dispatch_throw( const ::rtl::OUString& _rURL );
    };

	//--------------------------------------------------------------------
    DBG_NAME( UrlClickHandler )
	//--------------------------------------------------------------------
    UrlClickHandler::UrlClickHandler( const ComponentContext& _rContext, const Reference< XHyperlinkControl >& _rxControl )
        :m_aContext( _rContext )
    {
        if ( !_rxControl.is() )
            throw NullPointerException();

        osl_incrementInterlockedCount( &m_refCount );
        {
            _rxControl->addActionListener( this );
        }
        osl_decrementInterlockedCount( &m_refCount );
        OSL_ENSURE( m_refCount > 0, "UrlClickHandler::UrlClickHandler: leaking!" );

        DBG_CTOR( UrlClickHandler, NULL );
    }

    //--------------------------------------------------------------------
    UrlClickHandler::~UrlClickHandler()
    {
        DBG_DTOR( UrlClickHandler, NULL );
    }

    //--------------------------------------------------------------------
    void SAL_CALL UrlClickHandler::actionPerformed( const ActionEvent& rEvent ) throw (RuntimeException)
    {
        Reference< XPropertyControl > xControl( rEvent.Source, UNO_QUERY_THROW );
        Any aControlValue( xControl->getValue() );

        ::rtl::OUString sURL;
        if ( aControlValue.hasValue() && !( aControlValue >>= sURL ) )
            throw RuntimeException( ::rtl::OUString(), *this );

        if ( !sURL.getLength() )
            return;

        impl_dispatch_throw( sURL );
    }

    //--------------------------------------------------------------------
    void SAL_CALL UrlClickHandler::disposing( const EventObject& /*Source*/ ) throw (RuntimeException)
    {
        // not interested in
    }

    //--------------------------------------------------------------------
    void UrlClickHandler::impl_dispatch_throw( const ::rtl::OUString& _rURL )
    {
        Reference< XURLTransformer > xTransformer( m_aContext.createComponent( "com.sun.star.util.URLTransformer" ), UNO_QUERY_THROW );
        URL aURL; aURL.Complete = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:OpenHyperlink" ) );
        xTransformer->parseStrict( aURL );

        Reference< XDispatchProvider > xDispProv( m_aContext.createComponent( "com.sun.star.frame.Desktop" ), UNO_QUERY_THROW );
        Reference< XDispatch > xDispatch( xDispProv->queryDispatch( aURL, ::rtl::OUString(), 0 ), UNO_QUERY_THROW );

        Sequence< PropertyValue > aDispatchArgs(1);
        aDispatchArgs[0].Name   = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("URL"));
        aDispatchArgs[0].Value  <<= _rURL;

        xDispatch->dispatch( aURL, aDispatchArgs );
    }

    //====================================================================
	//= GenericPropertyHandler
	//====================================================================
    DBG_NAME( GenericPropertyHandler )
	//--------------------------------------------------------------------
    GenericPropertyHandler::GenericPropertyHandler( const Reference< XComponentContext >& _rxContext )
        :GenericPropertyHandler_Base( m_aMutex )
        ,m_aContext( _rxContext )
        ,m_aPropertyListeners( m_aMutex )
        ,m_bPropertyMapInitialized( false )
    {
        DBG_CTOR( GenericPropertyHandler, NULL );

		m_xTypeConverter = Reference< XTypeConverter >(
			m_aContext.createComponent( "com.sun.star.script.Converter" ),
			UNO_QUERY_THROW
		);
    }

	//--------------------------------------------------------------------
    GenericPropertyHandler::~GenericPropertyHandler()
    {
        DBG_DTOR( GenericPropertyHandler, NULL );
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SAL_CALL GenericPropertyHandler::getImplementationName(  ) throw (RuntimeException)
    {
        return getImplementationName_static();
    }

    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL GenericPropertyHandler::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
    {
        StlSyntaxSequence< ::rtl::OUString > aAllServices( getSupportedServiceNames() );
        return ::std::find( aAllServices.begin(), aAllServices.end(), ServiceName ) != aAllServices.end();
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getSupportedServiceNames(  ) throw (RuntimeException)
    {
        return getSupportedServiceNames_static();
    }

    //--------------------------------------------------------------------
    ::rtl::OUString SAL_CALL GenericPropertyHandler::getImplementationName_static(  ) throw (RuntimeException)
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.GenericPropertyHandler" ) );
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getSupportedServiceNames_static(  ) throw (RuntimeException)
    {
        Sequence< ::rtl::OUString > aSupported( 1 );
        aSupported[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.inspection.GenericPropertyHandler" ) );
        return aSupported;
    }

    //--------------------------------------------------------------------
    Reference< XInterface > SAL_CALL GenericPropertyHandler::Create( const Reference< XComponentContext >& _rxContext )
    {
        return *( new GenericPropertyHandler( _rxContext ) );
    }

    //--------------------------------------------------------------------
    void SAL_CALL GenericPropertyHandler::inspect( const Reference< XInterface >& _rxIntrospectee ) throw (RuntimeException, NullPointerException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( !_rxIntrospectee.is() )
            throw NullPointerException();

        // revoke old property change listeners
        ::cppu::OInterfaceIteratorHelper iterRemove( m_aPropertyListeners );
        ::cppu::OInterfaceIteratorHelper iterReAdd( m_aPropertyListeners ); // this holds a copy of the container ...
        while ( iterRemove.hasMoreElements() )
            m_xComponent->removePropertyChangeListener( ::rtl::OUString(), static_cast< XPropertyChangeListener* >( iterRemove.next() ) );

        m_xComponentIntrospectionAccess.clear();
        m_xComponent.clear();
        m_xPropertyState.clear();

        // create an introspection adapter for the component
        Reference< XIntrospection > xIntrospection;
        if ( !m_aContext.createComponent( "com.sun.star.beans.Introspection", xIntrospection ) )
            throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create an instance of the service com.sun.star.beans.Introspection." ) ), *this );

        Reference< XIntrospectionAccess > xIntrospectionAccess( xIntrospection->inspect( makeAny( _rxIntrospectee ) ) );
        if ( !xIntrospectionAccess.is() )
            throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The introspection service could not handle the given component." ) ), *this );

        m_xComponent = Reference< XPropertySet >( xIntrospectionAccess->queryAdapter( XPropertySet::static_type() ), UNO_QUERY_THROW );
        // now that we survived so far, remember m_xComponentIntrospectionAccess
        m_xComponentIntrospectionAccess = xIntrospectionAccess;
        m_xPropertyState = m_xPropertyState.query( m_xComponent );

        m_bPropertyMapInitialized = false;
        m_aProperties.clear();

        // re-add the property change listeners
        while ( iterReAdd.hasMoreElements() )
            m_xComponent->addPropertyChangeListener( ::rtl::OUString(), static_cast< XPropertyChangeListener* >( iterReAdd.next() ) );
    }

    //--------------------------------------------------------------------
    Any SAL_CALL GenericPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !m_xComponent.is() )
            throw UnknownPropertyException();

        return m_xComponent->getPropertyValue( _rPropertyName );
    }

    //--------------------------------------------------------------------
    void SAL_CALL GenericPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !m_xComponent.is() )
            throw UnknownPropertyException();

        m_xComponent->setPropertyValue( _rPropertyName, _rValue );
    }

    //--------------------------------------------------------------------
    ::rtl::Reference< IPropertyEnumRepresentation > GenericPropertyHandler::impl_getEnumConverter( const Type& _rEnumType )
    {
        ::rtl::Reference< IPropertyEnumRepresentation >& rConverter = m_aEnumConverters[ _rEnumType ];
        if ( !rConverter.is() )
            rConverter = new EnumRepresentation( m_aContext.getUNOContext(), _rEnumType );
        return rConverter;
    }

    //--------------------------------------------------------------------
    Any SAL_CALL GenericPropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();

        PropertyMap::const_iterator pos = m_aProperties.find( _rPropertyName );
        if ( pos == m_aProperties.end() )
            throw UnknownPropertyException();

        Any aPropertyValue;
        if ( !_rControlValue.hasValue() )
            // NULL is converted to NULL
            return aPropertyValue;

        if ( pos->second.Type.getTypeClass() == TypeClass_ENUM )
        {
            ::rtl::OUString sControlValue;
            OSL_VERIFY( _rControlValue >>= sControlValue );
            impl_getEnumConverter( pos->second.Type )->getValueFromDescription( sControlValue, aPropertyValue );
        }
        else
            aPropertyValue = PropertyHandlerHelper::convertToPropertyValue( m_aContext.getContext(),m_xTypeConverter, pos->second, _rControlValue );

        return aPropertyValue;
    }

    //--------------------------------------------------------------------
    Any SAL_CALL GenericPropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();

        PropertyMap::const_iterator pos = m_aProperties.find( _rPropertyName );
        if ( pos == m_aProperties.end() )
            throw UnknownPropertyException();

        Any aControlValue;
        if ( !_rPropertyValue.hasValue() )
            // NULL is converted to NULL
            return aControlValue;

        if ( pos->second.Type.getTypeClass() == TypeClass_ENUM )
        {
            aControlValue <<= impl_getEnumConverter( pos->second.Type )->getDescriptionForValue( _rPropertyValue );
        }
        else
            aControlValue = PropertyHandlerHelper::convertToControlValue( m_aContext.getContext(),m_xTypeConverter, _rPropertyValue, _rControlValueType );
        return aControlValue;
    }

    //--------------------------------------------------------------------
    PropertyState SAL_CALL GenericPropertyHandler::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyState eState = PropertyState_DIRECT_VALUE;
        if ( m_xPropertyState.is() )
            eState = m_xPropertyState->getPropertyState( _rPropertyName );
        return eState;
    }

    //--------------------------------------------------------------------
    void SAL_CALL GenericPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
    {
        if ( !_rxListener.is() )
            throw NullPointerException();

        ::osl::MutexGuard aGuard( m_aMutex );
        m_aPropertyListeners.addInterface( _rxListener );
        if ( m_xComponent.is() )
        {
            try
            {
                m_xComponent->addPropertyChangeListener( ::rtl::OUString(), _rxListener );
            }
            catch( const UnknownPropertyException& )
            {
                OSL_ENSURE( false, "GenericPropertyHandler::addPropertyChangeListener:\nThe inspected component does not allow registering for all properties at once! This violates the interface contract!" );
            }
        }
    }

    //--------------------------------------------------------------------
    void SAL_CALL GenericPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( m_xComponent.is() )
        {
            try
            {
                m_xComponent->removePropertyChangeListener( ::rtl::OUString(), _rxListener );
            }
            catch( const UnknownPropertyException& )
            {
                OSL_ENSURE( false, "GenericPropertyHandler::removePropertyChangeListener:\nThe inspected component does not allow de-registering for all properties at once! This violates the interface contract!" );
            }
        }
        m_aPropertyListeners.removeInterface( _rxListener );
    }

    //--------------------------------------------------------------------
    void GenericPropertyHandler::impl_ensurePropertyMap()
    {
        if ( !m_bPropertyMapInitialized )
        {
            m_bPropertyMapInitialized = true;
            try
            {
                Reference< XPropertySetInfo > xPSI;
                if ( m_xComponent.is() )
                    xPSI = m_xComponent->getPropertySetInfo();
                Sequence< Property > aProperties;
                if ( xPSI.is() )
                    aProperties = xPSI->getProperties();
                DBG_ASSERT( aProperties.getLength(), "GenericPropertyHandler::getSupportedProperties: no properties!" );

                for ( const Property* pProperties = aProperties.getConstArray();
                      pProperties != aProperties.getConstArray() + aProperties.getLength();
                      ++pProperties
                    )
                {
                    switch ( pProperties->Type.getTypeClass() )
                    {
                    case TypeClass_BOOLEAN:
                    case TypeClass_BYTE:
                    case TypeClass_SHORT:
                    case TypeClass_UNSIGNED_SHORT:
                    case TypeClass_LONG:
                    case TypeClass_UNSIGNED_LONG:
                    case TypeClass_HYPER:
                    case TypeClass_UNSIGNED_HYPER:
                    case TypeClass_FLOAT:
                    case TypeClass_DOUBLE:
                    case TypeClass_ENUM:
                    case TypeClass_STRING:
                        // allowed, we can handle this type
                        break;

                    case TypeClass_SEQUENCE:
                    {
                        TypeClass eElementTypeClass = ::comphelper::getSequenceElementType( pProperties->Type ).getTypeClass();
                        if  (   ( eElementTypeClass != TypeClass_STRING )
                            &&  ( eElementTypeClass != TypeClass_BYTE )
                            &&  ( eElementTypeClass != TypeClass_SHORT )
                            &&  ( eElementTypeClass != TypeClass_UNSIGNED_SHORT )
                            &&  ( eElementTypeClass != TypeClass_LONG )
                            &&  ( eElementTypeClass != TypeClass_UNSIGNED_LONG )
                            )
                            // can only handle the above
                            continue;
                    }
                    break;

                    default:
                        // next property, we don't support this type
                        continue;
                    }

                    m_aProperties.insert( PropertyMap::value_type( pProperties->Name, *pProperties ) );
                }
            }
            catch( const Exception& )
            {
            	OSL_ENSURE( sal_False, "GenericPropertyHandler::impl_ensurePropertyMap: caught an exception!" );
            }
        }
    }

    //--------------------------------------------------------------------
    Sequence< Property > SAL_CALL GenericPropertyHandler::getSupportedProperties() throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();

        Sequence< Property > aReturn( m_aProperties.size() );
        ::std::transform( m_aProperties.begin(), m_aProperties.end(),
            aReturn.getArray(), ::std::select2nd< PropertyMap::value_type >() );
        return aReturn;
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
    {
        // no superseded properties at all. This handler offers the very basic PropertyHandler
        // functionality, so it's much more likely that other handlers want to supersede
        // *our* properties ....
        return Sequence< ::rtl::OUString >( );
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL GenericPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
    {
        // This basic PropertyHandler implementation is too dumb^Wgeneric to know
        // anything about property dependencies
        return Sequence< ::rtl::OUString >( );
    }

    //--------------------------------------------------------------------
    LineDescriptor SAL_CALL GenericPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
        const Reference< XPropertyControlFactory >& _rxControlFactory )
        throw (UnknownPropertyException, NullPointerException, RuntimeException)
    {
        if ( !_rxControlFactory.is() )
            throw NullPointerException();

        ::osl::MutexGuard aGuard( m_aMutex );
        const_cast< GenericPropertyHandler* >( this )->impl_ensurePropertyMap();

        PropertyMap::const_iterator pos = m_aProperties.find( _rPropertyName );
        if ( pos == m_aProperties.end() )
            throw UnknownPropertyException();

        LineDescriptor aDescriptor;
        aDescriptor.DisplayName = _rPropertyName;
        switch ( pos->second.Type.getTypeClass() )
        {
        case TypeClass_ENUM:
            aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory,
                impl_getEnumConverter( pos->second.Type )->getDescriptions(),
                PropertyHandlerHelper::requiresReadOnlyControl( pos->second.Attributes ),
                sal_False );
            break;
        case TypeClass_STRING:
        {
            // some special handling for URL properties
            bool bIsURLProperty = ( _rPropertyName.getLength() >= 3 ) && _rPropertyName.matchAsciiL( "URL", 3, _rPropertyName.getLength() - 3 );
            if ( bIsURLProperty )
            {
                aDescriptor.Control = _rxControlFactory->createPropertyControl(
                    PropertyControlType::HyperlinkField, PropertyHandlerHelper::requiresReadOnlyControl( pos->second.Attributes ) );

                Reference< XHyperlinkControl > xControl( aDescriptor.Control, UNO_QUERY_THROW );
                Reference< XActionListener > xEnsureDelete( new UrlClickHandler( m_aContext, xControl ) );
            }
        }
        break;
        default:
            break;
        }
        // fallback
        if ( !aDescriptor.Control.is() )
            PropertyHandlerHelper::describePropertyLine( pos->second, aDescriptor, _rxControlFactory );

        aDescriptor.Category = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "General" ) );
        return aDescriptor;
    }

    //--------------------------------------------------------------------
    ::sal_Bool SAL_CALL GenericPropertyHandler::isComposable( const ::rtl::OUString& /*_rPropertyName*/ ) throw (UnknownPropertyException, RuntimeException)
    {
        return sal_False;
    }

    //--------------------------------------------------------------------
    InteractiveSelectionResult SAL_CALL GenericPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& /*_rPropertyName*/, sal_Bool /*_bPrimary*/, Any& /*_rData*/, const Reference< XObjectInspectorUI >& /*_rxInspectorUI*/ ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
    {
        DBG_ERROR( "GenericPropertyHandler::onInteractivePropertySelection: I'm too dumb to know anything about property browse buttons!" );
        return InteractiveSelectionResult_Cancelled;
    }

    //--------------------------------------------------------------------
    void SAL_CALL GenericPropertyHandler::actuatingPropertyChanged( const ::rtl::OUString& /*_rActuatingPropertyName*/, const Any& /*_rNewValue*/, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& /*_rxInspectorUI*/, sal_Bool /*_bFirstTimeInit*/ ) throw (NullPointerException, RuntimeException)
    {
        DBG_ERROR( "GenericPropertyHandler::actuatingPropertyChanged: no no no, I did not register for any actuating properties!" );
    }

    //--------------------------------------------------------------------
    sal_Bool SAL_CALL GenericPropertyHandler::suspend( sal_Bool /*_bSuspend*/ ) throw (RuntimeException)
    {
        return sal_True;
    }

    //--------------------------------------------------------------------
    void SAL_CALL GenericPropertyHandler::disposing()
    {
        m_aPropertyListeners.clear();
            // not disposeAndClear: the listeners are (virtually) listeners at our introspectee, not
            // at this handler instance
    }

    //--------------------------------------------------------------------
    IMPLEMENT_FORWARD_XCOMPONENT( GenericPropertyHandler, GenericPropertyHandler_Base );

//........................................................................
}   // namespace pcr
//........................................................................
