/**************************************************************
 *
 * 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 "propcontroller.hxx"
#include "pcrstrings.hxx"
#include "standardcontrol.hxx"
#include "linedescriptor.hxx"
#ifndef EXTENSIONS_PROPRESID_HRC
#include "propresid.hrc"
#endif
#ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
#include "formresid.hrc"
#endif
#include "propertyeditor.hxx"
#ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
#include "modulepcr.hxx"
#endif
#include "formstrings.hxx"
#include "formmetadata.hxx"
#include "formbrowsertools.hxx"
#include "propertycomposer.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/inspection/PropertyControlType.hpp>
#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
/** === end UNO includes === **/
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <comphelper/types.hxx>
#include <comphelper/extract.hxx>
#include <toolkit/awt/vclxwindow.hxx>
#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#include <comphelper/property.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
#include <cppuhelper/component_context.hxx>
#include <cppuhelper/exc_hlp.hxx>

#include <algorithm>
#include <functional>

//------------------------------------------------------------------------
// !!! outside the namespace !!!
extern "C" void SAL_CALL createRegistryInfo_OPropertyBrowserController()
{
	::pcr::OAutoRegistration< ::pcr::OPropertyBrowserController > aAutoRegistration;
}

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

	using namespace ::com::sun::star;
	using namespace ::com::sun::star::uno;
	using namespace ::com::sun::star::awt;
	using namespace ::com::sun::star::form;
	using namespace ::com::sun::star::beans;
	using namespace ::com::sun::star::script;
	using namespace ::com::sun::star::lang;
	using namespace ::com::sun::star::container;
	using namespace ::com::sun::star::frame;
	using namespace ::com::sun::star::util;
	using namespace ::com::sun::star::inspection;
	using namespace ::com::sun::star::ucb;
	using namespace ::comphelper;

#define THISREF()	static_cast< XController* >(this)

    //========================================================================
	//= OPropertyBrowserController
	//========================================================================
	DBG_NAME(OPropertyBrowserController)
	//------------------------------------------------------------------------
	OPropertyBrowserController::OPropertyBrowserController( const Reference< XComponentContext >& _rxContext )
            :m_aContext(_rxContext)
			,m_aDisposeListeners( m_aMutex )
            ,m_aControlObservers( m_aMutex )
			,m_pView(NULL)
			,m_bContainerFocusListening( false )
            ,m_bSuspendingPropertyHandlers( false )
            ,m_bConstructed( false )
            ,m_bBindingIntrospectee( false )
	{
		DBG_CTOR(OPropertyBrowserController,NULL);
	}

	//------------------------------------------------------------------------
	OPropertyBrowserController::~OPropertyBrowserController()
	{
        // stop listening for property changes
        acquire();
		stopInspection( true );
		DBG_DTOR(OPropertyBrowserController,NULL);
	}

	//------------------------------------------------------------------------
    IMPLEMENT_FORWARD_REFCOUNT( OPropertyBrowserController, OPropertyBrowserController_Base )

	//------------------------------------------------------------------------
    Any SAL_CALL OPropertyBrowserController::queryInterface( const Type& _rType ) throw (RuntimeException)
	{
        Any aReturn = OPropertyBrowserController_Base::queryInterface( _rType );
        if ( !aReturn.hasValue() )
            aReturn = ::cppu::queryInterface(
                _rType,
                static_cast< XObjectInspectorUI* >( this )
            );
        return aReturn;
	}

	//------------------------------------------------------------------------
	void OPropertyBrowserController::startContainerWindowListening()
	{
		if (m_bContainerFocusListening)
			return;

		if (m_xFrame.is())
		{
			Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow();
			if (xContainerWindow.is())
			{
				xContainerWindow->addFocusListener(this);
				m_bContainerFocusListening = sal_True;
			}
		}

		DBG_ASSERT(m_bContainerFocusListening, "OPropertyBrowserController::startContainerWindowListening: unable to start listening (inconsistence)!");
	}

	//------------------------------------------------------------------------
	void OPropertyBrowserController::stopContainerWindowListening()
	{
		if (!m_bContainerFocusListening)
			return;

		if (m_xFrame.is())
		{
			Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow();
			if (xContainerWindow.is())
			{
				xContainerWindow->removeFocusListener(this);
				m_bContainerFocusListening = sal_False;
			}
		}

		DBG_ASSERT(!m_bContainerFocusListening, "OPropertyBrowserController::stopContainerWindowListening: unable to stop listening (inconsistence)!");
	}

    //--------------------------------------------------------------------
    Reference< XObjectInspectorModel > SAL_CALL OPropertyBrowserController::getInspectorModel() throw (RuntimeException)
    {
        return m_xModel;
    }

    //--------------------------------------------------------------------
    void OPropertyBrowserController::impl_initializeView_nothrow()
    {
        OSL_PRECOND( haveView(), "OPropertyBrowserController::impl_initializeView_nothrow: not to be called when we have no view!" );
        if ( !haveView() )
            return;

        if ( !m_xModel.is() )
            // allowed
            return;

        try
        {
            getPropertyBox().EnableHelpSection( m_xModel->getHasHelpSection() );
            getPropertyBox().SetHelpLineLimites( m_xModel->getMinHelpTextLines(), m_xModel->getMaxHelpTextLines() );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    void OPropertyBrowserController::impl_updateReadOnlyView_nothrow()
    {
        // this is a huge cudgel, admitted.
        // The problem is that in case we were previously read-only, all our controls
        // were created read-only, too. We cannot simply switch them to not-read-only.
        // Even if they had an API for this, we do not know whether they were
        // originally created read-only, or if they are read-only just because
        // the model was.
        impl_rebindToInspectee_nothrow( m_aInspectedObjects );
    }

    //--------------------------------------------------------------------
    bool OPropertyBrowserController::impl_isReadOnlyModel_throw() const
    {
        if ( !m_xModel.is() )
            return false;

        return m_xModel->getIsReadOnly();
    }

    //--------------------------------------------------------------------
    void OPropertyBrowserController::impl_startOrStopModelListening_nothrow( bool _bDoListen ) const
    {
        try
        {
            Reference< XPropertySet > xModelProperties( m_xModel, UNO_QUERY );
            if ( !xModelProperties.is() )
                // okay, so the model doesn't want to change its properties
                // dynamically - fine with us
                return;

            void (SAL_CALL XPropertySet::*pListenerOperation)( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& )
                = _bDoListen ? &XPropertySet::addPropertyChangeListener : &XPropertySet::removePropertyChangeListener;

            (xModelProperties.get()->*pListenerOperation)(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsReadOnly" ) ),
                const_cast< OPropertyBrowserController* >( this )
            );
        }
        catch( const Exception& )
        {
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    void OPropertyBrowserController::impl_bindToNewModel_nothrow( const Reference< XObjectInspectorModel >& _rxInspectorModel )
    {
        impl_startOrStopModelListening_nothrow( false );
        m_xModel = _rxInspectorModel;
        impl_startOrStopModelListening_nothrow( true );

        // initialize the view, if we already have one
        if ( haveView() )
            impl_initializeView_nothrow();

        // inspect again, if we already have inspectees
        if ( !m_aInspectedObjects.empty() )
            impl_rebindToInspectee_nothrow( m_aInspectedObjects );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::setInspectorModel( const Reference< XObjectInspectorModel >& _inspectorModel ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_xModel == _inspectorModel )
            return;

        impl_bindToNewModel_nothrow( _inspectorModel );
    }

    //--------------------------------------------------------------------
    Reference< XObjectInspectorUI > SAL_CALL OPropertyBrowserController::getInspectorUI() throw (RuntimeException)
    {
        // we're derived from this interface, though we do not expose it in queryInterface and getTypes.
        return this;
    }

    //--------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::inspect( const Sequence< Reference< XInterface > >& _rObjects ) throw (com::sun::star::util::VetoException, RuntimeException)
    {
        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( m_bSuspendingPropertyHandlers || !suspendAll_nothrow() )
        {   // we already are trying to suspend the component (this is somewhere up the stack)
            // OR one of our property handlers raised a veto against closing. Well, we *need* to close
            // it in order to inspect another object.
            throw VetoException();
        }
        if ( m_bBindingIntrospectee )
            throw VetoException();

        m_bBindingIntrospectee = true;
        impl_rebindToInspectee_nothrow( InterfaceArray( _rObjects.getConstArray(), _rObjects.getConstArray() + _rObjects.getLength() ) );
        m_bBindingIntrospectee = false;

    }

    //--------------------------------------------------------------------
    Reference< XDispatch > SAL_CALL OPropertyBrowserController::queryDispatch( const URL& /*URL*/, const ::rtl::OUString& /*TargetFrameName*/, ::sal_Int32 /*SearchFlags*/ ) throw (RuntimeException)
    {
        // we don't have any dispatches at all, right now
        return Reference< XDispatch >();
    }

    //--------------------------------------------------------------------
    Sequence< Reference< XDispatch > > SAL_CALL OPropertyBrowserController::queryDispatches( const Sequence< DispatchDescriptor >& Requests ) throw (RuntimeException)
    {
	    Sequence< Reference< XDispatch > > aReturn;
	    sal_Int32 nLen = Requests.getLength();
		aReturn.realloc( nLen );

                Reference< XDispatch >* pReturn 	= aReturn.getArray();
		const	Reference< XDispatch >* pReturnEnd	= aReturn.getArray() + nLen;
		const	DispatchDescriptor* 	pDescripts	= Requests.getConstArray();

		for ( ; pReturn != pReturnEnd; ++ pReturn, ++pDescripts )
			*pReturn = queryDispatch( pDescripts->FeatureURL, pDescripts->FrameName, pDescripts->SearchFlags );

	    return aReturn;
    }

    //------------------------------------------------------------------------
	void SAL_CALL OPropertyBrowserController::initialize( const Sequence< Any >& _arguments ) throw (Exception, RuntimeException)
    {
        if ( m_bConstructed )
            throw AlreadyInitializedException();

        StlSyntaxSequence< Any > arguments( _arguments );
        if ( arguments.empty() )
        {   // constructor: "createDefault()"
            createDefault();
            return;
        }

        Reference< XObjectInspectorModel > xModel;
        if ( arguments.size() == 1 )
        {   // constructor: "createWithModel( XObjectInspectorModel )"
            if ( !( arguments[0] >>= xModel ) )
                throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
            createWithModel( xModel );
            return;
        }

        throw IllegalArgumentException( ::rtl::OUString(), *this, 0 );
    }

    //------------------------------------------------------------------------
	void OPropertyBrowserController::createDefault()
    {
        m_bConstructed = true;
    }

    //------------------------------------------------------------------------
	void OPropertyBrowserController::createWithModel( const Reference< XObjectInspectorModel >& _rxModel )
    {
        osl_incrementInterlockedCount( &m_refCount );
        {
            setInspectorModel( _rxModel );
        }
        osl_decrementInterlockedCount( &m_refCount );

        m_bConstructed = true;
    }

    //------------------------------------------------------------------------
	void SAL_CALL OPropertyBrowserController::attachFrame( const Reference< XFrame >& _rxFrame ) throw(RuntimeException)
	{
        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        ::osl::MutexGuard aGuard( m_aMutex );

		if (_rxFrame.is() && haveView())
			throw RuntimeException(::rtl::OUString::createFromAscii("Unable to attach to a second frame."),*this);

		// revoke as focus listener from the old container window
		stopContainerWindowListening();

		m_xFrame = _rxFrame;
		if (!m_xFrame.is())
			return;

		// TODO: this construction perhaps should be done outside. Don't know the exact meaning of attachFrame.
		// Maybe it is intended to only announce the frame to the controller, and the instance doing this
		// announcement is responsible for calling setComponent, too.
		Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow();
		VCLXWindow*	pContainerWindow = VCLXWindow::GetImplementation(xContainerWindow);
		Window* pParentWin = pContainerWindow ? pContainerWindow->GetWindow() : NULL;
		if (!pParentWin)
			throw RuntimeException(::rtl::OUString::createFromAscii("The frame is invalid. Unable to extract the container window."),*this);

		if ( Construct( pParentWin ) )
        {
            try
            {
			    m_xFrame->setComponent( VCLUnoHelper::GetInterface( m_pView ), this );
            }
            catch( const Exception& )
            {
            	OSL_ENSURE( sal_False, "OPropertyBrowserController::attachFrame: caught an exception!" );
            }
        }

		startContainerWindowListening();

        UpdateUI();
	}

	//------------------------------------------------------------------------
	sal_Bool SAL_CALL OPropertyBrowserController::attachModel( const Reference< XModel >& _rxModel ) throw(RuntimeException)
	{
        Reference< XObjectInspectorModel > xModel( _rxModel, UNO_QUERY );
        if ( !xModel.is() )
            return false;

        setInspectorModel( xModel );
        return getInspectorModel() == _rxModel;
	}

	//------------------------------------------------------------------------
    sal_Bool OPropertyBrowserController::suspendAll_nothrow()
    {
        // if there is a handle inside its "onInteractivePropertySelection" method,
        // then veto
        // Normally, we could expect every handler to do this itself, but being
        // realistic, it's safer to handle this here in general.
        if ( m_xInteractiveHandler.is() )
            return sal_False;

        m_bSuspendingPropertyHandlers = true;
        sal_Bool bHandlerVeto = !suspendPropertyHandlers_nothrow( sal_True );
        m_bSuspendingPropertyHandlers = false;
        if ( bHandlerVeto )
            return sal_False;

        return sal_True;
    }

	//------------------------------------------------------------------------
    sal_Bool OPropertyBrowserController::suspendPropertyHandlers_nothrow( sal_Bool _bSuspend )
    {
        PropertyHandlerArray aAllHandlers;  // will contain every handler exactly once
        for (   PropertyHandlerRepository::const_iterator handler = m_aPropertyHandlers.begin();
                handler != m_aPropertyHandlers.end();
                ++handler
            )
        {
            if ( ::std::find( aAllHandlers.begin(), aAllHandlers.end(), handler->second ) != aAllHandlers.end() )
                // already visited this particular handler (m_aPropertyHandlers usually contains
                // the same handler more than once)
                continue;
            aAllHandlers.push_back( handler->second );
        }

        for ( PropertyHandlerArray::iterator loop = aAllHandlers.begin();
              loop != aAllHandlers.end();
              ++loop
            )
        {
            try
            {
                if ( !(*loop)->suspend( _bSuspend ) )
                    if ( _bSuspend )
                        // if we're not suspending, but reactivating, ignore the error
                        return sal_False;
            }
            catch( const Exception& )
            {
        	    OSL_ENSURE( sal_False, "OPropertyBrowserController::suspendPropertyHandlers_nothrow: caught an exception!" );
            }
        }
        return sal_True;
    }

	//------------------------------------------------------------------------
	sal_Bool SAL_CALL OPropertyBrowserController::suspend( sal_Bool _bSuspend ) throw(RuntimeException)
	{
        ::osl::MutexGuard aGuard( m_aMutex );
		OSL_ENSURE( haveView(), "OPropertyBrowserController::suspend: don't have a view anymore!" );

        if ( !_bSuspend )
        {   // this means a "suspend" is to be "revoked"
            suspendPropertyHandlers_nothrow( sal_False );
            // we ourself cannot revoke our suspend
            return sal_False;
        }

        if ( !suspendAll_nothrow() )
            return sal_False;

		// commit the editor's content
		if ( haveView() )
			getPropertyBox().CommitModified();

		// stop listening
		stopContainerWindowListening();

		// outtahere
		return sal_True;
	}

	//------------------------------------------------------------------------
	Any SAL_CALL OPropertyBrowserController::getViewData(  ) throw(RuntimeException)
	{
        return makeAny( m_sPageSelection );
	}

	//------------------------------------------------------------------------
	void SAL_CALL OPropertyBrowserController::restoreViewData( const Any& Data ) throw(RuntimeException)
	{
        ::rtl::OUString sPageSelection;
        if ( ( Data >>= sPageSelection ) && sPageSelection.getLength() )
        {
            m_sPageSelection = sPageSelection;
            selectPageFromViewData();
        }
	}

	//------------------------------------------------------------------------
	Reference< XModel > SAL_CALL OPropertyBrowserController::getModel(  ) throw(RuntimeException)
	{
		// have no model
		return Reference< XModel >();
	}

	//------------------------------------------------------------------------
	Reference< XFrame > SAL_CALL OPropertyBrowserController::getFrame(  ) throw(RuntimeException)
	{
		return m_xFrame;
	}

	//------------------------------------------------------------------------
	void SAL_CALL OPropertyBrowserController::dispose(  ) throw(RuntimeException)
	{
        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );

        // stop inspecting the current object
		stopInspection( false );

		// say our dispose listeners goodbye
		::com::sun::star::lang::EventObject aEvt;
		aEvt.Source = static_cast< ::cppu::OWeakObject* >(this);
		m_aDisposeListeners.disposeAndClear(aEvt);
        m_aControlObservers.disposeAndClear(aEvt);

		// don't delete explicitly (this is done by the frame we reside in)
		m_pView = NULL;

		Reference< XComponent > xViewAsComp( m_xView, UNO_QUERY );
		if ( xViewAsComp.is() )
			xViewAsComp->removeEventListener( static_cast< XPropertyChangeListener* >( this ) );
		m_xView.clear( );

        m_aInspectedObjects.clear();
        impl_bindToNewModel_nothrow( NULL );
	}

	//------------------------------------------------------------------------
	void SAL_CALL OPropertyBrowserController::addEventListener( const Reference< XEventListener >& _rxListener ) throw(RuntimeException)
	{
		m_aDisposeListeners.addInterface(_rxListener);
	}

	//------------------------------------------------------------------------
	void SAL_CALL OPropertyBrowserController::removeEventListener( const Reference< XEventListener >& _rxListener ) throw(RuntimeException)
	{
		m_aDisposeListeners.removeInterface(_rxListener);
	}

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

	//------------------------------------------------------------------------
	sal_Bool SAL_CALL OPropertyBrowserController::supportsService( const ::rtl::OUString& ServiceName ) throw(RuntimeException)
	{
		Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames());
		const ::rtl::OUString* pArray = aSupported.getConstArray();
		for (sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray)
			if (pArray->equals(ServiceName))
				return sal_True;
		return sal_False;
	}

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

	//------------------------------------------------------------------------
	::rtl::OUString OPropertyBrowserController::getImplementationName_static(  ) throw(RuntimeException)
	{
		return ::rtl::OUString::createFromAscii("org.openoffice.comp.extensions.ObjectInspector");
	}

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

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

	//------------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::focusGained( const FocusEvent& _rSource ) throw (RuntimeException)
	{
		Reference< XWindow > xSourceWindow(_rSource.Source, UNO_QUERY);
		Reference< XWindow > xContainerWindow;
		if (m_xFrame.is())
			xContainerWindow = m_xFrame->getContainerWindow();

		if ( xContainerWindow.get() == xSourceWindow.get() )
		{	// our container window got the focus
			if ( haveView() )
				getPropertyBox().GrabFocus();
		}
	}

	//------------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::focusLost( const FocusEvent& /*_rSource*/ ) throw (RuntimeException)
	{
		// not interested in
	}

	//------------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::disposing( const EventObject& _rSource ) throw(RuntimeException)
	{
		if ( m_xView.is() && ( m_xView == _rSource.Source ) )
		{
			m_xView = NULL;
			m_pView = NULL;
		}

        for (   InterfaceArray::iterator loop = m_aInspectedObjects.begin();
                loop != m_aInspectedObjects.end();
                ++loop
            )
        {
            if ( *loop == _rSource.Source )
            {
                m_aInspectedObjects.erase( loop );
                break;
            }
        }
	}

	//------------------------------------------------------------------------
	IMPL_LINK(OPropertyBrowserController, OnPageActivation, void*, EMPTYARG)
	{
		updateViewDataFromActivePage();
		return 0L;
	}

	//------------------------------------------------------------------------
	void OPropertyBrowserController::updateViewDataFromActivePage()
	{
		if (!haveView())
			return;

        ::rtl::OUString sOldSelection = m_sPageSelection;
        m_sPageSelection = ::rtl::OUString();

		const sal_uInt16 nCurrentPage = m_pView->getActivaPage();
		if ( (sal_uInt16)-1 != nCurrentPage )
        {
            for (   HashString2Int16::const_iterator pageId = m_aPageIds.begin();
                    pageId != m_aPageIds.end();
                    ++pageId
                )
            {
                if ( nCurrentPage == pageId->second )
                {
				    m_sPageSelection = pageId->first;
                    break;
                }
            }
        }

        if ( m_sPageSelection.getLength() )
            m_sLastValidPageSelection = m_sPageSelection;
        else if ( sOldSelection.getLength() )
            m_sLastValidPageSelection = sOldSelection;
	}

	//------------------------------------------------------------------------
    sal_uInt16 OPropertyBrowserController::impl_getPageIdForCategory_nothrow( const ::rtl::OUString& _rCategoryName ) const
    {
		sal_uInt16 nPageId = (sal_uInt16)-1;
        HashString2Int16::const_iterator pagePos = m_aPageIds.find( _rCategoryName );
        if ( pagePos != m_aPageIds.end() )
			nPageId = pagePos->second;
        return nPageId;
    }

	//------------------------------------------------------------------------
	void OPropertyBrowserController::selectPageFromViewData()
	{
		sal_uInt16 nNewPage = impl_getPageIdForCategory_nothrow( m_sPageSelection );

		if ( haveView() && ( nNewPage != (sal_uInt16)-1 ) )
			m_pView->activatePage( nNewPage );

		// just in case ...
		updateViewDataFromActivePage();
	}

	//------------------------------------------------------------------------
	sal_Bool OPropertyBrowserController::Construct(Window* _pParentWin)
	{
		DBG_ASSERT(!haveView(), "OPropertyBrowserController::Construct: already have a view!");
		DBG_ASSERT(_pParentWin, "OPropertyBrowserController::Construct: invalid parent window!");

		m_pView = new OPropertyBrowserView(m_aContext.getLegacyServiceFactory(), _pParentWin);
		m_pView->setPageActivationHandler(LINK(this, OPropertyBrowserController, OnPageActivation));

		// add as dispose listener for our view. The view is disposed by the frame we're plugged into,
		// and this disposal _deletes_ the view, so it would be deadly if we use our m_pView member
		// after that
		m_xView = VCLUnoHelper::GetInterface(m_pView);
		Reference< XComponent > xViewAsComp(m_xView, UNO_QUERY);
		if (xViewAsComp.is())
			xViewAsComp->addEventListener( static_cast< XPropertyChangeListener* >( this ) );

        getPropertyBox().SetLineListener(this);
		getPropertyBox().SetControlObserver(this);
        impl_initializeView_nothrow();

        m_pView->Show();

		return sal_True;
	}

	//------------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
    {
        if ( _rEvent.Source == m_xModel )
        {
            if ( _rEvent.PropertyName.equalsAscii( "IsReadOnly" ) )
                impl_updateReadOnlyView_nothrow();
            return;
        }

        if ( m_sCommittingProperty == _rEvent.PropertyName )
            return;

        if ( !haveView() )
            return;

        Any aNewValue( _rEvent.NewValue );
        if ( impl_hasPropertyHandlerFor_nothrow( _rEvent.PropertyName ) )
        {
            // forward the new value to the property box, to reflect the change in the UI
            aNewValue = impl_getPropertyValue_throw( _rEvent.PropertyName );

            // check whether the state is ambiguous. This is interesting in case we display the properties
            // for multiple objects at once: In this case, we'll get a notification from one of the objects,
            // but need to care for the "composed" value, which can be "ambiguous".
            PropertyHandlerRef xHandler( impl_getHandlerForProperty_throw( _rEvent.PropertyName ), UNO_SET_THROW );
            PropertyState ePropertyState( xHandler->getPropertyState( _rEvent.PropertyName ) );
	        bool bAmbiguousValue = ( PropertyState_AMBIGUOUS_VALUE == ePropertyState );

            getPropertyBox().SetPropertyValue( _rEvent.PropertyName, aNewValue, bAmbiguousValue );
        }

        // if it's a actuating property, then update the UI for any dependent
        // properties
        if ( impl_isActuatingProperty_nothrow( _rEvent.PropertyName ) )
            impl_broadcastPropertyChange_nothrow( _rEvent.PropertyName, aNewValue, _rEvent.OldValue, false );
    }

	//------------------------------------------------------------------------
    Reference< XPropertyControl > SAL_CALL OPropertyBrowserController::createPropertyControl( ::sal_Int16 ControlType, ::sal_Bool _CreateReadOnly ) throw (IllegalArgumentException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );

        Reference< XPropertyControl > xControl;

		// default winbits: a border only
		WinBits nWinBits = WB_BORDER;

        // read-only-ness
        _CreateReadOnly |= (sal_Bool)impl_isReadOnlyModel_throw();
		if ( _CreateReadOnly )
			nWinBits |= WB_READONLY;

		switch ( ControlType )
		{
            case PropertyControlType::StringListField:
				xControl = new OMultilineEditControl( &getPropertyBox(), eStringList, nWinBits | WB_DROPDOWN | WB_TABSTOP );
				break;

			case PropertyControlType::MultiLineTextField:
				xControl = new OMultilineEditControl( &getPropertyBox(), eMultiLineText, nWinBits | WB_DROPDOWN | WB_TABSTOP );
				break;

            case PropertyControlType::ListBox:
				xControl = new OListboxControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN);
				break;

			case PropertyControlType::ComboBox:
				xControl = new OComboboxControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN);
				break;

			case PropertyControlType::TextField:
				xControl = new OEditControl( &getPropertyBox(), sal_False, nWinBits | WB_TABSTOP );
				break;

			case PropertyControlType::CharacterField:
				xControl = new OEditControl( &getPropertyBox(), sal_True, nWinBits | WB_TABSTOP );
				break;

			case PropertyControlType::NumericField:
				xControl = new ONumericControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
				break;

            case PropertyControlType::DateTimeField:
				xControl = new ODateTimeControl( &getPropertyBox(), nWinBits | WB_TABSTOP );
				break;

			case PropertyControlType::DateField:
				xControl = new ODateControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
				break;

			case PropertyControlType::TimeField:
				xControl = new OTimeControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_SPIN | WB_REPEAT );
				break;

			case PropertyControlType::ColorListBox:
				xControl = new OColorControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN );
				break;

			case PropertyControlType::HyperlinkField:
				xControl = new OHyperlinkControl( &getPropertyBox(), nWinBits | WB_TABSTOP | WB_DROPDOWN );
				break;

			default:
                throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
		}

        return xControl;
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::impl_toggleInspecteeListening_nothrow( bool _bOn )
    {
        for (   InterfaceArray::const_iterator loop = m_aInspectedObjects.begin();
                loop != m_aInspectedObjects.end();
                ++loop
            )
        {
            try
            {
                Reference< XComponent > xComp( *loop, UNO_QUERY );
                if ( xComp.is() )
                {
                    if ( _bOn )
                        xComp->addEventListener( static_cast< XPropertyChangeListener* >( this ) );
                    else
                        xComp->removeEventListener( static_cast< XPropertyChangeListener* >( this ) );
                }
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
    }

	//------------------------------------------------------------------------
	void OPropertyBrowserController::stopInspection( bool _bCommitModified )
	{
        if ( haveView() )
        {
		    if ( _bCommitModified )
			    // commit the editor's content
			    getPropertyBox().CommitModified();

		    // hide the property box so that it does not flicker
		    getPropertyBox().Hide();

		    // clear the property box
		    getPropertyBox().ClearAll();
        }

		// destroy the view first
		if ( haveView() )
		{
			// remove the pages
            for (   HashString2Int16::const_iterator erase = m_aPageIds.begin();
                    erase != m_aPageIds.end();
                    ++erase
                )
                getPropertyBox().RemovePage( erase->second );
            clearContainer( m_aPageIds );
		}

		clearContainer( m_aProperties );

        // de-register as dispose-listener from our inspected objects
        impl_toggleInspecteeListening_nothrow( false );

        // handlers are obsolete, so is our "composer" for their UI requests
        if ( m_pUIRequestComposer.get() )
            m_pUIRequestComposer->dispose();
        m_pUIRequestComposer.reset();

        // clean up the property handlers
        PropertyHandlerArray aAllHandlers;  // will contain every handler exactly once
        for ( PropertyHandlerRepository::const_iterator aHandler = m_aPropertyHandlers.begin();
              aHandler != m_aPropertyHandlers.end();
              ++aHandler
            )
            if ( ::std::find( aAllHandlers.begin(), aAllHandlers.end(), aHandler->second ) == aAllHandlers.end() )
                aAllHandlers.push_back( aHandler->second );

        for ( PropertyHandlerArray::iterator loop = aAllHandlers.begin();
              loop != aAllHandlers.end();
              ++loop
            )
        {
            try
            {
                (*loop)->removePropertyChangeListener( this );
                (*loop)->dispose();
            }
            catch( const DisposedException& )
            {
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
        }

        clearContainer( m_aPropertyHandlers );
        clearContainer( m_aDependencyHandlers );
	}

    //------------------------------------------------------------------------
    bool OPropertyBrowserController::impl_hasPropertyHandlerFor_nothrow( const ::rtl::OUString& _rPropertyName ) const
    {
        PropertyHandlerRepository::const_iterator handlerPos = m_aPropertyHandlers.find( _rPropertyName );
        return ( handlerPos != m_aPropertyHandlers.end() );
    }

    //------------------------------------------------------------------------
    OPropertyBrowserController::PropertyHandlerRef OPropertyBrowserController::impl_getHandlerForProperty_throw( const ::rtl::OUString& _rPropertyName ) const
    {
        PropertyHandlerRepository::const_iterator handlerPos = m_aPropertyHandlers.find( _rPropertyName );
        if ( handlerPos == m_aPropertyHandlers.end() )
            throw RuntimeException();
        return handlerPos->second;
    }

    //------------------------------------------------------------------------
    Any OPropertyBrowserController::impl_getPropertyValue_throw( const ::rtl::OUString& _rPropertyName )
    {
        PropertyHandlerRef handler = impl_getHandlerForProperty_throw( _rPropertyName );
        return handler->getPropertyValue( _rPropertyName );
    }

	//------------------------------------------------------------------------
	void OPropertyBrowserController::impl_rebindToInspectee_nothrow( const InterfaceArray& _rObjects )
	{
		try
		{
			// stop inspecting the old object(s)
			stopInspection( true );

            // inspect the new object(s)
            m_aInspectedObjects = _rObjects;
			doInspection();

            // update the user interface
		    UpdateUI();
		}

		catch(Exception&)
		{
			DBG_ERROR("OPropertyBrowserController::impl_rebindToInspectee_nothrow: caught an exception !");
		}
    }

	//------------------------------------------------------------------------
	void OPropertyBrowserController::doInspection()
	{
		try
		{
			//////////////////////////////////////////////////////////////////////
			// obtain the properties of the object
            ::std::vector< Property > aProperties;

            PropertyHandlerArray aPropertyHandlers;
            getPropertyHandlers( m_aInspectedObjects, aPropertyHandlers );

            PropertyHandlerArray::iterator aHandler( aPropertyHandlers.begin() );
            while ( aHandler != aPropertyHandlers.end() )
            {
                DBG_ASSERT( aHandler->get(), "OPropertyBrowserController::doInspection: invalid handler!" );

                StlSyntaxSequence< Property > aThisHandlersProperties = (*aHandler)->getSupportedProperties();

                if ( aThisHandlersProperties.empty() )
                {
                    // this handler doesn't know anything about the current inspectee -> ignore it
                    (*aHandler)->dispose();
                    aHandler = aPropertyHandlers.erase( aHandler );
                    continue;
                }

                // append these properties to our "all properties" array
                aProperties.reserve( aProperties.size() + aThisHandlersProperties.size() );
                for (   StlSyntaxSequence< Property >::const_iterator copyProperty = aThisHandlersProperties.begin();
                        copyProperty != aThisHandlersProperties.end();
                        ++copyProperty
                    )
                {
                    ::std::vector< Property >::const_iterator previous = ::std::find_if(
                        aProperties.begin(),
                        aProperties.end(),
                        FindPropertyByName( copyProperty->Name )
                    );
                    if ( previous == aProperties.end() )
                    {
                        aProperties.push_back( *copyProperty );
                        continue;
                    }

                    // there already was another (previous) handler which supported this property.
                    // Don't add it to aProperties, again.

                    // Also, ensure that handlers which previously expressed interest in *changes*
                    // of this property are not notified.
                    // This is 'cause we have a new handler which is responsible for this property,
                    // which means it can give it a completely different meaning than the previous
                    // handler for this property is prepared for.
                    ::std::pair< PropertyHandlerMultiRepository::iterator, PropertyHandlerMultiRepository::iterator >
                        aDepHandlers = m_aDependencyHandlers.equal_range( copyProperty->Name );
                    m_aDependencyHandlers.erase( aDepHandlers.first, aDepHandlers.second );
                }

                // determine the superseded properties
                StlSyntaxSequence< ::rtl::OUString > aSupersededByThisHandler = (*aHandler)->getSupersededProperties();
                for (   StlSyntaxSequence< ::rtl::OUString >::const_iterator superseded = aSupersededByThisHandler.begin();
                        superseded != aSupersededByThisHandler.end();
                        ++superseded
                    )
                {
                    ::std::vector< Property >::iterator existent = ::std::find_if(
                        aProperties.begin(),
                        aProperties.end(),
                        FindPropertyByName( *superseded )
                    );
                    if ( existent != aProperties.end() )
                        // one of the properties superseded by this handler was supported by a previous
                        // one -> erase
                        aProperties.erase( existent );
                }

                // be notified of changes which this handler is responsible for
                (*aHandler)->addPropertyChangeListener( this );

                // remember this handler for every of the properties which it is responsible
                // for
                for (   StlSyntaxSequence< Property >::const_iterator remember = aThisHandlersProperties.begin();
                        remember != aThisHandlersProperties.end();
                        ++remember
                    )
                {
                    m_aPropertyHandlers[ remember->Name ] = *aHandler;
                    // note that this implies that if two handlers support the same property,
                    // the latter wins
                }

                // see if the handler expresses interest in any actuating properties
                StlSyntaxSequence< ::rtl::OUString > aInterestingActuations = (*aHandler)->getActuatingProperties();
                for (   StlSyntaxSequence< ::rtl::OUString >::const_iterator aLoop = aInterestingActuations.begin();
                        aLoop != aInterestingActuations.end();
                        ++aLoop
                    )
                {
                    m_aDependencyHandlers.insert( PropertyHandlerMultiRepository::value_type(
                        *aLoop, *aHandler ) );
                }

                ++aHandler;
            }

            // create a new composer for UI requests coming from the handlers
            m_pUIRequestComposer.reset( new ComposedPropertyUIUpdate( getInspectorUI(), this ) );

            // sort the properties by relative position, as indicated by the model
            for (   ::std::vector< Property >::const_iterator sourceProps = aProperties.begin();
                    sourceProps != aProperties.end();
                    ++sourceProps
                )
			{
                sal_Int32 nRelativePropertyOrder = sourceProps - aProperties.begin();
                if ( m_xModel.is() )
                    nRelativePropertyOrder = m_xModel->getPropertyOrderIndex( sourceProps->Name );
                while ( m_aProperties.find( nRelativePropertyOrder ) != m_aProperties.end() )
                    ++nRelativePropertyOrder;
				m_aProperties[ nRelativePropertyOrder ] = *sourceProps;
			}

            // be notified when one of our inspectees dies
            impl_toggleInspecteeListening_nothrow( true );
		}
		catch(Exception&)
		{
			DBG_ERROR("OPropertyBrowserController::doInspection : caught an exception !");
		}
	}

	//------------------------------------------------------------------------
	::com::sun::star::awt::Size SAL_CALL OPropertyBrowserController::getMinimumSize() throw (::com::sun::star::uno::RuntimeException)
	{
		::com::sun::star::awt::Size aSize;
		if( m_pView )
			return m_pView->getMinimumSize();
		else
			return aSize;
	}

	//------------------------------------------------------------------------
	::com::sun::star::awt::Size SAL_CALL OPropertyBrowserController::getPreferredSize() throw (::com::sun::star::uno::RuntimeException)
	{
		return getMinimumSize();
	}

	//------------------------------------------------------------------------
	::com::sun::star::awt::Size SAL_CALL OPropertyBrowserController::calcAdjustedSize( const ::com::sun::star::awt::Size& _rNewSize ) throw (::com::sun::star::uno::RuntimeException)
	{
		awt::Size aMinSize = getMinimumSize( );
		awt::Size aAdjustedSize( _rNewSize );
		if ( aAdjustedSize.Width < aMinSize.Width )
			aAdjustedSize.Width = aMinSize.Width;
		if ( aAdjustedSize.Height < aMinSize.Height )
			aAdjustedSize.Height = aMinSize.Height;
		return aAdjustedSize;
	}

	//------------------------------------------------------------------------
    void OPropertyBrowserController::describePropertyLine( const Property& _rProperty, OLineDescriptor& _rDescriptor ) SAL_THROW((Exception))
    {
        try
        {
            PropertyHandlerRepository::const_iterator handler = m_aPropertyHandlers.find( _rProperty.Name );
            if ( handler == m_aPropertyHandlers.end() )
                throw RuntimeException();   // caught below

            _rDescriptor.assignFrom( handler->second->describePropertyLine( _rProperty.Name, this ) );

		    //////////////////////////////////////////////////////////////////////

            _rDescriptor.xPropertyHandler = handler->second;
		    _rDescriptor.sName = _rProperty.Name;
            _rDescriptor.aValue = _rDescriptor.xPropertyHandler->getPropertyValue( _rProperty.Name );

            if ( !_rDescriptor.DisplayName.getLength() )
            {
            #ifdef DBG_UTIL
                ::rtl::OString sMessage( "OPropertyBrowserController::describePropertyLine: handler did not provide a display name for '" );
                sMessage += ::rtl::OString( _rProperty.Name.getStr(), _rProperty.Name.getLength(), RTL_TEXTENCODING_ASCII_US );
                sMessage += ::rtl::OString( "'!" );
                DBG_ASSERT( _rDescriptor.DisplayName.getLength(), sMessage );
            #endif
		        _rDescriptor.DisplayName = _rProperty.Name;
            }

            PropertyState   ePropertyState( _rDescriptor.xPropertyHandler->getPropertyState( _rProperty.Name ) );
		    if ( PropertyState_AMBIGUOUS_VALUE == ePropertyState )
		    {
			    _rDescriptor.bUnknownValue = true;
			    _rDescriptor.aValue.clear();
		    }

            _rDescriptor.bReadOnly = impl_isReadOnlyModel_throw();
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "OPropertyBrowserController::describePropertyLine: caught an exception!" );
        }
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::impl_buildCategories_throw()
    {
        OSL_PRECOND( m_aPageIds.empty(), "OPropertyBrowserController::impl_buildCategories_throw: duplicate call!" );

        StlSyntaxSequence< PropertyCategoryDescriptor > aCategories;
        if ( m_xModel.is() )
            aCategories = m_xModel->describeCategories();

        for (   StlSyntaxSequence< PropertyCategoryDescriptor >::const_iterator category = aCategories.begin();
                category != aCategories.end();
                ++category
            )
        {
            OSL_ENSURE( m_aPageIds.find( category->ProgrammaticName ) == m_aPageIds.end(),
                "OPropertyBrowserController::impl_buildCategories_throw: duplicate programmatic name!" );

            m_aPageIds[ category->ProgrammaticName ] =
                getPropertyBox().AppendPage( category->UIName, HelpIdUrl::getHelpId( category->HelpURL ) );
        }
    }

	//------------------------------------------------------------------------
	void OPropertyBrowserController::UpdateUI()
	{
		try
		{
            if ( !haveView() )
                // too early, will return later
                return;

			getPropertyBox().DisableUpdate();

			sal_Bool bHaveFocus = getPropertyBox().HasChildPathFocus();

            // create our tab pages
            impl_buildCategories_throw();
            // (and allow for pages to be actually unused)
            ::std::set< sal_uInt16 > aUsedPages;

            // when building the UI below, remember which properties are actuating,
            // to allow for a initial actuatinPropertyChanged call
            ::std::vector< ::rtl::OUString > aActuatingProperties;
            ::std::vector< Any > aActuatingPropertyValues;

            // ask the handlers to describe the property UI, and insert the resulting
            // entries into our list boxes
            OrderedPropertyMap::const_iterator property( m_aProperties.begin() );
            for ( ; property != m_aProperties.end(); ++property )
			{
                OLineDescriptor aDescriptor;
                describePropertyLine( property->second, aDescriptor );

                bool bIsActuatingProperty = impl_isActuatingProperty_nothrow( property->second.Name );

            #if OSL_DEBUG_LEVEL > 0
                if ( !aDescriptor.Category.getLength() )
                {
                    ::rtl::OString sMessage( "OPropertyBrowserController::UpdateUI: empty category provided for property '" );
                    sMessage += ::rtl::OString( property->second.Name.getStr(), property->second.Name.getLength(), osl_getThreadTextEncoding() );
                    sMessage += "'!";
                    OSL_ENSURE( false, sMessage );
                }
            #endif
                // finally insert this property control
                sal_uInt16 nTargetPageId = impl_getPageIdForCategory_nothrow( aDescriptor.Category );
                if ( nTargetPageId == (sal_uInt16)-1 )
                {
                    // this category does not yet exist. This is allowed, as an inspector model might be lazy, and not provide
                    // any category information of its own. In this case, we have a fallback ...
                    m_aPageIds[ aDescriptor.Category ] =
                    getPropertyBox().AppendPage( aDescriptor.Category, rtl::OString() );
                    nTargetPageId = impl_getPageIdForCategory_nothrow( aDescriptor.Category );
                }

                getPropertyBox().InsertEntry( aDescriptor, nTargetPageId );
                aUsedPages.insert( nTargetPageId );

                // if it's an actuating property, remember it
                if ( bIsActuatingProperty )
                {
                    aActuatingProperties.push_back( property->second.Name );
                    aActuatingPropertyValues.push_back( impl_getPropertyValue_throw( property->second.Name ) );
                }
			}

            // update any dependencies for the actuating properties which we encountered
            {
                ::std::vector< ::rtl::OUString >::const_iterator aProperty = aActuatingProperties.begin();
                ::std::vector< Any >::const_iterator aPropertyValue = aActuatingPropertyValues.begin();
                for ( ; aProperty != aActuatingProperties.end(); ++aProperty, ++aPropertyValue )
                    impl_broadcastPropertyChange_nothrow( *aProperty, *aPropertyValue, *aPropertyValue, true );
            }

            // remove any unused pages (which we did not encounter properties for)
            HashString2Int16 aSurvivingPageIds;
            for (   HashString2Int16::iterator pageId = m_aPageIds.begin();
                    pageId != m_aPageIds.end();
                    ++pageId
                )
            {
                if ( aUsedPages.find( pageId->second ) == aUsedPages.end() )
                    getPropertyBox().RemovePage( pageId->second );
                else
                    aSurvivingPageIds.insert( *pageId );
            }
            m_aPageIds.swap( aSurvivingPageIds );


            getPropertyBox().Show();
			getPropertyBox().EnableUpdate();
			if ( bHaveFocus )
				getPropertyBox().GrabFocus();

			// activate the first page
            if ( !m_aPageIds.empty() )
            {
                Sequence< PropertyCategoryDescriptor > aCategories( m_xModel->describeCategories() );
                if ( aCategories.getLength() )
				    m_pView->activatePage( m_aPageIds[ aCategories[0].ProgrammaticName ] );
                else
                    // allowed: if we default-created the pages ...
				    m_pView->activatePage( m_aPageIds.begin()->second );
            }

            // activate the previously active page (if possible)
            if ( m_sLastValidPageSelection.getLength() )
                m_sPageSelection = m_sLastValidPageSelection;
			selectPageFromViewData();
		}
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
	}

	//------------------------------------------------------------------------
    void OPropertyBrowserController::Clicked( const ::rtl::OUString& _rName, sal_Bool _bPrimary )
	{
		try
		{
            // since the browse buttons do not get the focus when clicked with the mouse,
            // we need to commit the changes in the current property field
            getPropertyBox().CommitModified();

            PropertyHandlerRepository::const_iterator handler = m_aPropertyHandlers.find( _rName );
            DBG_ASSERT( handler != m_aPropertyHandlers.end(), "OPropertyBrowserController::Clicked: a property without handler? This will crash!" );

            ComposedUIAutoFireGuard aAutoFireGuard( *m_pUIRequestComposer );

            Any aData;
            m_xInteractiveHandler = handler->second;
            InteractiveSelectionResult eResult =
                handler->second->onInteractivePropertySelection( _rName, _bPrimary, aData,
                    m_pUIRequestComposer->getUIForPropertyHandler( handler->second ) );

            switch ( eResult )
            {
            case InteractiveSelectionResult_Cancelled:
            case InteractiveSelectionResult_Success:
                // okay, nothing to do
                break;
            case InteractiveSelectionResult_ObtainedValue:
                handler->second->setPropertyValue( _rName, aData );
                break;
            case InteractiveSelectionResult_Pending:
                // also okay, we expect that the handler has disabled the UI as necessary
                break;
            default:
                OSL_ENSURE( false, "OPropertyBrowserController::Clicked: unknown result value!" );
                break;
            }
		}
		catch (Exception&)
		{
            DBG_UNHANDLED_EXCEPTION();
		}
        m_xInteractiveHandler = NULL;
	}

	//------------------------------------------------------------------------
    sal_Bool SAL_CALL OPropertyBrowserController::hasPropertyByName( const ::rtl::OUString& _rName ) throw (RuntimeException)
    {
        for (   OrderedPropertyMap::const_iterator search = m_aProperties.begin();
                search != m_aProperties.end();
                ++search
            )
            if ( search->second.Name == _rName )
                return true;
        return false;
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::Commit( const ::rtl::OUString& rName, const Any& _rValue )
	{
		try
		{
            rtl::OUString sPlcHolder = String( PcrRes( RID_EMBED_IMAGE_PLACEHOLDER ) );
            bool bIsPlaceHolderValue = false;

            if ( rName.equals( PROPERTY_IMAGE_URL ) )
            {
                // if the prop value is the PlaceHolder
                // can ignore it
                rtl::OUString sVal;
                _rValue >>= sVal;
                if ( sVal.equals( sPlcHolder ) )
                    bIsPlaceHolderValue = true;
            }
            m_sCommittingProperty = rName;

            bool bIsActuatingProperty = impl_isActuatingProperty_nothrow( rName );

            Any aOldValue;
            if ( bIsActuatingProperty )
                aOldValue = impl_getPropertyValue_throw( rName );

            // do we have a dedicated handler for this property, which we can delegate some tasks to?
            PropertyHandlerRef handler = impl_getHandlerForProperty_throw( rName );

			//////////////////////////////////////////////////////////////////////
			// set the value ( only if it's not a placeholder )
            if ( !bIsPlaceHolderValue )
                handler->setPropertyValue( rName, _rValue );

			//////////////////////////////////////////////////////////////////////
            // re-retrieve the value
            Any aNormalizedValue = handler->getPropertyValue( rName );

            // care for any inter-property dependencies
            if ( bIsActuatingProperty )
                impl_broadcastPropertyChange_nothrow( rName, aNormalizedValue, aOldValue, false );

            // and display it again. This ensures proper formatting
			getPropertyBox().SetPropertyValue( rName, aNormalizedValue, false );
		}
		catch(PropertyVetoException& eVetoException)
		{
			InfoBox(m_pView, eVetoException.Message).Execute();
            PropertyHandlerRef handler = impl_getHandlerForProperty_throw( rName );
            Any aNormalizedValue = handler->getPropertyValue( rName );
            getPropertyBox().SetPropertyValue( rName, aNormalizedValue, false );
		}
		catch(Exception&)
		{
			DBG_ERROR("OPropertyBrowserController::Commit : caught an exception !");
		}

        m_sCommittingProperty = ::rtl::OUString();
    }

    //--------------------------------------------------------------------
    namespace
    {
    }

    //--------------------------------------------------------------------
    void OPropertyBrowserController::focusGained( const Reference< XPropertyControl >& _Control )
    {
        m_aControlObservers.notifyEach( &XPropertyControlObserver::focusGained, _Control );
    }

    //--------------------------------------------------------------------
    void OPropertyBrowserController::valueChanged( const Reference< XPropertyControl >& _Control )
    {
        m_aControlObservers.notifyEach( &XPropertyControlObserver::valueChanged, _Control );
    }

	//------------------------------------------------------------------------
    namespace
    {
        Reference< XPropertyHandler > lcl_createHandler( const ComponentContext& _rContext, const Any& _rFactoryDescriptor )
        {
            Reference< XPropertyHandler > xHandler;

            ::rtl::OUString sServiceName;
            Reference< XSingleServiceFactory > xServiceFac;
            Reference< XSingleComponentFactory > xComponentFac;

            if ( _rFactoryDescriptor >>= sServiceName )
                _rContext.createComponent( sServiceName, xHandler );
            else if ( _rFactoryDescriptor >>= xServiceFac )
                xHandler = xHandler.query( xServiceFac->createInstance() );
            else if ( _rFactoryDescriptor >>= xComponentFac )
                xHandler = xHandler.query( xComponentFac->createInstanceWithContext( _rContext.getUNOContext() ) );
            OSL_ENSURE(xHandler.is(),"lcl_createHandler: Can not create handler");
            return xHandler;
        }
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::getPropertyHandlers( const InterfaceArray& _rObjects, PropertyHandlerArray& _rHandlers )
    {
        _rHandlers.resize( 0 );
        if ( _rObjects.empty() )
            return;

        // create a component context for the handlers, containing some information about where
        // they live
        Reference< XComponentContext > xHandlerContext( m_aContext.getUNOContext() );

        // if our own creator did not pass a dialog parent window, use our own view for this
        Reference< XWindow > xParentWindow( m_aContext.getContextValueByAsciiName( "DialogParentWindow" ), UNO_QUERY );
        if ( !xParentWindow.is() )
        {
            ::cppu::ContextEntry_Init aHandlerContextInfo[] =
            {
                ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogParentWindow" ) ), makeAny( VCLUnoHelper::GetInterface( m_pView ) ) )
            };
            xHandlerContext = ::cppu::createComponentContext(
                aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ),
                m_aContext.getUNOContext() );
        }

        Sequence< Any > aHandlerFactories;
        if ( m_xModel.is() )
            aHandlerFactories = m_xModel->getHandlerFactories();

        const Any* pHandlerFactory = aHandlerFactories.getConstArray();
        const Any* pHandlerFactoryEnd = aHandlerFactories.getConstArray() + aHandlerFactories.getLength();

        while ( pHandlerFactory != pHandlerFactoryEnd )
        {
            if ( _rObjects.size() == 1 )
            {   // we're inspecting only one object -> one handler
                Reference< XPropertyHandler > xHandler( lcl_createHandler( m_aContext, *pHandlerFactory ) );
                if ( xHandler.is() )
                {
                    xHandler->inspect( _rObjects[0] );
                    _rHandlers.push_back( xHandler );
                }
            }
            else
            {
                // create a single handler for every single object
                ::std::vector< Reference< XPropertyHandler > > aSingleHandlers( _rObjects.size() );
                ::std::vector< Reference< XPropertyHandler > >::iterator pHandler = aSingleHandlers.begin();

                InterfaceArray::const_iterator pObject = _rObjects.begin();
                InterfaceArray::const_iterator pObjectEnd = _rObjects.end();

                for ( ; pObject != pObjectEnd; ++pObject )
                {
                    *pHandler = lcl_createHandler( m_aContext, *pHandlerFactory );
                    if ( pHandler->is() )
                    {
                        (*pHandler)->inspect( *pObject );
                        ++pHandler;
                    }
                }
                aSingleHandlers.resize( pHandler - aSingleHandlers.begin() );

                // then create a handler which composes information out of those single handlers
                if ( !aSingleHandlers.empty() )
                    _rHandlers.push_back( new PropertyComposer( aSingleHandlers ) );
            }

            ++pHandlerFactory;
        }

        // note that the handlers will not be used by our caller, if they indicate that there are no
        // properties they feel responsible for
    }

    //------------------------------------------------------------------------
    bool OPropertyBrowserController::impl_findObjectProperty_nothrow( const ::rtl::OUString& _rName, OrderedPropertyMap::const_iterator* _pProperty )
    {
        OrderedPropertyMap::const_iterator search = m_aProperties.begin();
        for ( ; search != m_aProperties.end(); ++search )
            if ( search->second.Name == _rName )
                break;
        if ( _pProperty )
            *_pProperty = search;
        return ( search != m_aProperties.end() );
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::rebuildPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        OrderedPropertyMap::const_iterator propertyPos;
        if ( !impl_findObjectProperty_nothrow( _rPropertyName, &propertyPos ) )
            return;

        OLineDescriptor aDescriptor;
        try
        {
            describePropertyLine( propertyPos->second, aDescriptor );
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "OPropertyBrowserController::rebuildPropertyUI: caught an exception!" );
        }

        getPropertyBox().ChangeEntry( aDescriptor );
   }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::enablePropertyUI( const ::rtl::OUString& _rPropertyName, sal_Bool _bEnable ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        if ( !impl_findObjectProperty_nothrow( _rPropertyName ) )
            return;

        getPropertyBox().EnablePropertyLine( _rPropertyName, _bEnable );
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::enablePropertyUIElements( const ::rtl::OUString& _rPropertyName, sal_Int16 _nElements, sal_Bool _bEnable ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        if ( !impl_findObjectProperty_nothrow( _rPropertyName ) )
            return;

        getPropertyBox().EnablePropertyControls( _rPropertyName, _nElements, _bEnable );
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::showPropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        // look up the property in our object properties
        OrderedPropertyMap::const_iterator propertyPos;
        if ( !impl_findObjectProperty_nothrow( _rPropertyName, &propertyPos ) )
            return;

        if ( getPropertyBox().GetPropertyPos( _rPropertyName ) != LISTBOX_ENTRY_NOTFOUND )
        {
            rebuildPropertyUI( _rPropertyName );
            return;
        }

        OLineDescriptor aDescriptor;
        describePropertyLine( propertyPos->second, aDescriptor );

        // look for the position to insert the property

        // side note: The methods GetPropertyPos and InsertEntry of the OPropertyEditor work
        // only on the current page. This implies that it's impossible to use this method here
        // to show property lines which are *not* on the current page.
        // This is sufficient for now, but should be changed in the future.

        // by definition, the properties in m_aProperties are in the order in which they appear in the UI
        // So all we need is a predecessor of pProperty in m_aProperties
        sal_uInt16 nUIPos = LISTBOX_ENTRY_NOTFOUND;
        do
        {
            if ( propertyPos != m_aProperties.begin() )
                --propertyPos;
            nUIPos = getPropertyBox().GetPropertyPos( propertyPos->second.Name );
        }
        while ( ( nUIPos == LISTBOX_ENTRY_NOTFOUND ) && ( propertyPos != m_aProperties.begin() ) );

        if ( nUIPos == LISTBOX_ENTRY_NOTFOUND )
            // insert at the very top
            nUIPos = 0;
        else
            // insert right after the predecessor we found
            ++nUIPos;

        getPropertyBox().InsertEntry(
            aDescriptor, impl_getPageIdForCategory_nothrow( aDescriptor.Category ), nUIPos );
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::hidePropertyUI( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        if ( !impl_findObjectProperty_nothrow( _rPropertyName ) )
            return;

        getPropertyBox().RemoveEntry( _rPropertyName );
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::showCategory( const ::rtl::OUString& _rCategory, sal_Bool _bShow ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        sal_uInt16 nPageId = impl_getPageIdForCategory_nothrow( _rCategory );
        OSL_ENSURE( nPageId != (sal_uInt16)-1, "OPropertyBrowserController::showCategory: invalid category!" );

        getPropertyBox().ShowPropertyPage( nPageId, _bShow );
    }

	//------------------------------------------------------------------------
    Reference< XPropertyControl > SAL_CALL OPropertyBrowserController::getPropertyControl( const ::rtl::OUString& _rPropertyName ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( !haveView() )
            throw RuntimeException();

        Reference< XPropertyControl > xControl( getPropertyBox().GetPropertyControl( _rPropertyName ) );
        return xControl;
    }

    //--------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::registerControlObserver( const Reference< XPropertyControlObserver >& _Observer ) throw (RuntimeException)
    {
        m_aControlObservers.addInterface( _Observer );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::revokeControlObserver( const Reference< XPropertyControlObserver >& _Observer ) throw (RuntimeException)
    {
        m_aControlObservers.removeInterface( _Observer );
    }

	//------------------------------------------------------------------------
    void SAL_CALL OPropertyBrowserController::setHelpSectionText( const ::rtl::OUString& _rHelpText ) throw (NoSupportException, RuntimeException)
    {
        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        ::osl::MutexGuard aGuard( m_aMutex );

        if ( !haveView() )
            throw DisposedException();

        if ( !getPropertyBox().HasHelpSection() )
            throw NoSupportException();

        getPropertyBox().SetHelpText( _rHelpText );
    }

	//------------------------------------------------------------------------
    void OPropertyBrowserController::impl_broadcastPropertyChange_nothrow( const ::rtl::OUString& _rPropertyName, const Any& _rNewValue, const Any& _rOldValue, bool _bFirstTimeInit ) const
    {
        // are there one or more handlers which are interested in the actuation?
        ::std::pair< PropertyHandlerMultiRepository::const_iterator, PropertyHandlerMultiRepository::const_iterator > aInterestedHandlers =
            m_aDependencyHandlers.equal_range( _rPropertyName );
        if ( aInterestedHandlers.first == aInterestedHandlers.second )
            // none of our handlers is interested in this
            return;

        ComposedUIAutoFireGuard aAutoFireGuard( *m_pUIRequestComposer );
        try
        {
            // collect the responses from all interested handlers
            PropertyHandlerMultiRepository::const_iterator handler = aInterestedHandlers.first;
            while ( handler != aInterestedHandlers.second )
            {
                handler->second->actuatingPropertyChanged( _rPropertyName, _rNewValue, _rOldValue,
                    m_pUIRequestComposer->getUIForPropertyHandler( handler->second ),
                    _bFirstTimeInit );
                ++handler;
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

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