/**************************************************************
 * 
 * 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 "browserlistbox.hxx"
#ifndef EXTENSIONS_PROPRESID_HRC
#include "propresid.hrc"
#endif
#include "proplinelistener.hxx"
#include "propcontrolobserver.hxx"
#include "linedescriptor.hxx"
#include "inspectorhelpwindow.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/inspection/PropertyControlType.hpp>
/** === end UNO includes === **/
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <comphelper/asyncnotification.hxx>
#include <cppuhelper/implbase1.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>

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

    #define FRAME_OFFSET 4
	    // TODO: find out what this is really for ... and check if it does make sense in the new
	    // browser environment
    #define LAYOUT_HELP_WINDOW_DISTANCE_APPFONT 3

    /** === begin UNO using === **/
    using ::com::sun::star::uno::Any;
    using ::com::sun::star::uno::Exception;
    using ::com::sun::star::inspection::XPropertyControlContext;
    using ::com::sun::star::uno::Reference;
    using ::com::sun::star::inspection::XPropertyControl;
    using ::com::sun::star::uno::RuntimeException;
    using ::com::sun::star::lang::DisposedException;
    using ::com::sun::star::lang::XComponent;
    using ::com::sun::star::uno::UNO_QUERY;
    using ::com::sun::star::graphic::XGraphic;
    /** === end UNO using === **/
    namespace PropertyControlType = ::com::sun::star::inspection::PropertyControlType;

	//==================================================================
	//= ControlEvent
	//==================================================================
    enum ControlEventType
    {
        FOCUS_GAINED,
        VALUE_CHANGED,
        ACTIVATE_NEXT
    };

    struct ControlEvent : public ::comphelper::AnyEvent
    {
        Reference< XPropertyControl >   xControl;
        ControlEventType                eType;

        ControlEvent( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType )
            :xControl( _rxControl )
            ,eType( _eType )
        {
        }
    };

	//==================================================================
	//= SharedNotifier
	//==================================================================
    class SharedNotifier
    {
    private:
        static ::osl::Mutex&                                        getMutex();
        static ::rtl::Reference< ::comphelper::AsyncEventNotifier > s_pNotifier;

    public:
        static const ::rtl::Reference< ::comphelper::AsyncEventNotifier >&
            getNotifier();

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

	//------------------------------------------------------------------
    ::rtl::Reference< ::comphelper::AsyncEventNotifier > SharedNotifier::s_pNotifier;

	//------------------------------------------------------------------
    ::osl::Mutex& SharedNotifier::getMutex()
    {
        static ::osl::Mutex s_aMutex;
        return s_aMutex;
    }

	//------------------------------------------------------------------
    const ::rtl::Reference< ::comphelper::AsyncEventNotifier >& SharedNotifier::getNotifier()
    {
        ::osl::MutexGuard aGuard( getMutex() );
        if ( !s_pNotifier.is() )
        {
            s_pNotifier.set( new ::comphelper::AsyncEventNotifier );
            s_pNotifier->create();
        }
        return s_pNotifier;
    }

	//==================================================================
	//= PropertyControlContext_Impl
	//==================================================================
    /** implementation for of <type scope="com::sun::star::inspection">XPropertyControlContext</type>
        which forwards all events to a non-UNO version of this interface
    */
    typedef ::cppu::WeakImplHelper1< XPropertyControlContext > PropertyControlContext_Impl_Base;
    class PropertyControlContext_Impl   :public PropertyControlContext_Impl_Base
                                        ,public ::comphelper::IEventProcessor
    {
    public:
        enum NotifcationMode
        {
            eSynchronously,
            eAsynchronously
        };

    private:
        IControlContext*    m_pContext;
        NotifcationMode     m_eMode;

    public:
        /** creates an instance
            @param _rContextImpl
                the instance to delegate events to
        */
        PropertyControlContext_Impl( IControlContext& _rContextImpl );

        /** disposes the context.

            When you call this method, all subsequent callbacks to the
            <type scope="com::sun::star::inspection">XPropertyControlContext</type> methods
            will throw a <type scope="com::sun::star::lang">DisposedException</type>.
        */
        void SAL_CALL dispose();

        /** sets the notification mode, so that notifications recieved from the controls are
            forwarded to our IControlContext either synchronously or asynchronously
            @param  _eMode
                the new notification mode
        */
        void setNotificationMode( NotifcationMode _eMode );

        virtual void SAL_CALL acquire() throw();
        virtual void SAL_CALL release() throw();

    protected:
        ~PropertyControlContext_Impl();

        // XPropertyControlObserver
        virtual void SAL_CALL focusGained( const Reference< XPropertyControl >& Control ) throw (RuntimeException);
        virtual void SAL_CALL valueChanged( const Reference< XPropertyControl >& Control ) throw (RuntimeException);
        // XPropertyControlContext
        virtual void SAL_CALL activateNextControl( const Reference< XPropertyControl >& CurrentControl ) throw (RuntimeException);

        // IEventProcessor
        virtual void processEvent( const ::comphelper::AnyEvent& _rEvent );

    private:
        /** processes the given event, i.e. notifies it to our IControlContext
            @param  _rEvent
                the event no notify 
            @precond
                our mutex (well, the SolarMutex) is locked
        */
        void impl_processEvent_throw( const ::comphelper::AnyEvent& _rEvent );

        /** checks whether we're alive

            @throws DisposedException
                if the instance is already disposed
        */
        void impl_checkAlive_throw() const;

        /** checks whether the instance is already disposed
        */
        bool impl_isDisposed_nothrow() const { return m_pContext == NULL; }

        /** notifies the given event originating from the given control
        @throws DisposedException
        @param  _rxControl
        @param  _eType
        */
        void impl_notify_throw( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType );
    };

    //--------------------------------------------------------------------
    PropertyControlContext_Impl::PropertyControlContext_Impl( IControlContext& _rContextImpl )
        :m_pContext( &_rContextImpl )
        ,m_eMode( eAsynchronously )
    {
    }

    //--------------------------------------------------------------------
    PropertyControlContext_Impl::~PropertyControlContext_Impl()
    {
        if ( !impl_isDisposed_nothrow() )
            dispose();
    }

    //--------------------------------------------------------------------
    void PropertyControlContext_Impl::impl_checkAlive_throw() const
    {
        if ( impl_isDisposed_nothrow() )
            throw DisposedException( ::rtl::OUString(), *const_cast< PropertyControlContext_Impl* >( this ) );
    }

    //--------------------------------------------------------------------
    void SAL_CALL PropertyControlContext_Impl::dispose()
    {
        ::vos::OGuard aGuard( Application::GetSolarMutex() );
        if ( impl_isDisposed_nothrow() )
            return;

        SharedNotifier::getNotifier()->removeEventsForProcessor( this );
        m_pContext = NULL;
    }

    //--------------------------------------------------------------------
    void PropertyControlContext_Impl::setNotificationMode( NotifcationMode _eMode )
    {
        ::vos::OGuard aGuard( Application::GetSolarMutex() );
        m_eMode = _eMode;
    }

    //--------------------------------------------------------------------
    void PropertyControlContext_Impl::impl_notify_throw( const Reference< XPropertyControl >& _rxControl, ControlEventType _eType )
    {
        ::comphelper::AnyEventRef pEvent;

        {
            ::vos::OGuard aGuard( Application::GetSolarMutex() );
            impl_checkAlive_throw();
            pEvent = new ControlEvent( _rxControl, _eType );

            if ( m_eMode == eSynchronously )
            {
                impl_processEvent_throw( *pEvent );
                return;
            }
        }

        SharedNotifier::getNotifier()->addEvent( pEvent, this );
    }

    //--------------------------------------------------------------------
    void SAL_CALL PropertyControlContext_Impl::focusGained( const Reference< XPropertyControl >& Control ) throw (RuntimeException)
    {
        DBG_TRACE( "PropertyControlContext_Impl: FOCUS_GAINED" );
        impl_notify_throw( Control, FOCUS_GAINED );
    }

    //--------------------------------------------------------------------
    void SAL_CALL PropertyControlContext_Impl::valueChanged( const Reference< XPropertyControl >& Control ) throw (RuntimeException)
    {
        DBG_TRACE( "PropertyControlContext_Impl: VALUE_CHANGED" );
        impl_notify_throw( Control, VALUE_CHANGED );
    }

    //--------------------------------------------------------------------
    void SAL_CALL PropertyControlContext_Impl::activateNextControl( const Reference< XPropertyControl >& CurrentControl ) throw (RuntimeException)
    {
        DBG_TRACE( "PropertyControlContext_Impl: ACTIVATE_NEXT" );
        impl_notify_throw( CurrentControl, ACTIVATE_NEXT );
    }

    //--------------------------------------------------------------------
    void SAL_CALL PropertyControlContext_Impl::acquire() throw()
    {
        PropertyControlContext_Impl_Base::acquire();
    }

    //--------------------------------------------------------------------
    void SAL_CALL PropertyControlContext_Impl::release() throw()
    {
        PropertyControlContext_Impl_Base::release();
    }

    //--------------------------------------------------------------------
    void PropertyControlContext_Impl::processEvent( const ::comphelper::AnyEvent& _rEvent )
    {
        ::vos::OGuard aGuard( Application::GetSolarMutex() );
        if ( impl_isDisposed_nothrow() )
            return;

        try
        {
            impl_processEvent_throw( _rEvent );
        }
        catch( const Exception& )
        {
            // can't handle otherwise, since our caller (the notification thread) does not allow
            // for exceptions (it could itself abort only)
        	DBG_UNHANDLED_EXCEPTION();
        }
    }

    //--------------------------------------------------------------------
    void PropertyControlContext_Impl::impl_processEvent_throw( const ::comphelper::AnyEvent& _rEvent )
    {
        const ControlEvent& rControlEvent = static_cast< const ControlEvent& >( _rEvent );
        switch ( rControlEvent.eType )
        {
        case FOCUS_GAINED:
            DBG_TRACE( "PropertyControlContext_Impl::processEvent: FOCUS_GAINED" );
            m_pContext->focusGained( rControlEvent.xControl );
            break;
        case VALUE_CHANGED:
            DBG_TRACE( "PropertyControlContext_Impl::processEvent: VALUE_CHANGED" );
            m_pContext->valueChanged( rControlEvent.xControl );
            break;
        case ACTIVATE_NEXT:
            DBG_TRACE( "PropertyControlContext_Impl::processEvent: ACTIVATE_NEXT" );
            m_pContext->activateNextControl( rControlEvent.xControl );
            break;
        }
    }

    //==================================================================
	//= OBrowserListBox
	//==================================================================
	DBG_NAME(OBrowserListBox)
	//------------------------------------------------------------------
	OBrowserListBox::OBrowserListBox( Window* pParent, WinBits nWinStyle)
			:Control(pParent, nWinStyle| WB_CLIPCHILDREN)
			,m_aLinesPlayground(this,WB_DIALOGCONTROL | WB_CLIPCHILDREN)
			,m_aVScroll(this,WB_VSCROLL|WB_REPEAT|WB_DRAG)
            ,m_pHelpWindow( new InspectorHelpWindow( this ) )
			,m_pLineListener(NULL)
            ,m_pControlObserver( NULL )
			,m_nYOffset(0)
            ,m_nCurrentPreferredHelpHeight(0)
			,m_nTheNameSize(0)
			,m_bIsActive(sal_False)
			,m_bUpdate(sal_True)
            ,m_pControlContextImpl( new PropertyControlContext_Impl( *this ) )
	{
		DBG_CTOR(OBrowserListBox,NULL);

		ListBox aListBox(this,WB_DROPDOWN);
		aListBox.SetPosSizePixel(Point(0,0),Size(100,100));
		m_nRowHeight = (sal_uInt16)aListBox.GetSizePixel().Height()+2;
		SetBackground( pParent->GetBackground() );
        m_aLinesPlayground.SetBackground( GetBackground() );

		m_aLinesPlayground.SetPosPixel(Point(0,0));
		m_aLinesPlayground.SetPaintTransparent(sal_True);
		m_aLinesPlayground.Show();
		m_aVScroll.Hide();
		m_aVScroll.SetScrollHdl(LINK(this, OBrowserListBox, ScrollHdl));
	}

	//------------------------------------------------------------------
	OBrowserListBox::~OBrowserListBox()
	{
		OSL_ENSURE( !IsModified(), "OBrowserListBox::~OBrowserListBox: still modified - should have been committed before!" );
			// doing the commit here, while we, as well as our owner, as well as some other components,
			// are already "half dead" (means within their dtor) is potentially dangerous.
			// By definition, CommitModified has to be called (if necessary) before destruction
			// #105868# - 2002-12-13 - fs@openoffice.org

        m_pControlContextImpl->dispose();
        m_pControlContextImpl.clear();

		Hide();
		Clear();

		DBG_DTOR(OBrowserListBox,NULL);
	}

	//------------------------------------------------------------------
	sal_Bool OBrowserListBox::IsModified( ) const
	{
		sal_Bool bModified = sal_False;

		if ( m_bIsActive && m_xActiveControl.is() )
			bModified = m_xActiveControl->isModified();

        return bModified;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::CommitModified( )
	{
		if ( IsModified() && m_xActiveControl.is() )
        {
            // for the time of this commit, notify all events synchronously
            // #i63814# / 2006-03-31 / frank.schoenheit@sun.com
            m_pControlContextImpl->setNotificationMode( PropertyControlContext_Impl::eSynchronously );
            try
            {
			    m_xActiveControl->notifyModifiedValue();
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
            m_pControlContextImpl->setNotificationMode( PropertyControlContext_Impl::eAsynchronously );
        }
	}

	//------------------------------------------------------------------
	void OBrowserListBox::ActivateListBox(sal_Bool _bActive)
	{
		m_bIsActive = _bActive;
		if (m_bIsActive)
		{
			// TODO: what's the sense of this?
			m_aVScroll.SetThumbPos(100);
			MoveThumbTo(0);
			Resize();
		}
	}

	//------------------------------------------------------------------
    long OBrowserListBox::impl_getPrefererredHelpHeight()
    {
        return HasHelpSection() ? m_pHelpWindow->GetOptimalHeightPixel() : 0;
    }

	//------------------------------------------------------------------
	void OBrowserListBox::Resize()
	{
        Rectangle aPlayground( Point( 0, 0 ), GetOutputSizePixel() );
        Size aHelpWindowDistance( LogicToPixel( Size( 0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT ), MAP_APPFONT ) );

        long nHelpWindowHeight = m_nCurrentPreferredHelpHeight = impl_getPrefererredHelpHeight();
        bool bPositionHelpWindow = ( nHelpWindowHeight != 0 );

        Rectangle aLinesArea( aPlayground );
        if ( bPositionHelpWindow )
        {
            aLinesArea.Bottom() -= nHelpWindowHeight;
            aLinesArea.Bottom() -= aHelpWindowDistance.Height();
        }
		m_aLinesPlayground.SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() );

		UpdateVScroll();

		sal_Bool bNeedScrollbar = m_aOrderedLines.size() > (sal_uInt32)CalcVisibleLines();
        if ( !bNeedScrollbar )
		{
			if ( m_aVScroll.IsVisible() )
				m_aVScroll.Hide();
            // scroll to top
			m_nYOffset = 0;
			m_aVScroll.SetThumbPos( 0 );
		}
		else
		{
            Size aVScrollSize( m_aVScroll.GetSizePixel() );

            // adjust the playground's width
            aLinesArea.Right() -= aVScrollSize.Width();
		    m_aLinesPlayground.SetPosSizePixel( aLinesArea.TopLeft(), aLinesArea.GetSize() );

            // position the scrollbar
			aVScrollSize.Height() = aLinesArea.GetHeight();
            Point aVScrollPos( aLinesArea.GetWidth(), 0 );
            m_aVScroll.SetPosSizePixel( aVScrollPos, aVScrollSize );
		}

		for ( sal_uInt16 i = 0; i < m_aOrderedLines.size(); ++i )
            m_aOutOfDateLines.insert( i );

		// repaint
		EnablePaint(sal_False);
		UpdatePlayGround();
		EnablePaint(sal_True);

		// show the scrollbar
		if ( bNeedScrollbar )
			m_aVScroll.Show();

        // position the help window
        if ( bPositionHelpWindow )
        {
            Rectangle aHelpArea( aPlayground );
            aHelpArea.Top() = aLinesArea.Bottom() + aHelpWindowDistance.Height();
            m_pHelpWindow->SetPosSizePixel( aHelpArea.TopLeft(), aHelpArea.GetSize() );
        }
	}

	//------------------------------------------------------------------
	void OBrowserListBox::SetListener( IPropertyLineListener* _pListener )
	{
		m_pLineListener = _pListener;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::SetObserver( IPropertyControlObserver* _pObserver )
	{
		m_pControlObserver = _pObserver;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::EnableHelpSection( bool _bEnable )
    {
        m_pHelpWindow->Show( _bEnable );
        Resize();
    }

	//------------------------------------------------------------------
    bool OBrowserListBox::HasHelpSection() const
    {
        return m_pHelpWindow->IsVisible();
    }

	//------------------------------------------------------------------
	void OBrowserListBox::SetHelpText( const ::rtl::OUString& _rHelpText )
    {
        OSL_ENSURE( HasHelpSection(), "OBrowserListBox::SetHelpText: help section not visible!" );
        m_pHelpWindow->SetText( _rHelpText );
        if ( m_nCurrentPreferredHelpHeight != impl_getPrefererredHelpHeight() )
            Resize();
    }

	//------------------------------------------------------------------
	void OBrowserListBox::SetHelpLineLimites( sal_Int32 _nMinLines, sal_Int32 _nMaxLines )
    {
        m_pHelpWindow->SetLimits( _nMinLines, _nMaxLines );
    }

	//------------------------------------------------------------------
	sal_uInt16 OBrowserListBox::CalcVisibleLines()
	{
		Size aSize(m_aLinesPlayground.GetOutputSizePixel());
		sal_uInt16 nResult = 0;
		if (0 != m_nRowHeight)
			nResult = (sal_uInt16) aSize.Height()/m_nRowHeight;

		return nResult;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::UpdateVScroll()
	{
		sal_uInt16 nLines = CalcVisibleLines();
		m_aVScroll.SetPageSize(nLines-1);
		m_aVScroll.SetVisibleSize(nLines-1);

		size_t nCount = m_aLines.size();
		if (nCount>0)
		{
			m_aVScroll.SetRange(Range(0,nCount-1));
			m_nYOffset = -m_aVScroll.GetThumbPos()*m_nRowHeight;
		}
		else
		{
			m_aVScroll.SetRange(Range(0,0));
			m_nYOffset = 0;
		}
	}

	//------------------------------------------------------------------
	void OBrowserListBox::PositionLine( sal_uInt16 _nIndex )
	{
		Size aSize(m_aLinesPlayground.GetOutputSizePixel());
		Point aPos(0, m_nYOffset);

		aSize.Height() = m_nRowHeight;

		aPos.Y() += _nIndex * m_nRowHeight;

		if ( _nIndex < m_aOrderedLines.size() )
		{
    		m_aOrderedLines[ _nIndex ]->second.pLine->SetPosSizePixel( aPos, aSize );

			m_aOrderedLines[ _nIndex ]->second.pLine->SetTitleWidth( m_nTheNameSize + 2 * FRAME_OFFSET );

			// show the line if necessary
			if ( !m_aOrderedLines[ _nIndex ]->second.pLine->IsVisible() )
				m_aOrderedLines[ _nIndex ]->second.pLine->Show();
		}
	}

	//------------------------------------------------------------------
	void OBrowserListBox::UpdatePosNSize()
	{
        for  (  ::std::set< sal_uInt16 >::const_iterator aLoop = m_aOutOfDateLines.begin();
                aLoop != m_aOutOfDateLines.end();
                ++aLoop
             )
        {
            DBG_ASSERT( *aLoop < m_aOrderedLines.size(), "OBrowserListBox::UpdatePosNSize: invalid line index!" );
            if ( *aLoop < m_aOrderedLines.size() )
				PositionLine( *aLoop );
		}
        m_aOutOfDateLines.clear();
	}

	//------------------------------------------------------------------
	void OBrowserListBox::UpdatePlayGround()
	{
		sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();
		sal_Int32 nLines = CalcVisibleLines();

		sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines);
		if (nEnd >= m_aOrderedLines.size())
			nEnd = (sal_uInt16)m_aOrderedLines.size()-1;

		if ( !m_aOrderedLines.empty() )
		{
			for ( sal_uInt16 i = (sal_uInt16)nThumbPos; i <= nEnd; ++i )
                m_aOutOfDateLines.insert( i );
			UpdatePosNSize();
		}
	}

	//------------------------------------------------------------------
	void OBrowserListBox::UpdateAll()
	{
		Resize();
	}

	//------------------------------------------------------------------
	void OBrowserListBox::DisableUpdate()
	{
		m_bUpdate = sal_False;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::EnableUpdate()
	{
		m_bUpdate = sal_True;
		UpdateAll();
	}

	//------------------------------------------------------------------
	void OBrowserListBox::SetPropertyValue(const ::rtl::OUString& _rEntryName, const Any& _rValue, bool _bUnknownValue )
	{
        ListBoxLines::iterator line = m_aLines.find( _rEntryName );
        if ( line != m_aLines.end() )
        {
            if ( _bUnknownValue )
            {
                Reference< XPropertyControl > xControl( line->second.pLine->getControl() );
                OSL_ENSURE( xControl.is(), "OBrowserListBox::SetPropertyValue: illegal control!" );
                if ( xControl.is() )
		            xControl->setValue( Any() );
            }
            else
                impl_setControlAsPropertyValue( line->second, _rValue );
        }
	}

	//------------------------------------------------------------------------
	sal_uInt16 OBrowserListBox::GetPropertyPos( const ::rtl::OUString& _rEntryName ) const
	{
		sal_uInt16 nRet = LISTBOX_ENTRY_NOTFOUND;
        for ( OrderedListBoxLines::const_iterator linePos = m_aOrderedLines.begin();
              linePos != m_aOrderedLines.end();
              ++linePos
            )
        {
            if ( (*linePos)->first == _rEntryName )
            {
                nRet = (sal_uInt16)( linePos - m_aOrderedLines.begin() );
                break;
            }
        }

        return nRet;
	}

	//------------------------------------------------------------------------
    bool OBrowserListBox::impl_getBrowserLineForName( const ::rtl::OUString& _rEntryName, BrowserLinePointer& _out_rpLine ) const
    {
        ListBoxLines::const_iterator line = m_aLines.find( _rEntryName );
        if ( line != m_aLines.end() )
            _out_rpLine = line->second.pLine;
        else
            _out_rpLine.reset();
        return ( NULL != _out_rpLine.get() );
    }

	//------------------------------------------------------------------------
    void OBrowserListBox::EnablePropertyControls( const ::rtl::OUString& _rEntryName, sal_Int16 _nControls, bool _bEnable )
    {
        BrowserLinePointer pLine;
        if ( impl_getBrowserLineForName( _rEntryName, pLine ) )
            pLine->EnablePropertyControls( _nControls, _bEnable );
    }

    //------------------------------------------------------------------------
    void OBrowserListBox::EnablePropertyLine( const ::rtl::OUString& _rEntryName, bool _bEnable )
    {
        BrowserLinePointer pLine;
        if ( impl_getBrowserLineForName( _rEntryName, pLine ) )
            pLine->EnablePropertyLine( _bEnable );
    }

	//------------------------------------------------------------------------
	Reference< XPropertyControl > OBrowserListBox::GetPropertyControl( const ::rtl::OUString& _rEntryName )
	{
        BrowserLinePointer pLine;
        if ( impl_getBrowserLineForName( _rEntryName, pLine ) )
            return pLine->getControl();
        return NULL;
	}

	//------------------------------------------------------------------
	sal_uInt16 OBrowserListBox::InsertEntry(const OLineDescriptor& _rPropertyData, sal_uInt16 _nPos)
	{
		// create a new line
		BrowserLinePointer pBrowserLine( new OBrowserLine( _rPropertyData.sName, &m_aLinesPlayground ) );

        ListBoxLine aNewLine( pBrowserLine, _rPropertyData.xPropertyHandler );
        ::std::pair< ListBoxLines::iterator, bool > insertPoint =
            m_aLines.insert( ListBoxLines::value_type( _rPropertyData.sName, aNewLine ) );
        OSL_ENSURE( insertPoint.second, "OBrowserListBox::InsertEntry: already have another line for this name!" );

		sal_uInt16 nInsertPos = _nPos;
        if ( nInsertPos > m_aOrderedLines.size() )
            nInsertPos = EDITOR_LIST_APPEND;
		if ( EDITOR_LIST_APPEND == nInsertPos )
		{
			nInsertPos = (sal_uInt16)m_aOrderedLines.size();
			m_aOrderedLines.push_back( insertPoint.first );
		}
		else
			m_aOrderedLines.insert( m_aOrderedLines.begin() + nInsertPos, insertPoint.first );

		pBrowserLine->SetTitleWidth(m_nTheNameSize);
		if (m_bUpdate)
		{
			UpdateVScroll();
			Invalidate();
		}

		// initialize the entry
		ChangeEntry(_rPropertyData, nInsertPos);

        // update the positions of possibly affected lines
        sal_uInt16 nUpdatePos = nInsertPos;
        while ( nUpdatePos < m_aOrderedLines.size() )
            m_aOutOfDateLines.insert( nUpdatePos++ );
        UpdatePosNSize( );

        return nInsertPos;
	}

	//------------------------------------------------------------------
	sal_Int32 OBrowserListBox::GetMinimumWidth()
	{
		return m_nTheNameSize + 2 * FRAME_OFFSET + (m_nRowHeight - 4) * 8;
	}

	//------------------------------------------------------------------
	sal_Int32 OBrowserListBox::GetMinimumHeight()
	{
        // assume that we want to display 5 rows, at least
        sal_Int32 nMinHeight = m_nRowHeight * 5;

        if ( HasHelpSection() )
        {
            Size aHelpWindowDistance( LogicToPixel( Size( 0, LAYOUT_HELP_WINDOW_DISTANCE_APPFONT ), MAP_APPFONT ) );
            nMinHeight += aHelpWindowDistance.Height();

            nMinHeight += m_pHelpWindow->GetMinimalHeightPixel();
        }

        return nMinHeight;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::ShowEntry(sal_uInt16 _nPos)
	{
		if ( _nPos < m_aOrderedLines.size() )
		{
			sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();

			if (_nPos < nThumbPos)
				MoveThumbTo(_nPos);
			else
			{
				sal_Int32 nLines = CalcVisibleLines();
				if (_nPos >= nThumbPos + nLines)
					MoveThumbTo(_nPos - nLines + 1);
			}
		}

	}

	//------------------------------------------------------------------
	void OBrowserListBox::MoveThumbTo(sal_Int32 _nNewThumbPos)
	{
		// disable painting to prevent flicker
		m_aLinesPlayground.EnablePaint(sal_False);

		sal_Int32 nDelta = _nNewThumbPos - m_aVScroll.GetThumbPos();
		// adjust the scrollbar
		m_aVScroll.SetThumbPos(_nNewThumbPos);
		sal_Int32 nThumbPos = _nNewThumbPos;

		m_nYOffset = -m_aVScroll.GetThumbPos() * m_nRowHeight;

		sal_Int32 nLines = CalcVisibleLines();
		sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + nLines);

		m_aLinesPlayground.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN);

		if (1 == nDelta)
		{
			// TODO: what's the sense of this two PositionLines? Why not just one call?
			PositionLine(nEnd-1);
			PositionLine(nEnd);
		}
		else if (-1 == nDelta)
		{
			PositionLine((sal_uInt16)nThumbPos);
		}
		else if (0 != nDelta)
		{
			UpdatePlayGround();
		}

		m_aLinesPlayground.EnablePaint(sal_True);
		m_aLinesPlayground.Invalidate(INVALIDATE_CHILDREN);
	}

	//------------------------------------------------------------------
	IMPL_LINK(OBrowserListBox, ScrollHdl, ScrollBar*, _pScrollBar )
	{
		DBG_ASSERT(_pScrollBar == &m_aVScroll, "OBrowserListBox::ScrollHdl: where does this come from?");
        (void)_pScrollBar;

		// disable painting to prevent flicker
		m_aLinesPlayground.EnablePaint(sal_False);

		sal_Int32 nThumbPos = m_aVScroll.GetThumbPos();

		sal_Int32 nDelta = m_aVScroll.GetDelta();
		m_nYOffset = -nThumbPos * m_nRowHeight;

		sal_uInt16 nEnd = (sal_uInt16)(nThumbPos + CalcVisibleLines());

		m_aLinesPlayground.Scroll(0, -nDelta * m_nRowHeight, SCROLL_CHILDREN);

		if (1 == nDelta)
		{
			PositionLine(nEnd-1);
			PositionLine(nEnd);
		}
		else if (nDelta==-1)
		{
			PositionLine((sal_uInt16)nThumbPos);
		}
		else if (nDelta!=0 || m_aVScroll.GetType() == SCROLL_DONTKNOW)
		{
			UpdatePlayGround();
		}

		m_aLinesPlayground.EnablePaint(sal_True);
		return 0;
	}

	//------------------------------------------------------------------
	void OBrowserListBox::buttonClicked( OBrowserLine* _pLine, sal_Bool _bPrimary )
    {
        DBG_ASSERT( _pLine, "OBrowserListBox::buttonClicked: invalid browser line!" );
		if ( _pLine && m_pLineListener )
		{
			m_pLineListener->Clicked( _pLine->GetEntryName(), _bPrimary );
		}
    }

	//------------------------------------------------------------------
    void OBrowserListBox::impl_setControlAsPropertyValue( const ListBoxLine& _rLine, const Any& _rPropertyValue )
    {
        Reference< XPropertyControl > xControl( _rLine.pLine->getControl() );
        try
        {
            if ( _rPropertyValue.getValueType().equals( _rLine.pLine->getControl()->getValueType() ) )
            {
		        xControl->setValue( _rPropertyValue );
            }
            else
            {
    #ifdef DBG_UTIL
                if ( !_rLine.xHandler.is() )
                {
                    ::rtl::OString sMessage( "OBrowserListBox::impl_setControlAsPropertyValue: no handler -> no conversion (property: '" );
                    ::rtl::OUString sPropertyName( _rLine.pLine->GetEntryName() );
                    sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US );
                    sMessage += ::rtl::OString( "')!" );
                    DBG_ERROR( sMessage );
                }
    #endif
                if ( _rLine.xHandler.is() )
                {
                    Any aControlValue = _rLine.xHandler->convertToControlValue(
                        _rLine.pLine->GetEntryName(), _rPropertyValue, xControl->getValueType() );
                    xControl->setValue( aControlValue );
                }
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }

	//------------------------------------------------------------------
    Any OBrowserListBox::impl_getControlAsPropertyValue( const ListBoxLine& _rLine ) const
    {
        Reference< XPropertyControl > xControl( _rLine.pLine->getControl() );
        Any aPropertyValue;
        try
        {
        #ifdef DBG_UTIL
            if ( !_rLine.xHandler.is() )
            {
                ::rtl::OString sMessage( "OBrowserListBox::impl_getControlAsPropertyValue: no handler -> no conversion (property: '" );
                ::rtl::OUString sPropertyName( _rLine.pLine->GetEntryName() );
                sMessage += ::rtl::OString( sPropertyName.getStr(), sPropertyName.getLength(), RTL_TEXTENCODING_ASCII_US );
                sMessage += ::rtl::OString( "')!" );
                DBG_ERROR( sMessage );
            }
        #endif
            if ( _rLine.xHandler.is() )
                aPropertyValue = _rLine.xHandler->convertToPropertyValue( _rLine.pLine->GetEntryName(), xControl->getValue() );
            else
                aPropertyValue = xControl->getValue();
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return aPropertyValue;
    }

    //------------------------------------------------------------------
    sal_uInt16 OBrowserListBox::impl_getControlPos( const Reference< XPropertyControl >& _rxControl ) const
    {
        for (   OrderedListBoxLines::const_iterator search = m_aOrderedLines.begin();
                search != m_aOrderedLines.end();
                ++search
            )
            if ( (*search)->second.pLine->getControl().get() == _rxControl.get() )
                return sal_uInt16( search - m_aOrderedLines.begin() );
        DBG_ERROR( "OBrowserListBox::impl_getControlPos: invalid control - not part of any of our lines!" );
        return (sal_uInt16)-1;
    }

    //--------------------------------------------------------------------
    void SAL_CALL OBrowserListBox::focusGained( const Reference< XPropertyControl >& _rxControl ) throw (RuntimeException)
    {
        DBG_TESTSOLARMUTEX();

        DBG_ASSERT( _rxControl.is(), "OBrowserListBox::focusGained: invalid event source!" );
		if ( !_rxControl.is() )
			return;

        if ( m_pControlObserver )
            m_pControlObserver->focusGained( _rxControl );

        m_xActiveControl = _rxControl;
		ShowEntry( impl_getControlPos( m_xActiveControl ) );
    }

    //--------------------------------------------------------------------
    void SAL_CALL OBrowserListBox::valueChanged( const Reference< XPropertyControl >& _rxControl ) throw (RuntimeException)
    {
        DBG_TESTSOLARMUTEX();

		DBG_ASSERT( _rxControl.is(), "OBrowserListBox::valueChanged: invalid event source!" );
		if ( !_rxControl.is() )
			return;

        if ( m_pControlObserver )
            m_pControlObserver->valueChanged( _rxControl );

		if ( m_pLineListener )
		{
            const ListBoxLine& rLine = impl_getControlLine( _rxControl );
			m_pLineListener->Commit(
				rLine.pLine->GetEntryName(),
				impl_getControlAsPropertyValue( rLine )
			);
		}
    }

    //--------------------------------------------------------------------
    void SAL_CALL OBrowserListBox::activateNextControl( const Reference< XPropertyControl >& _rxCurrentControl ) throw (RuntimeException)
    {
        DBG_TESTSOLARMUTEX();

		sal_uInt16 nLine = impl_getControlPos( _rxCurrentControl );

		// cycle forwards, 'til we've the next control which can grab the focus
		++nLine;
		while ( (size_t)nLine < m_aOrderedLines.size() )
		{
			if ( m_aOrderedLines[nLine]->second.pLine->GrabFocus() )
				break;
			++nLine;
		}

		if	(	( (size_t)nLine >= m_aOrderedLines.size() )
			&&	( m_aOrderedLines.size() > 0 )
			)
			// wrap around
			m_aOrderedLines[0]->second.pLine->GrabFocus();
    }

	//------------------------------------------------------------------
    namespace
    {
	    //..............................................................
        void lcl_implDisposeControl_nothrow( const Reference< XPropertyControl >& _rxControl )
        {
            if ( !_rxControl.is() )
                return;
            try
            {
			    _rxControl->setControlContext( NULL );
                Reference< XComponent > xControlComponent( _rxControl, UNO_QUERY );
                if ( xControlComponent.is() )
                    xControlComponent->dispose();
            }
            catch( const Exception& )
            {
                DBG_UNHANDLED_EXCEPTION();
            }
        }
    }

	//------------------------------------------------------------------
	void OBrowserListBox::Clear()
	{
        for (	ListBoxLines::iterator loop = m_aLines.begin();
				loop != m_aLines.end();
				++loop
			)
		{
			// hide the line
			loop->second.pLine->Hide();
			// reset the listener
            lcl_implDisposeControl_nothrow( loop->second.pLine->getControl() );
		}

        clearContainer( m_aLines );
        clearContainer( m_aOrderedLines );
	}

	//------------------------------------------------------------------
	sal_Bool OBrowserListBox::RemoveEntry( const ::rtl::OUString& _rName )
    {
        sal_uInt16 nPos = GetPropertyPos( _rName );
        if ( nPos == LISTBOX_ENTRY_NOTFOUND )
            return sal_False;

        OrderedListBoxLines::iterator orderedPos = m_aOrderedLines.begin() + nPos;
        BrowserLinePointer pLine = (*orderedPos)->second.pLine;
        pLine->Hide();
        lcl_implDisposeControl_nothrow( pLine->getControl() );

        m_aLines.erase( *orderedPos );
        m_aOrderedLines.erase( orderedPos );
        m_aOutOfDateLines.erase( (sal_uInt16)m_aOrderedLines.size() );
            // this index *may* have been out of date, which is obsoleted now by m_aOrderedLines shrinking

        // update the positions of possibly affected lines
        while ( nPos < m_aOrderedLines.size() )
            m_aOutOfDateLines.insert( nPos++ );
        UpdatePosNSize( );

        return sal_True;
    }

	//------------------------------------------------------------------
	void OBrowserListBox::ChangeEntry( const OLineDescriptor& _rPropertyData, sal_uInt16 nPos )
	{
        OSL_PRECOND( _rPropertyData.Control.is(), "OBrowserListBox::ChangeEntry: invalid control!" );
        if ( !_rPropertyData.Control.is() )
            return;

        if ( nPos == EDITOR_LIST_REPLACE_EXISTING )
            nPos = GetPropertyPos( _rPropertyData.sName );

		if ( nPos < m_aOrderedLines.size() )
		{
			Window*	pRefWindow = NULL;
			if ( nPos > 0 )
				pRefWindow = m_aOrderedLines[nPos-1]->second.pLine->GetRefWindow();

			// the current line and control
            ListBoxLine& rLine = m_aOrderedLines[nPos]->second;

            // the old control and some data about it
            Reference< XPropertyControl > xControl = rLine.pLine->getControl();
            Window* pControlWindow = rLine.pLine->getControlWindow();
			Point aControlPos;
			if ( pControlWindow )
				aControlPos = pControlWindow->GetPosPixel();

            // clean up the old control
            lcl_implDisposeControl_nothrow( xControl );

            // set the new control at the line
			rLine.pLine->setControl( _rPropertyData.Control );
            xControl = rLine.pLine->getControl();

            if ( xControl.is() )
				xControl->setControlContext( m_pControlContextImpl.get() );

			// the initial property value
            if ( _rPropertyData.bUnknownValue )
		        xControl->setValue( Any() );
            else
                impl_setControlAsPropertyValue( rLine, _rPropertyData.aValue );

			rLine.pLine->SetTitle(_rPropertyData.DisplayName);
            rLine.xHandler = _rPropertyData.xPropertyHandler;

			sal_uInt16 nTextWidth = (sal_uInt16)m_aLinesPlayground.GetTextWidth(_rPropertyData.DisplayName);
			if (m_nTheNameSize< nTextWidth)
				m_nTheNameSize = nTextWidth;

			if ( _rPropertyData.HasPrimaryButton )
			{
                if ( _rPropertyData.PrimaryButtonImageURL.getLength() )
				    rLine.pLine->ShowBrowseButton( _rPropertyData.PrimaryButtonImageURL, true );
                else if ( _rPropertyData.PrimaryButtonImage.is() )
				    rLine.pLine->ShowBrowseButton( Image( _rPropertyData.PrimaryButtonImage ), true );
                else
                    rLine.pLine->ShowBrowseButton( true );

                if ( _rPropertyData.HasSecondaryButton )
                {
                    if ( _rPropertyData.SecondaryButtonImageURL.getLength() )
				        rLine.pLine->ShowBrowseButton( _rPropertyData.SecondaryButtonImageURL, false );
                    else if ( _rPropertyData.SecondaryButtonImage.is() )
				        rLine.pLine->ShowBrowseButton( Image( _rPropertyData.SecondaryButtonImage ), false );
                    else
                        rLine.pLine->ShowBrowseButton( false );
                }
                else
    				rLine.pLine->HideBrowseButton( false );

                rLine.pLine->SetClickListener( this );
			}
			else
            {
				rLine.pLine->HideBrowseButton( true );
    			rLine.pLine->HideBrowseButton( false );
            }

            DBG_ASSERT( ( _rPropertyData.IndentLevel == 0 ) || ( _rPropertyData.IndentLevel == 1 ),
                "OBrowserListBox::ChangeEntry: unsupported indent level!" );
			rLine.pLine->IndentTitle( _rPropertyData.IndentLevel > 0 );

			if ( nPos > 0 )
				rLine.pLine->SetTabOrder( pRefWindow, WINDOW_ZORDER_BEHIND );
			else
				rLine.pLine->SetTabOrder( pRefWindow, WINDOW_ZORDER_FIRST );

            m_aOutOfDateLines.insert( nPos );
			rLine.pLine->SetComponentHelpIds(
                HelpIdUrl::getHelpId( _rPropertyData.HelpURL ),
                rtl::OUStringToOString( _rPropertyData.PrimaryButtonId, RTL_TEXTENCODING_UTF8 ),
                rtl::OUStringToOString( _rPropertyData.SecondaryButtonId, RTL_TEXTENCODING_UTF8 )
            );

            if ( _rPropertyData.bReadOnly )
            {
                rLine.pLine->SetReadOnly( true );
            
                // user controls (i.e. the ones not provided by the usual
                // XPropertyControlFactory) have no chance to know that they should be read-only,
                // since XPropertyHandler::describePropertyLine does not transport this
                // information.
                // So, we manually switch this to read-only.
                if ( xControl.is() && ( xControl->getControlType() == PropertyControlType::Unknown ) )
                {
                    Edit* pControlWindowAsEdit = dynamic_cast< Edit* >( rLine.pLine->getControlWindow() );
                    if ( pControlWindowAsEdit )
                        pControlWindowAsEdit->SetReadOnly( sal_True );
                    else
                        pControlWindowAsEdit->Enable( sal_False );
                }
            }
		}
	}

	//------------------------------------------------------------------
	long OBrowserListBox::PreNotify( NotifyEvent& _rNEvt )
    {
        switch ( _rNEvt.GetType() )
        {
        case EVENT_KEYINPUT:
        {
            const KeyEvent* pKeyEvent = _rNEvt.GetKeyEvent();
            if  (   ( pKeyEvent->GetKeyCode().GetModifier() != 0 )
                ||  (   ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEUP )
                    &&  ( pKeyEvent->GetKeyCode().GetCode() != KEY_PAGEDOWN )
                    )
                )
                break;

            long nScrollOffset = 0;
            if ( m_aVScroll.IsVisible() )
            {
                if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEUP )
                    nScrollOffset = -m_aVScroll.GetPageSize();
                else if ( pKeyEvent->GetKeyCode().GetCode() == KEY_PAGEDOWN )
                    nScrollOffset = m_aVScroll.GetPageSize();
            }

            if ( nScrollOffset )
            {
                long nNewThumbPos = m_aVScroll.GetThumbPos() + nScrollOffset;
                nNewThumbPos = ::std::max( nNewThumbPos, m_aVScroll.GetRangeMin() );
                nNewThumbPos = ::std::min( nNewThumbPos, m_aVScroll.GetRangeMax() );
                m_aVScroll.DoScroll( nNewThumbPos );
                nNewThumbPos = m_aVScroll.GetThumbPos();

                sal_uInt16 nFocusControlPos = 0;
                sal_uInt16 nActiveControlPos = impl_getControlPos( m_xActiveControl );
                if ( nActiveControlPos < nNewThumbPos )
                    nFocusControlPos = (sal_uInt16)nNewThumbPos;
                else if ( nActiveControlPos >= nNewThumbPos + CalcVisibleLines() )
                    nFocusControlPos = (sal_uInt16)nNewThumbPos + CalcVisibleLines() - 1;
                if ( nFocusControlPos )
                {
                    if ( nFocusControlPos < m_aOrderedLines.size() )
                    {
			            m_aOrderedLines[ nFocusControlPos ]->second.pLine->GrabFocus();
                    }
                    else
                        OSL_ENSURE( false, "OBrowserListBox::PreNotify: internal error, invalid focus control position!" );
                }
            }

            return 1L; 
            // handled this. In particular, we also consume PageUp/Down events if we do not use them for scrolling,
            // otherwise they would be used to scroll the document view, which does not sound like it is desired by
            // the user.
        }
        }
        return Control::PreNotify( _rNEvt );
    }

	//------------------------------------------------------------------
	long OBrowserListBox::Notify( NotifyEvent& _rNEvt )
	{
        switch ( _rNEvt.GetType() )
        {
        case EVENT_COMMAND:
        {
            const CommandEvent* pCommand = _rNEvt.GetCommandEvent();
            if	(   ( COMMAND_WHEEL == pCommand->GetCommand() )
                ||	( COMMAND_STARTAUTOSCROLL == pCommand->GetCommand() )
                ||	( COMMAND_AUTOSCROLL == pCommand->GetCommand() )
                )
            {
                // interested in scroll events if we have a scrollbar
		        if ( m_aVScroll.IsVisible() )
		        {
					HandleScrollCommand( *pCommand, NULL, &m_aVScroll );
                }
		    }
		}
        break;
        }

		return Control::Notify( _rNEvt );
	}

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


