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

#include "ComboBox.hxx"
#include "property.hxx"
#include "property.hrc"
#include "services.hxx"

#include "frm_resource.hxx"
#include "frm_resource.hrc"
#include "BaseListBox.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/sdb/SQLErrorEvent.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
#include <com/sun/star/sdb/XQueriesSupplier.hpp>
#include <com/sun/star/util/NumberFormat.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdb/CommandType.hpp>
/** === end UNO includes === **/

#include <comphelper/numbers.hxx>
#include <comphelper/basicio.hxx>
#include <connectivity/dbtools.hxx>
#include <connectivity/dbconversion.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <rtl/ustrbuf.hxx>
#include <tools/debug.hxx>
#include <tools/diagnose_ex.h>
#include <unotools/sharedunocomponent.hxx>

#include <limits.h>

using namespace dbtools;

//.........................................................................
namespace frm
{
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdbcx;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::form::binding;

//========================================================================
// class OComboBoxModel
//========================================================================
//------------------------------------------------------------------
InterfaceRef SAL_CALL OComboBoxModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
{
	return (*new OComboBoxModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OComboBoxModel::_getTypes()
{
	return ::comphelper::concatSequences(
		OBoundControlModel::_getTypes(),
        OEntryListHelper::getTypes(),
		OErrorBroadcaster::getTypes()
	);
}

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OComboBoxModel::getSupportedServiceNames() throw(RuntimeException)
{
	StringSequence aSupported = OBoundControlModel::getSupportedServiceNames();

    sal_Int32 nOldLen = aSupported.getLength();
	aSupported.realloc( nOldLen + 8 );
	::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen;

    *pStoreTo++ = BINDABLE_CONTROL_MODEL;
    *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
    *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;

    *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL;
    *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL;

    *pStoreTo++ = FRM_SUN_COMPONENT_COMBOBOX;
    *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_COMBOBOX;
    *pStoreTo++ = BINDABLE_DATABASE_COMBO_BOX;

	return aSupported;
}

//------------------------------------------------------------------------------
Any SAL_CALL OComboBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException)
{
	Any aReturn = OBoundControlModel::queryAggregation( _rType );
    if ( !aReturn.hasValue() )
        aReturn = OEntryListHelper::queryInterface( _rType );
    if ( !aReturn.hasValue() )
        aReturn = OErrorBroadcaster::queryInterface( _rType );
    return aReturn;
}

//------------------------------------------------------------------
DBG_NAME( OComboBoxModel )
//------------------------------------------------------------------
OComboBoxModel::OComboBoxModel(const Reference<XMultiServiceFactory>& _rxFactory)
	:OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_COMBOBOX, FRM_SUN_CONTROL_COMBOBOX, sal_True, sal_True, sal_True )
					// use the old control name for compytibility reasons
    ,OEntryListHelper( (OControlModel&)*this )
	,OErrorBroadcaster( OComponentHelper::rBHelper )
    ,m_aListRowSet( getContext() )
	,m_eListSourceType(ListSourceType_TABLE)
	,m_bEmptyIsNull(sal_True)
{
	DBG_CTOR( OComboBoxModel, NULL );

	m_nClassId = FormComponentType::COMBOBOX;
    initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT );
}

//------------------------------------------------------------------
OComboBoxModel::OComboBoxModel( const OComboBoxModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
	:OBoundControlModel( _pOriginal, _rxFactory )
    ,OEntryListHelper( *_pOriginal, (OControlModel&)*this )
	,OErrorBroadcaster( OComponentHelper::rBHelper )
    ,m_aListRowSet( getContext() )
	,m_aListSource( _pOriginal->m_aListSource )
	,m_aDefaultText( _pOriginal->m_aDefaultText )
	,m_eListSourceType( _pOriginal->m_eListSourceType )
	,m_bEmptyIsNull( _pOriginal->m_bEmptyIsNull )
{
	DBG_CTOR( OComboBoxModel, NULL );
}

//------------------------------------------------------------------
OComboBoxModel::~OComboBoxModel()
{
	if (!OComponentHelper::rBHelper.bDisposed)
	{
		acquire();
		dispose();
	}

	DBG_DTOR( OComboBoxModel, NULL );
}

// XCloneable
//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OComboBoxModel )

//------------------------------------------------------------------------------
void OComboBoxModel::disposing()
{
	OBoundControlModel::disposing();
    OEntryListHelper::disposing();
	OErrorBroadcaster::disposing();
	m_xFormatter = NULL;
}

//------------------------------------------------------------------------------
void OComboBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
{
	switch (_nHandle)
	{
        case PROPERTY_ID_LISTSOURCETYPE:
            _rValue <<= m_eListSourceType;
            break;

		case PROPERTY_ID_LISTSOURCE:
            _rValue <<= m_aListSource;
            break;

        case PROPERTY_ID_EMPTY_IS_NULL:
            _rValue <<= m_bEmptyIsNull;
            break;

        case PROPERTY_ID_DEFAULT_TEXT:
            _rValue <<= m_aDefaultText;
            break;

        case PROPERTY_ID_STRINGITEMLIST:
            _rValue <<= getStringItemList();
            break;

		default:
			OBoundControlModel::getFastPropertyValue(_rValue, _nHandle);
	}
}

//------------------------------------------------------------------------------
void OComboBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
						throw (Exception)
{
	switch (_nHandle)
	{
		case PROPERTY_ID_LISTSOURCETYPE :
			DBG_ASSERT(_rValue.getValueType().equals(::getCppuType(reinterpret_cast<ListSourceType*>(NULL))),
				"OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
			_rValue >>= m_eListSourceType;
			break;

		case PROPERTY_ID_LISTSOURCE :
			DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING,
				"OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
			_rValue >>= m_aListSource;
			// die ListSource hat sich geaendert -> neu laden
			if (ListSourceType_VALUELIST != m_eListSourceType)
			{
				if ( m_xCursor.is() && !hasField() && !hasExternalListSource() )
                    // combo box is already connected to a database, and no external list source
				    // data source changed -> refresh
                    loadData( false );
			}
			break;

		case PROPERTY_ID_EMPTY_IS_NULL :
			DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN,
				"OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
			_rValue >>= m_bEmptyIsNull;
			break;

		case PROPERTY_ID_DEFAULT_TEXT :
			DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING,
				"OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
			_rValue >>= m_aDefaultText;
			resetNoBroadcast();
			break;

        case PROPERTY_ID_STRINGITEMLIST:
        {
            ControlModelLock aLock( *this );
            setNewStringItemList( _rValue, aLock );
                // TODO: this is bogus. setNewStringItemList expects a guard which has the *only*
                // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with
                // a lock - so we effectively has two locks here, of which setNewStringItemList can
                // only control one.
        }
        break;

		default:
			OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue);
	}
}

//------------------------------------------------------------------------------
sal_Bool OComboBoxModel::convertFastPropertyValue(
						Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
						throw (IllegalArgumentException)
{
	sal_Bool bModified(sal_False);
	switch (_nHandle)
	{
		case PROPERTY_ID_LISTSOURCETYPE :
			bModified = tryPropertyValueEnum(_rConvertedValue, _rOldValue, _rValue, m_eListSourceType);
			break;

		case PROPERTY_ID_LISTSOURCE :
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aListSource);
			break;

		case PROPERTY_ID_EMPTY_IS_NULL :
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bEmptyIsNull);
			break;

		case PROPERTY_ID_DEFAULT_TEXT :
			bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aDefaultText);
			break;

        case PROPERTY_ID_STRINGITEMLIST:
            bModified = convertNewListSourceProperty( _rConvertedValue, _rOldValue, _rValue );
            break;

		default:
			bModified = OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
			break;
	}
	return bModified;
}

//------------------------------------------------------------------------------
void OComboBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
	BEGIN_DESCRIBE_PROPERTIES( 6, OBoundControlModel )
		DECL_PROP1(TABINDEX,			sal_Int16,					BOUND);
		DECL_PROP1(LISTSOURCETYPE,		ListSourceType, BOUND);
		DECL_PROP1(LISTSOURCE,			::rtl::OUString,			BOUND);
		DECL_BOOL_PROP1(EMPTY_IS_NULL,								BOUND);
		DECL_PROP1(DEFAULT_TEXT,		::rtl::OUString,			BOUND);
        DECL_PROP1(STRINGITEMLIST,      Sequence< ::rtl::OUString >,BOUND);
	END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
void OComboBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
{
    OBoundControlModel::describeAggregateProperties( _rAggregateProps );

    // superseded properties:
    RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
}

//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OComboBoxModel::getServiceName() throw(RuntimeException)
{
	return FRM_COMPONENT_COMBOBOX;	// old (non-sun) name for compatibility !
}

//------------------------------------------------------------------------------
void SAL_CALL OComboBoxModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream)
		throw(stario::IOException, RuntimeException)
{
	OBoundControlModel::write(_rxOutStream);

	// Version
	// Version 0x0002:	EmptyIsNull
	// Version 0x0003:	ListSource->Seq
	// Version 0x0004:	DefaultText
	// Version 0x0005:	HelpText
	_rxOutStream->writeShort(0x0006);

	// Maskierung fuer any
	sal_uInt16 nAnyMask = 0;
	if (m_aBoundColumn.getValueType().getTypeClass() == TypeClass_SHORT)
		nAnyMask |= BOUNDCOLUMN;
	_rxOutStream << nAnyMask;

	StringSequence aListSourceSeq(&m_aListSource, 1);
	_rxOutStream << aListSourceSeq;
	_rxOutStream << (sal_Int16)m_eListSourceType;

	if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
	{
		sal_Int16 nBoundColumn = 0;
		m_aBoundColumn >>= nBoundColumn;
		_rxOutStream << nBoundColumn;
	}

	_rxOutStream << (sal_Bool)m_bEmptyIsNull;
	_rxOutStream << m_aDefaultText;
	writeHelpTextCompatibly(_rxOutStream);

	// from version 0x0006 : common properties
	writeCommonProperties(_rxOutStream);
}

//------------------------------------------------------------------------------
void SAL_CALL OComboBoxModel::read(const Reference<stario::XObjectInputStream>& _rxInStream) throw(stario::IOException, RuntimeException)
{
	OBoundControlModel::read(_rxInStream);
	ControlModelLock aLock( *this );

    // since we are "overwriting" the StringItemList of our aggregate (means we have
    // an own place to store the value, instead of relying on our aggregate storing it),
    // we need to respect what the aggregate just read for the StringItemList property.
    try
    {
        if ( m_xAggregateSet.is() )
            setNewStringItemList( m_xAggregateSet->getPropertyValue( PROPERTY_STRINGITEMLIST ), aLock );
    }
    catch( const Exception& )
    {
    	OSL_ENSURE( sal_False, "OComboBoxModel::read: caught an exception while examining the aggregate's string item list!" );
    }

	// Version
	sal_uInt16 nVersion = _rxInStream->readShort();
	DBG_ASSERT(nVersion > 0, "OComboBoxModel::read : version 0 ? this should never have been written !");

	if (nVersion > 0x0006)
	{
		DBG_ERROR("OComboBoxModel::read : invalid (means unknown) version !");
		m_aListSource = ::rtl::OUString();
		m_aBoundColumn <<= (sal_Int16)0;
		m_aDefaultText = ::rtl::OUString();
		m_eListSourceType = ListSourceType_TABLE;
		m_bEmptyIsNull = sal_True;
		defaultCommonProperties();
		return;
	}

	// Maskierung fuer any
	sal_uInt16 nAnyMask;
	_rxInStream >> nAnyMask;

	// ListSource
	if (nVersion < 0x0003)
	{
		::rtl::OUString sListSource;
		_rxInStream >> m_aListSource;
	}
	else // nVersion == 4
	{
		m_aListSource = ::rtl::OUString();
		StringSequence aListSource;
		_rxInStream >> aListSource;
		const ::rtl::OUString* pToken = aListSource.getConstArray();
		sal_Int32 nLen = aListSource.getLength();
		for (sal_Int32 i = 0; i < nLen; ++i, ++pToken)
			m_aListSource += *pToken;
	}

	sal_Int16 nListSourceType;
	_rxInStream >> nListSourceType;
	m_eListSourceType = (ListSourceType)nListSourceType;

	if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
	{
		sal_Int16 nValue;
		_rxInStream >> nValue;
		m_aBoundColumn <<= nValue;
	}

	if (nVersion > 0x0001)
	{
		sal_Bool bNull;
		_rxInStream >> bNull;
		m_bEmptyIsNull = bNull;
	}

	if (nVersion > 0x0003)	// nVersion == 4
		_rxInStream >> m_aDefaultText;

    // Stringliste muss geleert werden, wenn eine Listenquelle gesetzt ist
	// dieses kann der Fall sein wenn im alive modus gespeichert wird
	if  (   m_aListSource.getLength()
        &&  !hasExternalListSource()
        )
	{
    	setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) );
	}

	if (nVersion > 0x0004)
		readHelpTextCompatibly(_rxInStream);

	if (nVersion > 0x0005)
		readCommonProperties(_rxInStream);

	// Nach dem Lesen die Defaultwerte anzeigen
	if ( getControlSource().getLength() )
	{
		// (not if we don't have a control source - the "State" property acts like it is persistent, then
		resetNoBroadcast();
	}
}

//------------------------------------------------------------------------------
void OComboBoxModel::loadData( bool _bForce )
{
	DBG_ASSERT(m_eListSourceType != ListSourceType_VALUELIST, "OComboBoxModel::loadData : do not call for a value list !");
    DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::loadData: cannot load from DB when I have an external list source!" );

    if ( hasExternalListSource() )
        return;

	// Connection holen
	Reference<XRowSet> xForm(m_xCursor, UNO_QUERY);
	if (!xForm.is())
		return;
	Reference<XConnection> xConnection = getConnection(xForm);
	if (!xConnection.is())
		return;

	Reference<XServiceInfo> xServiceInfo(xConnection, UNO_QUERY);
	if (!xServiceInfo.is() || !xServiceInfo->supportsService(SRV_SDB_CONNECTION))
	{
		DBG_ERROR("OComboBoxModel::loadData : invalid connection !");
		return;
	}

    if (!m_aListSource.getLength() || m_eListSourceType == ListSourceType_VALUELIST)
		return;

    ::utl::SharedUNOComponent< XResultSet > xListCursor;
	try
	{
        m_aListRowSet.setConnection( xConnection );

        bool bExecuteRowSet( false );
		switch (m_eListSourceType)
		{
			case ListSourceType_TABLEFIELDS:
				// don't work with a statement here, the fields will be collected below
				break;
			case ListSourceType_TABLE:
			{
				// does the bound field belong to the table ?
				// if we use an alias for the bound field, we won't find it
				// in that case we use the first field of the table

				Reference<XNameAccess> xFieldsByName = getTableFields(xConnection, m_aListSource);
				Reference<XIndexAccess> xFieldsByIndex(xFieldsByName, UNO_QUERY);

				::rtl::OUString aFieldName;
				if ( xFieldsByName.is() && xFieldsByName->hasByName( getControlSource() ) )
				{
					aFieldName = getControlSource();
				}
				else
				{
                    // otherwise look for the alias
                    Reference<XPropertySet> xFormProp(xForm,UNO_QUERY);
                    Reference< XColumnsSupplier > xSupplyFields;
                    xFormProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupplyFields;

					// search the field
					DBG_ASSERT(xSupplyFields.is(), "OComboBoxModel::loadData : invalid query composer !");

					Reference< XNameAccess > xFieldNames = xSupplyFields->getColumns();
					if ( xFieldNames->hasByName( getControlSource() ) )
					{
                        Reference< XPropertySet > xComposerFieldAsSet;
                        xFieldNames->getByName( getControlSource() ) >>= xComposerFieldAsSet;
						if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet))
							xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName;
					}
				}

				if (!aFieldName.getLength())
					break;

				Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
				OSL_ENSURE(xMeta.is(),"No database meta data!");
				if ( xMeta.is() )
				{
					::rtl::OUString aQuote = xMeta->getIdentifierQuoteString();

                    ::rtl::OUString sCatalog, sSchema, sTable;
	                qualifiedNameComponents( xMeta, m_aListSource, sCatalog, sSchema, sTable, eInDataManipulation );

                    ::rtl::OUStringBuffer aStatement;
                    aStatement.appendAscii( "SELECT DISTINCT " );
                    aStatement.append     ( quoteName( aQuote, aFieldName ) );
                    aStatement.appendAscii( " FROM " );
                    aStatement.append     ( composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable ) );

                    m_aListRowSet.setEscapeProcessing( sal_False );
                    m_aListRowSet.setCommand( aStatement.makeStringAndClear() );
                    bExecuteRowSet = true;
				}
			}	break;
			case ListSourceType_QUERY:
			{
                m_aListRowSet.setCommandFromQuery( m_aListSource );
                bExecuteRowSet = true;
			}
            break;

			default:
			{
                m_aListRowSet.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH != m_eListSourceType );
                m_aListRowSet.setCommand( m_aListSource );
                bExecuteRowSet = true;
			}
		}

        if ( bExecuteRowSet )
        {
            if ( !_bForce && !m_aListRowSet.isDirty() )
            {
                // if none of the settings of the row set changed, compared to the last
                // invocation of loadData, then don't re-fill the list. Instead, assume
                // the list entries are the same.
                return;
            }
            xListCursor.reset( m_aListRowSet.execute() );
        }
	}
	catch(SQLException& eSQL)
	{
		onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
		return;
	}
	catch( const Exception& )
	{
        DBG_UNHANDLED_EXCEPTION();
		return;
	}

	::std::vector< ::rtl::OUString >	aStringList;
	aStringList.reserve(16);
	try
	{
        OSL_ENSURE( xListCursor.is() || ( ListSourceType_TABLEFIELDS == m_eListSourceType ),
            "OComboBoxModel::loadData: logic error!" );
        if ( !xListCursor.is() && ( ListSourceType_TABLEFIELDS != m_eListSourceType ) )
		    return;

		switch (m_eListSourceType)
		{
			case ListSourceType_SQL:
			case ListSourceType_SQLPASSTHROUGH:
			case ListSourceType_TABLE:
			case ListSourceType_QUERY:
			{
				// die XDatabaseVAriant der ersten Spalte
				Reference<XColumnsSupplier> xSupplyCols(xListCursor, UNO_QUERY);
				DBG_ASSERT(xSupplyCols.is(), "OComboBoxModel::loadData : cursor supports the row set service but is no column supplier?!");
				Reference<XIndexAccess> xColumns;
				if (xSupplyCols.is())
				{
					xColumns = Reference<XIndexAccess>(xSupplyCols->getColumns(), UNO_QUERY);
					DBG_ASSERT(xColumns.is(), "OComboBoxModel::loadData : no columns supplied by the row set !");
				}
				Reference< XPropertySet > xDataField;
				if ( xColumns.is() )
					xColumns->getByIndex(0) >>= xDataField;
				if ( !xDataField.is() )
					return;

                ::dbtools::FormattedColumnValue aValueFormatter( getContext(), xForm, xDataField );

				// Listen fuellen
				sal_Int16 i = 0;
				// per definitionem the list cursor is positioned _before_ the first row at the moment
				while (xListCursor->next() && (i++<SHRT_MAX)) // max anzahl eintraege
				{
                    aStringList.push_back( aValueFormatter.getFormattedValue() );
				}
			}
			break;
			case ListSourceType_TABLEFIELDS:
			{
				Reference<XNameAccess> xFieldNames = getTableFields(xConnection, m_aListSource);
				if (xFieldNames.is())
				{
					StringSequence seqNames = xFieldNames->getElementNames();
					sal_Int32 nFieldsCount = seqNames.getLength();
					const ::rtl::OUString* pustrNames = seqNames.getConstArray();

					for (sal_Int32 k=0; k<nFieldsCount; ++k)
						aStringList.push_back(pustrNames[k]);
				}
			}
			break;
            default:
                OSL_ENSURE( false, "OComboBoxModel::loadData: unreachable!" );
                break;
		}
	}
	catch(SQLException& eSQL)
	{
		onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST));
		return;
	}
	catch( const Exception& )
	{
		DBG_UNHANDLED_EXCEPTION();
		return;
	}

		// String-Sequence fuer ListBox erzeugen
	StringSequence aStringSeq(aStringList.size());
	::rtl::OUString* pStringAry = aStringSeq.getArray();
	for (sal_Int32 i = 0; i<aStringSeq.getLength(); ++i)
		pStringAry[i] = aStringList[i];

	// String-Sequence an ListBox setzen
	setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringSeq ) );
}

//------------------------------------------------------------------------------
void OComboBoxModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm )
{
	Reference<XPropertySet> xField = getField();
	if ( xField.is() )
        m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) );
    getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= m_aDesignModeStringItems;

	// Daten nur laden, wenn eine Listenquelle angegeben wurde
	if ( m_aListSource.getLength() && m_xCursor.is() && !hasExternalListSource() )
		loadData( false );
}

//------------------------------------------------------------------------------
void OComboBoxModel::onDisconnectedDbColumn()
{
    m_pValueFormatter.reset();

	// reset the string item list
    if ( !hasExternalListSource() )
        setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( m_aDesignModeStringItems ) );

    m_aListRowSet.dispose();
}

//------------------------------------------------------------------------------
void SAL_CALL OComboBoxModel::reloaded( const EventObject& aEvent ) throw(RuntimeException)
{
	OBoundControlModel::reloaded(aEvent);

	// reload data if we have a list source
	if ( m_aListSource.getLength() && m_xCursor.is() && !hasExternalListSource() )
		loadData( false );
}

//------------------------------------------------------------------------------
void OComboBoxModel::resetNoBroadcast()
{
    OBoundControlModel::resetNoBroadcast();
    m_aLastKnownValue.clear();
}

//-----------------------------------------------------------------------------
sal_Bool OComboBoxModel::commitControlValueToDbColumn( bool _bPostReset )
{
    Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) );

    ::rtl::OUString sNewValue;
    aNewValue >>= sNewValue;

    bool bModified = ( aNewValue != m_aLastKnownValue );
    if ( bModified )
	{
		if  (   !aNewValue.hasValue()
            ||  (   !sNewValue.getLength()      // an empty string
                &&  m_bEmptyIsNull              // which should be interpreted as NULL
                )
            )
        {
			m_xColumnUpdate->updateNull();
        }
		else
		{
			try
			{
                OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::commitControlValueToDbColumn: no value formatter!" );
                if ( m_pValueFormatter.get() )
                {
                    if ( !m_pValueFormatter->setFormattedValue( sNewValue ) )
                        return sal_False;
                }
				else
					m_xColumnUpdate->updateString( sNewValue );
			}
			catch ( const Exception& )
			{
				return sal_False;
			}
		}

		m_aLastKnownValue = aNewValue;
	}

	// add the new value to the list
	sal_Bool bAddToList = bModified && !_bPostReset;
    	// (only if this is not the "commit" triggered by a "reset")

    if ( bAddToList )
    {
        StringSequence aStringItemList;
        if ( getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aStringItemList )
	    {
		    const ::rtl::OUString* pStringItems = aStringItemList.getConstArray();
		    sal_Int32 i;
		    for (i=0; i<aStringItemList.getLength(); ++i, ++pStringItems)
		    {
			    if ( pStringItems->equals( sNewValue ) )
				    break;
		    }

		    // not found -> add
		    if (i >= aStringItemList.getLength())
		    {
			    sal_Int32 nOldLen = aStringItemList.getLength();
			    aStringItemList.realloc( nOldLen + 1 );
			    aStringItemList.getArray()[ nOldLen ] = sNewValue;

                setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringItemList ) );
		    }
        }
	}

	return sal_True;
}

// XPropertiesChangeListener
//------------------------------------------------------------------------------
Any OComboBoxModel::translateDbColumnToControlValue()
{
    OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::translateDbColumnToControlValue: no value formatter!" );
    if ( m_pValueFormatter.get() )
    {
        ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
        if  (   !sValue.getLength()
            &&  m_pValueFormatter->getColumn().is()
            &&  m_pValueFormatter->getColumn()->wasNull()
            )
        {
            m_aLastKnownValue.clear();
        }
        else
        {

	        m_aLastKnownValue <<= sValue;
        }
    }
    else
        m_aLastKnownValue.clear();

    return m_aLastKnownValue.hasValue() ? m_aLastKnownValue : makeAny( ::rtl::OUString() );
        // (m_aLastKnownValue is alllowed to be VOID, the control value isn't)
}

//------------------------------------------------------------------------------
Any OComboBoxModel::getDefaultForReset() const
{
    return makeAny( m_aDefaultText );
}

//--------------------------------------------------------------------
void OComboBoxModel::stringItemListChanged( ControlModelLock& /*_rInstanceLock*/ )
{
    if ( m_xAggregateSet.is() )
        m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) );
}

//--------------------------------------------------------------------
void OComboBoxModel::connectedExternalListSource( )
{
    // TODO?
}

//--------------------------------------------------------------------
void OComboBoxModel::disconnectedExternalListSource( )
{
    // TODO?
}

//--------------------------------------------------------------------
void OComboBoxModel::refreshInternalEntryList()
{
    DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::refreshInternalEntryList: invalid call!" );

    if  (   !hasExternalListSource( )
        &&  ( m_eListSourceType != ListSourceType_VALUELIST )
        &&  ( m_xCursor.is() )
        )
    {
        loadData( true );
    }
}

//--------------------------------------------------------------------
void SAL_CALL OComboBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException )
{
    if ( !OEntryListHelper::handleDisposing( _rSource ) )
        OBoundControlModel::disposing( _rSource );
}

//========================================================================
//= OComboBoxControl
//========================================================================

//------------------------------------------------------------------
InterfaceRef SAL_CALL OComboBoxControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException)
{
	return *(new OComboBoxControl(_rxFactory));
}

//------------------------------------------------------------------------------
OComboBoxControl::OComboBoxControl(const Reference<XMultiServiceFactory>& _rxFactory)
	:OBoundControl(_rxFactory, VCL_CONTROL_COMBOBOX)
{
}

//------------------------------------------------------------------------------
StringSequence SAL_CALL OComboBoxControl::getSupportedServiceNames() throw(RuntimeException)
{
	StringSequence aSupported = OBoundControl::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 1);

	::rtl::OUString* pArray = aSupported.getArray();
	pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_COMBOBOX;
	return aSupported;
}

//.........................................................................
}
//.........................................................................

