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

#include <com/sun/star/uno/Type.hxx>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/container/XIndexAccess.hpp>
#include <com/sun/star/form/XSubmit.hpp>
#include <com/sun/star/util/NumberFormat.hpp>
#include <com/sun/star/sdbc/DataType.hpp>
#include <com/sun/star/awt/XVclWindowPeer.hpp>

#include <vcl/svapp.hxx>
#include <tools/wintypes.hxx>

#include <connectivity/dbtools.hxx>
#include <connectivity/formattedcolumnvalue.hxx>
#include <connectivity/dbconversion.hxx>

#include <tools/diagnose_ex.h>
#include <tools/debug.hxx>

#include <comphelper/container.hxx>
#include <comphelper/numbers.hxx>

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;

//------------------------------------------------------------------
InterfaceRef SAL_CALL OEditControl_CreateInstance(const Reference< XMultiServiceFactory > & _rxFactory)
{
	return *(new OEditControl(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OEditControl::_getTypes()
{
	static Sequence<Type> aTypes;
	if (!aTypes.getLength())
	{
		// my two base classes
		aTypes = concatSequences(OBoundControl::_getTypes(), OEditControl_BASE::getTypes());
	}
	return aTypes;
}

//------------------------------------------------------------------------------
Any SAL_CALL OEditControl::queryAggregation(const Type& _rType) throw (RuntimeException)
{
	Any aReturn = OBoundControl::queryAggregation(_rType);
	if (!aReturn.hasValue())
		aReturn = OEditControl_BASE::queryInterface(_rType);

	return aReturn;
}

DBG_NAME(OEditControl);
//------------------------------------------------------------------------------
OEditControl::OEditControl(const Reference<XMultiServiceFactory>& _rxFactory)
			   :OBoundControl( _rxFactory, FRM_SUN_CONTROL_RICHTEXTCONTROL )
			   ,m_aChangeListeners(m_aMutex)
			   ,m_nKeyEvent( 0 )
{
	DBG_CTOR(OEditControl,NULL);

	increment(m_refCount);
	{
		Reference<XWindow>  xComp;
		if (query_aggregation(m_xAggregate, xComp))
		{
			xComp->addFocusListener(this);
			xComp->addKeyListener(this);
		}
	}
	decrement(m_refCount);
}

//------------------------------------------------------------------------------
OEditControl::~OEditControl()
{
	if( m_nKeyEvent )
		Application::RemoveUserEvent( m_nKeyEvent );

	if (!OComponentHelper::rBHelper.bDisposed)
	{
		acquire();
		dispose();
	}

	DBG_DTOR(OEditControl,NULL);
}

// XChangeBroadcaster
//------------------------------------------------------------------------------
void OEditControl::addChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
{
	m_aChangeListeners.addInterface( l );
}

//------------------------------------------------------------------------------
void OEditControl::removeChangeListener(const Reference<XChangeListener>& l) throw ( ::com::sun::star::uno::RuntimeException)
{
	m_aChangeListeners.removeInterface( l );
}

// OComponentHelper
//------------------------------------------------------------------------------
void OEditControl::disposing()
{
	OBoundControl::disposing();

	EventObject aEvt(static_cast<XWeak*>(this));
	m_aChangeListeners.disposeAndClear(aEvt);
}

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence	OEditControl::getSupportedServiceNames() throw()
{
	StringSequence aSupported = OBoundControl::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 1);

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

// XEventListener
//------------------------------------------------------------------------------
void OEditControl::disposing(const EventObject& Source) throw( RuntimeException )
{
	OBoundControl::disposing(Source);
}

// XFocusListener
//------------------------------------------------------------------------------
void OEditControl::focusGained( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
{
	Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
	if (xSet.is())
		xSet->getPropertyValue( PROPERTY_TEXT ) >>= m_aHtmlChangeValue;
}

//------------------------------------------------------------------------------
void OEditControl::focusLost( const FocusEvent& /*e*/ ) throw ( ::com::sun::star::uno::RuntimeException)
{
	Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
	if (xSet.is())
	{
		::rtl::OUString sNewHtmlChangeValue;
		xSet->getPropertyValue( PROPERTY_TEXT ) >>= sNewHtmlChangeValue;
		if( sNewHtmlChangeValue != m_aHtmlChangeValue )
		{
			EventObject aEvt( *this );
            m_aChangeListeners.notifyEach( &XChangeListener::changed, aEvt );
		}
	}
}

// XKeyListener
//------------------------------------------------------------------------------
void OEditControl::keyPressed(const ::com::sun::star::awt::KeyEvent& e) throw ( ::com::sun::star::uno::RuntimeException)
{
	if( e.KeyCode != KEY_RETURN || e.Modifiers != 0 )
		return;

	// Steht das Control in einem Formular mit einer Submit-URL?
	Reference<XPropertySet>  xSet(getModel(), UNO_QUERY);
	if( !xSet.is() )
		return;

	// nicht fuer multiline edits
	Any aTmp( xSet->getPropertyValue(PROPERTY_MULTILINE));
	if ((aTmp.getValueType().equals(::getBooleanCppuType())) && getBOOL(aTmp))
		return;

	Reference<XFormComponent>  xFComp(xSet, UNO_QUERY);
	InterfaceRef  xParent = xFComp->getParent();
	if( !xParent.is() )
		return;

	Reference<XPropertySet>  xFormSet(xParent, UNO_QUERY);
	if( !xFormSet.is() )
		return;

	aTmp = xFormSet->getPropertyValue( PROPERTY_TARGET_URL );
	if (!aTmp.getValueType().equals(::getCppuType((const ::rtl::OUString*)NULL)) ||
		!getString(aTmp).getLength() )
		return;

	Reference<XIndexAccess>  xElements(xParent, UNO_QUERY);
	sal_Int32 nCount = xElements->getCount();
	if( nCount > 1 )
	{
		Reference<XPropertySet>  xFCSet;
		for( sal_Int32 nIndex=0; nIndex < nCount; nIndex++ )
		{
			//	Any aElement(xElements->getByIndex(nIndex));
			xElements->getByIndex(nIndex) >>= xFCSet;
			OSL_ENSURE(xFCSet.is(),"OEditControl::keyPressed: No XPropertySet!");

			if (hasProperty(PROPERTY_CLASSID, xFCSet) &&
				getINT16(xFCSet->getPropertyValue(PROPERTY_CLASSID)) == FormComponentType::TEXTFIELD)
			{
				// Noch ein weiteres Edit gefunden ==> dann nicht submitten
				if (xFCSet != xSet)
					return;
			}
		}
	}

	// Da wir noch im Haender stehen, submit asynchron ausloesen
	if( m_nKeyEvent )
		Application::RemoveUserEvent( m_nKeyEvent );
	m_nKeyEvent = Application::PostUserEvent( LINK(this, OEditControl,OnKeyPressed) );
}

//------------------------------------------------------------------------------
void OEditControl::keyReleased(const ::com::sun::star::awt::KeyEvent& /*e*/) throw ( ::com::sun::star::uno::RuntimeException)
{
}

//------------------------------------------------------------------------------
IMPL_LINK(OEditControl, OnKeyPressed, void*, /*EMPTYARG*/)
{
	m_nKeyEvent = 0;

	Reference<XFormComponent>  xFComp(getModel(), UNO_QUERY);
	InterfaceRef  xParent = xFComp->getParent();
	Reference<XSubmit>  xSubmit(xParent, UNO_QUERY);
	if (xSubmit.is())
		xSubmit->submit( Reference<XControl>(), ::com::sun::star::awt::MouseEvent() );
	return 0L;
}

//------------------------------------------------------------------
void SAL_CALL OEditControl::createPeer( const Reference< XToolkit>& _rxToolkit, const Reference< XWindowPeer>& _rxParent ) throw ( RuntimeException )
{
	OBoundControl::createPeer(_rxToolkit, _rxParent);
}

/*************************************************************************/
//------------------------------------------------------------------
InterfaceRef SAL_CALL OEditModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory)
{
	return *(new OEditModel(_rxFactory));
}

//------------------------------------------------------------------------------
Sequence<Type> OEditModel::_getTypes()
{
	return OEditBaseModel::_getTypes();
}


DBG_NAME(OEditModel);
//------------------------------------------------------------------
OEditModel::OEditModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OEditBaseModel( _rxFactory, FRM_SUN_COMPONENT_RICHTEXTCONTROL, FRM_SUN_CONTROL_TEXTFIELD, sal_True, sal_True )
    ,m_bMaxTextLenModified(sal_False)
    ,m_bWritingFormattedFake(sal_False)
{
	DBG_CTOR(OEditModel,NULL);

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

//------------------------------------------------------------------
OEditModel::OEditModel( const OEditModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory )
    :OEditBaseModel( _pOriginal, _rxFactory )
    ,m_bMaxTextLenModified(sal_False)
    ,m_bWritingFormattedFake(sal_False)
{
	DBG_CTOR( OEditModel, NULL );

	// Note that most of the properties are not clone from the original object:
	// Things as the format key, it's type, and such, depend on the field being part of a loaded form
	// (they're initialized in onConnectedDbColumn). Even if the original object _is_ part of such a form, we ourself
	// certainly aren't, so these members are defaulted. If we're inserted into a form which is already loaded,
	// they will be set to new values, anyway ....
}

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

	DBG_DTOR(OEditModel,NULL);
}

//------------------------------------------------------------------------------
IMPLEMENT_DEFAULT_CLONING( OEditModel )

//------------------------------------------------------------------------------
void OEditModel::disposing()
{
	OEditBaseModel::disposing();
    m_pValueFormatter.reset();
}

// XPersistObject
//------------------------------------------------------------------------------
::rtl::OUString SAL_CALL OEditModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException)
{
	return FRM_COMPONENT_EDIT;	// old (non-sun) name for compatibility !
}

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence SAL_CALL OEditModel::getSupportedServiceNames() throw()
{
	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_TEXTFIELD;
    *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_TEXTFIELD;
    *pStoreTo++ = BINDABLE_DATABASE_TEXT_FIELD;

	return aSupported;
}

// XPropertySet
void SAL_CALL OEditModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
{
	if ( PROPERTY_ID_PERSISTENCE_MAXTEXTLENGTH == nHandle )
	{
		if ( m_bMaxTextLenModified )
			rValue <<= sal_Int16(0);
		else if ( m_xAggregateSet.is() )
			rValue = m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN);
	}
	else
	{
		OEditBaseModel::getFastPropertyValue(rValue, nHandle );
	}
}

//------------------------------------------------------------------------------
void OEditModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
	BEGIN_DESCRIBE_PROPERTIES( 5, OEditBaseModel )
		DECL_PROP2(PERSISTENCE_MAXTEXTLENGTH,sal_Int16,			READONLY, TRANSIENT);
		DECL_PROP2(DEFAULT_TEXT,		::rtl::OUString,		BOUND, MAYBEDEFAULT);
		DECL_BOOL_PROP1(EMPTY_IS_NULL,							BOUND);
		DECL_PROP1(TABINDEX,			sal_Int16,				BOUND);
		DECL_BOOL_PROP2(FILTERPROPOSAL,							BOUND, MAYBEDEFAULT);
	END_DESCRIBE_PROPERTIES();
}

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

    // our aggregate is a rich text model, which also derives from OControlModel, as
    // do we, so we need to remove some duplicate properties
    RemoveProperty( _rAggregateProps, PROPERTY_TABINDEX );
    RemoveProperty( _rAggregateProps, PROPERTY_CLASSID );
    RemoveProperty( _rAggregateProps, PROPERTY_NAME );
    RemoveProperty( _rAggregateProps, PROPERTY_TAG );
    RemoveProperty( _rAggregateProps, PROPERTY_NATIVE_LOOK );

}

//------------------------------------------------------------------------------
bool OEditModel::implActsAsRichText( ) const
{
    sal_Bool bActAsRichText = sal_False;
    if ( m_xAggregateSet.is() )
    {
        OSL_VERIFY( m_xAggregateSet->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bActAsRichText );
    }
    return bActAsRichText;
}

//------------------------------------------------------------------------------
void SAL_CALL OEditModel::reset(  ) throw(RuntimeException)
{
    // no reset if we currently act as rich text control
    if ( implActsAsRichText() )
        return;

    OEditBaseModel::reset();
}

//------------------------------------------------------------------------------
namespace
{
    void lcl_transferProperties( const Reference< XPropertySet >& _rxSource, const Reference< XPropertySet >& _rxDest )
    {
        try
        {
            Reference< XPropertySetInfo > xSourceInfo;
            if ( _rxSource.is() )
                xSourceInfo = _rxSource->getPropertySetInfo();

            Reference< XPropertySetInfo > xDestInfo;
            if ( _rxDest.is() )
                xDestInfo = _rxDest->getPropertySetInfo();

            if ( !xSourceInfo.is() || !xDestInfo.is() )
            {
                OSL_ENSURE( sal_False, "lcl_transferProperties: invalid property set(s)!" );
                return;
            }

            Sequence< Property > aSourceProps( xSourceInfo->getProperties() );
            const Property* pSourceProps = aSourceProps.getConstArray();
            const Property* pSourcePropsEnd = aSourceProps.getConstArray() + aSourceProps.getLength();
            while ( pSourceProps != pSourcePropsEnd )
            {
                if ( !xDestInfo->hasPropertyByName( pSourceProps->Name ) )
                {
                    ++pSourceProps;
                    continue;
                }

                Property aDestProp( xDestInfo->getPropertyByName( pSourceProps->Name ) );
                if ( 0 != ( aDestProp.Attributes & PropertyAttribute::READONLY ) )
                {
                    ++pSourceProps;
                    continue;
                }

                try
                {
                    _rxDest->setPropertyValue( pSourceProps->Name, _rxSource->getPropertyValue( pSourceProps->Name ) );
                }
                catch( IllegalArgumentException e )
                {
#if OSL_DEBUG_LEVEL > 0
                    ::rtl::OString sMessage( "could not transfer the property named '" );
                    sMessage += ::rtl::OString( pSourceProps->Name.getStr(), pSourceProps->Name.getLength(), RTL_TEXTENCODING_ASCII_US );
                    sMessage += ::rtl::OString( "'." );
                    if ( e.Message.getLength() )
                    {
                        sMessage += ::rtl::OString( "\n\nMessage:\n" );
                        sMessage += ::rtl::OString( e.Message.getStr(), e.Message.getLength(), RTL_TEXTENCODING_ASCII_US );
                    }
                    OSL_ENSURE( sal_False, sMessage.getStr() );
#endif
                }

                ++pSourceProps;
            }
        }
        catch( const Exception& )
        {
            DBG_UNHANDLED_EXCEPTION();
        }
    }
}

//------------------------------------------------------------------------------
void OEditModel::writeAggregate( const Reference< XObjectOutputStream >& _rxOutStream ) const
{
    // we need to fake the writing of our aggregate. Since #i24387#, we have another aggregate,
    // but for compatibility, we need to use an "old" aggregate for writing and reading

    Reference< XPropertySet > xFakedAggregate(
        getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
        UNO_QUERY
    );
    OSL_ENSURE( xFakedAggregate.is(), "OEditModel::writeAggregate: could not create an old EditControlModel!" );
    if ( !xFakedAggregate.is() )
        return;

    lcl_transferProperties( m_xAggregateSet, xFakedAggregate );

    Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
    OSL_ENSURE( xFakedPersist.is(), "OEditModel::writeAggregate: no XPersistObject!" );
    if ( xFakedPersist.is() )
        xFakedPersist->write( _rxOutStream );
}

//------------------------------------------------------------------------------
void OEditModel::readAggregate( const Reference< XObjectInputStream >& _rxInStream )
{
    // we need to fake the reading of our aggregate. Since #i24387#, we have another aggregate,
    // but for compatibility, we need to use an "old" aggregate for writing and reading

    Reference< XPropertySet > xFakedAggregate(
        getContext().createComponent( (rtl::OUString)VCL_CONTROLMODEL_EDIT ),
        UNO_QUERY
    );
    Reference< XPersistObject > xFakedPersist( xFakedAggregate, UNO_QUERY );
    OSL_ENSURE( xFakedPersist.is(), "OEditModel::readAggregate: no XPersistObject, or no faked aggregate at all!" );
    if ( xFakedPersist.is() )
    {
        xFakedPersist->read( _rxInStream );
        lcl_transferProperties( xFakedAggregate, m_xAggregateSet );
    }
}

//------------------------------------------------------------------------------
void OEditModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	Any aCurrentText;
	sal_Int16 nOldTextLen = 0;
	// bin ich gerade loaded und habe dazu zeitweilig die MaxTextLen umgesetzt ?
	if ( m_bMaxTextLenModified )
	{	// -> fuer die Dauer des Speicherns meinem aggregierten Model die alte TextLen einreden

		// before doing this we have to save the current text value of the aggregate, as this may be affected by resetting the text len
		// FS - 08.12.99 - 70606
		aCurrentText = m_xAggregateSet->getPropertyValue(PROPERTY_TEXT);

		m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN) >>= nOldTextLen;
		m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny((sal_Int16)0));
	}

	OEditBaseModel::write(_rxOutStream);

	if ( m_bMaxTextLenModified )
	{	// wieder zuruecksetzen
		m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, makeAny(nOldTextLen));
		// and reset the text
		// First we set it to an empty string : Without this the second setPropertyValue would not do anything as it thinks
		// we aren't changing the prop (it didn't notify the - implicite - change of the text prop while setting the max text len)
		// This seems to be a bug with in toolkit's EditControl-implementation.
		m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, makeAny(::rtl::OUString()));
		m_xAggregateSet->setPropertyValue(PROPERTY_TEXT, aCurrentText);
	}
}

//------------------------------------------------------------------------------
void OEditModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OEditBaseModel::read(_rxInStream);

	// Some versions (5.1 'til about 552) wrote a wrong DefaultControl-property value which is unknown
	// to older versions (5.0).
	// correct this ...
	if (m_xAggregateSet.is())
	{
		Any aDefaultControl = m_xAggregateSet->getPropertyValue(PROPERTY_DEFAULTCONTROL);
		if	(	(aDefaultControl.getValueType().getTypeClass() == TypeClass_STRING)
			&&	(getString(aDefaultControl).compareTo(STARDIV_ONE_FORM_CONTROL_TEXTFIELD) == COMPARE_EQUAL)
			)
		{
			m_xAggregateSet->setPropertyValue( PROPERTY_DEFAULTCONTROL, makeAny( (::rtl::OUString)STARDIV_ONE_FORM_CONTROL_EDIT ) );
			// Older as well as current versions should understand this : the former knew only the STARDIV_ONE_FORM_CONTROL_EDIT,
			// the latter are registered for both STARDIV_ONE_FORM_CONTROL_EDIT and STARDIV_ONE_FORM_CONTROL_TEXTFIELD.
		}
	}
}

//------------------------------------------------------------------------------
sal_uInt16 OEditModel::getPersistenceFlags() const
{
	sal_uInt16 nFlags = OEditBaseModel::getPersistenceFlags();

	if (m_bWritingFormattedFake)
		nFlags |= PF_FAKE_FORMATTED_FIELD;

	return nFlags;
}

//------------------------------------------------------------------------------
void OEditModel::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 ) );

        if ( m_pValueFormatter->getKeyType() != NumberFormat::SCIENTIFIC )
		{
			m_bMaxTextLenModified =	getINT16(m_xAggregateSet->getPropertyValue(PROPERTY_MAXTEXTLEN)) != 0;
			if ( !m_bMaxTextLenModified )
			{
				sal_Int32 nFieldLen = 0;
				xField->getPropertyValue(::rtl::OUString::createFromAscii("Precision")) >>= nFieldLen;

				if (nFieldLen && nFieldLen <= USHRT_MAX)
				{
					Any aVal;
					aVal <<= (sal_Int16)nFieldLen;
					m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);

					m_bMaxTextLenModified = sal_True;
				}
			}
			else
				m_bMaxTextLenModified = sal_False; // to get sure that the text len won't be set in unloaded
		}
	}
}

//------------------------------------------------------------------------------
void OEditModel::onDisconnectedDbColumn()
{
	OEditBaseModel::onDisconnectedDbColumn();

    m_pValueFormatter.reset();

    if ( hasField() && m_bMaxTextLenModified )
	{
		Any aVal;
		aVal <<= (sal_Int16)0;	// nur wenn es 0 war, habe ich es in onConnectedDbColumn umgesetzt
		m_xAggregateSet->setPropertyValue(PROPERTY_MAXTEXTLEN, aVal);
		m_bMaxTextLenModified = sal_False;
	}
}

//------------------------------------------------------------------------------
sal_Bool OEditModel::approveDbColumnType( sal_Int32 _nColumnType )
{
    // if we act as rich text currently, we do not allow binding to a database column
    if ( implActsAsRichText() )
        return sal_False;

    return OEditBaseModel::approveDbColumnType( _nColumnType );
}

//------------------------------------------------------------------------------
void OEditModel::resetNoBroadcast()
{
    OEditBaseModel::resetNoBroadcast();
}

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

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

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

    return sal_True;
}

//------------------------------------------------------------------------------
Any OEditModel::translateDbColumnToControlValue()
{
    OSL_PRECOND( m_pValueFormatter.get(), "OEditModel::translateDbColumnToControlValue: no value formatter!" );
    Any aRet;
    if ( m_pValueFormatter.get() )
    {
        ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() );
        if  (   !sValue.getLength()
            &&  m_pValueFormatter->getColumn().is()
            &&  m_pValueFormatter->getColumn()->wasNull()
            )
        {
        }
        else
        {
	        // #i2817# OJ
	        sal_uInt16 nMaxTextLen = getINT16( m_xAggregateSet->getPropertyValue( PROPERTY_MAXTEXTLEN ) );
	        if ( nMaxTextLen && sValue.getLength() > nMaxTextLen )
	        {
		        sal_Int32 nDiff = sValue.getLength() - nMaxTextLen;
		        sValue = sValue.replaceAt( nMaxTextLen, nDiff, ::rtl::OUString() );
	        }

	        aRet <<= sValue;
        }
    }

    return aRet.hasValue() ? aRet : makeAny( ::rtl::OUString() );
}

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

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