/**************************************************************
 * 
 * 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 "controltype.hxx"
#include "propctrlr.hrc"
#include "extensio.hrc"
#include "fontdialog.hxx"
#include "formcomponenthandler.hxx"
#include "formlinkdialog.hxx"
#include "formmetadata.hxx"
#include "formresid.hrc"
#include "formstrings.hxx"
#include "handlerhelper.hxx"
#include "listselectiondlg.hxx"
#include "pcrcommon.hxx"
#include "selectlabeldialog.hxx"
#include "taborder.hxx"
#include "usercontrol.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/lang/NullPointerException.hpp>
#include <com/sun/star/awt/XControlModel.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/container/XChild.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/form/XGridColumnFactory.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/form/ListSourceType.hpp>
#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
#include <com/sun/star/sdb/XSingleSelectQueryComposer.hpp>
#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/awt/XTabControllerModel.hpp>
#include <com/sun/star/form/FormSubmitEncoding.hpp>
#include <com/sun/star/awt/VisualEffect.hpp>
#include <com/sun/star/form/FormButtonType.hpp>
#include <com/sun/star/inspection/PropertyControlType.hpp>
#include <com/sun/star/util/MeasureUnit.hpp>
#include <com/sun/star/inspection/XObjectInspectorUI.hpp>
#include <com/sun/star/inspection/PropertyLineElement.hpp>
#include <com/sun/star/resource/XStringResourceManager.hpp>
#include <com/sun/star/resource/MissingResourceException.hpp>
#include <com/sun/star/graphic/GraphicObject.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
/** === end UNO includes === **/

#include <comphelper/extract.hxx>
#include <connectivity/dbconversion.hxx>
#include <connectivity/dbexception.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <sfx2/app.hxx>
#include <sfx2/basedlgs.hxx>
#include <sfx2/docfilt.hxx>
#include <sfx2/filedlghelper.hxx>
#include <svl/ctloptions.hxx>
#include <svtools/colrdlg.hxx>
#include <svl/filenotation.hxx>
#include <svl/intitem.hxx>
#include <svl/itemset.hxx>
#include <unotools/moduleoptions.hxx>
#include <svl/numuno.hxx>
#include <svl/urihelper.hxx>
#include <svx/dialogs.hrc>
#include <svx/numinf.hxx>
#include <svx/svxdlg.hxx>
#include <svx/svxids.hrc>
#include <toolkit/helper/vclunohelper.hxx>
#include <tools/diagnose_ex.h>
#include <vcl/msgbox.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/wrkwin.hxx>
#include <tools/StringListResource.hxx>

#include <limits>

#define GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
//------------------------------------------------------------------------
extern "C" void SAL_CALL createRegistryInfo_FormComponentPropertyHandler()
{
    ::pcr::FormComponentPropertyHandler::registerImplementation();
}

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

    using namespace ::com::sun::star;
    using namespace uno;
    using namespace lang;
    using namespace beans;
    using namespace frame;
    using namespace script;
    using namespace form;
    using namespace util;
    using namespace awt;
    using namespace sdb;
    using namespace sdbc;
    using namespace sdbcx;
    using namespace form;
    using namespace container;
    using namespace ui::dialogs;
    using namespace inspection;
    using namespace ::dbtools;

    namespace WritingMode2 = ::com::sun::star::text::WritingMode2;

    //====================================================================
    //= FormComponentPropertyHandler
    //====================================================================
    DBG_NAME( FormComponentPropertyHandler )
#define PROPERTY_ID_ROWSET 1
    //--------------------------------------------------------------------
    FormComponentPropertyHandler::FormComponentPropertyHandler( const Reference< XComponentContext >& _rxContext )
        :FormComponentPropertyHandler_Base( _rxContext )
        ,::comphelper::OPropertyContainer(FormComponentPropertyHandler_Base::rBHelper)
        ,m_sDefaultValueString( String( PcrRes( RID_STR_STANDARD ) ) )
        ,m_eComponentClass( eUnknown )
        ,m_bComponentIsSubForm( false )
        ,m_bHaveListSource( false )
        ,m_bHaveCommand( false )
        ,m_nClassId( 0 )
    {
        DBG_CTOR( FormComponentPropertyHandler, NULL );
        registerProperty(PROPERTY_ROWSET,PROPERTY_ID_ROWSET,0,&m_xRowSet,::getCppuType(&m_xRowSet));
    }

    //--------------------------------------------------------------------
    FormComponentPropertyHandler::~FormComponentPropertyHandler()
    {
        DBG_DTOR( FormComponentPropertyHandler, NULL );
    }
    //--------------------------------------------------------------------
    IMPLEMENT_FORWARD_XINTERFACE2(FormComponentPropertyHandler,FormComponentPropertyHandler_Base,::comphelper::OPropertyContainer)
    //--------------------------------------------------------------------
    ::rtl::OUString SAL_CALL FormComponentPropertyHandler::getImplementationName_static(  ) throw (RuntimeException)
    {
        return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.extensions.FormComponentPropertyHandler" ) );
    }

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

	//============================================
	// TODO: -> export from toolkit
	struct LanguageDependentProp
	{
		const char* pPropName;
		sal_Int32   nPropNameLength;
	};

	static LanguageDependentProp aLanguageDependentProp[] =
	{
		{ "Text",            4 },
		{ "Label",           5 },
		{ "Title",           5 },
		{ "HelpText",        8 },
		{ "CurrencySymbol", 14 },
	    { "StringItemList", 14 },
		{ 0, 0                 }
	};

    namespace
    {
		bool lcl_isLanguageDependentProperty( ::rtl::OUString aName )
		{
			bool bRet = false;

			LanguageDependentProp* pLangDepProp = aLanguageDependentProp;
			while( pLangDepProp->pPropName != 0 )
			{
				if( aName.equalsAsciiL( pLangDepProp->pPropName, pLangDepProp->nPropNameLength ))
				{
					bRet = true;
					break;
				}
				pLangDepProp++;
			}
			return bRet;
		}

		Reference< resource::XStringResourceResolver > lcl_getStringResourceResolverForProperty
			( Reference< XPropertySet > _xComponent, const ::rtl::OUString& _rPropertyName,
			  const Any& _rPropertyValue )
		{
            Reference< resource::XStringResourceResolver > xRet;
            const TypeClass eType = _rPropertyValue.getValueType().getTypeClass();
            if ( (eType == TypeClass_STRING || eType == TypeClass_SEQUENCE) &&
				    lcl_isLanguageDependentProperty( _rPropertyName ) )
            {
                static const ::rtl::OUString s_sResourceResolverPropName(RTL_CONSTASCII_USTRINGPARAM("ResourceResolver"));

			    Reference< resource::XStringResourceResolver > xStringResourceResolver;
			    try
			    {
				    xStringResourceResolver.set( _xComponent->getPropertyValue( s_sResourceResolverPropName ),UNO_QUERY);
                    if( xStringResourceResolver.is() &&
				        xStringResourceResolver->getLocales().getLength() > 0 )
			        {
				        xRet = xStringResourceResolver;
			        }
			    }
			    catch(UnknownPropertyException&)
			    {
                    // nii
                }
            }

			return xRet;
		}
	}

    //--------------------------------------------------------------------
    Any FormComponentPropertyHandler::impl_getPropertyValue_throw( const ::rtl::OUString& _rPropertyName ) const
    {
        const PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );

        Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );

		Reference< resource::XStringResourceResolver > xStringResourceResolver
			= lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, aPropertyValue );
		if( xStringResourceResolver.is() )
	    {
	        TypeClass eType = aPropertyValue.getValueType().getTypeClass();
			if( eType == TypeClass_STRING )
			{
				::rtl::OUString aPropStr;
				aPropertyValue >>= aPropStr;
				if( aPropStr.getLength() > 1 )
				{
					::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
					if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
					{
						::rtl::OUString aResourceStr = xStringResourceResolver->resolveString( aPureIdStr );
						aPropertyValue <<= aResourceStr;
					}
				}
			}
			// StringItemList?
			else if( eType == TypeClass_SEQUENCE )
			{
                Sequence< ::rtl::OUString > aStrings;
				aPropertyValue >>= aStrings;

                const ::rtl::OUString* pStrings = aStrings.getConstArray();
				sal_Int32 nCount = aStrings.getLength();

                Sequence< ::rtl::OUString > aResolvedStrings;
				aResolvedStrings.realloc( nCount );
                ::rtl::OUString* pResolvedStrings = aResolvedStrings.getArray();
				try
				{
					for ( sal_Int32 i = 0; i < nCount; ++i )
					{
						::rtl::OUString aIdStr = pStrings[i];
						::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
						if( xStringResourceResolver->hasEntryForId( aPureIdStr ) )
							pResolvedStrings[i] = xStringResourceResolver->resolveString( aPureIdStr );
						else
							pResolvedStrings[i] = aIdStr;
					}
				}
				catch( resource::MissingResourceException & )
				{}
				aPropertyValue <<= aResolvedStrings;
			}
	    }
		else
	        impl_normalizePropertyValue_nothrow( aPropertyValue, nPropId );

        return aPropertyValue;
    }

    //--------------------------------------------------------------------
    Any SAL_CALL FormComponentPropertyHandler::getPropertyValue( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
    {
        if( _rPropertyName == PROPERTY_ROWSET )
            return ::comphelper::OPropertyContainer::getPropertyValue( _rPropertyName );

        ::osl::MutexGuard aGuard( m_aMutex );
        return impl_getPropertyValue_throw( _rPropertyName );
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormComponentPropertyHandler::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rValue ) throw (UnknownPropertyException, RuntimeException)
    {
        if( _rPropertyName == PROPERTY_ROWSET )
        {
            ::comphelper::OPropertyContainer::setPropertyValue( _rPropertyName, _rValue );
            return;
        }

        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) ); // check if property is known by the handler

        Reference< graphic::XGraphicObject > xGrfObj;
        if ( PROPERTY_ID_IMAGE_URL == nPropId && ( _rValue >>= xGrfObj ) )
        {
            DBG_ASSERT( xGrfObj.is(), "FormComponentPropertyHandler::setPropertyValue() xGrfObj is invalid");
            rtl::OUString sObjectID( RTL_CONSTASCII_USTRINGPARAM( GRAPHOBJ_URLPREFIX ) );
            sObjectID = sObjectID + xGrfObj->getUniqueID();
            m_xComponent->setPropertyValue( _rPropertyName, uno::makeAny( sObjectID ) );
        }
        else if ( PROPERTY_ID_FONT == nPropId )
        {
            // special handling, the value is a faked value we generated ourself in impl_executeFontDialog_nothrow
            Sequence< NamedValue > aFontPropertyValues;
            OSL_VERIFY( _rValue >>= aFontPropertyValues );
            const NamedValue* fontPropertyValue = aFontPropertyValues.getConstArray();
            const NamedValue* fontPropertyValueEnd = fontPropertyValue + aFontPropertyValues.getLength();
            for ( ; fontPropertyValue != fontPropertyValueEnd; ++fontPropertyValue )
                m_xComponent->setPropertyValue( fontPropertyValue->Name, fontPropertyValue->Value );
        }
        else
        {
			Any aValue = _rValue;

			Reference< resource::XStringResourceResolver > xStringResourceResolver
				= lcl_getStringResourceResolverForProperty( m_xComponent, _rPropertyName, _rValue );
			if( xStringResourceResolver.is() )
			{
				Reference< resource::XStringResourceManager >
					xStringResourceManager( xStringResourceResolver, UNO_QUERY );
				if( xStringResourceManager.is() )
				{
					Any aPropertyValue( m_xComponent->getPropertyValue( _rPropertyName ) );
					TypeClass eType = aPropertyValue.getValueType().getTypeClass();
					if( eType == TypeClass_STRING )
					{
						::rtl::OUString aPropStr;
						aPropertyValue >>= aPropStr;
						if( aPropStr.getLength() > 1 )
						{
							::rtl::OUString aPureIdStr = aPropStr.copy( 1 );
							::rtl::OUString aValueStr;
							_rValue >>= aValueStr;
							xStringResourceManager->setString( aPureIdStr, aValueStr );
							aValue = aPropertyValue;	// set value to force modified
						}
					}
					// StringItemList?
					else if( eType == TypeClass_SEQUENCE )
					{
						static ::rtl::OUString aDot = ::rtl::OUString::createFromAscii( "." );
						static ::rtl::OUString aEsc = ::rtl::OUString::createFromAscii( "&" );

						// Put strings into resource using new ids
						Sequence< ::rtl::OUString > aNewStrings;
						_rValue >>= aNewStrings;

						const ::rtl::OUString* pNewStrings = aNewStrings.getConstArray();
						sal_Int32 nNewCount = aNewStrings.getLength();

						// Create new Ids
						::rtl::OUString* pNewPureIds = new ::rtl::OUString[nNewCount];
						::rtl::OUString aIdStrBase = aDot;
						Any aNameAny = m_xComponent->getPropertyValue(PROPERTY_NAME);
						::rtl::OUString sControlName;
						aNameAny >>= sControlName;
						aIdStrBase += sControlName;
						aIdStrBase += aDot;
						aIdStrBase += _rPropertyName;
						sal_Int32 i;
						::rtl::OUString aDummyStr;
						for ( i = 0; i < nNewCount; ++i )
						{
							sal_Int32 nUniqueId = xStringResourceManager->getUniqueNumericId();
							::rtl::OUString aPureIdStr = ::rtl::OUString::valueOf( nUniqueId );
							aPureIdStr += aIdStrBase;
							pNewPureIds[i] = aPureIdStr;
							// Force usage of next Unique Id
							xStringResourceManager->setString( aPureIdStr, aDummyStr );
						}

						// Move strings to new Ids for all locales
						Sequence< Locale > aLocaleSeq = xStringResourceManager->getLocales();
						const Locale* pLocale = aLocaleSeq.getConstArray();
						sal_Int32 nLocaleCount = aLocaleSeq.getLength();
						Sequence< ::rtl::OUString > aOldIdStrings;
						aPropertyValue >>= aOldIdStrings;
						try
						{
							const ::rtl::OUString* pOldIdStrings = aOldIdStrings.getConstArray();
							sal_Int32 nOldIdCount = aOldIdStrings.getLength();
							for ( i = 0; i < nNewCount; ++i )
							{
								::rtl::OUString aOldIdStr;
								::rtl::OUString aOldPureIdStr;
								if( i < nOldIdCount )
								{
									aOldIdStr = pOldIdStrings[i];
									aOldPureIdStr = aOldIdStr.copy( 1 );
								}
								::rtl::OUString aNewPureIdStr = pNewPureIds[i];

								for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
								{
									Locale aLocale = pLocale[iLocale];

									::rtl::OUString aResourceStr;
									if( aOldPureIdStr.getLength() != 0 )
									{
										if( xStringResourceManager->hasEntryForIdAndLocale( aOldPureIdStr, aLocale ) )
										{
											aResourceStr = xStringResourceManager->
												resolveStringForLocale( aOldPureIdStr, aLocale );
										}
									}
									xStringResourceManager->setStringForLocale( aNewPureIdStr, aResourceStr, aLocale );
								}
							}
						}
						catch( resource::MissingResourceException & )
						{}


						// Set new strings for current locale and create
						// new Id sequence as new property value
						Sequence< ::rtl::OUString > aNewIdStrings;
						aNewIdStrings.realloc( nNewCount );
						::rtl::OUString* pNewIdStrings = aNewIdStrings.getArray();
						for ( i = 0; i < nNewCount; ++i )
						{
							::rtl::OUString aPureIdStr = pNewPureIds[i];
							::rtl::OUString aStr = pNewStrings[i];
							xStringResourceManager->setString( aPureIdStr, aStr );

							::rtl::OUString aIdStr = aEsc;
							aIdStr += aPureIdStr;
							pNewIdStrings[i] = aIdStr;
						}
						aValue <<= aNewIdStrings;

						// Remove old ids from resource for all locales
						const ::rtl::OUString* pOldIdStrings = aOldIdStrings.getConstArray();
						sal_Int32 nOldIdCount = aOldIdStrings.getLength();
						for( i = 0 ; i < nOldIdCount ; ++i )
						{
							::rtl::OUString aIdStr = pOldIdStrings[i];
							::rtl::OUString aPureIdStr = aIdStr.copy( 1 );
							for ( sal_Int32 iLocale = 0; iLocale < nLocaleCount; ++iLocale )
							{
								Locale aLocale = pLocale[iLocale];
								try
								{
									xStringResourceManager->removeIdForLocale( aPureIdStr, aLocale );
								}
								catch( resource::MissingResourceException & )
								{}
							}
						}
						delete[] pNewPureIds;
					}
				}
			}

            m_xComponent->setPropertyValue( _rPropertyName, aValue );
        }
    }

    //--------------------------------------------------------------------
    Any SAL_CALL FormComponentPropertyHandler::convertToPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& _rControlValue ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
        Property aProperty( impl_getPropertyFromId_throw( nPropId ) );

        Any aPropertyValue( _rControlValue );
        if ( !aPropertyValue.hasValue() )
        {
            if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) == 0 )
                // default construct an instance of the proper type
                aPropertyValue = Any( NULL, aProperty.Type );
            // nothing to do
            return aPropertyValue;
        }

        /// care for the special "default" string, translate it to VOID
        if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
        {
            // it's a control with a string list
            ::rtl::OUString sStringValue;
            if ( _rControlValue >>= sStringValue )
            {   // note that ColorListBoxes might transfer values either as string or as css.util.Color,
                // so this check here is important
                if ( sStringValue == m_sDefaultValueString )
                    return Any();
            }
        }

        switch ( nPropId )
        {
        case PROPERTY_ID_DATASOURCE:
        {
            ::rtl::OUString sControlValue;
            OSL_VERIFY( _rControlValue >>= sControlValue );

            if ( sControlValue.getLength() )
            {
                Reference< XNameAccess > xDatabaseContext;
                m_aContext.createComponent( (::rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
                if ( !xDatabaseContext.is() || !xDatabaseContext->hasByName( sControlValue ) )
                {
                    ::svt::OFileNotation aTransformer(sControlValue);
                    aPropertyValue <<= ::rtl::OUString( aTransformer.get( ::svt::OFileNotation::N_URL ) );
                }
            }
        }
        break;  // case PROPERTY_ID_DATASOURCE

        case PROPERTY_ID_SHOW_POSITION:
        case PROPERTY_ID_SHOW_NAVIGATION:
        case PROPERTY_ID_SHOW_RECORDACTIONS:
        case PROPERTY_ID_SHOW_FILTERSORT:
        {
            ::rtl::OUString sControlValue;
            OSL_VERIFY( _rControlValue >>= sControlValue );

            ::std::vector< ::rtl::OUString > aListEntries;
            tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
            OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToPropertyValue: broken resource for Show/Hide!" );
            sal_Bool bShow = ( aListEntries.size() < 2 ) || ( sControlValue == aListEntries[1] );

            aPropertyValue <<= bShow;
        }
        break;

        case PROPERTY_ID_TARGET_URL:
        case PROPERTY_ID_IMAGE_URL:
        {
            ::rtl::OUString sControlValue;
            OSL_VERIFY( _rControlValue >>= sControlValue );
            // Don't convert a placeholder
            if ( nPropId == PROPERTY_ID_IMAGE_URL && sControlValue.equals( String( PcrRes( RID_EMBED_IMAGE_PLACEHOLDER ) ) ) )
                aPropertyValue <<= sControlValue;
            else
            {
                INetURLObject aDocURL( impl_getDocumentURL_nothrow() );
                aPropertyValue <<= (::rtl::OUString)URIHelper::SmartRel2Abs( aDocURL, sControlValue, Link(), false, true, INetURLObject::WAS_ENCODED, INetURLObject::DECODE_TO_IURI );
            }
        }
        break;

        case PROPERTY_ID_DATEMIN:
        case PROPERTY_ID_DATEMAX:
        case PROPERTY_ID_DEFAULT_DATE:
        case PROPERTY_ID_DATE:
        {
            util::Date aDate;
            OSL_VERIFY( _rControlValue >>= aDate );
            aPropertyValue <<= (sal_Int32)DBTypeConversion::toINT32( aDate );
        }
        break;

        case PROPERTY_ID_TIMEMIN:
        case PROPERTY_ID_TIMEMAX:
        case PROPERTY_ID_DEFAULT_TIME:
        case PROPERTY_ID_TIME:
        {
            util::Time aTime;
            OSL_VERIFY( _rControlValue >>= aTime );
            aPropertyValue <<= (sal_Int32)DBTypeConversion::toINT32( aTime );
        }
        break;

        case PROPERTY_ID_WRITING_MODE:
        {
            aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );

            sal_Int16 nNormalizedValue( 2 );
            OSL_VERIFY( aPropertyValue >>= nNormalizedValue );
            sal_Int16 nWritingMode = WritingMode2::CONTEXT;
            switch ( nNormalizedValue )
            {
            case 0: nWritingMode = WritingMode2::LR_TB;      break;
            case 1: nWritingMode = WritingMode2::RL_TB;      break;
            case 2: nWritingMode = WritingMode2::CONTEXT;    break;
            default:
                OSL_ENSURE( false, "FormComponentPropertyHandler::convertToPropertyValue: unexpected 'normalized value' for WritingMode!" );
                nWritingMode = WritingMode2::CONTEXT;
                break;
            }

            aPropertyValue <<= nWritingMode;
        }
        break;

        default:
            aPropertyValue = FormComponentPropertyHandler_Base::convertToPropertyValue( _rPropertyName, _rControlValue );
            break;  // default

        }   // switch ( nPropId )

        return aPropertyValue;
    }

    //--------------------------------------------------------------------
    Any SAL_CALL FormComponentPropertyHandler::convertToControlValue( const ::rtl::OUString& _rPropertyName, const Any& _rPropertyValue, const Type& _rControlValueType ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        sal_Int32 nPropId = m_pInfoService->getPropertyId( _rPropertyName );
        DBG_ASSERT( nPropId != -1, "FormComponentPropertyHandler::convertToPropertyValue: not one of my properties!!" );

        Property aProperty( impl_getPropertyFromId_throw( nPropId ) );

        Any aControlValue( _rPropertyValue );
        if ( !aControlValue.hasValue() )
        {
            // if the property is represented with a list box or color list box, we need to
            // translate this into the string "Default"
            if ( m_aPropertiesWithDefListEntry.find( _rPropertyName ) != m_aPropertiesWithDefListEntry.end() )
                aControlValue <<= m_sDefaultValueString;

            return aControlValue;
        }

        switch ( nPropId )
        {
        //////////////////////////////////////////////////////////////
        case PROPERTY_ID_SHOW_POSITION:
        case PROPERTY_ID_SHOW_NAVIGATION:
        case PROPERTY_ID_SHOW_RECORDACTIONS:
        case PROPERTY_ID_SHOW_FILTERSORT:
        {
            ::std::vector< ::rtl::OUString > aListEntries;
            tools::StringListResource aRes( PcrRes( RID_RSC_ENUM_SHOWHIDE ), aListEntries );
            OSL_ENSURE( aListEntries.size() == 2, "FormComponentPropertyHandler::convertToControlValue: broken resource for Show/Hide!" );

            if ( aListEntries.size() == 2 )
            {
                ::rtl::OUString sControlValue =     ::comphelper::getBOOL( _rPropertyValue )
                                                ?   aListEntries[1]
                                                :   aListEntries[0];
                aControlValue <<= sControlValue;
            }
        }
        break;

        //////////////////////////////////////////////////////////////
        case PROPERTY_ID_DATASOURCE:
        {
            OSL_ENSURE( _rControlValueType.getTypeClass() == TypeClass_STRING,
                "FormComponentPropertyHandler::convertToControlValue: wrong ControlValueType!" );

            ::rtl::OUString sDataSource;
            _rPropertyValue >>= sDataSource;
            if ( sDataSource.getLength() )
            {
                ::svt::OFileNotation aTransformer( sDataSource );
                sDataSource = aTransformer.get( ::svt::OFileNotation::N_SYSTEM );
            }
            aControlValue <<= sDataSource;
        }
        break;

        //////////////////////////////////////////////////////////////
        case PROPERTY_ID_CONTROLLABEL:
        {
            ::rtl::OUString sControlValue;

            Reference< XPropertySet >  xSet;
            _rPropertyValue >>= xSet;
            Reference< XPropertySetInfo > xPSI;
            if ( xSet.is() )
                xPSI = xSet->getPropertySetInfo();
            if ( xPSI.is() && xPSI->hasPropertyByName( PROPERTY_LABEL ) )
            {
                ::rtl::OUStringBuffer aValue;
                aValue.append( (sal_Unicode)'<' );
                ::rtl::OUString sLabel;
                OSL_VERIFY( xSet->getPropertyValue( PROPERTY_LABEL ) >>= sLabel );
                aValue.append( sLabel );
                aValue.append( (sal_Unicode)'>' );
                sControlValue = aValue.makeStringAndClear();
            }

            aControlValue <<= sControlValue;
        }
        break;

        //////////////////////////////////////////////////////////////
        case PROPERTY_ID_DATEMIN:
        case PROPERTY_ID_DATEMAX:
        case PROPERTY_ID_DEFAULT_DATE:
        case PROPERTY_ID_DATE:
        {
            sal_Int32 nDate = 0;
            OSL_VERIFY( _rPropertyValue >>= nDate );
            aControlValue <<= DBTypeConversion::toDate( nDate );
        }
        break;

        case PROPERTY_ID_TIMEMIN:
        case PROPERTY_ID_TIMEMAX:
        case PROPERTY_ID_DEFAULT_TIME:
        case PROPERTY_ID_TIME:
        {
            sal_Int32 nTime = 0;
            OSL_VERIFY( _rPropertyValue >>= nTime );
            aControlValue <<= DBTypeConversion::toTime( nTime );
        }
        break;

        case PROPERTY_ID_WRITING_MODE:
        {
            sal_Int16 nWritingMode( WritingMode2::CONTEXT );
            OSL_VERIFY( _rPropertyValue >>= nWritingMode );
            sal_Int16 nNormalized = 2;
            switch ( nWritingMode )
            {
            case WritingMode2::LR_TB:   nNormalized = 0;    break;
            case WritingMode2::RL_TB:   nNormalized = 1;    break;
            case WritingMode2::CONTEXT: nNormalized = 2;    break;
            default:
                OSL_ENSURE( false, "FormComponentPropertyHandler::convertToControlValue: unsupported API value for WritingMode!" );
                nNormalized = 2;
                break;
            }

            aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, makeAny( nNormalized ), _rControlValueType );
        }
        break;

        case PROPERTY_ID_FONT:
        {
            FontDescriptor aFont;
            OSL_VERIFY( _rPropertyValue >>= aFont );

            ::rtl::OUStringBuffer displayName;
            if ( !aFont.Name.getLength() )
            {
                displayName.append( String( PcrRes( RID_STR_FONT_DEFAULT ) ) );
            }
            else
            {
                // font name
                displayName.append( aFont.Name );
                displayName.appendAscii( ", " );

                // font style
                ::FontWeight  eWeight = VCLUnoHelper::ConvertFontWeight( aFont.Weight );
                sal_uInt16 nStyleResID = RID_STR_FONTSTYLE_REGULAR;
                if ( aFont.Slant == FontSlant_ITALIC )
                {
                    if ( eWeight > WEIGHT_NORMAL )
                        nStyleResID = RID_STR_FONTSTYLE_BOLD_ITALIC;
                    else
                        nStyleResID = RID_STR_FONTSTYLE_ITALIC;
                }
                else
                {
                    if ( eWeight > WEIGHT_NORMAL )
                        nStyleResID = RID_STR_FONTSTYLE_BOLD;
                }
                displayName.append( String( PcrRes( nStyleResID ) ) );

                // font size
                if ( aFont.Height )
                {
                    displayName.appendAscii( ", " );
                    displayName.append( sal_Int32( aFont.Height ) );
                }
            }

            aControlValue <<= displayName.makeStringAndClear();
        }
        break;

        default:
            aControlValue = FormComponentPropertyHandler_Base::convertToControlValue( _rPropertyName, _rPropertyValue, _rControlValueType );
            break;

        }   // switch ( nPropId )

        return aControlValue;
    }

    //--------------------------------------------------------------------
    PropertyState SAL_CALL FormComponentPropertyHandler::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( m_xPropertyState.is() )
            return m_xPropertyState->getPropertyState( _rPropertyName );
        return PropertyState_DIRECT_VALUE;
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormComponentPropertyHandler::addPropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        FormComponentPropertyHandler_Base::addPropertyChangeListener( _rxListener );
        if ( m_xComponent.is() )
            m_xComponent->addPropertyChangeListener( ::rtl::OUString(), _rxListener );
    }

    //--------------------------------------------------------------------
    void SAL_CALL FormComponentPropertyHandler::removePropertyChangeListener( const Reference< XPropertyChangeListener >& _rxListener ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( m_xComponent.is() )
            m_xComponent->removePropertyChangeListener( ::rtl::OUString(), _rxListener );
        FormComponentPropertyHandler_Base::removePropertyChangeListener( _rxListener );
    }

    //--------------------------------------------------------------------
    void FormComponentPropertyHandler::onNewComponent()
    {
        FormComponentPropertyHandler_Base::onNewComponent();
        if ( !m_xComponentPropertyInfo.is() && m_xComponent.is() )
            throw NullPointerException();

        m_xPropertyState.set( m_xComponent, UNO_QUERY );
        m_eComponentClass = eUnknown;
        m_bComponentIsSubForm = m_bHaveListSource = m_bHaveCommand = false;
        m_nClassId = 0;

        impl_initComponentMetaData_throw();
    }

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

        ::std::vector< Property > aProperties;

        Sequence< Property > aAllProperties( m_xComponentPropertyInfo->getProperties() );
        aProperties.reserve( aAllProperties.getLength() );

        // filter the properties
        PropertyId nPropId( 0 );
        ::rtl::OUString sDisplayName;

        Property* pProperty = aAllProperties.getArray();
        Property* pPropertiesEnd = pProperty + aAllProperties.getLength();
        for ( ; pProperty != pPropertiesEnd; ++pProperty )
        {
            nPropId = m_pInfoService->getPropertyId( pProperty->Name );
            if ( nPropId == -1 )
                continue;
            pProperty->Handle = nPropId;

            sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
            if ( !sDisplayName.getLength() )
                continue;

            sal_uInt32  nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
            bool bIsVisibleForForms   = ( nPropertyUIFlags & PROP_FLAG_FORM_VISIBLE   ) != 0;
            bool bIsVisibleForDialogs = ( nPropertyUIFlags & PROP_FLAG_DIALOG_VISIBLE ) != 0;

            // depending on whether we're working for a form or a UNO dialog, some
            // properties are not displayed
            if  (  ( m_eComponentClass == eFormControl   && !bIsVisibleForForms )
                || ( m_eComponentClass == eDialogControl && !bIsVisibleForDialogs )
                )
                continue;

            // some generic sanity checks
            if ( impl_shouldExcludeProperty_nothrow( *pProperty ) )
                continue;

            switch ( nPropId )
            {
            case PROPERTY_ID_BORDER:
            case PROPERTY_ID_TABSTOP:
                // BORDER and TABSTOP are normalized (see impl_normalizePropertyValue_nothrow)
                // to not allow VOID values
                pProperty->Attributes &= ~( PropertyAttribute::MAYBEVOID );
                break;

            case PROPERTY_ID_LISTSOURCE:
                // no cursor source if no Base is installed. #124939#
                // This fix is not intendend to appear on the main trunk. If you find it there,
                // please tell me! frank.schoenheit@sun.com
                if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
                    const_cast< FormComponentPropertyHandler* >( this )->m_bHaveListSource = true;
                break;

            case PROPERTY_ID_COMMAND:
                // no cursor source if no Base is installed. #124939#
                // This fix is not intendend to appear on the main trunk. If you find it there,
                // please tell me! frank.schoenheit@sun.com
                if ( SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
                    const_cast< FormComponentPropertyHandler* >( this )->m_bHaveCommand = true;
                break;
            }   // switch ( nPropId )

            aProperties.push_back( *pProperty );
        }

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

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getSupersededProperties( ) throw (RuntimeException)
    {
        return Sequence< ::rtl::OUString >( );
    }

    //--------------------------------------------------------------------
    Sequence< ::rtl::OUString > SAL_CALL FormComponentPropertyHandler::getActuatingProperties( ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        ::std::vector< ::rtl::OUString > aInterestingProperties;
        aInterestingProperties.push_back( PROPERTY_DATASOURCE );
        aInterestingProperties.push_back( PROPERTY_COMMAND );
        aInterestingProperties.push_back( PROPERTY_COMMANDTYPE );
        aInterestingProperties.push_back( PROPERTY_LISTSOURCE );
        aInterestingProperties.push_back( PROPERTY_LISTSOURCETYPE );
        aInterestingProperties.push_back( PROPERTY_SUBMIT_ENCODING );
        aInterestingProperties.push_back( PROPERTY_REPEAT );
        aInterestingProperties.push_back( PROPERTY_TABSTOP );
        aInterestingProperties.push_back( PROPERTY_BORDER );
        aInterestingProperties.push_back( PROPERTY_CONTROLSOURCE );
        aInterestingProperties.push_back( PROPERTY_DROPDOWN );
        aInterestingProperties.push_back( PROPERTY_IMAGE_URL );
        aInterestingProperties.push_back( PROPERTY_TARGET_URL );
        aInterestingProperties.push_back( PROPERTY_STRINGITEMLIST );
        aInterestingProperties.push_back( PROPERTY_BUTTONTYPE );
        aInterestingProperties.push_back( PROPERTY_ESCAPE_PROCESSING );
        aInterestingProperties.push_back( PROPERTY_TRISTATE );
        aInterestingProperties.push_back( PROPERTY_DECIMAL_ACCURACY );
        aInterestingProperties.push_back( PROPERTY_SHOWTHOUSANDSEP );
        aInterestingProperties.push_back( PROPERTY_FORMATKEY );
        aInterestingProperties.push_back( PROPERTY_EMPTY_IS_NULL );
        aInterestingProperties.push_back( PROPERTY_TOGGLE );
        return Sequence< ::rtl::OUString >( &(*aInterestingProperties.begin()), aInterestingProperties.size() );
    }

    //--------------------------------------------------------------------
    LineDescriptor SAL_CALL FormComponentPropertyHandler::describePropertyLine( const ::rtl::OUString& _rPropertyName,
        const Reference< XPropertyControlFactory >& _rxControlFactory )
        throw (UnknownPropertyException, NullPointerException, RuntimeException)
    {
        if ( !_rxControlFactory.is() )
            throw NullPointerException();

        ::osl::MutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );
        Property aProperty( impl_getPropertyFromId_throw( nPropId ) );

        //////////////////////////////////////////////////////////////////////
        // for the MultiLine property, we have different UI translations depending on the control
        // type
        if ( nPropId == PROPERTY_ID_MULTILINE )
        {
            if (  ( m_nClassId == FormComponentType::FIXEDTEXT )
               || ( m_nClassId == FormComponentType::COMMANDBUTTON )
               || ( m_nClassId == FormComponentType::RADIOBUTTON )
               || ( m_nClassId == FormComponentType::CHECKBOX )
               )
                nPropId = PROPERTY_ID_WORDBREAK;
        }

        String sDisplayName = m_pInfoService->getPropertyTranslation( nPropId );
        if ( !sDisplayName.Len() )
        {
            DBG_ERROR( "FormComponentPropertyHandler::describePropertyLine: did getSupportedProperties not work properly?" );
            throw UnknownPropertyException();
        }

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

        LineDescriptor aDescriptor;
        aDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( nPropId ) );
        aDescriptor.DisplayName = sDisplayName;

        // for the moment, assume a text field
        sal_Int16 nControlType = PropertyControlType::TextField;
        sal_Bool bReadOnly = sal_False;
        aDescriptor.Control.clear();

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

        bool bNeedDefaultStringIfVoidAllowed = false;

        TypeClass eType = aProperty.Type.getTypeClass();

        switch ( nPropId )
        {
        case PROPERTY_ID_DEFAULT_SELECT_SEQ:
        case PROPERTY_ID_SELECTEDITEMS:
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SELECTION);
            break;

        case PROPERTY_ID_FILTER:
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FILTER);
            break;

        case PROPERTY_ID_SORT:
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_ORDER);
            break;

        case PROPERTY_ID_MASTERFIELDS:
        case PROPERTY_ID_DETAILFIELDS:
            nControlType = PropertyControlType::StringListField;
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FORMLINKFIELDS);
            break;

        case PROPERTY_ID_COMMAND:
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);
            break;

        case PROPERTY_ID_TABINDEX:
        {
            Reference< XControlContainer > xControlContext( impl_getContextControlContainer_nothrow() );
            if ( xControlContext.is() )
                aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_TABINDEX);
            nControlType = PropertyControlType::NumericField;
        };
        break;

        case PROPERTY_ID_FONT:
            bReadOnly = sal_True;
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FONT_TYPE);
            break;

        case PROPERTY_ID_TARGET_URL:
        case PROPERTY_ID_IMAGE_URL:
        {
            aDescriptor.Control = new OFileUrlControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );

            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(( PROPERTY_ID_TARGET_URL == nPropId )
                ? UID_PROP_DLG_ATTR_TARGET_URL : UID_PROP_DLG_IMAGE_URL);
        }
        break;

        case PROPERTY_ID_ECHO_CHAR:
            nControlType = PropertyControlType::CharacterField;
            break;

        case PROPERTY_ID_BACKGROUNDCOLOR:
        case PROPERTY_ID_FILLCOLOR:
        case PROPERTY_ID_SYMBOLCOLOR:
        case PROPERTY_ID_BORDERCOLOR:
            nControlType = PropertyControlType::ColorListBox;

            switch( nPropId )
            {
            case PROPERTY_ID_BACKGROUNDCOLOR:
                aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_BACKGROUNDCOLOR); break;
            case PROPERTY_ID_FILLCOLOR:
                aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_FILLCOLOR); break;
            case PROPERTY_ID_SYMBOLCOLOR:
                aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SYMBOLCOLOR); break;
            case PROPERTY_ID_BORDERCOLOR:
                aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_BORDERCOLOR); break;
            }
            break;

        case PROPERTY_ID_LABEL:
            nControlType = PropertyControlType::MultiLineTextField;
            break;

        case PROPERTY_ID_DEFAULT_TEXT:
        {
            if (FormComponentType::FILECONTROL == m_nClassId)
                nControlType = PropertyControlType::TextField;
            else
                nControlType = PropertyControlType::MultiLineTextField;
        }
        break;

        case PROPERTY_ID_TEXT:
            if ( impl_componentHasProperty_throw( PROPERTY_MULTILINE ) )
                nControlType = PropertyControlType::MultiLineTextField;
            break;

        case PROPERTY_ID_CONTROLLABEL:
            bReadOnly = sal_True;
            aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_CONTROLLABEL);
            break;

        case PROPERTY_ID_FORMATKEY:
        case PROPERTY_ID_EFFECTIVE_MIN:
        case PROPERTY_ID_EFFECTIVE_MAX:
        case PROPERTY_ID_EFFECTIVE_DEFAULT:
        case PROPERTY_ID_EFFECTIVE_VALUE:
        {
            // and the supplier is really available
            Reference< XNumberFormatsSupplier >  xSupplier;
            m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;
            if (xSupplier.is())
            {
                Reference< XUnoTunnel > xTunnel(xSupplier,UNO_QUERY);
                DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::describePropertyLine : xTunnel is invalid!");
                SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));

                if (pSupplier != NULL)
                {
                    sal_Bool bIsFormatKey = (PROPERTY_ID_FORMATKEY == nPropId);

                    bReadOnly = bIsFormatKey;

                    if ( bIsFormatKey )
                    {
                        OFormatSampleControl* pControl = new OFormatSampleControl( impl_getDefaultDialogParent_nothrow(), WB_READONLY | WB_TABSTOP | WB_BORDER );
                        aDescriptor.Control = pControl;
                        pControl->SetFormatSupplier( pSupplier );

                        aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_NUMBER_FORMAT);
                    }
                    else
                    {
                        OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER );
                        aDescriptor.Control = pControl;

                        FormatDescription aDesc;
                        aDesc.pSupplier = pSupplier;
                        Any aFormatKeyValue = m_xComponent->getPropertyValue(PROPERTY_FORMATKEY);
                        if ( !( aFormatKeyValue >>= aDesc.nKey ) )
                            aDesc.nKey = 0;

                        pControl->SetFormatDescription( aDesc );
                    }
                }
            }
        }
        break;

        case PROPERTY_ID_DATEMIN:
        case PROPERTY_ID_DATEMAX:
        case PROPERTY_ID_DEFAULT_DATE:
        case PROPERTY_ID_DATE:
            nControlType = PropertyControlType::DateField;
            break;

        case PROPERTY_ID_TIMEMIN:
        case PROPERTY_ID_TIMEMAX:
        case PROPERTY_ID_DEFAULT_TIME:
        case PROPERTY_ID_TIME:
            nControlType = PropertyControlType::TimeField;
            break;

        case PROPERTY_ID_VALUEMIN:
        case PROPERTY_ID_VALUEMAX:
        case PROPERTY_ID_DEFAULT_VALUE:
        case PROPERTY_ID_VALUE:
            {
                OFormattedNumericControl* pControl = new OFormattedNumericControl( impl_getDefaultDialogParent_nothrow(), WB_TABSTOP | WB_BORDER | WB_SPIN | WB_REPEAT );
                aDescriptor.Control = pControl;

                // we don't set a formatter so the control uses a default (which uses the application
                // language and a default numeric format)
                // but we set the decimal digits
                pControl->SetDecimalDigits(
                    ::comphelper::getINT16( m_xComponent->getPropertyValue( PROPERTY_DECIMAL_ACCURACY ) )
                );

                // and the thousands separator
                pControl->SetThousandsSep(
                    ::comphelper::getBOOL( m_xComponent->getPropertyValue(PROPERTY_SHOWTHOUSANDSEP) )
                );

                // and the default value for the property
                try
                {
                    if (m_xPropertyState.is() && ((PROPERTY_ID_VALUEMIN == nPropId) || (PROPERTY_ID_VALUEMAX == nPropId)))
                    {
                        double nDefault = 0;
                        if ( m_xPropertyState->getPropertyDefault( aProperty.Name ) >>= nDefault )
                            pControl->SetDefaultValue( nDefault );
                    }
                }
                catch (Exception&)
                {
                    // just ignore it
                }

                // and allow empty values only for the default value and the value
                pControl->EnableEmptyField( ( PROPERTY_ID_DEFAULT_VALUE == nPropId )
                                        ||  ( PROPERTY_ID_VALUE == nPropId ) );
            }
            break;

        default:
            if ( TypeClass_BYTE <= eType && eType <= TypeClass_DOUBLE )
            {
                sal_Int16 nDigits = 0;
                sal_Int16 nValueUnit = -1;
                sal_Int16 nDisplayUnit = -1;
                if ( m_eComponentClass == eFormControl )
                {
                    if  (  ( nPropId == PROPERTY_ID_WIDTH )
                        || ( nPropId == PROPERTY_ID_ROWHEIGHT )
                        || ( nPropId == PROPERTY_ID_HEIGHT )
                        )
                    {
                        nValueUnit = MeasureUnit::MM_10TH;
                        nDisplayUnit = impl_getDocumentMeasurementUnit_throw();
                        nDigits = 2;
                    }
                }

                Optional< double > aValueNotPresent( sal_False, 0 );
                aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
                    _rxControlFactory, nDigits, aValueNotPresent, aValueNotPresent, sal_False );

                Reference< XNumericControl > xNumericControl( aDescriptor.Control, UNO_QUERY_THROW );
                if ( nValueUnit != -1 )
                    xNumericControl->setValueUnit( nValueUnit );
                if ( nDisplayUnit != -1 )
                    xNumericControl->setDisplayUnit( nDisplayUnit );
            }
            break;
        }

        //////////////////////////////////////////////////////////////////////
        if ( eType == TypeClass_SEQUENCE )
            nControlType = PropertyControlType::StringListField;

        //////////////////////////////////////////////////////////////////////
        // boolean values
        if ( eType == TypeClass_BOOLEAN )
        {
            sal_uInt16 nResId = RID_RSC_ENUM_YESNO;
            if  (   ( nPropId == PROPERTY_ID_SHOW_POSITION )
                ||  ( nPropId == PROPERTY_ID_SHOW_NAVIGATION )
                ||  ( nPropId == PROPERTY_ID_SHOW_RECORDACTIONS )
                ||  ( nPropId == PROPERTY_ID_SHOW_FILTERSORT )
                )
                nResId = RID_RSC_ENUM_SHOWHIDE;

            ::std::vector< ::rtl::OUString > aListEntries;
            tools::StringListResource aRes(PcrRes(nResId),aListEntries);
            aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
            bNeedDefaultStringIfVoidAllowed = true;
        }

        //////////////////////////////////////////////////////////////////////
        // enum properties
        sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( nPropId );
        bool bIsEnumProperty = ( nPropertyUIFlags & PROP_FLAG_ENUM ) != 0;
        if ( bIsEnumProperty || ( PROPERTY_ID_TARGET_FRAME == nPropId ) )
        {
            ::std::vector< ::rtl::OUString > aEnumValues = m_pInfoService->getPropertyEnumRepresentations( nPropId );
            ::std::vector< ::rtl::OUString >::const_iterator pStart = aEnumValues.begin();
            ::std::vector< ::rtl::OUString >::const_iterator pEnd = aEnumValues.end();

            // for a checkbox: if "ambiguous" is not allowed, remove this from the sequence
            if  (   ( PROPERTY_ID_DEFAULT_STATE == nPropId )
                ||  ( PROPERTY_ID_STATE == nPropId )
                )
            {
                if ( impl_componentHasProperty_throw( PROPERTY_TRISTATE ) )
                {
                    if ( !::comphelper::getBOOL( m_xComponent->getPropertyValue( PROPERTY_TRISTATE ) ) )
                    {   // remove the last sequence element
                        if ( pEnd > pStart )
                            --pEnd;
                    }
                }
                else
                    --pEnd;
            }

            if ( PROPERTY_ID_LISTSOURCETYPE == nPropId )
                if ( FormComponentType::COMBOBOX == m_nClassId )
                    // remove the first sequence element -> value list not possible for combo boxes
                    ++pStart;

            // copy the sequence
            ::std::vector< ::rtl::OUString > aListEntries( pEnd - pStart );
            ::std::copy( pStart, pEnd, aListEntries.begin() );

            // create the control
            if ( PROPERTY_ID_TARGET_FRAME == nPropId )
                aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
            else
            {
                aDescriptor.Control = PropertyHandlerHelper::createListBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
                bNeedDefaultStringIfVoidAllowed = true;
            }
        }

        //////////////////////////////////////////////////////////////////////
        switch( nPropId )
        {
            case PROPERTY_ID_REPEAT_DELAY:
            {
                OTimeDurationControl* pControl = new OTimeDurationControl( impl_getDefaultDialogParent_nothrow(), WB_BORDER | WB_TABSTOP );
                aDescriptor.Control = pControl;

                pControl->setMinValue( Optional< double >( sal_True, 0 ) );
                pControl->setMaxValue( Optional< double >( sal_True, ::std::numeric_limits< double >::max() ) );
            }
            break;

            case PROPERTY_ID_TABINDEX:
            case PROPERTY_ID_BOUNDCOLUMN:
            case PROPERTY_ID_VISIBLESIZE:
            case PROPERTY_ID_MAXTEXTLEN:
            case PROPERTY_ID_LINEINCREMENT:
            case PROPERTY_ID_BLOCKINCREMENT:
            case PROPERTY_ID_SPININCREMENT:
            {
                Optional< double > aMinValue( sal_True, 0 );
                Optional< double > aMaxValue( sal_True, 0x7FFFFFFF );

                if ( nPropId == PROPERTY_ID_MAXTEXTLEN )
                    aMinValue.Value = -1;
                else if ( nPropId == PROPERTY_ID_VISIBLESIZE )
                    aMinValue.Value = 1;
                else
                    aMinValue.Value = 0;

                aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
                    _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
            }
            break;

            case PROPERTY_ID_DECIMAL_ACCURACY:
            {
                Optional< double > aMinValue( sal_True, 0 );
                Optional< double > aMaxValue( sal_True, 20 );

                aDescriptor.Control = PropertyHandlerHelper::createNumericControl(
                    _rxControlFactory, 0, aMinValue, aMaxValue, sal_False );
            }
            break;

            //////////////////////////////////////////////////////////////////////
            // DataSource
            case PROPERTY_ID_DATASOURCE:
            {
                aDescriptor.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_ATTR_DATASOURCE);

                ::std::vector< ::rtl::OUString > aListEntries;

                Reference< XNameAccess > xDatabaseContext;
                m_aContext.createComponent( (rtl::OUString)SERVICE_DATABASE_CONTEXT, xDatabaseContext );
                if (xDatabaseContext.is())
                {
                    Sequence< ::rtl::OUString > aDatasources = xDatabaseContext->getElementNames();
                    aListEntries.resize( aDatasources.getLength() );
                    ::std::copy( aDatasources.getConstArray(), aDatasources.getConstArray() + aDatasources.getLength(),
                        aListEntries.begin() );
                }
                aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
                    _rxControlFactory, aListEntries, sal_False, sal_True );
            }
            break;

            case PROPERTY_ID_CONTROLSOURCE:
            {
                ::std::vector< ::rtl::OUString > aFieldNames;
                impl_initFieldList_nothrow( aFieldNames );
                aDescriptor.Control = PropertyHandlerHelper::createComboBoxControl(
                    _rxControlFactory, aFieldNames, sal_False, sal_False );
            }
            break;

            case PROPERTY_ID_COMMAND:
                impl_describeCursorSource_nothrow( aDescriptor, _rxControlFactory );
                break;

            case PROPERTY_ID_LISTSOURCE:
                impl_describeListSourceUI_throw( aDescriptor, _rxControlFactory );
                break;
        }

        if ( !aDescriptor.Control.is() )
            aDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnly );

        if ( ( aProperty.Attributes & PropertyAttribute::MAYBEVOID ) != 0 )
        {
            // insert the string "Default" string, if necessary
            if ( bNeedDefaultStringIfVoidAllowed || ( nControlType == PropertyControlType::ColorListBox ) )
            {
                Reference< XStringListControl > xStringList( aDescriptor.Control, UNO_QUERY_THROW );
                xStringList->prependListEntry( m_sDefaultValueString );
                m_aPropertiesWithDefListEntry.insert( _rPropertyName );
            }
        }

        if ( aDescriptor.PrimaryButtonId.getLength() )
            aDescriptor.HasPrimaryButton = sal_True;
        if ( aDescriptor.SecondaryButtonId.getLength() )
            aDescriptor.HasSecondaryButton = sal_True;

        bool bIsDataProperty = ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0;
        aDescriptor.Category = ::rtl::OUString::createFromAscii( bIsDataProperty ? "Data" : "General" );
        return aDescriptor;
    }

    //--------------------------------------------------------------------
    InteractiveSelectionResult SAL_CALL FormComponentPropertyHandler::onInteractivePropertySelection( const ::rtl::OUString& _rPropertyName, sal_Bool /*_bPrimary*/, Any& _rData, const Reference< XObjectInspectorUI >& _rxInspectorUI ) throw (UnknownPropertyException, NullPointerException, RuntimeException)
    {
        if ( !_rxInspectorUI.is() )
            throw NullPointerException();

        ::osl::ClearableMutexGuard aGuard( m_aMutex );
        PropertyId nPropId( impl_getPropertyId_throw( _rPropertyName ) );

        InteractiveSelectionResult eResult = InteractiveSelectionResult_Cancelled;
        switch ( nPropId )
        {
        case PROPERTY_ID_DEFAULT_SELECT_SEQ:
        case PROPERTY_ID_SELECTEDITEMS:
            if ( impl_dialogListSelection_nothrow( _rPropertyName, aGuard ) )
                eResult = InteractiveSelectionResult_Success;
            break;

        case PROPERTY_ID_FILTER:
        case PROPERTY_ID_SORT:
        {
            ::rtl::OUString sClause;
            if ( impl_dialogFilterOrSort_nothrow( PROPERTY_ID_FILTER == nPropId, sClause, aGuard ) )
            {
                _rData <<= sClause;
                eResult = InteractiveSelectionResult_ObtainedValue;
            }
        }
        break;

        case PROPERTY_ID_MASTERFIELDS:
        case PROPERTY_ID_DETAILFIELDS:
            if ( impl_dialogLinkedFormFields_nothrow( aGuard ) )
                eResult = InteractiveSelectionResult_Success;
            break;

        case PROPERTY_ID_FORMATKEY:
            if ( impl_dialogFormatting_nothrow( _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_IMAGE_URL:
            if ( impl_browseForImage_nothrow( _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_TARGET_URL:
            if ( impl_browseForTargetURL_nothrow( _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_FONT:
            if ( impl_executeFontDialog_nothrow( _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_DATASOURCE:
            if ( impl_browseForDatabaseDocument_throw( _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_BACKGROUNDCOLOR:
        case PROPERTY_ID_FILLCOLOR:
        case PROPERTY_ID_SYMBOLCOLOR:
        case PROPERTY_ID_BORDERCOLOR:
            if ( impl_dialogColorChooser_throw( nPropId, _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_CONTROLLABEL:
            if ( impl_dialogChooseLabelControl_nothrow( _rData, aGuard ) )
                eResult = InteractiveSelectionResult_ObtainedValue;
            break;

        case PROPERTY_ID_TABINDEX:
            if ( impl_dialogChangeTabOrder_nothrow( aGuard ) )
                eResult = InteractiveSelectionResult_Success;
            break;

        case PROPERTY_ID_COMMAND:
        case PROPERTY_ID_LISTSOURCE:
            if ( impl_doDesignSQLCommand_nothrow( _rxInspectorUI, nPropId ) )
                eResult = InteractiveSelectionResult_Pending;
            break;
        default:
            DBG_ERROR( "FormComponentPropertyHandler::onInteractivePropertySelection: request for a property which does not have dedicated UI!" );
            break;
        }
        return eResult;
    }

    //--------------------------------------------------------------------
    namespace
    {
        void lcl_rebuildAndResetCommand( const Reference< XObjectInspectorUI >& _rxInspectorUI, const Reference< XPropertyHandler >& _rxHandler )
        {
            OSL_PRECOND( _rxInspectorUI.is(), "lcl_rebuildAndResetCommand: invalid BrowserUI!" );
            OSL_PRECOND( _rxHandler.is(), "lcl_rebuildAndResetCommand: invalid handler!" );
            _rxInspectorUI->rebuildPropertyUI( PROPERTY_COMMAND );
            _rxHandler->setPropertyValue( PROPERTY_COMMAND, makeAny( ::rtl::OUString() ) );
        }
    }

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

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

        ::std::vector< PropertyId > aDependentProperties;

        switch ( nActuatingPropId )
        {
        // ----- EscapeProcessing -----
        case PROPERTY_ID_ESCAPE_PROCESSING:
            aDependentProperties.push_back( PROPERTY_ID_FILTER );
            aDependentProperties.push_back( PROPERTY_ID_SORT );
            break;  // case PROPERTY_ID_ESCAPE_PROCESSING

        // ----- CommandType -----
        case PROPERTY_ID_COMMANDTYPE:
            // available commands (tables or queries) might have changed
            if ( !_bFirstTimeInit && m_bHaveCommand )
                lcl_rebuildAndResetCommand( _rxInspectorUI, this );
            aDependentProperties.push_back( PROPERTY_ID_COMMAND );
            break;  // case PROPERTY_ID_COMMANDTYPE

        // ----- DataSourceName -----
        case PROPERTY_ID_DATASOURCE:
            // reset the connection, now that we have a new data source
            impl_clearRowsetConnection_nothrow();

            // available list source values (tables or queries) might have changed
            if ( !_bFirstTimeInit && m_bHaveListSource )
                _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );

            // available commands (tables or queries) might have changed
            if ( !_bFirstTimeInit && m_bHaveCommand )
                lcl_rebuildAndResetCommand( _rxInspectorUI, this );

            // Command also depends on DataSource
            aDependentProperties.push_back( PROPERTY_ID_COMMAND );
            // NO break!

        // ----- Command -----
        case PROPERTY_ID_COMMAND:
            aDependentProperties.push_back( PROPERTY_ID_FILTER );
            aDependentProperties.push_back( PROPERTY_ID_SORT );
            if ( m_bComponentIsSubForm )
                aDependentProperties.push_back( PROPERTY_ID_DETAILFIELDS );
            break;

        // ----- ListSourceType -----
        case PROPERTY_ID_LISTSOURCETYPE:
            if ( !_bFirstTimeInit && m_bHaveListSource )
                // available list source values (tables or queries) might have changed
                _rxInspectorUI->rebuildPropertyUI( PROPERTY_LISTSOURCE );
            aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
            aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
            // NO break!

        // ----- StringItemList -----
        case PROPERTY_ID_STRINGITEMLIST:
            aDependentProperties.push_back( PROPERTY_ID_SELECTEDITEMS );
            aDependentProperties.push_back( PROPERTY_ID_DEFAULT_SELECT_SEQ );
            break;

        // ----- ListSource -----
        case PROPERTY_ID_LISTSOURCE:
            aDependentProperties.push_back( PROPERTY_ID_STRINGITEMLIST );
            break;

        // ----- DataField -----
        case PROPERTY_ID_CONTROLSOURCE:
        {
            ::rtl::OUString sControlSource;
            _rNewValue >>= sControlSource;
            if ( impl_componentHasProperty_throw( PROPERTY_FILTERPROPOSAL ) )
                _rxInspectorUI->enablePropertyUI( PROPERTY_FILTERPROPOSAL, sControlSource.getLength() > 0 );
            if ( impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL ) )
                _rxInspectorUI->enablePropertyUI( PROPERTY_EMPTY_IS_NULL, sControlSource.getLength() > 0 );

            aDependentProperties.push_back( PROPERTY_ID_BOUNDCOLUMN );
            aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
            aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
            aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
        }
        break;

        case PROPERTY_ID_EMPTY_IS_NULL:
            aDependentProperties.push_back( PROPERTY_ID_INPUT_REQUIRED );
            break;

        // ----- SubmitEncoding -----
        case PROPERTY_ID_SUBMIT_ENCODING:
        {
            FormSubmitEncoding eEncoding = FormSubmitEncoding_URL;
            OSL_VERIFY( _rNewValue >>= eEncoding );
            _rxInspectorUI->enablePropertyUI( PROPERTY_SUBMIT_METHOD, eEncoding == FormSubmitEncoding_URL );
        }
        break;

        // ----- Repeat -----
        case PROPERTY_ID_REPEAT:
        {
            sal_Bool bIsRepeating = sal_False;
            OSL_VERIFY( _rNewValue >>= bIsRepeating );
            _rxInspectorUI->enablePropertyUI( PROPERTY_REPEAT_DELAY, bIsRepeating );
        }
        break;

        // ----- TabStop -----
        case PROPERTY_ID_TABSTOP:
        {
            if ( !impl_componentHasProperty_throw( PROPERTY_TABINDEX ) )
                break;
            sal_Bool bHasTabStop = sal_False;
            _rNewValue >>= bHasTabStop;
            _rxInspectorUI->enablePropertyUI( PROPERTY_TABINDEX, bHasTabStop );
        }
        break;

        // ----- Border -----
        case PROPERTY_ID_BORDER:
        {
            sal_Int16 nBordeType = VisualEffect::NONE;
            OSL_VERIFY( _rNewValue >>= nBordeType );
            _rxInspectorUI->enablePropertyUI( PROPERTY_BORDERCOLOR, nBordeType == VisualEffect::FLAT );
        }
        break;

        // ----- DropDown -----
        case PROPERTY_ID_DROPDOWN:
        {
            if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_LINECOUNT ) )
            {
                sal_Bool bDropDown = sal_True;
                _rNewValue >>= bDropDown;
                _rxInspectorUI->enablePropertyUI( PROPERTY_LINECOUNT, bDropDown );
            }
        }
        break;

        // ----- ImageURL -----
        case PROPERTY_ID_IMAGE_URL:
        {
            if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_IMAGEPOSITION ) )
            {
                ::rtl::OUString sImageURL;
                OSL_VERIFY( _rNewValue >>= sImageURL );
                _rxInspectorUI->enablePropertyUI( PROPERTY_IMAGEPOSITION, sImageURL.getLength() != 0 );
            }

            aDependentProperties.push_back( PROPERTY_ID_SCALEIMAGE );
            aDependentProperties.push_back( PROPERTY_ID_SCALE_MODE );
        }
        break;

        // ----- ButtonType -----
        case PROPERTY_ID_BUTTONTYPE:
        {
            FormButtonType eButtonType( FormButtonType_PUSH );
            OSL_VERIFY( _rNewValue >>= eButtonType );
            _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_URL, FormButtonType_URL == eButtonType );
        }
        // NO break!

        // ----- TargetURL -----
        case PROPERTY_ID_TARGET_URL:
            aDependentProperties.push_back( PROPERTY_ID_TARGET_FRAME );
            break;  // case PROPERTY_ID_TARGET_URL

        // ----- TriState -----
        case PROPERTY_ID_TRISTATE:
            if ( !_bFirstTimeInit )
                _rxInspectorUI->rebuildPropertyUI( m_eComponentClass == eFormControl ? PROPERTY_DEFAULT_STATE : PROPERTY_STATE );
            break;  // case PROPERTY_ID_TRISTATE

        // ----- DecimalAccuracy -----
        case PROPERTY_ID_DECIMAL_ACCURACY:
        // ----- ShowThousandsSeparator -----
        case PROPERTY_ID_SHOWTHOUSANDSEP:
        {
            sal_Bool bAccuracy = (PROPERTY_ID_DECIMAL_ACCURACY == nActuatingPropId);
            sal_uInt16  nNewDigits = 0;
            sal_Bool    bUseSep = sal_False;
            if ( bAccuracy )
                OSL_VERIFY( _rNewValue >>= nNewDigits );
            else
                OSL_VERIFY( _rNewValue >>= bUseSep );

            // propagate the changes to the min/max/default fields
            Any aCurrentProp;
            ::rtl::OUString aAffectedProps[] = { PROPERTY_VALUE, PROPERTY_DEFAULT_VALUE, PROPERTY_VALUEMIN, PROPERTY_VALUEMAX };
            for (sal_uInt16 i=0; i<sizeof(aAffectedProps)/sizeof(aAffectedProps[0]); ++i)
            {
                Reference< XPropertyControl > xControl;
                try
                {
                    xControl = _rxInspectorUI->getPropertyControl( aAffectedProps[i] );
                }
                catch( const UnknownPropertyException& e ) { (void)e; }
                if ( xControl.is() )
                {
                    OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
                    DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
                    if ( pControl )
                    {
                        if ( bAccuracy )
                            pControl->SetDecimalDigits( nNewDigits );
                        else
                            pControl->SetThousandsSep( bUseSep );
                    }
                }
            }
        }
        break;

        // ----- FormatKey -----
        case PROPERTY_ID_FORMATKEY:
        {
            FormatDescription aNewDesc;

            Reference< XNumberFormatsSupplier >  xSupplier;
            OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier );

            Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY );
            DBG_ASSERT(xTunnel.is(), "FormComponentPropertyHandler::actuatingPropertyChanged: xTunnel is invalid!");
            if ( xTunnel.is() )
            {
                SvNumberFormatsSupplierObj* pSupplier = reinterpret_cast<SvNumberFormatsSupplierObj*>(xTunnel->getSomething(SvNumberFormatsSupplierObj::getUnoTunnelId()));
                    // the same again

                aNewDesc.pSupplier = pSupplier;
                if ( !( _rNewValue >>= aNewDesc.nKey ) )
                    aNewDesc.nKey = 0;

                // give each control which has to know this an own copy of the description
                ::rtl::OUString aFormattedPropertyControls[] = {
                    PROPERTY_EFFECTIVE_MIN, PROPERTY_EFFECTIVE_MAX, PROPERTY_EFFECTIVE_DEFAULT, PROPERTY_EFFECTIVE_VALUE
                };
                for ( sal_uInt16 i=0; i<sizeof(aFormattedPropertyControls)/sizeof(aFormattedPropertyControls[0]); ++i )
                {
                    Reference< XPropertyControl > xControl;
                    try
                    {
                        xControl = _rxInspectorUI->getPropertyControl( aFormattedPropertyControls[i] );
                    }
                    catch( const UnknownPropertyException& e ) { (void)e; }
                    if ( xControl.is() )
                    {
                        OFormattedNumericControl* pControl = dynamic_cast< OFormattedNumericControl* >( xControl.get() );
                        DBG_ASSERT( pControl, "FormComponentPropertyHandler::actuatingPropertyChanged: invalid control!" );
                        if ( pControl )
                            pControl->SetFormatDescription( aNewDesc );
                    }
                }
            }
        }
        break;

        case PROPERTY_ID_TOGGLE:
        {
            sal_Bool bIsToggleButton = sal_False;
            OSL_VERIFY( _rNewValue >>= bIsToggleButton );
            _rxInspectorUI->enablePropertyUI( PROPERTY_DEFAULT_STATE, bIsToggleButton );
        }
        break;

        default:
            DBG_ERROR( "FormComponentPropertyHandler::actuatingPropertyChanged: did not register for this property!" );
            break;

        }   // switch ( nActuatingPropId )

        for ( ::std::vector< PropertyId >::const_iterator loopAffected = aDependentProperties.begin();
              loopAffected != aDependentProperties.end();
              ++loopAffected
            )
        {
            if ( impl_isSupportedProperty_nothrow( *loopAffected ) )
                impl_updateDependentProperty_nothrow( *loopAffected, _rxInspectorUI );
        }
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_updateDependentProperty_nothrow( PropertyId _nPropId, const Reference< XObjectInspectorUI >& _rxInspectorUI ) const
    {
        try
        {
            switch ( _nPropId )
            {
            // ----- StringItemList -----
            case PROPERTY_ID_STRINGITEMLIST:
            {
                ListSourceType eLSType = ListSourceType_VALUELIST;
                OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );

                ::rtl::OUString sListSource;
                {
                    Sequence< ::rtl::OUString > aListSource;
                    Any aListSourceValue( impl_getPropertyValue_throw( PROPERTY_LISTSOURCE ) );
                    if ( aListSourceValue >>= aListSource )
                    {
                        if ( aListSource.getLength() )
                            sListSource = aListSource[0];
                    }
                    else
                        OSL_VERIFY( aListSourceValue >>= sListSource );
                }

                sal_Bool bIsEnabled =   (  ( eLSType == ListSourceType_VALUELIST )
                                        || ( sListSource.getLength() == 0 )
                                        );
                _rxInspectorUI->enablePropertyUI( PROPERTY_STRINGITEMLIST, bIsEnabled );
            }
            break;  // case PROPERTY_ID_STRINGITEMLIST

            // ----- BoundColumn -----
            case PROPERTY_ID_BOUNDCOLUMN:
            {
                ::rtl::OUString sControlSource;
                OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );

                ListSourceType eLSType = ListSourceType_VALUELIST;
                OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType );

                _rxInspectorUI->enablePropertyUI( PROPERTY_BOUNDCOLUMN,
                        ( sControlSource.getLength() > 0 )
                    &&  ( eLSType != ListSourceType_TABLEFIELDS )
                    &&  ( eLSType != ListSourceType_VALUELIST )
                );
            }
            break;  // case PROPERTY_ID_BOUNDCOLUMN

            // ----- ScaleImage, ScaleMode -----
            case PROPERTY_ID_SCALEIMAGE:
            case PROPERTY_ID_SCALE_MODE:
            {
                ::rtl::OUString sControlSource;
                if ( impl_isSupportedProperty_nothrow( PROPERTY_ID_CONTROLSOURCE ) )
                    impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource;

                ::rtl::OUString sImageURL;
                impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sImageURL;

                _rxInspectorUI->enablePropertyUI( impl_getPropertyNameFromId_nothrow( _nPropId ),
                    ( sControlSource.getLength() != 0 ) || ( sImageURL.getLength() != 0 )
                );
            }
            break;  // case PROPERTY_ID_SCALEIMAGE, PROPERTY_ID_SCALE_MODE

            // ----- InputRequired -----
            case PROPERTY_ID_INPUT_REQUIRED:
            {
                ::rtl::OUString sControlSource;
                OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_CONTROLSOURCE ) >>= sControlSource );

                sal_Bool bEmptyIsNULL = sal_False;
                sal_Bool bHasEmptyIsNULL = impl_componentHasProperty_throw( PROPERTY_EMPTY_IS_NULL );
                if ( bHasEmptyIsNULL )
                    OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_EMPTY_IS_NULL ) >>= bEmptyIsNULL );

                // if the control is not bound to a DB field, there is no sense in having the "Input required"
                // property
                // Also, if an empty input of this control are *not* written as NULL, but as empty strings,
                // then "Input required" does not make sense, too (since there's always an input, even if the control
                // is empty).
                _rxInspectorUI->enablePropertyUI( PROPERTY_INPUT_REQUIRED,
                    ( sControlSource.getLength() != 0 ) && ( !bHasEmptyIsNULL || bEmptyIsNULL )
                );
            }
            break;

            // ----- SelectedItems, DefaultSelection -----
            case PROPERTY_ID_SELECTEDITEMS:
            case PROPERTY_ID_DEFAULT_SELECT_SEQ:
            {
                Sequence< ::rtl::OUString > aEntries;
                impl_getPropertyValue_throw( PROPERTY_STRINGITEMLIST ) >>= aEntries;
                bool isEnabled = aEntries.getLength() != 0;

                if ( ( m_nClassId == FormComponentType::LISTBOX ) && ( m_eComponentClass == eFormControl ) )
                {
                    ListSourceType eLSType = ListSourceType_VALUELIST;
                    impl_getPropertyValue_throw( PROPERTY_LISTSOURCETYPE ) >>= eLSType;
                    isEnabled &= ( eLSType == ListSourceType_VALUELIST );
                }
                _rxInspectorUI->enablePropertyUIElements( impl_getPropertyNameFromId_nothrow( _nPropId ),
                    PropertyLineElement::PrimaryButton, isEnabled );
            }
            break;  // case PROPERTY_ID_DEFAULT_SELECT_SEQ

            // ----- TargetFrame ------
            case PROPERTY_ID_TARGET_FRAME:
            {
                ::rtl::OUString sTargetURL;
                impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sTargetURL;
                FormButtonType eButtonType( FormButtonType_URL );
                if ( 0 != m_nClassId )
                {
                    OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_BUTTONTYPE ) >>= eButtonType );
                }
                // if m_nClassId is 0, then we're inspecting a form. In this case, eButtonType is always
                // FormButtonType_URL here
                _rxInspectorUI->enablePropertyUI( PROPERTY_TARGET_FRAME,
                    ( eButtonType == FormButtonType_URL ) && ( sTargetURL.getLength() > 0 )
                );
            }
            break;

            // ----- Order ------
            case PROPERTY_ID_SORT:
            // ----- Filter ------
            case PROPERTY_ID_FILTER:
            {
                Reference< XConnection > xConnection;
                bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );

                // if there's no escape processing, we cannot enter any values for this property
                sal_Bool  bDoEscapeProcessing( sal_False );
                impl_getPropertyValue_throw( PROPERTY_ESCAPE_PROCESSING ) >>= bDoEscapeProcessing;
                _rxInspectorUI->enablePropertyUI(
                    impl_getPropertyNameFromId_nothrow( _nPropId ),
                    bDoEscapeProcessing
                );

                // also care for the browse button - enabled if we have escape processing, and a valid
                // data source signature
                _rxInspectorUI->enablePropertyUIElements(
                    impl_getPropertyNameFromId_nothrow( _nPropId ),
                    PropertyLineElement::PrimaryButton,
                        impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
                    &&  bDoEscapeProcessing
                );
            }
            break;  // case PROPERTY_ID_FILTER:

            // ----- Command -----
            case PROPERTY_ID_COMMAND:
            {
                sal_Int32   nCommandType( CommandType::COMMAND );
                OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType );

                impl_ensureRowsetConnection_nothrow();
                Reference< XConnection > xConnection = m_xRowSetConnection.getTyped();
                bool bAllowEmptyDS = false;
                if ( !xConnection.is() )
                    bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );

                bool doEnable = ( nCommandType == CommandType::COMMAND )
                            &&  (  m_xRowSetConnection.is()
                                || xConnection.is()
								|| impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS)
                                );

                _rxInspectorUI->enablePropertyUIElements(
                    PROPERTY_COMMAND,
                    PropertyLineElement::PrimaryButton,
                    doEnable
                );
            }
            break;  // case PROPERTY_ID_COMMAND

            // ----- DetailFields -----
            case PROPERTY_ID_DETAILFIELDS:
            {
                Reference< XConnection > xConnection;
                bool bAllowEmptyDS = ::dbtools::isEmbeddedInDatabase( m_xComponent, xConnection );

                // both our current form, and it's parent form, need to have a valid
                // data source signature
                bool bDoEnableMasterDetailFields =
                        impl_hasValidDataSourceSignature_nothrow( m_xComponent, bAllowEmptyDS )
                    &&  impl_hasValidDataSourceSignature_nothrow( Reference< XPropertySet >( m_xObjectParent, UNO_QUERY ), bAllowEmptyDS );

                // in opposite to the other properties, here in real *two* properties are
                // affected
                _rxInspectorUI->enablePropertyUIElements( PROPERTY_DETAILFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
                _rxInspectorUI->enablePropertyUIElements( PROPERTY_MASTERFIELDS, PropertyLineElement::PrimaryButton, bDoEnableMasterDetailFields );
            }
            break;

            default:
                OSL_ENSURE( false, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: unexpected property to update!" );
                break;

            }   // switch
        }
        catch( const Exception& )
        {
        	OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_updateDependentProperty_nothrow: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    void SAL_CALL FormComponentPropertyHandler::disposing()
    {
        FormComponentPropertyHandler_Base::disposing();
        if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
            m_xCommandDesigner->dispose();
    }

    //------------------------------------------------------------------------
    sal_Bool SAL_CALL FormComponentPropertyHandler::suspend( sal_Bool _bSuspend ) throw (RuntimeException)
    {
        ::osl::MutexGuard aGuard( m_aMutex );
        if ( _bSuspend )
            if ( m_xCommandDesigner.is() && m_xCommandDesigner->isActive() )
                return m_xCommandDesigner->suspend();
        return sal_True;
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_initComponentMetaData_throw()
    {
        try
        {
            //////////////////////////////////////////////////////////////////
            // component class
            m_eComponentClass = eUnknown;

            if  (   impl_componentHasProperty_throw( PROPERTY_WIDTH )
                &&  impl_componentHasProperty_throw( PROPERTY_HEIGHT )
                &&  impl_componentHasProperty_throw( PROPERTY_POSITIONX )
                &&  impl_componentHasProperty_throw( PROPERTY_POSITIONY )
                &&  impl_componentHasProperty_throw( PROPERTY_STEP )
                &&  impl_componentHasProperty_throw( PROPERTY_TABINDEX )
                )
            {
                m_eComponentClass = eDialogControl;
            }
            else
            {
                m_eComponentClass = eFormControl;
            }

            //////////////////////////////////////////////////////////////////
            // (database) sub form?
            Reference< XForm > xAsForm( m_xComponent, UNO_QUERY );
            if ( xAsForm.is() )
            {
                Reference< XChild > xFormAsChild( xAsForm, UNO_QUERY );
                Reference< XForm > xFormsParent;
                if ( xFormAsChild.is() )
                    xFormsParent = xFormsParent.query( xFormAsChild->getParent() );
                m_bComponentIsSubForm = xFormsParent.is();
            }

            //////////////////////////////////////////////////////////////////
            // ClassId
            Reference< XChild > xCompAsChild( m_xComponent, UNO_QUERY );
            if ( xCompAsChild.is() )
                m_xObjectParent = xCompAsChild->getParent();

            //////////////////////////////////////////////////////////////////
            // ClassId
            impl_classifyControlModel_throw();
        }
        catch( const RuntimeException& )
        {
            throw;
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_initComponentMetaData_throw: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_classifyControlModel_throw( )
    {
        if ( impl_componentHasProperty_throw( PROPERTY_CLASSID ) )
        {
            OSL_VERIFY( m_xComponent->getPropertyValue( PROPERTY_CLASSID ) >>= m_nClassId );
        }
        else if ( eDialogControl == m_eComponentClass )
        {
            Reference< XControlModel > xControlModel( m_xComponent, UNO_QUERY );
            Reference< XServiceInfo > xServiceInfo( m_xComponent, UNO_QUERY );
            if ( xServiceInfo.is() )
            {
                // it's a control model, and can tell about it's supported services
                m_nClassId = FormComponentType::CONTROL;

                const sal_Char* aControlModelServiceNames[] =
                {
                    "UnoControlButtonModel",
                    "UnoControlCheckBoxModel",
                    "UnoControlComboBoxModel",
                    "UnoControlCurrencyFieldModel",
                    "UnoControlDateFieldModel",
                    "UnoControlEditModel",
                    "UnoControlFileControlModel",
                    "UnoControlFixedTextModel",
                    "UnoControlGroupBoxModel",
                    "UnoControlImageControlModel",
                    "UnoControlListBoxModel",
                    "UnoControlNumericFieldModel",
                    "UnoControlPatternFieldModel",
                    "UnoControlRadioButtonModel",
                    "UnoControlScrollBarModel",
                    "UnoControlSpinButtonModel",
                    "UnoControlTimeFieldModel",

                    "UnoControlFixedLineModel",
                    "UnoControlFormattedFieldModel",
                    "UnoControlProgressBarModel"
                };
                const sal_Int16 nClassIDs[] =
                {
                    FormComponentType::COMMANDBUTTON,
                    FormComponentType::CHECKBOX,
                    FormComponentType::COMBOBOX,
                    FormComponentType::CURRENCYFIELD,
                    FormComponentType::DATEFIELD,
                    FormComponentType::TEXTFIELD,
                    FormComponentType::FILECONTROL,
                    FormComponentType::FIXEDTEXT,
                    FormComponentType::GROUPBOX,
                    FormComponentType::IMAGECONTROL,
                    FormComponentType::LISTBOX,
                    FormComponentType::NUMERICFIELD,
                    FormComponentType::PATTERNFIELD,
                    FormComponentType::RADIOBUTTON,
                    FormComponentType::SCROLLBAR,
                    FormComponentType::SPINBUTTON,
                    FormComponentType::TIMEFIELD,

                    ControlType::FIXEDLINE,
                    ControlType::FORMATTEDFIELD,
                    ControlType::PROGRESSBAR
                };

                sal_Int32 nKnownControlTypes = sizeof( aControlModelServiceNames ) / sizeof( aControlModelServiceNames[ 0 ] );
                OSL_ENSURE( nKnownControlTypes == sizeof( nClassIDs ) / sizeof( nClassIDs[ 0 ] ),
                    "FormComponentPropertyHandler::impl_classifyControlModel_throw: inconsistence" );

                for ( sal_Int32 i = 0; i < nKnownControlTypes; ++i )
                {
                    ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt." ) );
                    sServiceName += ::rtl::OUString::createFromAscii( aControlModelServiceNames[ i ] );

                    if ( xServiceInfo->supportsService( sServiceName ) )
                    {
                        m_nClassId = nClassIDs[ i ];
                        break;
                    }
                }
            }
        }
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_normalizePropertyValue_nothrow( Any& _rValue, PropertyId _nPropId ) const
    {
        switch ( _nPropId )
        {
        case PROPERTY_ID_TABSTOP:
            if ( !_rValue.hasValue() )
            {
                switch ( m_nClassId )
                {
                case FormComponentType::COMMANDBUTTON:
                case FormComponentType::RADIOBUTTON:
                case FormComponentType::CHECKBOX:
                case FormComponentType::TEXTFIELD:
                case FormComponentType::LISTBOX:
                case FormComponentType::COMBOBOX:
                case FormComponentType::FILECONTROL:
                case FormComponentType::DATEFIELD:
                case FormComponentType::TIMEFIELD:
                case FormComponentType::NUMERICFIELD:
                case ControlType::FORMATTEDFIELD:
                case FormComponentType::CURRENCYFIELD:
                case FormComponentType::PATTERNFIELD:
                    _rValue = makeAny( (sal_Bool)sal_True );
                    break;
                default:
                    _rValue = makeAny( (sal_Bool)sal_False );
                    break;
                }
            }
            break;
        }
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow( const Property& _rProperty ) const
    {
        OSL_ENSURE( _rProperty.Handle == m_pInfoService->getPropertyId( _rProperty.Name ),
            "FormComponentPropertyHandler::impl_shouldExcludeProperty_nothrow: insonsistency in the property!" );

        if ( _rProperty.Handle == PROPERTY_ID_CONTROLLABEL )
            // prevent that this is caught below
            return false;

        if  (   ( _rProperty.Type.getTypeClass() == TypeClass_INTERFACE )
            ||  ( _rProperty.Type.getTypeClass() == TypeClass_ARRAY )
            ||  ( _rProperty.Type.getTypeClass() == TypeClass_UNKNOWN )
            )
            return true;

        if ( ( _rProperty.Attributes & PropertyAttribute::TRANSIENT ) && ( m_eComponentClass != eDialogControl ) )
            // strange enough, dialog controls declare a lot of their properties as transient
            return true;

        if ( _rProperty.Attributes & PropertyAttribute::READONLY )
            return true;

        switch ( _rProperty.Handle )
        {
        case PROPERTY_ID_MASTERFIELDS:
        case PROPERTY_ID_DETAILFIELDS:
            if ( !m_bComponentIsSubForm )
                // no master and detail fields for forms which are no sub forms
                return true;
            break;

        case PROPERTY_ID_DATASOURCE:
        {
            // don't show DataSource if the component is part of an embedded form document
            Reference< XConnection > xConn;
            if ( isEmbeddedInDatabase( m_xComponent, xConn ) )
                return true;
        }
        break;

        case PROPERTY_ID_TEXT:
            // don't show the "Text" property of formatted fields
            if ( ControlType::FORMATTEDFIELD == m_nClassId )
                return true;
            break;

        case PROPERTY_ID_FORMATKEY:
        case PROPERTY_ID_EFFECTIVE_MIN:
        case PROPERTY_ID_EFFECTIVE_MAX:
        case PROPERTY_ID_EFFECTIVE_DEFAULT:
        case PROPERTY_ID_EFFECTIVE_VALUE:
            // only if the set has a formats supplier, too
            if  ( !impl_componentHasProperty_throw( PROPERTY_FORMATSSUPPLIER ) )
                return true;
            // (form) date and time fields also have a formats supplier, but the format itself
            // is reflected in another property
            if  (   ( FormComponentType::DATEFIELD == m_nClassId )
                ||  ( FormComponentType::TIMEFIELD == m_nClassId )
                )
                return true;
            break;

        case PROPERTY_ID_SCALEIMAGE:
            if ( impl_componentHasProperty_throw( PROPERTY_SCALE_MODE ) )
                // ScaleImage is superseded by ScaleMode
                return true;
            break;

        case PROPERTY_ID_WRITING_MODE:
            if ( !SvtCTLOptions().IsCTLFontEnabled() )
                return true;
            break;
        }

        sal_uInt32 nPropertyUIFlags = m_pInfoService->getPropertyUIFlags( _rProperty.Handle );

        // don't show experimental properties unless allowed to do so
        if ( ( nPropertyUIFlags & PROP_FLAG_EXPERIMENTAL ) != 0 )
        {
            if ( true ) // TODO
                return true;
        }

        // no data properties if no Base is installed. #124939#
        // This fix is not intendend to appear on the main trunk. If you find it there,
        // please tell me! frank.schoenheit@sun.com
        if ( ( nPropertyUIFlags & PROP_FLAG_DATA_PROPERTY ) != 0 )
            if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SDATABASE ) )
                return true;

        return false;
    }

    //------------------------------------------------------------------------
    Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_throw( ) const
    {
        Reference< XRowSet > xRowSet = m_xRowSet;
        if ( !xRowSet.is() )
        {
            xRowSet.set( m_xComponent, UNO_QUERY );
            if ( !xRowSet.is() )
            {
                xRowSet = Reference< XRowSet >( m_xObjectParent, UNO_QUERY );
                if ( !xRowSet.is() )
                {
                    // are we inspecting a grid column?
                    if (Reference< XGridColumnFactory >( m_xObjectParent, UNO_QUERY) .is())
                    {   // yes
                        Reference< XChild > xParentAsChild( m_xObjectParent, UNO_QUERY );
                        if ( xParentAsChild.is() )
                            xRowSet = Reference< XRowSet >( xParentAsChild->getParent(), UNO_QUERY );
                    }
                }
                if ( !xRowSet.is() )
                    xRowSet = m_xRowSet;
            }
            DBG_ASSERT( xRowSet.is(), "FormComponentPropertyHandler::impl_getRowSet_throw: could not obtain the rowset for the introspectee!" );
        }
        return xRowSet;
    }

    //------------------------------------------------------------------------
    Reference< XRowSet > FormComponentPropertyHandler::impl_getRowSet_nothrow( ) const
    {
        Reference< XRowSet > xReturn;
        try
        {
            xReturn = impl_getRowSet_throw();
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_getRowSet_nothrow: caught an exception!" );
        }
        return xReturn;
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_initFieldList_nothrow( ::std::vector< ::rtl::OUString >& _rFieldNames ) const
    {
        clearContainer( _rFieldNames );
        try
        {
            WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );

            Reference< XPreparedStatement >  xStatement;

            // get the form of the control we're inspecting
            Reference< XPropertySet > xFormSet( impl_getRowSet_throw(), UNO_QUERY );
            if ( !xFormSet.is() )
                return;

            ::rtl::OUString sObjectName;
            OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMAND ) >>= sObjectName );
            // when there is no command we don't need to ask for columns
            if ( sObjectName.getLength() && impl_ensureRowsetConnection_nothrow() )
            {
                ::rtl::OUString aDatabaseName;
                OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_DATASOURCE ) >>= aDatabaseName );
                sal_Int32 nObjectType = CommandType::COMMAND;
                OSL_VERIFY( xFormSet->getPropertyValue( PROPERTY_COMMANDTYPE ) >>= nObjectType );

                Sequence< ::rtl::OUString > aFields( ::dbtools::getFieldNamesByCommandDescriptor( m_xRowSetConnection, nObjectType, sObjectName ) );

                const ::rtl::OUString* pFields = aFields.getConstArray();
                for ( sal_Int32 i = 0; i < aFields.getLength(); ++i, ++pFields )
                    _rFieldNames.push_back( *pFields );
            }
        }
        catch (Exception&)
        {
            DBG_ERROR( "FormComponentPropertyHandler::impl_initFieldList_nothrow: caught an exception!" );
        }
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_clearRowsetConnection_nothrow()
    {
        m_xRowSetConnection.clear();
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_displaySQLError_nothrow( const ::dbtools::SQLExceptionInfo& _rErrorDescriptor ) const
    {
        ::dbtools::showError( _rErrorDescriptor, VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ), m_aContext.getLegacyServiceFactory() );
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow() const
    {
        if ( !m_xRowSetConnection.is() )
        {
            uno::Reference<sdbc::XConnection> xConnection(m_aContext.getContextValueByAsciiName( "ActiveConnection" ),uno::UNO_QUERY);
            m_xRowSetConnection.reset(xConnection,::dbtools::SharedConnection::NoTakeOwnership);
        }
        if ( m_xRowSetConnection.is() )
            return true;

        Reference< XRowSet > xRowSet( impl_getRowSet_throw() );
        Reference< XPropertySet > xRowSetProps( xRowSet, UNO_QUERY );

        // connect the row set - this is delegated to elsewhere - while observing errors
        SQLExceptionInfo aError;
        try
        {
            if ( xRowSetProps.is() )
            {
                WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );
                m_xRowSetConnection = ::dbtools::ensureRowSetConnection( xRowSet, m_aContext.getLegacyServiceFactory(), false );
            }
        }
        catch ( const SQLException& ) { aError = SQLExceptionInfo( ::cppu::getCaughtException() ); }
        catch ( const WrappedTargetException& e ) { aError = SQLExceptionInfo( e.TargetException ); }
        catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }

        // report errors, if necessary
        if ( aError.isValid() )
        {
            ::rtl::OUString sDataSourceName;
            try
            {
                xRowSetProps->getPropertyValue( PROPERTY_DATASOURCE ) >>= sDataSourceName;
            }
            catch( const Exception& )
            {
                DBG_ERROR( "FormComponentPropertyHandler::impl_ensureRowsetConnection_nothrow: caught an exception during error handling!" );
            }
            // additional info about what happended
            String sInfo( PcrRes( RID_STR_UNABLETOCONNECT ) );
            INetURLObject aParser( sDataSourceName );
            if ( aParser.GetProtocol() != INET_PROT_NOT_VALID )
                sDataSourceName = aParser.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
            sInfo.SearchAndReplaceAllAscii( "$name$", sDataSourceName );

            SQLContext aContext;
            aContext.Message = sInfo;
            aContext.NextException = aError.get();
            impl_displaySQLError_nothrow( aContext );
        }

        return m_xRowSetConnection.is();
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_describeCursorSource_nothrow( LineDescriptor& _out_rProperty, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
    {
        try
        {
            WaitCursor aWaitCursor( impl_getDefaultDialogParent_nothrow() );

            ////////////////////////////////////////////////////////////
            // Setzen der UI-Daten
            _out_rProperty.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_COMMAND );

            _out_rProperty.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_COMMAND ) );
            _out_rProperty.PrimaryButtonId = rtl::OUString::createFromAscii(UID_PROP_DLG_SQLCOMMAND);

            ////////////////////////////////////////////////////////////
            sal_Int32 nCommandType = CommandType::COMMAND;
            impl_getPropertyValue_throw( PROPERTY_COMMANDTYPE ) >>= nCommandType;

            switch ( nCommandType )
            {
            case CommandType::TABLE:
            case CommandType::QUERY:
            {
                ::std::vector< ::rtl::OUString > aNames;
                if ( impl_ensureRowsetConnection_nothrow() )
                {
                    if ( nCommandType == CommandType::TABLE )
                        impl_fillTableNames_throw( aNames );
                    else
                        impl_fillQueryNames_throw( aNames );
                }
                _out_rProperty.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aNames, sal_False, sal_True );
            }
            break;

            default:
                _out_rProperty.Control = _rxControlFactory->createPropertyControl( PropertyControlType::MultiLineTextField, sal_False );
                break;
            }
        }
        catch (Exception&)
        {
            DBG_ERROR("FormComponentPropertyHandler::impl_describeCursorSource_nothrow: caught an exception !");
        }
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_fillTableNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
    {
        OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: need a connection!" );
        _out_rNames.resize( 0 );

        Reference< XTablesSupplier > xSupplyTables( m_xRowSetConnection, UNO_QUERY );
        Reference< XNameAccess > xTableNames;
        if ( xSupplyTables.is() )
            xTableNames = xSupplyTables->getTables();
        DBG_ASSERT( xTableNames.is(), "FormComponentPropertyHandler::impl_fillTableNames_throw: no way to obtain the tables of the connection!" );
        if ( !xTableNames.is() )
            return;

        Sequence< ::rtl::OUString> aTableNames = xTableNames->getElementNames();
        sal_uInt32 nCount = aTableNames.getLength();
        const ::rtl::OUString* pTableNames = aTableNames.getConstArray();

        for ( sal_uInt32 i=0; i<nCount; ++i ,++pTableNames )
            _out_rNames.push_back( *pTableNames );
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_fillQueryNames_throw( ::std::vector< ::rtl::OUString >& _out_rNames ) const
    {
        OSL_PRECOND( m_xRowSetConnection.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: need a connection!" );
        _out_rNames.resize( 0 );

        Reference< XQueriesSupplier > xSupplyQueries( m_xRowSetConnection, UNO_QUERY );
        Reference< XNameAccess > xQueryNames;
        if ( xSupplyQueries.is() )
        {
            xQueryNames = xSupplyQueries->getQueries();
            impl_fillQueryNames_throw(xQueryNames,_out_rNames);
        }
    }
    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_fillQueryNames_throw( const Reference< XNameAccess >& _xQueryNames,::std::vector< ::rtl::OUString >& _out_rNames,const ::rtl::OUString& _sName ) const
    {
        DBG_ASSERT( _xQueryNames.is(), "FormComponentPropertyHandler::impl_fillQueryNames_throw: no way to obtain the queries of the connection!" );
        if ( !_xQueryNames.is() )
            return;

        Sequence< ::rtl::OUString> aQueryNames = _xQueryNames->getElementNames();
        sal_uInt32 nCount = aQueryNames.getLength();
        const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray();
        sal_Bool bAdd = _sName.getLength();

        for ( sal_uInt32 i=0; i<nCount; i++, ++pQueryNames )
        {
            ::rtl::OUStringBuffer sTemp;
            if ( bAdd )
            {
                sTemp.append(_sName);
                sTemp.appendAscii("/");                
            }
            sTemp.append(*pQueryNames);
            Reference< XNameAccess > xSubQueries(_xQueryNames->getByName(*pQueryNames),UNO_QUERY);
            if ( xSubQueries.is() )
                impl_fillQueryNames_throw(xSubQueries,_out_rNames,sTemp.makeStringAndClear());
            else
                _out_rNames.push_back( sTemp.makeStringAndClear() );
        }
    }

    //------------------------------------------------------------------------
    void FormComponentPropertyHandler::impl_describeListSourceUI_throw( LineDescriptor& _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory ) const
    {
        OSL_PRECOND( m_xComponent.is(), "FormComponentPropertyHandler::impl_describeListSourceUI_throw: no component!" );

        ////////////////////////////////////////////////////////////
        // Auslesen des ListSourceTypes
        Any aListSourceType( m_xComponent->getPropertyValue( PROPERTY_LISTSOURCETYPE ) );

        sal_Int32 nListSourceType = ListSourceType_VALUELIST;
        ::cppu::enum2int( nListSourceType, aListSourceType );

        _out_rDescriptor.DisplayName = m_pInfoService->getPropertyTranslation( PROPERTY_ID_LISTSOURCE );
        _out_rDescriptor.HelpURL = HelpIdUrl::getHelpURL( m_pInfoService->getPropertyHelpId( PROPERTY_ID_LISTSOURCE ) );

        ////////////////////////////////////////////////////////////
        // Enums setzen
        switch( nListSourceType )
        {
        case ListSourceType_VALUELIST:
            _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( PropertyControlType::StringListField, sal_False );
            break;

        case ListSourceType_TABLEFIELDS:
        case ListSourceType_TABLE:
        case ListSourceType_QUERY:
        {
            ::std::vector< ::rtl::OUString > aListEntries;
            if ( impl_ensureRowsetConnection_nothrow() )
            {
                if ( nListSourceType == ListSourceType_QUERY )
                    impl_fillQueryNames_throw( aListEntries );
                else
                    impl_fillTableNames_throw( aListEntries );
            }
            _out_rDescriptor.Control = PropertyHandlerHelper::createComboBoxControl( _rxControlFactory, aListEntries, sal_False, sal_False );
        }
        break;
        case ListSourceType_SQL:
        case ListSourceType_SQLPASSTHROUGH:
            impl_ensureRowsetConnection_nothrow();
            _out_rDescriptor.HasPrimaryButton = m_xRowSetConnection.is();
            break;
        }
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogListSelection_nothrow( const ::rtl::OUString& _rProperty, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        OSL_PRECOND( m_pInfoService.get(), "FormComponentPropertyHandler::impl_dialogListSelection_nothrow: no property meta data!" );

        String sPropertyUIName( m_pInfoService->getPropertyTranslation( m_pInfoService->getPropertyId( _rProperty ) ) );
        ListSelectionDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, _rProperty, sPropertyUIName );
        _rClearBeforeDialog.clear();
        return ( RET_OK == aDialog.Execute() );
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow( bool _bFilter, ::rtl::OUString& _out_rSelectedClause, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        OSL_PRECOND( Reference< XRowSet >( m_xComponent, UNO_QUERY ).is(),
            "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: to be called for forms only!" );

        _out_rSelectedClause = ::rtl::OUString();
        bool bSuccess = false;
        SQLExceptionInfo aErrorInfo;
        try
        {
            if ( !impl_ensureRowsetConnection_nothrow() )
                return false;

            // get a composer for the statement which the form is currently based on
            Reference< XSingleSelectQueryComposer > xComposer( ::dbtools::getCurrentSettingsComposer( m_xComponent, m_aContext.getLegacyServiceFactory() ) );
            OSL_ENSURE( xComposer.is(), "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: could not obtain a composer!" );
            if ( !xComposer.is() )
                return false;

            ::rtl::OUString sPropertyUIName( m_pInfoService->getPropertyTranslation( _bFilter ? PROPERTY_ID_FILTER : PROPERTY_ID_SORT ) );

            const sal_Char* pAsciiServiceName = _bFilter ? "com.sun.star.sdb.FilterDialog" : "com.sun.star.sdb.OrderDialog";

            // create the dialog
            Reference< XExecutableDialog > xDialog;
            if ( !m_aContext.createComponent( pAsciiServiceName, xDialog ) )
            {
                ShowServiceNotAvailableError( impl_getDefaultDialogParent_nothrow(), ::rtl::OUString::createFromAscii( pAsciiServiceName ), sal_True );
                return false;
            }

            // initialize the dialog
            Reference< XPropertySet > xDialogProps( xDialog, UNO_QUERY_THROW );
            xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "QueryComposer" ) ), makeAny( xComposer ) );
            xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RowSet" ) ),        makeAny( m_xComponent ) );
            xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),  makeAny( VCLUnoHelper::GetInterface( impl_getDefaultDialogParent_nothrow() ) ) );
            xDialogProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ),         makeAny( sPropertyUIName ) );

            _rClearBeforeDialog.clear();
            bSuccess = ( xDialog->execute() != 0 );
            if ( bSuccess )
                _out_rSelectedClause = _bFilter ? xComposer->getFilter() : xComposer->getOrder();
        }
        catch (SQLContext& e) { aErrorInfo = e; }
        catch (SQLWarning& e) { aErrorInfo = e; }
        catch (SQLException& e) { aErrorInfo = e; }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFilterOrSort_nothrow: caught an exception!" );
        }

        if ( aErrorInfo.isValid() )
            impl_displaySQLError_nothrow( aErrorInfo );

        return bSuccess;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        Reference< XForm > xDetailForm( m_xComponent, UNO_QUERY );
        Reference< XForm > xMasterForm( m_xObjectParent, UNO_QUERY );
        uno::Reference<beans::XPropertySet> xMasterProp(m_xObjectParent,uno::UNO_QUERY);
        OSL_PRECOND( xDetailForm.is() && xMasterForm.is(), "FormComponentPropertyHandler::impl_dialogLinkedFormFields_nothrow: no forms!" );
        if ( !xDetailForm.is() || !xMasterForm.is() )
            return false;


        FormLinkDialog aDialog( impl_getDefaultDialogParent_nothrow(), m_xComponent, xMasterProp, m_aContext.getLegacyServiceFactory() );
        _rClearBeforeDialog.clear();
        return ( RET_OK == aDialog.Execute() );
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogFormatting_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        bool bChanged = false;
        try
        {
            // create the itemset for the dialog
            SfxItemSet aCoreSet(SFX_APP()->GetPool(),
                SID_ATTR_NUMBERFORMAT_VALUE, SID_ATTR_NUMBERFORMAT_VALUE,
                SID_ATTR_NUMBERFORMAT_INFO, SID_ATTR_NUMBERFORMAT_INFO,
                0);     // ripped this somewhere ... don't understand it :(

            // get the number formats supplier
            Reference< XNumberFormatsSupplier >  xSupplier;
            m_xComponent->getPropertyValue( PROPERTY_FORMATSSUPPLIER ) >>= xSupplier;

            DBG_ASSERT(xSupplier.is(), "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );
            Reference< XUnoTunnel > xTunnel( xSupplier, UNO_QUERY_THROW );
            SvNumberFormatsSupplierObj* pSupplier =
                reinterpret_cast< SvNumberFormatsSupplierObj* >( xTunnel->getSomething( SvNumberFormatsSupplierObj::getUnoTunnelId() ) );
            DBG_ASSERT( pSupplier != NULL, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: invalid call !" );

            sal_Int32 nFormatKey = 0;
            impl_getPropertyValue_throw( PROPERTY_FORMATKEY ) >>= nFormatKey;
            aCoreSet.Put( SfxUInt32Item( SID_ATTR_NUMBERFORMAT_VALUE, nFormatKey ) );

            SvNumberFormatter* pFormatter = pSupplier->GetNumberFormatter();
            double dPreviewVal = OFormatSampleControl::getPreviewValue(pFormatter,nFormatKey);
            SvxNumberInfoItem aFormatter( pFormatter, dPreviewVal, String( PcrRes( RID_STR_TEXT_FORMAT ) ), SID_ATTR_NUMBERFORMAT_INFO );
            aCoreSet.Put( aFormatter );

            // a tab dialog with a single page
            ::std::auto_ptr< SfxSingleTabDialog > pDialog( new SfxSingleTabDialog( impl_getDefaultDialogParent_nothrow(), aCoreSet, 0 ) );
            SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
            DBG_ASSERT( pFact, "CreateFactory fail!" );
            ::CreateTabPage fnCreatePage = pFact->GetTabPageCreatorFunc( RID_SVXPAGE_NUMBERFORMAT );
            if ( !fnCreatePage )
                throw RuntimeException();   // caught below

            SfxTabPage* pPage = (*fnCreatePage)( pDialog.get(), aCoreSet );
            pDialog->SetTabPage( pPage );

            _rClearBeforeDialog.clear();
            if ( RET_OK == pDialog->Execute() )
            {
                const SfxItemSet* pResult = pDialog->GetOutputItemSet();

                const SfxPoolItem* pItem = pResult->GetItem( SID_ATTR_NUMBERFORMAT_INFO );
                const SvxNumberInfoItem* pInfoItem = dynamic_cast< const SvxNumberInfoItem* >( pItem );
                if (pInfoItem && pInfoItem->GetDelCount())
                {
                    const sal_uInt32* pDeletedKeys = pInfoItem->GetDelArray();

                    for (sal_uInt16 i=0; i< pInfoItem->GetDelCount(); ++i, ++pDeletedKeys)
                        pFormatter->DeleteEntry(*pDeletedKeys);
                }

                pItem = NULL;
                if ( SFX_ITEM_SET == pResult->GetItemState( SID_ATTR_NUMBERFORMAT_VALUE, sal_False, &pItem ) )
                {
                    _out_rNewValue <<= (sal_Int32)( static_cast< const SfxUInt32Item* >( pItem )->GetValue() );
                    bChanged = true;
                }
            }
        }
        catch( const Exception& )
        {
            OSL_ENSURE( sal_False, "FormComponentPropertyHandler::impl_dialogFormatting_nothrow: : caught an exception!" );
        }
        return bChanged;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_browseForImage_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        bool bIsLink = true;// reflect the legacy behavior
        ::rtl::OUString aStrTrans = m_pInfoService->getPropertyTranslation( PROPERTY_ID_IMAGE_URL );

        ::sfx2::FileDialogHelper aFileDlg(SFXWB_GRAPHIC);

        aFileDlg.SetTitle(aStrTrans);
        // non-linked images ( e.g. those located in the document
        // stream ) cannot *currently* be handled by openoffice basic dialogs.
        bool bHandleNonLink = ( m_eComponentClass == eFormControl );

        Reference< XFilePickerControlAccess > xController(aFileDlg.GetFilePicker(), UNO_QUERY);
        DBG_ASSERT(xController.is(), "FormComponentPropertyHandler::impl_browseForImage_nothrow: missing the controller interface on the file picker!");
        if (xController.is())
        {
            // do a preview by default
            xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, ::cppu::bool2any(sal_True));

            xController->setValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, ::cppu::bool2any(bIsLink));
            xController->enableControl(ExtendedFilePickerElementIds::CHECKBOX_LINK, bHandleNonLink );

        }

        ::rtl::OUString sCurValue;
        OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_IMAGE_URL ) >>= sCurValue );
        if ( sCurValue.getLength() != 0 && sCurValue.compareToAscii(GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH(GRAPHOBJ_URLPREFIX) ) != 0 )
        {
            aFileDlg.SetDisplayDirectory( sCurValue );
            // TODO: need to set the display directory _and_ the default name
        }

        _rClearBeforeDialog.clear();
        bool bSuccess = ( 0 == aFileDlg.Execute() );
        if ( bSuccess )
        {
            if ( bHandleNonLink && xController.is() )
            {
                xController->getValue(ExtendedFilePickerElementIds::CHECKBOX_LINK, 0) >>= bIsLink;
            }
            if ( !bIsLink )
            {
                Graphic aGraphic;
                aFileDlg.GetGraphic( aGraphic );

                Reference< graphic::XGraphicObject > xGrfObj = graphic::GraphicObject::create( m_aContext.getUNOContext() );
                xGrfObj->setGraphic( aGraphic.GetXGraphic() );


                _out_rNewValue <<= xGrfObj;

            }
            else
                _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
        }
        return bSuccess;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_browseForTargetURL_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        ::sfx2::FileDialogHelper aFileDlg( WB_3DLOOK );

        ::rtl::OUString sURL;
        OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_TARGET_URL ) >>= sURL );
        INetURLObject aParser( sURL );
        if ( INET_PROT_FILE == aParser.GetProtocol() )
            // set the initial directory only for file-URLs. Everything else
            // is considered to be potentially expensive
            // 106126 - 2002/12/10 - fs@openoffice.org
            aFileDlg.SetDisplayDirectory( sURL );

        _rClearBeforeDialog.clear();
        bool bSuccess = ( 0 == aFileDlg.Execute() );
        if ( bSuccess )
            _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
        return bSuccess;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_executeFontDialog_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        bool bSuccess = false;

        // create an item set for use with the dialog
        SfxItemSet* pSet = NULL;
        SfxItemPool* pPool = NULL;
        SfxPoolItem** pDefaults = NULL;
        ControlCharacterDialog::createItemSet(pSet, pPool, pDefaults);
        ControlCharacterDialog::translatePropertiesToItems(m_xComponent, pSet);

        {   // do this in an own block. The dialog needs to be destroyed before we call
            // destroyItemSet
            ControlCharacterDialog aDlg( impl_getDefaultDialogParent_nothrow(), *pSet );
            _rClearBeforeDialog.clear();
            if ( RET_OK == aDlg.Execute() )
            {
                const SfxItemSet* pOut = aDlg.GetOutputItemSet();
                if ( pOut )
                {
                    Sequence< NamedValue > aFontPropertyValues;
                    ControlCharacterDialog::translateItemsToProperties( *pOut, aFontPropertyValues );
                    _out_rNewValue <<= aFontPropertyValues;
                    bSuccess = true;
                }
            }
        }

        ControlCharacterDialog::destroyItemSet(pSet, pPool, pDefaults);
        return bSuccess;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_browseForDatabaseDocument_throw( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        ::sfx2::FileDialogHelper aFileDlg(WB_3DLOOK|WB_OPEN,::String::CreateFromAscii("sdatabase"));

        ::rtl::OUString sDataSource;
        OSL_VERIFY( impl_getPropertyValue_throw( PROPERTY_DATASOURCE ) >>= sDataSource );
        INetURLObject aParser( sDataSource );
        if ( INET_PROT_FILE == aParser.GetProtocol() )
            // set the initial directory only for file-URLs. Everything else
            // is considered to be potentially expensive
            // 106126 - 2002/12/10 - fs@openoffice.org
            aFileDlg.SetDisplayDirectory( sDataSource );

        const String s_sDatabaseType = String::CreateFromAscii("StarOffice XML (Base)");
        const SfxFilter* pFilter = SfxFilter::GetFilterByName( s_sDatabaseType);
        OSL_ENSURE(pFilter,"Filter: StarOffice XML (Base) could not be found!");
        if ( pFilter )
        {
            aFileDlg.SetCurrentFilter(pFilter->GetUIName());
            //aFileDlg.AddFilter(pFilter->GetFilterName(),pFilter->GetDefaultExtension());
        }

        _rClearBeforeDialog.clear();
        bool bSuccess = ( 0 == aFileDlg.Execute() );
        if ( bSuccess )
            _out_rNewValue <<= (::rtl::OUString)aFileDlg.GetPath();
        return bSuccess;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogColorChooser_throw( sal_Int32 _nColorPropertyId, Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        sal_Int32 nColor = 0;
        OSL_VERIFY( impl_getPropertyValue_throw( impl_getPropertyNameFromId_nothrow( _nColorPropertyId ) ) >>= nColor );
        ::Color aColor( nColor );
        SvColorDialog aColorDlg( impl_getDefaultDialogParent_nothrow() );
        aColorDlg.SetColor( aColor );

        _rClearBeforeDialog.clear();
        if ( !aColorDlg.Execute() )
            return false;

        aColor = aColorDlg.GetColor();
        nColor = aColor.GetColor();
        _out_rNewValue <<= (sal_Int32)nColor;
        return true;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogChooseLabelControl_nothrow( Any& _out_rNewValue, ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        OSelectLabelDialog dlgSelectLabel( impl_getDefaultDialogParent_nothrow(), m_xComponent );
        _rClearBeforeDialog.clear();
        bool bSuccess = ( RET_OK == dlgSelectLabel.Execute() );
        if ( bSuccess )
            _out_rNewValue <<= dlgSelectLabel.GetSelected();
        return bSuccess;
    }

    //------------------------------------------------------------------------
    Reference< XControlContainer > FormComponentPropertyHandler::impl_getContextControlContainer_nothrow() const
    {
        Reference< XControlContainer > xControlContext(
            m_aContext.getContextValueByAsciiName( "ControlContext" ),
            UNO_QUERY );
        return xControlContext;
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow( ::osl::ClearableMutexGuard& _rClearBeforeDialog ) const
    {
        OSL_PRECOND( impl_getContextControlContainer_nothrow().is(), "FormComponentPropertyHandler::impl_dialogChangeTabOrder_nothrow: invalid control context!" );

        Reference< XTabControllerModel > xTabControllerModel( impl_getRowSet_nothrow(), UNO_QUERY );
        TabOrderDialog aDialog(
            impl_getDefaultDialogParent_nothrow(),
            xTabControllerModel,
            impl_getContextControlContainer_nothrow(),
            m_aContext.getLegacyServiceFactory()
        );
        _rClearBeforeDialog.clear();
        return ( RET_OK == aDialog.Execute() );
    }

    //------------------------------------------------------------------------
    namespace
    {
        //--------------------------------------------------------------------
        //- ISQLCommandPropertyUI
        //--------------------------------------------------------------------
        class ISQLCommandPropertyUI : public ISQLCommandAdapter
        {
        public:
            /** returns the empty-string-terminated list of names of properties
                whose UI is to be disabled while the SQL command property is
                being edited.
            */
            virtual ::rtl::OUString*    getPropertiesToDisable() = 0;
        };

        //--------------------------------------------------------------------
        //- SQLCommandPropertyUI
        //--------------------------------------------------------------------
        class SQLCommandPropertyUI : public ISQLCommandPropertyUI
        {
        protected:
            SQLCommandPropertyUI( const Reference< XPropertySet >& _rxObject )
                :m_xObject( _rxObject )
            {
                if ( !m_xObject.is() )
                    throw NullPointerException();
            }

            virtual oslInterlockedCount SAL_CALL acquire()
            {
                return osl_incrementInterlockedCount( &m_refCount );
            }

            virtual oslInterlockedCount SAL_CALL release()
            {
                if ( 0 == osl_decrementInterlockedCount( &m_refCount ) )
                {
                    delete this;
                    return 0;
                }
                return m_refCount;
            }

        protected:
            Reference< XPropertySet >   m_xObject;

        private:
            oslInterlockedCount         m_refCount;
        };

        //--------------------------------------------------------------------
        //- FormSQLCommandUI - declaration
        //--------------------------------------------------------------------
        class FormSQLCommandUI : public SQLCommandPropertyUI
        {
        public:
            FormSQLCommandUI( const Reference< XPropertySet >& _rxForm );

            // ISQLCommandAdapter
            virtual ::rtl::OUString getSQLCommand() const;
            virtual sal_Bool        getEscapeProcessing() const;
            virtual void            setSQLCommand( const ::rtl::OUString& _rCommand ) const;
            virtual void            setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;

            // ISQLCommandPropertyUI
            virtual ::rtl::OUString*    getPropertiesToDisable();
        };

        //--------------------------------------------------------------------
        //- FormSQLCommandUI - implementation
        //--------------------------------------------------------------------
        //....................................................................
        FormSQLCommandUI::FormSQLCommandUI( const Reference< XPropertySet >& _rxForm )
            :SQLCommandPropertyUI( _rxForm )
        {
        }

        //....................................................................
        ::rtl::OUString FormSQLCommandUI::getSQLCommand() const
        {
            ::rtl::OUString sCommand;
            OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_COMMAND ) >>= sCommand );
            return sCommand;
        }

        //....................................................................
        sal_Bool FormSQLCommandUI::getEscapeProcessing() const
        {
            sal_Bool bEscapeProcessing( sal_False );
            OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_ESCAPE_PROCESSING ) >>= bEscapeProcessing );
            return bEscapeProcessing;
        }

        //....................................................................
        void FormSQLCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
        {
            m_xObject->setPropertyValue( PROPERTY_COMMAND, makeAny( _rCommand ) );
        }

        //....................................................................
        void FormSQLCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
        {
            m_xObject->setPropertyValue( PROPERTY_ESCAPE_PROCESSING, makeAny( _bEscapeProcessing ) );
        }

        //....................................................................
        ::rtl::OUString* FormSQLCommandUI::getPropertiesToDisable()
        {
            static ::rtl::OUString s_aCommandProps[] = {
                PROPERTY_DATASOURCE,
                PROPERTY_COMMAND,
                PROPERTY_COMMANDTYPE,
                PROPERTY_ESCAPE_PROCESSING,
                ::rtl::OUString()
            };
            return s_aCommandProps;
        }
        //--------------------------------------------------------------------
        //- ValueListCommandUI - declaration
        //--------------------------------------------------------------------
        class ValueListCommandUI : public SQLCommandPropertyUI
        {
        public:
            ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo );

            // ISQLCommandAdapter
            virtual ::rtl::OUString getSQLCommand() const;
            virtual sal_Bool        getEscapeProcessing() const;
            virtual void            setSQLCommand( const ::rtl::OUString& _rCommand ) const;
            virtual void            setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const;

            // ISQLCommandPropertyUI
            virtual ::rtl::OUString*    getPropertiesToDisable();
        private:
            mutable bool    m_bPropertyValueIsList;
        };

        //--------------------------------------------------------------------
        //- ValueListCommandUI - implementation
        //--------------------------------------------------------------------
        //....................................................................
        ValueListCommandUI::ValueListCommandUI( const Reference< XPropertySet >& _rxListOrCombo )
            :SQLCommandPropertyUI( _rxListOrCombo )
            ,m_bPropertyValueIsList( false )
        {
        }

        //....................................................................
        ::rtl::OUString ValueListCommandUI::getSQLCommand() const
        {
            ::rtl::OUString sValue;
            m_bPropertyValueIsList = false;

            // for combo boxes, the property is a mere string
            Any aValue( m_xObject->getPropertyValue( PROPERTY_LISTSOURCE ) );
            if ( aValue >>= sValue )
                return sValue;

            Sequence< ::rtl::OUString > aValueList;
            if ( aValue >>= aValueList )
            {
                m_bPropertyValueIsList = true;
                if ( aValueList.getLength() )
                    sValue = aValueList[0];
                return sValue;
            }

            OSL_ENSURE( false, "ValueListCommandUI::getSQLCommand: unexpected property type!" );
            return sValue;
        }

        //....................................................................
        sal_Bool ValueListCommandUI::getEscapeProcessing() const
        {
            enum ListSourceType eType( ListSourceType_SQL );
            OSL_VERIFY( m_xObject->getPropertyValue( PROPERTY_LISTSOURCETYPE ) >>= eType );
            OSL_ENSURE( ( eType == ListSourceType_SQL ) || ( eType == ListSourceType_SQLPASSTHROUGH ),
                "ValueListCommandUI::getEscapeProcessing: unexpected list source type!" );
            return ( eType == ListSourceType_SQL );
        }

        //....................................................................
        void ValueListCommandUI::setSQLCommand( const ::rtl::OUString& _rCommand ) const
        {
            Any aValue;
            if ( m_bPropertyValueIsList )
                aValue <<= Sequence< ::rtl::OUString >( &_rCommand, 1 );
            else
                aValue <<= _rCommand;
            m_xObject->setPropertyValue( PROPERTY_LISTSOURCE, aValue );
        }

        //....................................................................
        void ValueListCommandUI::setEscapeProcessing( const sal_Bool _bEscapeProcessing ) const
        {
            m_xObject->setPropertyValue( PROPERTY_LISTSOURCETYPE, makeAny(
                _bEscapeProcessing ? ListSourceType_SQL : ListSourceType_SQLPASSTHROUGH ) );
        }

        //....................................................................
        ::rtl::OUString* ValueListCommandUI::getPropertiesToDisable()
        {
            static ::rtl::OUString s_aListSourceProps[] = {
                PROPERTY_LISTSOURCETYPE,
                PROPERTY_LISTSOURCE,
                ::rtl::OUString()
            };
            return s_aListSourceProps;
        }
    }

    //------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_doDesignSQLCommand_nothrow( const Reference< XObjectInspectorUI >& _rxInspectorUI, PropertyId _nDesignForProperty )
    {
        try
        {
            if ( m_xCommandDesigner.is() )
            {
                if ( m_xCommandDesigner->isActive() )
                {
                    m_xCommandDesigner->raise();
                    return true;
                }
                m_xCommandDesigner->dispose();
                m_xCommandDesigner.set( NULL );
            }

            if ( !impl_ensureRowsetConnection_nothrow() )
                return false;

            Reference< XPropertySet > xComponentProperties( m_xComponent, UNO_QUERY_THROW );

            ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI;
            switch ( _nDesignForProperty )
            {
            case PROPERTY_ID_COMMAND:
                xCommandUI = new FormSQLCommandUI( xComponentProperties );
                break;
            case PROPERTY_ID_LISTSOURCE:
                xCommandUI = new ValueListCommandUI( xComponentProperties );
                break;
            default:
                OSL_ENSURE( false, "FormComponentPropertyHandler::OnDesignerClosed: invalid property id!" );
                return false;
            }

            m_xCommandDesigner.set( new SQLCommandDesigner( m_aContext.getUNOContext(), xCommandUI.get(), m_xRowSetConnection, LINK( this, FormComponentPropertyHandler, OnDesignerClosed ) ) );

            DBG_ASSERT( _rxInspectorUI.is(), "FormComponentPropertyHandler::OnDesignerClosed: no access to the property browser ui!" );
            if ( m_xCommandDesigner->isActive() && _rxInspectorUI.is() )
            {
                m_xBrowserUI = _rxInspectorUI;
                // disable everything which would affect this property
                const ::rtl::OUString* pToDisable = xCommandUI->getPropertiesToDisable();
                while ( pToDisable->getLength() )
                {
                    m_xBrowserUI->enablePropertyUIElements( *pToDisable++, PropertyLineElement::All, sal_False );
                }

                // but enable the browse button for the property itself - so it can be used to raise the query designer
                ::rtl::OUString sPropertyName( impl_getPropertyNameFromId_nothrow( _nDesignForProperty ) );
                m_xBrowserUI->enablePropertyUIElements( sPropertyName, PropertyLineElement::PrimaryButton, sal_True );
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return m_xCommandDesigner.is();
    }

    //------------------------------------------------------------------------
    IMPL_LINK( FormComponentPropertyHandler, OnDesignerClosed, void*, /*NOTINTERESTEDIN*/ )
    {
        OSL_ENSURE( m_xBrowserUI.is() && m_xCommandDesigner.is(), "FormComponentPropertyHandler::OnDesignerClosed: too many NULLs!" );
        if ( m_xBrowserUI.is() && m_xCommandDesigner.is() )
        {
            try
            {
                ::rtl::Reference< ISQLCommandPropertyUI > xCommandUI(
                    dynamic_cast< ISQLCommandPropertyUI* >( m_xCommandDesigner->getPropertyAdapter().get() ) );
                if ( !xCommandUI.is() )
                    throw NullPointerException();

                const ::rtl::OUString* pToEnable = xCommandUI->getPropertiesToDisable();
                while ( pToEnable->getLength() )
                {
                    m_xBrowserUI->enablePropertyUIElements( *pToEnable++, PropertyLineElement::All, sal_True );
                }
            }
            catch( const Exception& )
            {
            	DBG_UNHANDLED_EXCEPTION();
            }
        }

        return 0L;
    }

	//------------------------------------------------------------------------
    bool FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow( const Reference< XPropertySet >& _xFormProperties, bool _bAllowEmptyDataSourceName ) SAL_THROW(())
    {
        bool bHas = false;
        if ( _xFormProperties.is() )
        {
            try
            {
                ::rtl::OUString sPropertyValue;
                // first, we need the name of an existent data source
                if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATASOURCE) )
                    _xFormProperties->getPropertyValue( PROPERTY_DATASOURCE ) >>= sPropertyValue;
                bHas = ( sPropertyValue.getLength() != 0 ) || _bAllowEmptyDataSourceName;

                // then, the command should not be empty
                if ( bHas )
                {
                    if ( _xFormProperties->getPropertySetInfo()->hasPropertyByName(PROPERTY_COMMAND) )
                        _xFormProperties->getPropertyValue( PROPERTY_COMMAND ) >>= sPropertyValue;
                    bHas = ( sPropertyValue.getLength() != 0 );
                }
            }
            catch( const Exception& )
            {
                OSL_ENSURE( false, "FormComponentPropertyHandler::impl_hasValidDataSourceSignature_nothrow: caught an exception!" );
            }
        }
        return bHas;
    }
    //------------------------------------------------------------------------
    ::rtl::OUString FormComponentPropertyHandler::impl_getDocumentURL_nothrow() const
    {
        ::rtl::OUString sURL;
        try
        {
            Reference< XModel > xDocument( impl_getContextDocument_nothrow() );
            if ( xDocument.is() )
                sURL = xDocument->getURL();
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
        return sURL;
    }
    // -------------------------------------------------------------------------
    ::cppu::IPropertyArrayHelper* FormComponentPropertyHandler::createArrayHelper( ) const
    {
        uno::Sequence< beans::Property > aProps;
	    describeProperties(aProps);
	    return new ::cppu::OPropertyArrayHelper(aProps);

    }
    // -------------------------------------------------------------------------
    ::cppu::IPropertyArrayHelper & FormComponentPropertyHandler::getInfoHelper()
    {
	    return *const_cast<FormComponentPropertyHandler*>(this)->getArrayHelper();
    }
    // -----------------------------------------------------------------------------
    uno::Reference< beans::XPropertySetInfo > SAL_CALL FormComponentPropertyHandler::getPropertySetInfo(  ) throw(uno::RuntimeException)
    {
	    return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
    }

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

