/**************************************************************
 *
 * 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();
}
