/**************************************************************
 * 
 * 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 "propertyhandler.hxx"
#include "formmetadata.hxx"
#include "formstrings.hxx"
#include "handlerhelper.hxx"
#include "cellbindinghelper.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/inspection/XObjectInspectorUI.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/container/XMap.hpp>
#include <com/sun/star/inspection/XNumericControl.hpp>
#include <com/sun/star/util/MeasureUnit.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <com/sun/star/table/XColumnRowRange.hpp>
#include <com/sun/star/table/XCellRange.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/form/XGridColumnFactory.hpp>
/** === end UNO includes === **/

#include <cppuhelper/interfacecontainer.hxx>
#include <comphelper/componentbase.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>

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

	/** === begin UNO using === **/
	using ::com::sun::star::uno::Reference;
	using ::com::sun::star::uno::XInterface;
	using ::com::sun::star::uno::UNO_QUERY;
	using ::com::sun::star::uno::UNO_QUERY_THROW;
	using ::com::sun::star::uno::UNO_SET_THROW;
	using ::com::sun::star::uno::Exception;
	using ::com::sun::star::uno::RuntimeException;
	using ::com::sun::star::uno::Any;
	using ::com::sun::star::uno::makeAny;
	using ::com::sun::star::uno::Sequence;
	using ::com::sun::star::uno::Type;
    using ::com::sun::star::uno::XComponentContext;
    using ::com::sun::star::beans::UnknownPropertyException;
    using ::com::sun::star::beans::Property;
    using ::com::sun::star::awt::XControlModel;
    using ::com::sun::star::drawing::XControlShape;
    using ::com::sun::star::container::XMap;
    using ::com::sun::star::inspection::LineDescriptor;
    using ::com::sun::star::inspection::XPropertyControlFactory;
    using ::com::sun::star::lang::NullPointerException;
    using ::com::sun::star::beans::Optional;
    using ::com::sun::star::inspection::XNumericControl;
    using ::com::sun::star::drawing::XShape;
    using ::com::sun::star::beans::PropertyChangeEvent;
    using ::com::sun::star::lang::EventObject;
    using ::com::sun::star::beans::XPropertySet;
    using ::com::sun::star::beans::XPropertyChangeListener;
    using ::com::sun::star::text::TextContentAnchorType;
    using ::com::sun::star::text::TextContentAnchorType_AT_PARAGRAPH;
    using ::com::sun::star::text::TextContentAnchorType_AS_CHARACTER;
    using ::com::sun::star::beans::XPropertySetInfo;
    using ::com::sun::star::inspection::XObjectInspectorUI;
    using ::com::sun::star::lang::XServiceInfo;
    using ::com::sun::star::sheet::XSpreadsheet;
    using ::com::sun::star::table::XColumnRowRange;
    using ::com::sun::star::table::XTableColumns;
    using ::com::sun::star::table::XTableRows;
    using ::com::sun::star::table::XCellRange;
    using ::com::sun::star::container::XIndexAccess;
    using ::com::sun::star::container::XChild;
    using ::com::sun::star::form::XGridColumnFactory;
	/** === end UNO using === **/
    namespace MeasureUnit = ::com::sun::star::util::MeasureUnit;

    typedef ::com::sun::star::awt::Point    AwtPoint;
    typedef ::com::sun::star::awt::Size     AwtSize;

    #define ANCHOR_TO_SHEET 0
    #define ANCHOR_TO_CELL  1

    //====================================================================
	//= BroadcastHelperBase
	//====================================================================
    class BroadcastHelperBase
    {
    protected:
        BroadcastHelperBase( ::osl::Mutex& _rMutex )
            :maBHelper( _rMutex )
        {
        }

    protected:
        ::cppu::OBroadcastHelper& getBroadcastHelper() { return maBHelper; }

    private:
        ::cppu::OBroadcastHelper    maBHelper;
    };

    //====================================================================
	//= ShapeGeometryChangeNotifier - declaration
	//====================================================================
    /** helper class to work around the ...unfortunate implementation of property change broadcasts
        in the XShape implementation, which broadcasts way too generous and unspecified
    */
    typedef ::comphelper::ComponentBase ShapeGeometryChangeNotifier_CBase;
    typedef ::cppu::WeakImplHelper1 <   ::com::sun::star::beans::XPropertyChangeListener
                                    >   ShapeGeometryChangeNotifier_IBase;

    class ShapeGeometryChangeNotifier   :public BroadcastHelperBase
                                        ,public ShapeGeometryChangeNotifier_CBase
                                        ,public ShapeGeometryChangeNotifier_IBase
    {
    public:
        ShapeGeometryChangeNotifier( ::cppu::OWeakObject& _rParent, ::osl::Mutex& _rParentMutex, const Reference< XShape >& _shape )
            :BroadcastHelperBase( _rParentMutex )
            ,ShapeGeometryChangeNotifier_CBase( BroadcastHelperBase::getBroadcastHelper(), ::comphelper::ComponentBase::NoInitializationNeeded() )
            ,ShapeGeometryChangeNotifier_IBase()
            ,m_rParent( _rParent )
            ,m_aPropertyChangeListeners( _rParentMutex )
            ,m_xShape( _shape )
        {
            ENSURE_OR_THROW( m_xShape.is(), "illegal shape!" );
            impl_init_nothrow();
        }

        // property change broadcasting
        void addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
        {
            m_aPropertyChangeListeners.addInterface( _listener );
        }
        void removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener )
        {
            m_aPropertyChangeListeners.removeInterface( _listener );
        }

        // XComponent equivalent
        void dispose()
        {
            ::osl::MutexGuard aGuard( getMutex() );
            impl_dispose_nothrow();
        }

        // XInterface
        virtual void SAL_CALL acquire(  ) throw ()
        {
            m_rParent.acquire();
        }

        virtual void SAL_CALL release(  ) throw ()
        {
            m_rParent.release();
        }

        // XPropertyChangeListener
        virtual void SAL_CALL propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException);

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

    protected:
        virtual ~ShapeGeometryChangeNotifier()
        {
            if ( !getBroadcastHelper().bDisposed )
            {
                acquire();
                dispose();
            }
        }

    protected:
        ::cppu::OBroadcastHelper& getBroadcastHelper() { return BroadcastHelperBase::getBroadcastHelper(); }

    private:
        void    impl_init_nothrow();
        void    impl_dispose_nothrow();

    private:
        ::cppu::OWeakObject&                m_rParent;
        ::cppu::OInterfaceContainerHelper   m_aPropertyChangeListeners;
        Reference< XShape >                 m_xShape;
    };

	//====================================================================
	//= FormGeometryHandler - declaration
	//====================================================================
    class FormGeometryHandler;
    typedef HandlerComponentBase< FormGeometryHandler > FormGeometryHandler_Base;
    /** a property handler for any virtual string properties
    */
    class FormGeometryHandler : public FormGeometryHandler_Base
	{
    public:
        FormGeometryHandler(
            const Reference< XComponentContext >& _rxContext
        );

        static ::rtl::OUString SAL_CALL getImplementationName_static(  ) throw (RuntimeException);
        static Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames_static(  ) throw (RuntimeException);

    protected:
        ~FormGeometryHandler();

    protected:
        // XPropertyHandler overriables
        virtual Any                         SAL_CALL getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException);
        virtual void                        SAL_CALL setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException);
        virtual LineDescriptor              SAL_CALL describePropertyLine( const ::rtl::OUString& _rPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::inspection::XPropertyControlFactory >& _rxControlFactory ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException);
        virtual void                        SAL_CALL addPropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual void                        SAL_CALL removePropertyChangeListener( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& _rxListener ) throw (::com::sun::star::uno::RuntimeException);
        virtual Sequence< ::rtl::OUString > SAL_CALL getActuatingProperties( ) throw (RuntimeException);
        virtual void                        SAL_CALL actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& _rOldValue, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool _bFirstTimeInit ) throw (NullPointerException, RuntimeException);

        // OComponentHandler overridables
        virtual void SAL_CALL disposing();

        // PropertyHandler overridables
        virtual Sequence< Property >        SAL_CALL doDescribeSupportedProperties() const;

    protected:
        virtual void onNewComponent();

    private:
        bool    impl_haveTextAnchorType_nothrow() const;
        bool    impl_haveSheetAnchorType_nothrow() const;
        void    impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const;

    private:
        Reference< XControlShape >                      m_xAssociatedShape;
        Reference< XPropertySet >                       m_xShapeProperties;
        ::rtl::Reference< ShapeGeometryChangeNotifier > m_xChangeNotifier;
	};

    //====================================================================
	//= FormGeometryHandler - implementation
	//====================================================================
    DBG_NAME( FormGeometryHandler )
	//--------------------------------------------------------------------
    FormGeometryHandler::FormGeometryHandler( const Reference< XComponentContext >& _rxContext )
        :FormGeometryHandler_Base( _rxContext )
    {
        DBG_CTOR( FormGeometryHandler, NULL );
    }

	//--------------------------------------------------------------------
    FormGeometryHandler::~FormGeometryHandler( )
    {
        if ( !rBHelper.bDisposed )
        {
            acquire();
            dispose();
        }

        DBG_DTOR( FormGeometryHandler, NULL );
    }

    //--------------------------------------------------------------------
    void FormGeometryHandler::onNewComponent()
    {
        if ( m_xChangeNotifier.is() )
        {
            m_xChangeNotifier->dispose();
            m_xChangeNotifier.clear();
        }
        m_xAssociatedShape.clear();
        m_xShapeProperties.clear();

        FormGeometryHandler_Base::onNewComponent();

        try
        {
            Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
            if ( xControlModel.is() )
            {
                // do not ask the map for shapes for grid control columns ....
                Reference< XChild > xCompChild( m_xComponent, UNO_QUERY_THROW );
                Reference< XGridColumnFactory > xCheckGrid( xCompChild->getParent(), UNO_QUERY );
                if ( !xCheckGrid.is() )
                {
                    Reference< XMap > xControlMap( m_aContext.getContextValueByAsciiName( "ControlShapeAccess" ), UNO_QUERY_THROW );
                    m_xAssociatedShape.set( xControlMap->get( makeAny( xControlModel ) ), UNO_QUERY_THROW );
                    m_xShapeProperties.set( m_xAssociatedShape, UNO_QUERY_THROW );
                }
            }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

        if ( m_xAssociatedShape.is() )
            m_xChangeNotifier = new ShapeGeometryChangeNotifier( *this, m_aMutex, m_xAssociatedShape.get() );
    }

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

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

    //--------------------------------------------------------------------
    Any SAL_CALL FormGeometryHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );

        ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
        ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: no shape properties!", *this );

        Any aReturn;
        try
        {
            switch ( nPropId )
            {
            case PROPERTY_ID_POSITIONX:
                aReturn <<= m_xAssociatedShape->getPosition().X;
                break;
            case PROPERTY_ID_POSITIONY:
                aReturn <<= m_xAssociatedShape->getPosition().Y;
                break;
            case PROPERTY_ID_WIDTH:
                aReturn <<= m_xAssociatedShape->getSize().Width;
                break;
            case PROPERTY_ID_HEIGHT:
                aReturn <<= m_xAssociatedShape->getSize().Height;
                break;
            case PROPERTY_ID_TEXT_ANCHOR_TYPE:
                aReturn = m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR_TYPE );
                OSL_ENSURE( aReturn.hasValue(), "FormGeometryHandler::getPropertyValue: illegal anchor type!" );
                break;
            case PROPERTY_ID_SHEET_ANCHOR_TYPE:
            {
                Reference< XSpreadsheet > xAnchorSheet( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ), UNO_QUERY );
                aReturn <<= sal_Int32( xAnchorSheet.is() ? ANCHOR_TO_SHEET : ANCHOR_TO_CELL );
            }
            break;

            default:
                OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
                break;
            }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return aReturn;
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormGeometryHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );

        ENSURE_OR_THROW2( m_xAssociatedShape.is(), "internal error: properties, but no shape!", *this );
        ENSURE_OR_THROW2( m_xShapeProperties.is(), "internal error: properties, but no shape!", *this );

        try
        {
            switch ( nPropId )
            {
            case PROPERTY_ID_POSITIONX:
            case PROPERTY_ID_POSITIONY:
            {
                sal_Int32 nPosition(0);
                OSL_VERIFY( _rValue >>= nPosition );

                AwtPoint aPos( m_xAssociatedShape->getPosition() );
                if ( nPropId == PROPERTY_ID_POSITIONX )
                    aPos.X = nPosition;
                else
                    aPos.Y = nPosition;
                m_xAssociatedShape->setPosition( aPos );
            }
            break;

            case PROPERTY_ID_WIDTH:
            case PROPERTY_ID_HEIGHT:
            {
                sal_Int32 nSize(0);
                OSL_VERIFY( _rValue >>= nSize );

                AwtSize aSize( m_xAssociatedShape->getSize() );
                if ( nPropId == PROPERTY_ID_WIDTH )
                    aSize.Width = nSize;
                else
                    aSize.Height = nSize;
				m_xAssociatedShape->setSize( aSize );
            }
            break;

            case PROPERTY_ID_TEXT_ANCHOR_TYPE:
                m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR_TYPE, _rValue );
                break;

            case PROPERTY_ID_SHEET_ANCHOR_TYPE:
            {
                sal_Int32 nSheetAnchorType = 0;
                OSL_VERIFY( _rValue >>= nSheetAnchorType );
                impl_setSheetAnchorType_nothrow( nSheetAnchorType );
            }
            break;

            default:
                OSL_ENSURE( false, "FormGeometryHandler::getPropertyValue: huh?" );
                break;
            }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    LineDescriptor SAL_CALL FormGeometryHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
            const Reference< XPropertyControlFactory >& _rxControlFactory )
        throw (UnknownPropertyException, NullPointerException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );

        LineDescriptor aLineDesc( PropertyHandler::describePropertyLine( _rPropertyName, _rxControlFactory ) );
        try
        {
            bool bIsSize = false;
            switch ( nPropId )
            {
            case PROPERTY_ID_WIDTH:
            case PROPERTY_ID_HEIGHT:
                bIsSize = true;
                // NO break!
            case PROPERTY_ID_POSITIONX:
            case PROPERTY_ID_POSITIONY:
            {
                Optional< double > aZero( sal_True, 0 );
                Optional< double > aValueNotPresent( sal_False, 0 );
                aLineDesc.Control = PropertyHandlerHelper::createNumericControl(
                    _rxControlFactory, 2, bIsSize ? aZero : aValueNotPresent, aValueNotPresent, sal_False );

                Reference< XNumericControl > xNumericControl( aLineDesc.Control, UNO_QUERY_THROW );
                xNumericControl->setValueUnit( MeasureUnit::MM_100TH );
                xNumericControl->setDisplayUnit( impl_getDocumentMeasurementUnit_throw() );
            }
            break;

            case PROPERTY_ID_TEXT_ANCHOR_TYPE:
            case PROPERTY_ID_SHEET_ANCHOR_TYPE:
                // default handling from PropertyHandler is sufficient
                break;

            default:
                OSL_ENSURE( false, "FormGeometryHandler::describePropertyLine: huh?" );
                break;
            }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return aLineDesc;
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormGeometryHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _listener ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::addPropertyChangeListener: no notified, implies no shape!?" );
        if ( m_xChangeNotifier.is() )
            m_xChangeNotifier->addPropertyChangeListener( _listener );
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormGeometryHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _listener ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        OSL_PRECOND( m_xChangeNotifier.is(), "FormGeometryHandler::removePropertyChangeListener: no notified, implies no shape!?" );
        if ( m_xChangeNotifier.is() )
            m_xChangeNotifier->removePropertyChangeListener( _listener );
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL FormGeometryHandler::getActuatingProperties( ) throw (RuntimeException)
    {
        Sequence< ::rtl::OUString > aInterestedIn(1);
        aInterestedIn[0] = PROPERTY_TEXT_ANCHOR_TYPE;
        return aInterestedIn;
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormGeometryHandler::actuatingPropertyChanged( const ::rtl::OUString& _rActuatingPropertyName, const Any& _rNewValue, const Any& /*_rOldValue*/, const Reference< XObjectInspectorUI >& _rxInspectorUI, sal_Bool /*_bFirstTimeInit*/ ) throw (NullPointerException, RuntimeException)
    {
        if ( !_rxInspectorUI.is() )
            throw NullPointerException();

        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nActuatingPropId( impl_getPropertyId_throw( _rActuatingPropertyName ) );

        switch ( nActuatingPropId )
        {
        case PROPERTY_ID_TEXT_ANCHOR_TYPE:
        {
            TextContentAnchorType eAnchorType( TextContentAnchorType_AT_PARAGRAPH );
            OSL_VERIFY( _rNewValue >>= eAnchorType );
            _rxInspectorUI->enablePropertyUI( PROPERTY_POSITIONX, eAnchorType != TextContentAnchorType_AS_CHARACTER );
        }
        break;
        default:
            OSL_ENSURE( false, "FormGeometryHandler::actuatingPropertyChanged: not registered for this property!" );
            break;
        }
    }

    //--------------------------------------------------------------------
    Sequence< Property > SAL_CALL FormGeometryHandler::doDescribeSupportedProperties() const
    {
        if ( !m_xAssociatedShape.is() )
            return Sequence< Property >();

        ::std::vector< Property > aProperties;

        addInt32PropertyDescription( aProperties, PROPERTY_POSITIONX );
        addInt32PropertyDescription( aProperties, PROPERTY_POSITIONY );
        addInt32PropertyDescription( aProperties, PROPERTY_WIDTH );
        addInt32PropertyDescription( aProperties, PROPERTY_HEIGHT );

        if ( impl_haveTextAnchorType_nothrow() )
            implAddPropertyDescription( aProperties, PROPERTY_TEXT_ANCHOR_TYPE, ::cppu::UnoType< TextContentAnchorType >::get() );

        if ( impl_haveSheetAnchorType_nothrow() )
            addInt32PropertyDescription( aProperties, PROPERTY_SHEET_ANCHOR_TYPE );

        return Sequence< Property >( &(*aProperties.begin()), aProperties.size() );
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormGeometryHandler::disposing()
    {
        FormGeometryHandler_Base::disposing();

        if ( m_xChangeNotifier.is() )
        {
            m_xChangeNotifier->dispose();
            m_xChangeNotifier.clear();
        }
    }

    //--------------------------------------------------------------------
    bool FormGeometryHandler::impl_haveTextAnchorType_nothrow() const
    {
        ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
        try
        {
            Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
            if ( xPSI->hasPropertyByName( PROPERTY_ANCHOR_TYPE ) )
                return true;
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return false;
    }

    //--------------------------------------------------------------------
    bool FormGeometryHandler::impl_haveSheetAnchorType_nothrow() const
    {
        ENSURE_OR_THROW( m_xShapeProperties.is(), "not to be called without shape properties" );
        try
        {
            Reference< XPropertySetInfo > xPSI( m_xShapeProperties->getPropertySetInfo(), UNO_SET_THROW );
            if ( !xPSI->hasPropertyByName( PROPERTY_ANCHOR ) )
                return false;
            Reference< XServiceInfo > xSI( m_xAssociatedShape, UNO_QUERY_THROW );
            if ( xSI->supportsService( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.Shape" ) ) ) )
                return true;
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        return false;
    }

    //--------------------------------------------------------------------
    namespace
    {
        static sal_Int32 lcl_getLowerBoundRowOrColumn( const Reference< XIndexAccess >& _rxRowsOrColumns, const bool _bRows,
            const AwtPoint& _rRelativePosition )
        {
            sal_Int32 nAccumulated = 0;

            const sal_Int32& rRelativePos = _bRows ? _rRelativePosition.Y : _rRelativePosition.X;

            sal_Int32 nElements = _rxRowsOrColumns->getCount();
            sal_Int32 currentPos = 0;
            for ( currentPos=0; currentPos<nElements; ++currentPos )
            {
                Reference< XPropertySet > xRowOrColumn( _rxRowsOrColumns->getByIndex( currentPos ), UNO_QUERY_THROW );

                sal_Bool bIsVisible = sal_True;
                OSL_VERIFY( xRowOrColumn->getPropertyValue( PROPERTY_IS_VISIBLE ) >>= bIsVisible );
                if ( !bIsVisible )
                    continue;

                sal_Int32 nHeightOrWidth( 0 );
                OSL_VERIFY( xRowOrColumn->getPropertyValue( _bRows ? PROPERTY_HEIGHT : PROPERTY_WIDTH ) >>= nHeightOrWidth );

                if ( nAccumulated + nHeightOrWidth > rRelativePos )
                    break;

                nAccumulated += nHeightOrWidth;
            }

            return currentPos;
        }
    }

    //--------------------------------------------------------------------
    void FormGeometryHandler::impl_setSheetAnchorType_nothrow( const sal_Int32 _nAnchorType ) const
    {
        ENSURE_OR_THROW( m_xShapeProperties.is(), "illegal to be called without shape properties." );
        try
        {
            CellBindingHelper aHelper( m_xComponent, impl_getContextDocument_nothrow() );
            // find the sheet which the control belongs to
            Reference< XSpreadsheet > xSheet;
            aHelper.getControlSheetIndex( xSheet );

            switch ( _nAnchorType )
            {
            case ANCHOR_TO_SHEET:
                OSL_ENSURE( xSheet.is(),
                    "FormGeometryHandler::impl_setSheetAnchorType_nothrow: sheet not found!" );
                if ( xSheet.is() )
                {
                    AwtPoint aPreservePosition( m_xAssociatedShape->getPosition() );
                    m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, makeAny( xSheet ) );
                    m_xAssociatedShape->setPosition( aPreservePosition );
                }
                break;

            case ANCHOR_TO_CELL:
            {
                Reference< XColumnRowRange > xColsRows( xSheet, UNO_QUERY_THROW );

                // get the current anchor
                Reference< XSpreadsheet > xCurrentAnchor;
                OSL_VERIFY( m_xShapeProperties->getPropertyValue( PROPERTY_ANCHOR ) >>= xCurrentAnchor );
                OSL_ENSURE( xCurrentAnchor.is(), "FormGeometryHandler::impl_setSheetAnchorType_nothrow: only to be called when currently anchored to a sheet!" );

                // get the current position
                AwtPoint aRelativePosition( m_xAssociatedShape->getPosition() );

                Reference< XTableColumns > xCols( xColsRows->getColumns(), UNO_SET_THROW );
                sal_Int32 nNewAnchorCol = lcl_getLowerBoundRowOrColumn( xCols.get(), false, aRelativePosition );

                Reference< XTableRows > xRows( xColsRows->getRows(), UNO_SET_THROW );
                sal_Int32 nNewAnchorRow = lcl_getLowerBoundRowOrColumn( xRows.get(), true, aRelativePosition );

                Reference< XCellRange > xSheetCellRange( xSheet, UNO_QUERY_THROW );
                Any aNewAnchorCell( xSheetCellRange->getCellByPosition( nNewAnchorCol, nNewAnchorRow ) );
                m_xShapeProperties->setPropertyValue( PROPERTY_ANCHOR, aNewAnchorCell );
            }
            break;

            default:
                OSL_ENSURE( false, "FormGeometryHandler::impl_setSheetAnchorType_nothrow: illegal anchor type!" );
                break;
            }
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //====================================================================
	//= ShapeGeometryChangeNotifier - implementation
	//====================================================================
    namespace
    {
        struct EventTranslation
        {
            ::rtl::OUString sPropertyName;
            Any             aNewPropertyValue;

            EventTranslation( const ::rtl::OUString& _propertyName, const Any& _newPropertyValue )
                :sPropertyName( _propertyName )
                ,aNewPropertyValue( _newPropertyValue )
            {
            }
        };
    }

    //--------------------------------------------------------------------
    void SAL_CALL ShapeGeometryChangeNotifier::propertyChange( const PropertyChangeEvent& _event ) throw (RuntimeException)
    {
        ::comphelper::ComponentMethodGuard aGuard( *this );

        ::std::vector< EventTranslation > aEventTranslations;
        aEventTranslations.reserve(2);

        if ( _event.PropertyName.equalsAscii( "Position" ) )
        {
            AwtPoint aPos = m_xShape->getPosition();
            aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONX, makeAny( aPos.X ) ) );
            aEventTranslations.push_back( EventTranslation( PROPERTY_POSITIONY, makeAny( aPos.Y ) ) );
        }
        else if ( _event.PropertyName.equalsAscii( "Size" ) )
        {
            AwtSize aSize = m_xShape->getSize();
            aEventTranslations.push_back( EventTranslation( PROPERTY_WIDTH, makeAny( aSize.Width ) ) );
            aEventTranslations.push_back( EventTranslation( PROPERTY_HEIGHT, makeAny( aSize.Height ) ) );
        }
        else if ( _event.PropertyName == PROPERTY_ANCHOR_TYPE )
        {
            aEventTranslations.push_back( EventTranslation( PROPERTY_TEXT_ANCHOR_TYPE, makeAny( _event.NewValue ) ) );
        }
        else if ( _event.PropertyName == PROPERTY_ANCHOR )
        {
            aEventTranslations.push_back( EventTranslation( PROPERTY_SHEET_ANCHOR_TYPE, makeAny( _event.NewValue ) ) );
        }

        PropertyChangeEvent aTranslatedEvent( _event );
        aTranslatedEvent.Source = m_rParent;

        aGuard.clear();
        for ( ::std::vector< EventTranslation >::const_iterator t = aEventTranslations.begin();
              t != aEventTranslations.end();
              ++t
            )
        {
            aTranslatedEvent.PropertyName = t->sPropertyName;
            aTranslatedEvent.NewValue = t->aNewPropertyValue;
            m_aPropertyChangeListeners.notifyEach( &XPropertyChangeListener::propertyChange, aTranslatedEvent );
        }
    }
    
    //--------------------------------------------------------------------
    void SAL_CALL ShapeGeometryChangeNotifier::disposing( const EventObject& /*_event*/ ) throw (RuntimeException)
    {
        ::comphelper::ComponentMethodGuard aGuard( *this );
        impl_dispose_nothrow();
    }

    //--------------------------------------------------------------------
    void ShapeGeometryChangeNotifier::impl_init_nothrow()
    {
        osl_incrementInterlockedCount( &m_refCount );
        try
        {
            Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
            xShapeProperties->addPropertyChangeListener( ::rtl::OUString(), this );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
        osl_decrementInterlockedCount( &m_refCount );
    }

    //--------------------------------------------------------------------
    void ShapeGeometryChangeNotifier::impl_dispose_nothrow()
    {
        try
        {
            Reference< XPropertySet > xShapeProperties( m_xShape, UNO_QUERY_THROW );
            xShapeProperties->removePropertyChangeListener( ::rtl::OUString(), this );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }

        getBroadcastHelper().bDisposed = true;
    }

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

extern "C" void SAL_CALL createRegistryInfo_FormGeometryHandler()
{
    ::pcr::FormGeometryHandler::registerImplementation();
}
