/**************************************************************
 *
 * 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_toolkit.hxx"

#include <toolkit/controls/controlmodelcontainerbase.hxx>
#include <vcl/svapp.hxx>
#include <vcl/window.hxx>
#include <vcl/wall.hxx>
#include <vos/mutex.hxx>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/unopropertyarrayhelper.hxx>
#include <toolkit/controls/geometrycontrolmodel.hxx>
#include <toolkit/controls/unocontrols.hxx>
#include "toolkit/controls/formattedcontrol.hxx"
#include "toolkit/controls/roadmapcontrol.hxx"
#include "toolkit/controls/tkscrollbar.hxx"
#include "toolkit/controls/tabpagemodel.hxx"
#include <toolkit/controls/stdtabcontroller.hxx>
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/resource/XStringResourceResolver.hpp>
#include <com/sun/star/graphic/XGraphicProvider.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <tools/list.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <comphelper/processfactory.hxx>
#include <vcl/svapp.hxx>
#include <vcl/outdev.hxx>
#include <comphelper/types.hxx>

#include <comphelper/componentcontext.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <toolkit/helper/tkresmgr.hxx>
#include <unotools/ucbstreamhelper.hxx>
#include <vcl/graph.hxx>
#include <vcl/image.hxx>

#include "tree/treecontrol.hxx"
#include "grid/gridcontrol.hxx"
#include <toolkit/controls/tabpagecontainer.hxx>

#include <map>
#include <algorithm>
#include <functional>
#include "tools/urlobj.hxx"
#include "osl/file.hxx"

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::util;
using namespace toolkit;

#define PROPERTY_RESOURCERESOLVER ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceResolver" ))

//HELPER
::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl );

struct LanguageDependentProp
{
    const char* pPropName;
    sal_Int32   nPropNameLength;
};

// ----------------------------------------------------------------------------
namespace
{
    static const Sequence< ::rtl::OUString >& lcl_getLanguageDependentProperties()
    {
        static Sequence< ::rtl::OUString > s_aLanguageDependentProperties;
        if ( s_aLanguageDependentProperties.getLength() == 0 )
        {
            ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
            if ( s_aLanguageDependentProperties.getLength() == 0 )
            {
                s_aLanguageDependentProperties.realloc( 2 );
                s_aLanguageDependentProperties[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "HelpText" ) );
                s_aLanguageDependentProperties[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
                // note: properties must be sorted
            }
        }
        return s_aLanguageDependentProperties;
	}
}

// ----------------------------------------------------------------------------
// functor for disposing a control model
struct DisposeControlModel : public ::std::unary_function< Reference< XControlModel >, void >
{
	void operator()( Reference< XControlModel >& _rxModel )
	{
		try
		{
			::comphelper::disposeComponent( _rxModel );
		}
		catch( const Exception& )
		{
			DBG_ERROR( "DisposeControlModel::(): caught an exception while disposing a component!" );
		}
	}
};

// ----------------------------------------------------------------------------
// functor for searching control model by name
struct FindControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool >
{
private:
	const ::rtl::OUString& m_rName;

public:
	FindControlModel( const ::rtl::OUString& _rName ) : m_rName( _rName ) { }

	bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare )
	{
		return ( _rCompare.second == m_rName ) ? true : false;
	}
};

// ----------------------------------------------------------------------------
// functor for cloning a control model, and insertion into a target list
struct CloneControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, void >
{
private:
	ControlModelContainerBase::UnoControlModelHolderList&	m_rTargetList;

public:
	CloneControlModel( ControlModelContainerBase::UnoControlModelHolderList& _rTargetList )
		:m_rTargetList( _rTargetList )
	{
	}

	void operator()( const ControlModelContainerBase::UnoControlModelHolder& _rSource )
	{
		// clone the source object
		Reference< XCloneable > xCloneSource( _rSource.first, UNO_QUERY );
		Reference< XControlModel > xClone( xCloneSource->createClone(), UNO_QUERY );
		// add to target list
		m_rTargetList.push_back( ControlModelContainerBase::UnoControlModelHolder( xClone, _rSource.second ) );
	}
};

// ----------------------------------------------------------------------------
// functor for comparing a XControlModel with a given reference
struct CompareControlModel : public ::std::unary_function< ControlModelContainerBase::UnoControlModelHolder, bool >
{
private:
	Reference< XControlModel > m_xReference;
public:
	CompareControlModel( const Reference< XControlModel >& _rxReference ) : m_xReference( _rxReference ) { }

	bool operator()( const ControlModelContainerBase::UnoControlModelHolder& _rCompare )
	{
		return ( _rCompare.first.get() == m_xReference.get() ) ? true : false;
	}
};

// ----------------------------------------------------------------------------
static void lcl_throwIllegalArgumentException( )
{	// throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
	throw IllegalArgumentException();
}

// ----------------------------------------------------------------------------
static void lcl_throwNoSuchElementException( )
{	// throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
	throw NoSuchElementException();
}

// ----------------------------------------------------------------------------
static void lcl_throwElementExistException( )
{	// throwing is expensive (in terms of code size), thus we hope the compiler does not inline this ....
	throw ElementExistException();
}

// ----------------------------------------------------------------------------
static const ::rtl::OUString& getTabIndexPropertyName( )
{
	static const ::rtl::OUString s_sTabIndexProperty( RTL_CONSTASCII_USTRINGPARAM( "TabIndex" ) );
	return s_sTabIndexProperty;
}

// ----------------------------------------------------------------------------
static const ::rtl::OUString& getStepPropertyName( )
{
	static const ::rtl::OUString s_sStepProperty( RTL_CONSTASCII_USTRINGPARAM( "Step" ) );
	return s_sStepProperty;
}

//	----------------------------------------------------
//	class ControlModelContainerBase
//	----------------------------------------------------
ControlModelContainerBase::ControlModelContainerBase( const Reference< XMultiServiceFactory >& i_factory )
    :ControlModelContainer_IBase( i_factory )
	,maContainerListeners( *this )
	,maChangeListeners ( GetMutex() )
	,mbGroupsUpToDate( sal_False )
    ,m_bEnabled( sal_True )
{
}

ControlModelContainerBase::ControlModelContainerBase( const ControlModelContainerBase& rModel )
	: ControlModelContainer_IBase( rModel )
	, maContainerListeners( *this )
	, maChangeListeners ( GetMutex() )
	, mbGroupsUpToDate( sal_False )
{
}

ControlModelContainerBase::~ControlModelContainerBase()
{
	maModels.clear();
	mbGroupsUpToDate = sal_False;
}

Any ControlModelContainerBase::ImplGetDefaultValue( sal_uInt16 nPropId ) const
{
    Any aAny;

    switch ( nPropId )
    {
        case BASEPROPERTY_DEFAULTCONTROL:
		    aAny <<= ::rtl::OUString::createFromAscii( szServiceName_UnoControlDialog );
            break;
        default:
            aAny = UnoControlModel::ImplGetDefaultValue( nPropId );
    }

    return aAny;
}

::cppu::IPropertyArrayHelper& ControlModelContainerBase::getInfoHelper()
{
	static UnoPropertyArrayHelper* pHelper = NULL;
	if ( !pHelper )
	{
		Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
		pHelper = new UnoPropertyArrayHelper( aIDs );
	}
	return *pHelper;
}

void SAL_CALL ControlModelContainerBase::dispose(  ) throw(RuntimeException)
{
    // ====================================================================
	// tell our listeners
	{
		::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

		EventObject aDisposeEvent;
		aDisposeEvent.Source = static_cast< XAggregation* >( static_cast< ::cppu::OWeakAggObject* >( this ) );

		maContainerListeners.disposeAndClear( aDisposeEvent );
		maChangeListeners.disposeAndClear( aDisposeEvent );
	}

    // ====================================================================
	// call the base class
	UnoControlModel::dispose();

    // ====================================================================
	// dispose our child models
	// for this, collect the models (we collect them from maModels, and this is modified when disposing children)
	::std::vector< Reference< XControlModel > > aChildModels( maModels.size() );

	::std::transform(
		maModels.begin(), maModels.end(),				// source range
		aChildModels.begin(),							// target location
		::std::select1st< UnoControlModelHolder >( )	// operation to apply -> select the XControlModel part
	);

	// now dispose
	::std::for_each( aChildModels.begin(), aChildModels.end(), DisposeControlModel() );
	aChildModels.clear();

	mbGroupsUpToDate = sal_False;
}

// XMultiPropertySet
Reference< XPropertySetInfo > ControlModelContainerBase::getPropertySetInfo(  ) throw(RuntimeException)
{
	static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
	return xInfo;
}
void ControlModelContainerBase::Clone_Impl(ControlModelContainerBase& _rClone) const
{
    // clone all children
	::std::for_each(
		maModels.begin(), maModels.end(),
		CloneControlModel( _rClone.maModels )
	);
}
UnoControlModel* ControlModelContainerBase::Clone() const
{
	// clone the container itself
	ControlModelContainerBase* pClone = new ControlModelContainerBase( *this );
    Clone_Impl(*pClone);

	return pClone;
}

ControlModelContainerBase::UnoControlModelHolderList::iterator ControlModelContainerBase::ImplFindElement( const ::rtl::OUString& rName )
{
	return ::std::find_if( maModels.begin(), maModels.end(), FindControlModel( rName ) );
}

// ::XMultiServiceFactory
Reference< XInterface > ControlModelContainerBase::createInstance( const ::rtl::OUString& aServiceSpecifier ) throw(Exception, RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	OGeometryControlModel_Base* pNewModel = NULL;

    const Reference< XMultiServiceFactory > xFactory( maContext.getLegacyServiceFactory() );
	if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlEditModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlEditModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFormattedFieldModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlFormattedFieldModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFileControlModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlFileControlModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlButtonModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlButtonModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlImageControlModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlImageControlModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRadioButtonModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlRadioButtonModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCheckBoxModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlCheckBoxModel >( xFactory );
    else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedHyperlinkModel ) == 0 )
        pNewModel = new OGeometryControlModel< UnoControlFixedHyperlinkModel >( xFactory );
    else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlFixedTextModel ) == 0 )
        pNewModel = new OGeometryControlModel< UnoControlFixedTextModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlGroupBoxModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlGroupBoxModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlListBoxModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlListBoxModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlComboBoxModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlComboBoxModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlDateFieldModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlDateFieldModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlTimeFieldModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlTimeFieldModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlNumericFieldModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlNumericFieldModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlCurrencyFieldModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlCurrencyFieldModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlPatternFieldModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlPatternFieldModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlProgressBarModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlProgressBarModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlScrollBarModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlScrollBarModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlFixedLineModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlFixedLineModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName2_UnoControlRoadmapModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlRoadmapModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName_TreeControlModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoTreeModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName_GridControlModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoGridModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageContainerModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlTabPageContainerModel >( xFactory );
	else if ( aServiceSpecifier.compareToAscii( szServiceName_UnoControlTabPageModel ) == 0 )
		pNewModel = new OGeometryControlModel< UnoControlTabPageModel >( xFactory );

	if ( !pNewModel )
	{
		if ( xFactory.is() )
		{
			Reference< XInterface > xObject = xFactory->createInstance( aServiceSpecifier );
			Reference< XServiceInfo > xSI( xObject, UNO_QUERY );
			Reference< XCloneable > xCloneAccess( xSI, UNO_QUERY );
			Reference< XAggregation > xAgg( xCloneAccess, UNO_QUERY );
			if ( xAgg.is() )
			{
				if ( xSI->supportsService( ::rtl::OUString::createFromAscii( "com.sun.star.awt.UnoControlModel" ) ) )
				{
					// release 3 of the 4 references we have to the object
					xAgg.clear();
					xSI.clear();
					xObject.clear();

					pNewModel = new OCommonGeometryControlModel( xCloneAccess, aServiceSpecifier );
				}
			}
		}
	}

	Reference< XInterface > xNewModel = (::cppu::OWeakObject*)pNewModel;
	return xNewModel;
}

Reference< XInterface > ControlModelContainerBase::createInstanceWithArguments( const ::rtl::OUString& ServiceSpecifier, const Sequence< Any >& i_arguments ) throw(Exception, RuntimeException)
{
    const Reference< XInterface > xInstance( createInstance( ServiceSpecifier ) );
    const Reference< XInitialization > xInstanceInit( xInstance, UNO_QUERY );
    ENSURE_OR_RETURN( xInstanceInit.is(), "ControlModelContainerBase::createInstanceWithArguments: can't pass the arguments!", xInstance );
    xInstanceInit->initialize( i_arguments );
	return xInstance;
}

Sequence< ::rtl::OUString > ControlModelContainerBase::getAvailableServiceNames() throw(RuntimeException)
{
	static Sequence< ::rtl::OUString >* pNamesSeq = NULL;
	if ( !pNamesSeq )
	{
		pNamesSeq = new Sequence< ::rtl::OUString >( 24 );
		::rtl::OUString* pNames = pNamesSeq->getArray();
		pNames[0] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlEditModel );
		pNames[1] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFormattedFieldModel );
		pNames[2] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFileControlModel );
		pNames[3] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlButtonModel );
		pNames[4] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlImageControlModel );
		pNames[5] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel );
		pNames[6] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCheckBoxModel );
		pNames[7] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedTextModel );
		pNames[8] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlGroupBoxModel );
		pNames[9] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlListBoxModel );
		pNames[10] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlComboBoxModel );
		pNames[11] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlDateFieldModel );
		pNames[12] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlTimeFieldModel );
		pNames[13] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlNumericFieldModel );
		pNames[14] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlCurrencyFieldModel );
		pNames[15] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlPatternFieldModel );
		pNames[16] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlProgressBarModel );
		pNames[17] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlScrollBarModel );
		pNames[18] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlFixedLineModel );
		pNames[19] = ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRoadmapModel );
		pNames[20] = ::rtl::OUString::createFromAscii( szServiceName_TreeControlModel );
		pNames[21] = ::rtl::OUString::createFromAscii( szServiceName_GridControlModel );
		pNames[22] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageContainerModel );
		pNames[23] = ::rtl::OUString::createFromAscii( szServiceName_UnoControlTabPageModel );
	}
	return *pNamesSeq;
}

// XContainer
void ControlModelContainerBase::addContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
{
	maContainerListeners.addInterface( l );
}

void ControlModelContainerBase::removeContainerListener( const Reference< XContainerListener >& l ) throw(RuntimeException)
{
	maContainerListeners.removeInterface( l );
}

// XElementAcces
Type ControlModelContainerBase::getElementType() throw(RuntimeException)
{
	Type aType = getCppuType( ( Reference< XControlModel>* ) NULL );
	return aType;
}

sal_Bool ControlModelContainerBase::hasElements() throw(RuntimeException)
{
	return !maModels.empty();
}

// XNameContainer, XNameReplace, XNameAccess
void ControlModelContainerBase::replaceByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	Reference< XControlModel > xNewModel;
	aElement >>= xNewModel;
	if ( !xNewModel.is() )
		lcl_throwIllegalArgumentException();

	UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
	if ( maModels.end() == aElementPos )
		lcl_throwNoSuchElementException();

	// stop listening at the old model
	stopControlListening( aElementPos->first );
	Reference< XControlModel > xReplaced( aElementPos->first );
	// remember the new model, and start listening
	aElementPos->first = xNewModel;
	startControlListening( xNewModel );

	ContainerEvent aEvent;
	aEvent.Source = *this;
	aEvent.Element = aElement;
	aEvent.ReplacedElement <<= xReplaced;
	aEvent.Accessor <<= aName;

	// notify the container listener
	maContainerListeners.elementReplaced( aEvent );

	// our "tab controller model" has potentially changed -> notify this
	implNotifyTabModelChange( aName );
}

Any ControlModelContainerBase::getByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
	if ( maModels.end() == aElementPos )
		lcl_throwNoSuchElementException();

	return makeAny( aElementPos->first );
}

Sequence< ::rtl::OUString > ControlModelContainerBase::getElementNames() throw(RuntimeException)
{
	Sequence< ::rtl::OUString > aNames( maModels.size() );

	::std::transform(
		maModels.begin(), maModels.end(),				// source range
		aNames.getArray(),								// target range
		::std::select2nd< UnoControlModelHolder >()		// operator to apply: select the second element (the name)
	);

	return aNames;
}

sal_Bool ControlModelContainerBase::hasByName( const ::rtl::OUString& aName ) throw(RuntimeException)
{
	return maModels.end() != ImplFindElement( aName );
}

void ControlModelContainerBase::insertByName( const ::rtl::OUString& aName, const Any& aElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	Reference< XControlModel > xM;
	aElement >>= xM;

	if ( xM.is() )
	{
		Reference< beans::XPropertySet > xProps( xM, UNO_QUERY );
			if ( xProps.is() )
			{

				Reference< beans::XPropertySetInfo > xPropInfo = xProps.get()->getPropertySetInfo();

				::rtl::OUString sImageSourceProperty = GetPropertyName( BASEPROPERTY_IMAGEURL );
				if ( xPropInfo.get()->hasPropertyByName(  sImageSourceProperty ) && ImplHasProperty(BASEPROPERTY_DIALOGSOURCEURL) )
				{
					Any aUrl = xProps.get()->getPropertyValue(  sImageSourceProperty );

					::rtl::OUString absoluteUrl =
						getPhysicalLocation( getPropertyValue( GetPropertyName( BASEPROPERTY_DIALOGSOURCEURL ) ), aUrl );

					aUrl <<= absoluteUrl;

					xProps.get()->setPropertyValue(  sImageSourceProperty , aUrl );
				}
			}
	}



    if ( !aName.getLength() || !xM.is() )
		lcl_throwIllegalArgumentException();

	UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
	if ( maModels.end() != aElementPos )
        lcl_throwElementExistException();

	maModels.push_back( UnoControlModelHolder( xM, aName ) );
	mbGroupsUpToDate = sal_False;
	startControlListening( xM );

	ContainerEvent aEvent;
	aEvent.Source = *this;
	aEvent.Element <<= aElement;
	aEvent.Accessor <<= aName;
	maContainerListeners.elementInserted( aEvent );

	// our "tab controller model" has potentially changed -> notify this
	implNotifyTabModelChange( aName );
}

void ControlModelContainerBase::removeByName( const ::rtl::OUString& aName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	UnoControlModelHolderList::iterator aElementPos = ImplFindElement( aName );
	if ( maModels.end() == aElementPos )
        lcl_throwNoSuchElementException();

    ContainerEvent aEvent;
	aEvent.Source = *this;
	aEvent.Element <<= aElementPos->first;
	aEvent.Accessor <<= aName;
	maContainerListeners.elementRemoved( aEvent );

	stopControlListening( aElementPos->first );
    Reference< XPropertySet > xPS( aElementPos->first, UNO_QUERY );
	maModels.erase( aElementPos );
	mbGroupsUpToDate = sal_False;

    if ( xPS.is() )
        try
        {
            xPS->setPropertyValue( PROPERTY_RESOURCERESOLVER, makeAny( Reference< resource::XStringResourceResolver >() ) );
        }
        catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }

	// our "tab controller model" has potentially changed -> notify this
	implNotifyTabModelChange( aName );
}

// ----------------------------------------------------------------------------
sal_Bool SAL_CALL ControlModelContainerBase::getGroupControl(  ) throw (RuntimeException)
{
	return sal_True;
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::setGroupControl( sal_Bool ) throw (RuntimeException)
{
	DBG_ERROR( "UnoControlDialogModel::setGroupControl: explicit grouping not supported" );
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::setControlModels( const Sequence< Reference< XControlModel > >& _rControls ) throw (RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	// set the tab indexes according to the order of models in the sequence
	const Reference< XControlModel >* pControls = _rControls.getConstArray( );
	const Reference< XControlModel >* pControlsEnd = _rControls.getConstArray( ) + _rControls.getLength();

	sal_Int16 nTabIndex = 1;

	for ( ; pControls != pControlsEnd; ++pControls )
	{
		// look up the control in our own structure. This is to prevent invalid arguments
		UnoControlModelHolderList::const_iterator aPos =
			::std::find_if(
				maModels.begin(), maModels.end(),
				CompareControlModel( *pControls )
			);
		if ( maModels.end() != aPos )
		{
			// okay, this is an existent model
			// now set the TabIndex property (if applicable)
			Reference< XPropertySet > xProps( aPos->first, UNO_QUERY );
			Reference< XPropertySetInfo > xPSI;
			if ( xProps.is() )
				xPSI = xProps->getPropertySetInfo();
			if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
				xProps->setPropertyValue( getTabIndexPropertyName(), makeAny( nTabIndex++ ) );
		}
		mbGroupsUpToDate = sal_False;
	}
}


typedef ::std::multimap< sal_Int32, Reference< XControlModel >, ::std::less< sal_Int32 > > MapIndexToModel;

// ----------------------------------------------------------------------------
Sequence< Reference< XControlModel > > SAL_CALL ControlModelContainerBase::getControlModels(  ) throw (RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	MapIndexToModel aSortedModels;
		// will be the sorted container of all models which have a tab index property
	::std::vector< Reference< XControlModel > > aUnindexedModels;
		// will be the container of all models which do not have a tab index property

	UnoControlModelHolderList::const_iterator aLoop = maModels.begin();
	for ( ; aLoop != maModels.end(); ++aLoop )
	{
		Reference< XControlModel > xModel( aLoop->first );

		// see if the model has a TabIndex property
		Reference< XPropertySet > xControlProps( xModel, UNO_QUERY );
		Reference< XPropertySetInfo > xPSI;
		if ( xControlProps.is() )
			xPSI = xControlProps->getPropertySetInfo( );
		DBG_ASSERT( xPSI.is(), "UnoControlDialogModel::getControlModels: invalid child model!" );

		// has it?
		if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
		{	// yes
			sal_Int32 nTabIndex = -1;
			xControlProps->getPropertyValue( getTabIndexPropertyName() ) >>= nTabIndex;

			aSortedModels.insert( MapIndexToModel::value_type( nTabIndex, xModel ) );
		}
		else if ( xModel.is() )
			// no, it hasn't, but we have to include it, anyway
			aUnindexedModels.push_back( xModel );
	}

	// okay, here we have a container of all our models, sorted by tab index,
	// plus a container of "unindexed" models
	// -> merge them
	Sequence< Reference< XControlModel > > aReturn( aUnindexedModels.size() + aSortedModels.size() );
	::std::transform(
			aSortedModels.begin(), aSortedModels.end(),
			::std::copy( aUnindexedModels.begin(), aUnindexedModels.end(), aReturn.getArray() ),
			::std::select2nd< MapIndexToModel::value_type >( )
		);

	return aReturn;
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::setGroup( const Sequence< Reference< XControlModel > >&, const ::rtl::OUString& ) throw (RuntimeException)
{
	// not supported. We have only implicit grouping:
	// We only have a sequence of control models, and we _know_ (yes, that's a HACK relying on
	// implementation details) that VCL does grouping according to the order of controls automatically
	// At least VCL does this for all we're interested in: Radio buttons.
	DBG_ERROR( "UnoControlDialogModel::setGroup: grouping not supported" );
}

////----- XInitialization -------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::initialize (const Sequence<Any>& rArguments) throw (com::sun::star::uno::Exception, com::sun::star::uno::RuntimeException)
{
	sal_Int16 nPageId = -1;
	if ( rArguments.getLength() == 1 )
    {
         if ( !( rArguments[ 0 ] >>= nPageId ))
             throw lang::IllegalArgumentException();
        m_nTabPageId = nPageId;
    }
	else
		m_nTabPageId = -1;
}
::sal_Int16 SAL_CALL ControlModelContainerBase::getTabPageID() throw (::com::sun::star::uno::RuntimeException)
{
	return m_nTabPageId;
}
::sal_Bool SAL_CALL ControlModelContainerBase::getEnabled() throw (::com::sun::star::uno::RuntimeException)
{
	return m_bEnabled;
}
void SAL_CALL ControlModelContainerBase::setEnabled( ::sal_Bool _enabled ) throw (::com::sun::star::uno::RuntimeException)
{
	m_bEnabled = _enabled;
}
::rtl::OUString SAL_CALL ControlModelContainerBase::getTitle() throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
	Reference<XPropertySet> xThis(*this,UNO_QUERY);
    ::rtl::OUString sTitle;
    xThis->getPropertyValue(GetPropertyName(BASEPROPERTY_TITLE)) >>= sTitle;
    return sTitle;
}
void SAL_CALL ControlModelContainerBase::setTitle( const ::rtl::OUString& _title ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    Reference<XPropertySet> xThis(*this,UNO_QUERY);
    xThis->setPropertyValue(GetPropertyName(BASEPROPERTY_TITLE),makeAny(_title));
}
::rtl::OUString SAL_CALL ControlModelContainerBase::getImageURL() throw (::com::sun::star::uno::RuntimeException)
{
	return m_sImageURL;
}
void SAL_CALL ControlModelContainerBase::setImageURL( const ::rtl::OUString& _imageurl ) throw (::com::sun::star::uno::RuntimeException)
{
	m_sImageURL = _imageurl;
}
::rtl::OUString SAL_CALL ControlModelContainerBase::getToolTip() throw (::com::sun::star::uno::RuntimeException)
{
	return m_sTooltip;
}
void SAL_CALL ControlModelContainerBase::setToolTip( const ::rtl::OUString& _tooltip ) throw (::com::sun::star::uno::RuntimeException)
{
	m_sTooltip = _tooltip;
}

// ----------------------------------------------------------------------------
namespace
{
	enum GroupingMachineState
	{
		eLookingForGroup,
		eExpandingGroup
	};

	// ........................................................................
	static sal_Int32 lcl_getDialogStep( const Reference< XControlModel >& _rxModel )
	{
		sal_Int32 nStep = 0;
		try
		{
			Reference< XPropertySet > xModelProps( _rxModel, UNO_QUERY );
			xModelProps->getPropertyValue( getStepPropertyName() ) >>= nStep;
		}
		catch( const Exception& )
		{
			DBG_ERROR( "lcl_getDialogStep: caught an exception while determining the dialog page!" );
		}
		return nStep;
	}
}

// ----------------------------------------------------------------------------
sal_Int32 SAL_CALL ControlModelContainerBase::getGroupCount(  ) throw (RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	implUpdateGroupStructure();

	return maGroups.size();
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::getGroup( sal_Int32 _nGroup, Sequence< Reference< XControlModel > >& _rGroup, ::rtl::OUString& _rName ) throw (RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	implUpdateGroupStructure();

	if ( ( _nGroup < 0 ) || ( _nGroup >= (sal_Int32)maGroups.size() ) )
	{
		DBG_ERROR( "UnoControlDialogModel::getGroup: invalid argument and I am not allowed to throw an exception!" );
		_rGroup.realloc( 0 );
		_rName = ::rtl::OUString();
	}
	else
	{
		AllGroups::const_iterator aGroupPos = maGroups.begin() + _nGroup;
		_rGroup.realloc( aGroupPos->size() );
		// copy the models
		::std::copy( aGroupPos->begin(), aGroupPos->end(), _rGroup.getArray() );
		// give the group a name
		_rName = ::rtl::OUString::valueOf( _nGroup );
	}
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::getGroupByName( const ::rtl::OUString& _rName, Sequence< Reference< XControlModel > >& _rGroup ) throw (RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	::rtl::OUString sDummyName;
	getGroup( _rName.toInt32( ), _rGroup, sDummyName );
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::addChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
{
	maChangeListeners.addInterface( _rxListener );
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::removeChangesListener( const Reference< XChangesListener >& _rxListener ) throw (RuntimeException)
{
	maChangeListeners.removeInterface( _rxListener );
}

// ----------------------------------------------------------------------------
void ControlModelContainerBase::implNotifyTabModelChange( const ::rtl::OUString& _rAccessor )
{
	// multiplex to our change listeners:
	// the changes event
	ChangesEvent aEvent;
	aEvent.Source = *this;
	aEvent.Base <<= aEvent.Source;	// the "base of the changes root" is also ourself
	aEvent.Changes.realloc( 1 );	// exactly one change
	aEvent.Changes[ 0 ].Accessor <<= _rAccessor;


	Sequence< Reference< XInterface > > aChangeListeners( maChangeListeners.getElements() );
	const Reference< XInterface >* pListener = aChangeListeners.getConstArray();
	const Reference< XInterface >* pListenerEnd = aChangeListeners.getConstArray() + aChangeListeners.getLength();
	for ( ; pListener != pListenerEnd; ++pListener )
	{
		if ( pListener->is() )
			static_cast< XChangesListener* >( pListener->get() )->changesOccurred( aEvent );
	}
}


// ----------------------------------------------------------------------------
void ControlModelContainerBase::implUpdateGroupStructure()
{
	if ( mbGroupsUpToDate )
		// nothing to do
		return;

	// conditions for a group:
	// * all elements of the group are radio buttons
	// * all elements of the group are on the same dialog page
	// * in the overall control order (determined by the tab index), all elements are subsequent

	maGroups.clear();

	Sequence< Reference< XControlModel > > aControlModels = getControlModels();
	const Reference< XControlModel >* pControlModels = aControlModels.getConstArray();
	const Reference< XControlModel >* pControlModelsEnd = pControlModels + aControlModels.getLength();

	// in extreme we have as much groups as controls
	maGroups.reserve( aControlModels.getLength() );

	GroupingMachineState eState = eLookingForGroup;		// the current state of our machine
	Reference< XServiceInfo > xModelSI;					// for checking for a radion button
	AllGroups::iterator aCurrentGroup = maGroups.end();	// the group which we're currently building
	sal_Int32	nCurrentGroupStep = -1;					// the step which all controls of the current group belong to
	sal_Bool	bIsRadioButton;							// is it a radio button?

#if OSL_DEBUG_LEVEL > 1
	::std::vector< ::rtl::OUString > aCurrentGroupLabels;
#endif

	for ( ; pControlModels != pControlModelsEnd; ++pControlModels )
	{
		// we'll need this in every state
		xModelSI = xModelSI.query( *pControlModels );
		bIsRadioButton = xModelSI.is() && xModelSI->supportsService( ::rtl::OUString::createFromAscii( szServiceName2_UnoControlRadioButtonModel ) );

		switch ( eState )
		{
			case eLookingForGroup:
			{
				if ( !bIsRadioButton )
					// this is no radio button -> still looking for the beginning of a group
					continue;
				// the current model is a radio button
				// -> we found the beginning of a new group
				// create the place for this group
				size_t nGroups = maGroups.size();
				maGroups.resize( nGroups + 1 );
				aCurrentGroup = maGroups.begin() + nGroups;
				// and add the (only, til now) member
				aCurrentGroup->push_back( *pControlModels );

				// get the step which all controls of this group now have to belong to
				nCurrentGroupStep = lcl_getDialogStep( *pControlModels );
				// new state: looking for further members
				eState = eExpandingGroup;

#if OSL_DEBUG_LEVEL > 1
				Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
				::rtl::OUString sLabel;
				if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
					xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
				aCurrentGroupLabels.push_back( sLabel );
#endif
			}
			break;

			case eExpandingGroup:
			{
				if ( !bIsRadioButton )
				{	// no radio button -> the group is done
					aCurrentGroup = maGroups.end();
					eState = eLookingForGroup;
#if OSL_DEBUG_LEVEL > 1
					aCurrentGroupLabels.clear();
#endif
					continue;
				}

				// it is a radio button - is it on the proper page?
				const sal_Int32 nThisModelStep = lcl_getDialogStep( *pControlModels );
				if	(	( nThisModelStep == nCurrentGroupStep )	// the current button is on the same dialog page
					||	( 0 == nThisModelStep )					// the current button appears on all pages
					)
				{
					// -> it belongs to the same group
					aCurrentGroup->push_back( *pControlModels );
					// state still is eExpandingGroup - we're looking for further elements
					eState = eExpandingGroup;

#if OSL_DEBUG_LEVEL > 1
					Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
					::rtl::OUString sLabel;
					if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
						xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
					aCurrentGroupLabels.push_back( sLabel );
#endif
					continue;
				}

				// it's a radio button, but on a different page
				// -> we open a new group for it

				// close the old group
				aCurrentGroup = maGroups.end();
#if OSL_DEBUG_LEVEL > 1
				aCurrentGroupLabels.clear();
#endif

				// open a new group
				size_t nGroups = maGroups.size();
				maGroups.resize( nGroups + 1 );
				aCurrentGroup = maGroups.begin() + nGroups;
				// and add the (only, til now) member
				aCurrentGroup->push_back( *pControlModels );

				nCurrentGroupStep = nThisModelStep;

				// state is the same: we still are looking for further elements of the current group
				eState = eExpandingGroup;
#if OSL_DEBUG_LEVEL > 1
				Reference< XPropertySet > xModelProps( *pControlModels, UNO_QUERY );
				::rtl::OUString sLabel;
				if ( xModelProps.is() && xModelProps->getPropertySetInfo().is() && xModelProps->getPropertySetInfo()->hasPropertyByName( ::rtl::OUString::createFromAscii( "Label" ) ) )
					xModelProps->getPropertyValue( ::rtl::OUString::createFromAscii( "Label" ) ) >>= sLabel;
				aCurrentGroupLabels.push_back( sLabel );
#endif
			}
			break;
		}
	}

	mbGroupsUpToDate = sal_True;
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::propertyChange( const PropertyChangeEvent& _rEvent ) throw (RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	DBG_ASSERT( 0 == _rEvent.PropertyName.compareToAscii( "TabIndex" ),
		"UnoControlDialogModel::propertyChange: not listening for this property!" );

	// the accessor for the changed element
	::rtl::OUString sAccessor;
	UnoControlModelHolderList::const_iterator aPos =
		::std::find_if(
			maModels.begin(), maModels.end(),
			CompareControlModel( Reference< XControlModel >( _rEvent.Source, UNO_QUERY ) )
		);
	OSL_ENSURE( maModels.end() != aPos, "UnoControlDialogModel::propertyChange: don't know this model!" );
	if ( maModels.end() != aPos )
		sAccessor = aPos->second;

	// our groups are not up-to-date
	mbGroupsUpToDate = sal_False;

	// notify
	implNotifyTabModelChange( sAccessor );
}

// ----------------------------------------------------------------------------
void SAL_CALL ControlModelContainerBase::disposing( const EventObject& /*rEvent*/ ) throw (RuntimeException)
{
}

// ----------------------------------------------------------------------------
void ControlModelContainerBase::startControlListening( const Reference< XControlModel >& _rxChildModel )
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
	Reference< XPropertySetInfo > xPSI;
	if ( xModelProps.is() )
		xPSI = xModelProps->getPropertySetInfo();

	if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
		xModelProps->addPropertyChangeListener( getTabIndexPropertyName(), this );
}

// ----------------------------------------------------------------------------
void ControlModelContainerBase::stopControlListening( const Reference< XControlModel >& _rxChildModel )
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	Reference< XPropertySet > xModelProps( _rxChildModel, UNO_QUERY );
	Reference< XPropertySetInfo > xPSI;
	if ( xModelProps.is() )
		xPSI = xModelProps->getPropertySetInfo();

	if ( xPSI.is() && xPSI->hasPropertyByName( getTabIndexPropertyName() ) )
		xModelProps->removePropertyChangeListener( getTabIndexPropertyName(), this );
}

// ============================================================================
// = class ResourceListener
// ============================================================================

ResourceListener::ResourceListener(
    const Reference< util::XModifyListener >& rListener ) :
    OWeakObject(),
    m_xListener( rListener ),
    m_bListening( false )
{
}

ResourceListener::~ResourceListener()
{
}

// XInterface
Any SAL_CALL ResourceListener::queryInterface( const Type& rType )
throw ( RuntimeException )
{
	Any a = ::cppu::queryInterface(
				rType ,
                static_cast< XModifyListener* >( this ),
				static_cast< XEventListener* >( this ));

	if ( a.hasValue() )
		return a;

	return OWeakObject::queryInterface( rType );
}

void SAL_CALL ResourceListener::acquire() throw ()
{
    OWeakObject::acquire();
}

void SAL_CALL ResourceListener::release() throw ()
{
    OWeakObject::release();
}

void ResourceListener::startListening(
    const Reference< resource::XStringResourceResolver  >& rResource )
{
    Reference< util::XModifyBroadcaster > xModifyBroadcaster( rResource, UNO_QUERY );

    {
        // --- SAFE ---
		::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
		bool bListening( m_bListening );
		bool bResourceSet( m_xResource.is() );
		aGuard.clear();
		// --- SAFE ---

        if ( bListening && bResourceSet )
            stopListening();

        // --- SAFE ---
        aGuard.reset();
        m_xResource = rResource;
        aGuard.clear();
        // --- SAFE ---
    }

    Reference< util::XModifyListener > xThis( static_cast<OWeakObject*>( this ), UNO_QUERY );
    if ( xModifyBroadcaster.is() )
    {
        try
        {
            xModifyBroadcaster->addModifyListener( xThis );

            // --- SAFE ---
            ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
            m_bListening = true;
            // --- SAFE ---
        }
        catch ( RuntimeException& )
        {
            throw;
        }
        catch ( Exception& )
        {
        }
    }
}

void ResourceListener::stopListening()
{
    Reference< util::XModifyBroadcaster > xModifyBroadcaster;

    // --- SAFE ---
    ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
    if ( m_bListening && m_xResource.is() )
        xModifyBroadcaster = Reference< util::XModifyBroadcaster >( m_xResource, UNO_QUERY );
    aGuard.clear();
    // --- SAFE ---

    Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
    if ( xModifyBroadcaster.is() )
    {
        try
        {
            // --- SAFE ---
            aGuard.reset();
            m_bListening = false;
            m_xResource.clear();
            aGuard.clear();
            // --- SAFE ---

            xModifyBroadcaster->removeModifyListener( xThis );
        }
        catch ( RuntimeException& )
        {
            throw;
        }
        catch ( Exception& )
        {
        }
    }
}

// XModifyListener
void SAL_CALL ResourceListener::modified(
    const lang::EventObject& aEvent )
throw ( RuntimeException )
{
    Reference< util::XModifyListener > xListener;

    // --- SAFE ---
    ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
    xListener = m_xListener;
    aGuard.clear();
    // --- SAFE ---

    if ( xListener.is() )
    {
        try
        {
            xListener->modified( aEvent );
        }
        catch ( RuntimeException& )
        {
            throw;
        }
        catch ( Exception& )
        {
        }
    }
}

// XEventListener
void SAL_CALL ResourceListener::disposing(
    const EventObject& Source )
throw ( RuntimeException )
{
    Reference< lang::XEventListener > xListener;
    Reference< resource::XStringResourceResolver > xResource;

    // --- SAFE ---
    ::osl::ResettableGuard < ::osl::Mutex > aGuard( m_aMutex );
    Reference< XInterface > xIfacRes( m_xResource, UNO_QUERY );
    Reference< XInterface > xIfacList( m_xListener, UNO_QUERY );
    aGuard.clear();
    // --- SAFE ---

    if ( Source.Source == xIfacRes )
    {
        // --- SAFE ---
        aGuard.reset();
        m_bListening = false;
        xResource = m_xResource;
        xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
        m_xResource.clear();
        aGuard.clear();
        // --- SAFE ---

        if ( xListener.is() )
        {
            try
            {
                xListener->disposing( Source );
            }
            catch ( RuntimeException& )
            {
                throw;
            }
            catch ( Exception& )
            {
            }
        }
    }
    else if ( Source.Source == xIfacList )
    {
        // --- SAFE ---
        aGuard.reset();
        m_bListening = false;
        xListener = Reference< lang::XEventListener >( m_xListener, UNO_QUERY );
        xResource = m_xResource;
        m_xResource.clear();
        m_xListener.clear();
        aGuard.clear();
        // --- SAFE ---

        // Remove ourself as listener from resource resolver
        Reference< util::XModifyBroadcaster > xModifyBroadcaster( xResource, UNO_QUERY );
        Reference< util::XModifyListener > xThis( static_cast< OWeakObject* >( this ), UNO_QUERY );
        if ( xModifyBroadcaster.is() )
        {
            try
            {
                xModifyBroadcaster->removeModifyListener( xThis );
            }
            catch ( RuntimeException& )
            {
                throw;
            }
            catch ( Exception& )
            {
            }
        }
    }
}

//===============================================================
//	----------------------------------------------------
//	class DialogContainerControl
//	----------------------------------------------------
ControlContainerBase::ControlContainerBase( const Reference< XMultiServiceFactory >& i_factory )
    :ContainerControl_IBase( i_factory )
    ,mbSizeModified(false)
    ,mbPosModified(false)
{
	maComponentInfos.nWidth = 280;
	maComponentInfos.nHeight = 400;
	mxListener = new ResourceListener( Reference< util::XModifyListener >(
                        static_cast< OWeakObject* >( this ), UNO_QUERY ));
}

ControlContainerBase::~ControlContainerBase()
{
}

void ControlContainerBase::createPeer( const Reference< XToolkit > & rxToolkit, const Reference< XWindowPeer >  & rParentPeer ) throw(RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    UnoControlContainer::createPeer( rxToolkit, rParentPeer );
}

void ControlContainerBase::ImplInsertControl( Reference< XControlModel >& rxModel, const ::rtl::OUString& rName )
{
    Reference< XPropertySet > xP( rxModel, UNO_QUERY );

    ::rtl::OUString aDefCtrl;
    xP->getPropertyValue( GetPropertyName( BASEPROPERTY_DEFAULTCONTROL ) ) >>= aDefCtrl;
	Reference < XControl > xCtrl;
    maContext.createComponent( aDefCtrl, xCtrl );

    DBG_ASSERT( xCtrl.is(), "ControlContainerBase::ImplInsertControl: could not create the control!" );
    if ( xCtrl.is() )
    {
        xCtrl->setModel( rxModel );
        addControl( rName, xCtrl );
            // will implicitly call addingControl, where we can add the PropertiesChangeListener to the model
            // (which we formerly did herein)
            // 08.01.2001 - 96008 - fs@openoffice.org

        ImplSetPosSize( xCtrl );
    }
}

void ControlContainerBase::ImplRemoveControl( Reference< XControlModel >& rxModel )
{
    Sequence< Reference< XControl > > aControls = getControls();
    Reference< XControl > xCtrl = StdTabController::FindControl( aControls, rxModel );
    if ( xCtrl.is() )
    {
        removeControl( xCtrl );
        try
        {
            Reference< XComponent > const xControlComp( xCtrl, UNO_QUERY_THROW );
            xControlComp->dispose();
        }
        catch( Exception const & )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
}

void ControlContainerBase::ImplSetPosSize( Reference< XControl >& rxCtrl )
{
    Reference< XPropertySet > xP( rxCtrl->getModel(), UNO_QUERY );

    sal_Int32 nX = 0, nY = 0, nWidth = 0, nHeight = 0;
    xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) ) ) >>= nX;
    xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) ) ) >>= nY;
    xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Width" ) ) ) >>= nWidth;
    xP->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Height" ) ) ) >>= nHeight;
	MapMode aMode( MAP_APPFONT );
    OutputDevice*pOutDev = Application::GetDefaultDevice();
    if ( pOutDev )
    {
        ::Size aTmp( nX, nY );
		aTmp = pOutDev->LogicToPixel( aTmp, aMode );
        nX = aTmp.Width();
        nY = aTmp.Height();
        aTmp = ::Size( nWidth, nHeight );
		aTmp = pOutDev->LogicToPixel( aTmp, aMode );
        nWidth = aTmp.Width();
        nHeight = aTmp.Height();
    }
    else
    {
        Reference< XWindowPeer > xPeer = ImplGetCompatiblePeer( sal_True );
        Reference< XDevice > xD( xPeer, UNO_QUERY );

        SimpleFontMetric aFM;
        FontDescriptor aFD;
        Any aVal = ImplGetPropertyValue( GetPropertyName( BASEPROPERTY_FONTDESCRIPTOR ) );
        aVal >>= aFD;
        if ( aFD.StyleName.getLength() )
        {
            Reference< XFont > xFont = xD->getFont( aFD );
            aFM = xFont->getFontMetric();
        }
        else
        {
            Reference< XGraphics > xG = xD->createGraphics();
            aFM = xG->getFontMetric();
        }

        sal_Int16 nH = aFM.Ascent + aFM.Descent;
        sal_Int16 nW = nH/2;	// calculate average width?!

        nX *= nW;
        nX /= 4;
        nWidth *= nW;
        nWidth /= 4;
        nY *= nH;
        nY /= 8;
        nHeight *= nH;
        nHeight /= 8;
    }
    Reference < XWindow > xW( rxCtrl, UNO_QUERY );
    xW->setPosSize( nX, nY, nWidth, nHeight, PosSize::POSSIZE );
}

void ControlContainerBase::dispose() throw(RuntimeException)
{
	vos::OGuard aSolarGuard( Application::GetSolarMutex() );

	EventObject aEvt;
	aEvt.Source = static_cast< ::cppu::OWeakObject* >( this );
	// Notify our listener helper about dispose
    // --- SAFE ---
    ::osl::ResettableGuard< ::osl::Mutex > aGuard( GetMutex() );
    Reference< XEventListener > xListener( mxListener, UNO_QUERY );
    mxListener.clear();
    aGuard.clear();
    // --- SAFE ---

    if ( xListener.is() )
        xListener->disposing( aEvt );
    UnoControlContainer::dispose();
}

void SAL_CALL ControlContainerBase::disposing(
    const EventObject& Source )
throw(RuntimeException)
{
    UnoControlContainer::disposing( Source );
}

sal_Bool ControlContainerBase::setModel( const Reference< XControlModel >& rxModel ) throw(RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );

    // destroy the old tab controller, if existent
    if ( mxTabController.is() )
    {
        mxTabController->setModel( NULL );					// just to be sure, should not be necessary
        removeTabController( mxTabController );
        ::comphelper::disposeComponent( mxTabController );	// just to be sure, should not be necessary
        mxTabController.clear();
    }

    if ( getModel().is() )
    {
        Sequence< Reference< XControl > > aControls = getControls();
        const Reference< XControl >* pCtrls = aControls.getConstArray();
        const Reference< XControl >* pCtrlsEnd = pCtrls + aControls.getLength();

        for ( ; pCtrls < pCtrlsEnd; ++pCtrls )
            removeControl( *pCtrls );
                // will implicitly call removingControl, which will remove the PropertyChangeListener
                // (which we formerly did herein)
                // 08.01.2001 - 96008 - fs@openoffice.org

        Reference< XContainer > xC( getModel(), UNO_QUERY );
        if ( xC.is() )
            xC->removeContainerListener( this );

        Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
        if ( xChangeNotifier.is() )
            xChangeNotifier->removeChangesListener( this );
    }

    sal_Bool bRet = UnoControl::setModel( rxModel );

    if ( getModel().is() )
    {
        Reference< XNameAccess > xNA( getModel(), UNO_QUERY );
        if ( xNA.is() )
        {
            Sequence< ::rtl::OUString > aNames = xNA->getElementNames();
            const ::rtl::OUString* pNames = aNames.getConstArray();
            sal_uInt32 nCtrls = aNames.getLength();

            Reference< XControlModel > xCtrlModel;
            for( sal_uInt32 n = 0; n < nCtrls; ++n, ++pNames )
            {
                xNA->getByName( *pNames ) >>= xCtrlModel;
                ImplInsertControl( xCtrlModel, *pNames );
            }
        }

        Reference< XContainer > xC( getModel(), UNO_QUERY );
        if ( xC.is() )
            xC->addContainerListener( this );

        Reference< XChangesNotifier > xChangeNotifier( getModel(), UNO_QUERY );
        if ( xChangeNotifier.is() )
            xChangeNotifier->addChangesListener( this );
    }

    Reference< XTabControllerModel > xTabbing( getModel(), UNO_QUERY );
    if ( xTabbing.is() )
    {
        mxTabController = new StdTabController;
        mxTabController->setModel( xTabbing );
        addTabController( mxTabController );
    }
    ImplStartListingForResourceEvents();

    return bRet;
}
void ControlContainerBase::setDesignMode( sal_Bool bOn ) throw(RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );

    UnoControl::setDesignMode( bOn );

    Sequence< Reference< XControl > > xCtrls = getControls();
    sal_Int32 nControls = xCtrls.getLength();
    Reference< XControl >* pControls = xCtrls.getArray();
    for ( sal_Int32 n = 0; n < nControls; n++ )
        pControls[n]->setDesignMode( bOn );

    // #109067# in design mode the tab controller is not notified about
    // tab index changes, therefore the tab order must be activated
    // when switching from design mode to live mode
    if ( mxTabController.is() && !bOn )
        mxTabController->activateTabOrder();
}

void ControlContainerBase::elementInserted( const ContainerEvent& Event ) throw(RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );

    Reference< XControlModel > xModel;
    ::rtl::OUString aName;

    Event.Accessor >>= aName;
    Event.Element >>= xModel;
    ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementInserted: illegal element!" );
    try
    {
	    ImplInsertControl( xModel, aName );
    }
    catch ( const RuntimeException& e ) { throw; }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

void ControlContainerBase::elementRemoved( const ContainerEvent& Event ) throw(RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );

    Reference< XControlModel > xModel;
    Event.Element >>= xModel;
    ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementRemoved: illegal element!" );
    try
    {
	    ImplRemoveControl( xModel );
    }
    catch ( const RuntimeException& e ) { throw; }
    catch( const Exception& )
    {
	    DBG_UNHANDLED_EXCEPTION();
    }
}

void ControlContainerBase::elementReplaced( const ContainerEvent& Event ) throw(RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );

    Reference< XControlModel > xModel;
    Event.ReplacedElement >>= xModel;
    try
    {
        OSL_ENSURE( xModel.is(), "ControlContainerBase::elementReplaced: invalid ReplacedElement!" );
        if ( xModel.is() )
	        ImplRemoveControl( xModel );
    }
    catch ( const RuntimeException& e ) { throw; }
    catch( const Exception& )
    {
	    DBG_UNHANDLED_EXCEPTION();
    }

    ::rtl::OUString aName;
    Event.Accessor >>= aName;
    Event.Element >>= xModel;
    ENSURE_OR_RETURN_VOID( xModel.is(), "ControlContainerBase::elementReplaced: invalid new element!" );
    try
    {
	    ImplInsertControl( xModel, aName );
    }
    catch ( const RuntimeException& e ) { throw; }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }
}

// XPropertiesChangeListener
void ControlContainerBase::ImplModelPropertiesChanged( const Sequence< PropertyChangeEvent >& rEvents ) throw(RuntimeException)
{
    if( !isDesignMode() && !mbCreatingCompatiblePeer )
    {
        ::rtl::OUString s1( RTL_CONSTASCII_USTRINGPARAM( "PositionX" ) );
        ::rtl::OUString s2( RTL_CONSTASCII_USTRINGPARAM( "PositionY" ) );
        ::rtl::OUString s3( RTL_CONSTASCII_USTRINGPARAM( "Width" ) );
        ::rtl::OUString s4( RTL_CONSTASCII_USTRINGPARAM( "Height" ) );

        sal_Int32 nLen = rEvents.getLength();
        for( sal_Int32 i = 0; i < nLen; i++ )
        {
            const PropertyChangeEvent& rEvt = rEvents.getConstArray()[i];
            Reference< XControlModel > xModel( rEvt.Source, UNO_QUERY );
            sal_Bool bOwnModel = (XControlModel*)xModel.get() == (XControlModel*)getModel().get();
            if ( ( rEvt.PropertyName == s1 ) ||
                 ( rEvt.PropertyName == s2 ) ||
                 ( rEvt.PropertyName == s3 ) ||
                 ( rEvt.PropertyName == s4 ) )
            {
                if ( bOwnModel )
                {
                    if ( !mbPosModified && !mbSizeModified )
                    {
                        // Don't set new pos/size if we get new values from window listener
                        Reference< XControl > xThis( (XAggregation*)(::cppu::OWeakAggObject*)this, UNO_QUERY );
                        ImplSetPosSize( xThis );
                    }
                }
                else
                {
                    Sequence<Reference<XControl> > aControlSequence(getControls());
                    Reference<XControl> aControlRef( StdTabController::FindControl( aControlSequence, xModel ) );
                    ImplSetPosSize( aControlRef );
                }
                break;
            }
        }
    }

    UnoControlContainer::ImplModelPropertiesChanged( rEvents );
}

void ControlContainerBase::addingControl( const Reference< XControl >& _rxControl )
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    UnoControlContainer::addingControl( _rxControl );

    if ( _rxControl.is() )
    {
        Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
        if ( xProps.is() )
        {
            Sequence< ::rtl::OUString > aNames( 4 );
            ::rtl::OUString* pNames = aNames.getArray();
            *pNames++ = ::rtl::OUString::createFromAscii( "PositionX" );
            *pNames++ = ::rtl::OUString::createFromAscii( "PositionY" );
            *pNames++ = ::rtl::OUString::createFromAscii( "Width" );
            *pNames++ = ::rtl::OUString::createFromAscii( "Height" );

            xProps->addPropertiesChangeListener( aNames, this );
        }
    }
}

void ControlContainerBase::removingControl( const Reference< XControl >& _rxControl )
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    UnoControlContainer::removingControl( _rxControl );

    if ( _rxControl.is() )
    {
        Reference< XMultiPropertySet > xProps( _rxControl->getModel(), UNO_QUERY );
        if ( xProps.is() )
            xProps->removePropertiesChangeListener( this );
    }

}

void SAL_CALL ControlContainerBase::changesOccurred( const ChangesEvent& ) throw (RuntimeException)
{
    vos::OGuard aSolarGuard( Application::GetSolarMutex() );
    // a tab controller model may have changed

    // #109067# in design mode don't notify the tab controller
    // about tab index changes
    if ( mxTabController.is() && !mbDesignMode )
        mxTabController->activateTabOrder();
}
void lcl_ApplyResolverToNestedContainees(  const Reference< resource::XStringResourceResolver >& xStringResourceResolver, const Reference< XControlContainer >& xContainer )
{
    rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );

    Any xNewStringResourceResolver; xNewStringResourceResolver <<= xStringResourceResolver;

    Sequence< rtl::OUString > aPropNames(1);
    aPropNames[0] = aPropName;

    const Sequence< Reference< awt::XControl > > aSeq = xContainer->getControls();
    for ( sal_Int32 i = 0; i < aSeq.getLength(); i++ )
    {
		Reference< XControl > xControl( aSeq[i] );
        Reference< XPropertySet > xPropertySet;

        if ( xControl.is() )
            xPropertySet = Reference< XPropertySet >( xControl->getModel(), UNO_QUERY );

        if ( !xPropertySet.is() )
            continue;

        try
        {
            Reference< resource::XStringResourceResolver > xCurrStringResourceResolver;
            Any aOldValue = xPropertySet->getPropertyValue( aPropName );
            if  (   ( aOldValue >>= xCurrStringResourceResolver )
                &&  ( xStringResourceResolver == xCurrStringResourceResolver )
                )
            {
                Reference< XMultiPropertySet >	xMultiPropSet( xPropertySet, UNO_QUERY );
                Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
                xMultiPropSet->firePropertiesChangeEvent( aPropNames, xListener );
            }
            else
                xPropertySet->setPropertyValue( aPropName, xNewStringResourceResolver );
        }
        /*catch ( NoSuchElementException& )*/ // that's nonsense, this is never thrown above ...
        catch ( const Exception& )
        {
        }

        uno::Reference< XControlContainer > xNestedContainer( xControl, uno::UNO_QUERY );
        if ( xNestedContainer.is() )
            lcl_ApplyResolverToNestedContainees(  xStringResourceResolver, xNestedContainer );

    }

}
void ControlContainerBase::ImplStartListingForResourceEvents()
{
    Reference< resource::XStringResourceResolver > xStringResourceResolver;

    ImplGetPropertyValue( PROPERTY_RESOURCERESOLVER ) >>= xStringResourceResolver;

    // Add our helper as listener to retrieve notifications about changes
    Reference< util::XModifyListener > rListener( mxListener );
    ResourceListener* pResourceListener = static_cast< ResourceListener* >( rListener.get() );

    // resource listener will stop listening if resolver reference is empty
    if ( pResourceListener )
        pResourceListener->startListening( xStringResourceResolver );
    ImplUpdateResourceResolver();
}

void ControlContainerBase::ImplUpdateResourceResolver()
{
    rtl::OUString aPropName( PROPERTY_RESOURCERESOLVER );
    Reference< resource::XStringResourceResolver > xStringResourceResolver;

    ImplGetPropertyValue( aPropName ) >>= xStringResourceResolver;
    if ( !xStringResourceResolver.is() )
        return;

    lcl_ApplyResolverToNestedContainees(  xStringResourceResolver, this );

    // propagate resource resolver changes to language dependent props of the dialog
    Reference< XPropertySet > xPropertySet( getModel(), UNO_QUERY );
    if ( xPropertySet.is() )
    {
        Reference< XMultiPropertySet >	xMultiPropSet( xPropertySet, UNO_QUERY );
        Reference< XPropertiesChangeListener > xListener( xPropertySet, UNO_QUERY );
        xMultiPropSet->firePropertiesChangeEvent( lcl_getLanguageDependentProperties(), xListener );
    }
}


uno::Reference< graphic::XGraphic > ControlContainerBase::Impl_getGraphicFromURL_nothrow( const ::rtl::OUString& _rURL )
{
    uno::Reference< graphic::XGraphic > xGraphic;
    if ( !_rURL.getLength() )
        return xGraphic;

    try
    {
        uno::Reference< graphic::XGraphicProvider > xProvider;
        if ( maContext.createComponent( "com.sun.star.graphic.GraphicProvider", xProvider ) )
        {
            uno::Sequence< beans::PropertyValue > aMediaProperties(1);
            aMediaProperties[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
            aMediaProperties[0].Value <<= _rURL;
            xGraphic = xProvider->queryGraphic( aMediaProperties );
        }
    }
    catch( const Exception& )
    {
    	DBG_UNHANDLED_EXCEPTION();
    }

    return xGraphic;
}
////	----------------------------------------------------
////	Helper Method to convert relative url to physical location
////	----------------------------------------------------

::rtl::OUString getPhysicalLocation( const ::com::sun::star::uno::Any& rbase, const ::com::sun::star::uno::Any& rUrl )
{

	::rtl::OUString baseLocation;
	::rtl::OUString url;

	rbase  >>= baseLocation;
	rUrl  >>= url;

    ::rtl::OUString absoluteURL( url );
	if ( url.getLength() > 0 )
	{
		INetURLObject urlObj(baseLocation);
		urlObj.removeSegment();
		baseLocation = urlObj.GetMainURL( INetURLObject::NO_DECODE );

        const INetURLObject protocolCheck( url );
        const INetProtocol protocol = protocolCheck.GetProtocol();
        if ( protocol == INET_PROT_NOT_VALID )
        {
            ::rtl::OUString testAbsoluteURL;
            if ( ::osl::FileBase::E_None == ::osl::FileBase::getAbsoluteFileURL( baseLocation, url, testAbsoluteURL ) )
                absoluteURL = testAbsoluteURL;
        }
	}

	return absoluteURL;
}
