/**************************************************************
 * 
 * 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 "Columns.hxx"
#include "findpos.hxx"
#include "Grid.hxx"
#include "property.hrc"
#include "property.hxx"
#include "services.hxx"

/** === begin UNO includes === **/
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/form/XLoadable.hpp>
#include <com/sun/star/text/WritingMode2.hpp>
/** === end UNO includes === **/

#include <comphelper/basicio.hxx>
#include <comphelper/container.hxx>
#include <comphelper/extract.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/svapp.hxx>

using namespace ::com::sun::star::uno;

//.........................................................................
namespace frm
{
//.........................................................................
using namespace ::com::sun::star;
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::view;

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

const sal_uInt16 ROWHEIGHT			=	0x0001;
const sal_uInt16 FONTTYPE			=	0x0002;
const sal_uInt16 FONTSIZE			=	0x0004;
const sal_uInt16 FONTATTRIBS		=	0x0008;
const sal_uInt16 TABSTOP			=	0x0010;
const sal_uInt16 TEXTCOLOR			=	0x0020;
const sal_uInt16 FONTDESCRIPTOR 	=	0x0040;
const sal_uInt16 RECORDMARKER		=	0x0080;
const sal_uInt16 BACKGROUNDCOLOR	=	0x0100;

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

DBG_NAME(OGridControlModel);
//------------------------------------------------------------------
OGridControlModel::OGridControlModel(const Reference<XMultiServiceFactory>& _rxFactory)
    :OControlModel(_rxFactory, ::rtl::OUString())
    ,OInterfaceContainer(_rxFactory, m_aMutex, ::getCppuType(static_cast<Reference<XPropertySet>*>(NULL)))
    ,OErrorBroadcaster( OComponentHelper::rBHelper )
    ,FontControlModel( false )
    ,m_aSelectListeners(m_aMutex)
    ,m_aResetListeners(m_aMutex)
    ,m_aRowSetChangeListeners(m_aMutex)
    ,m_aDefaultControl( FRM_SUN_CONTROL_GRIDCONTROL )
    ,m_nBorder(1)
    ,m_nWritingMode( WritingMode2::CONTEXT )
    ,m_nContextWritingMode( WritingMode2::CONTEXT )
    ,m_bEnableVisible(sal_True)
    ,m_bEnable(sal_True)
    ,m_bNavigation(sal_True)
    ,m_bRecordMarker(sal_True)
    ,m_bPrintable(sal_True)
    ,m_bAlwaysShowCursor(sal_False)
    ,m_bDisplaySynchron(sal_True)
{
	DBG_CTOR(OGridControlModel,NULL);

	m_nClassId = FormComponentType::GRIDCONTROL;
}

//------------------------------------------------------------------
OGridControlModel::OGridControlModel( const OGridControlModel* _pOriginal, const Reference< XMultiServiceFactory >& _rxFactory )
	:OControlModel( _pOriginal, _rxFactory )
	,OInterfaceContainer( _rxFactory, m_aMutex, ::getCppuType( static_cast<Reference<XPropertySet>*>( NULL ) ) )
	,OErrorBroadcaster( OComponentHelper::rBHelper )
    ,FontControlModel( _pOriginal )
	,m_aSelectListeners( m_aMutex )
	,m_aResetListeners( m_aMutex )
    ,m_aRowSetChangeListeners( m_aMutex )
{
	DBG_CTOR(OGridControlModel,NULL);

	m_aDefaultControl = _pOriginal->m_aDefaultControl;
	m_bEnable = _pOriginal->m_bEnable;
	m_bEnableVisible = _pOriginal->m_bEnableVisible;
	m_bNavigation = _pOriginal->m_bNavigation;
	m_nBorder = _pOriginal->m_nBorder;
    m_nWritingMode = _pOriginal->m_nWritingMode;
    m_nContextWritingMode = _pOriginal->m_nContextWritingMode;
	m_bRecordMarker = _pOriginal->m_bRecordMarker;
	m_bPrintable = _pOriginal->m_bPrintable;
	m_bAlwaysShowCursor = _pOriginal->m_bAlwaysShowCursor;
	m_bDisplaySynchron = _pOriginal->m_bDisplaySynchron;

	// clone the columns
	cloneColumns( _pOriginal );

	// TODO: clone the events?
}

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

	DBG_DTOR(OGridControlModel,NULL);
}

// XCloneable
//------------------------------------------------------------------------------
Reference< XCloneable > SAL_CALL OGridControlModel::createClone( ) throw (RuntimeException)
{
    OGridControlModel* pClone = new OGridControlModel( this, getContext().getLegacyServiceFactory() );
    osl_incrementInterlockedCount( &pClone->m_refCount );
    pClone->OControlModel::clonedFrom( this );
    // do not call OInterfaceContainer::clonedFrom, it would clone the elements aka columns, which is
    // already done in the ctor
    //pClone->OInterfaceContainer::clonedFrom( *this );
    osl_decrementInterlockedCount( &pClone->m_refCount );
    return static_cast< XCloneable* >( static_cast< OControlModel* >( pClone ) );
}

//------------------------------------------------------------------------------
void OGridControlModel::cloneColumns( const OGridControlModel* _pOriginalContainer )
{
	try
	{
		Reference< XCloneable > xColCloneable;

		const OInterfaceArray::const_iterator pColumnStart = _pOriginalContainer->m_aItems.begin();
		const OInterfaceArray::const_iterator pColumnEnd = _pOriginalContainer->m_aItems.end();
		for ( OInterfaceArray::const_iterator pColumn = pColumnStart; pColumn != pColumnEnd; ++pColumn )
		{
			// ask the col for a factory for the clone
			xColCloneable = xColCloneable.query( *pColumn );
			DBG_ASSERT( xColCloneable.is(), "OGridControlModel::cloneColumns: column is not cloneable!" );

			if ( xColCloneable.is() )
			{
				// create a clone of the column
				Reference< XCloneable > xColClone( xColCloneable->createClone() );
				DBG_ASSERT( xColClone.is(), "OGridControlModel::cloneColumns: invalid column clone!" );

				if ( xColClone.is() )
				{
					// insert this clone into our own container
					insertByIndex( pColumn - pColumnStart, xColClone->queryInterface( m_aElementType ) );
				}

			}
		}
	}
	catch( const Exception& )
	{
		DBG_ERROR( "OGridControlModel::cloneColumns: caught an exception while cloning the columns!" );
	}
}

// XServiceInfo
//------------------------------------------------------------------------------
StringSequence OGridControlModel::getSupportedServiceNames() throw(RuntimeException)
{
	StringSequence aSupported = OControlModel::getSupportedServiceNames();
	aSupported.realloc(aSupported.getLength() + 2);

	::rtl::OUString*pArray = aSupported.getArray();
	pArray[aSupported.getLength()-2] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.awt.UnoControlModel"));
	pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_GRIDCONTROL;
	return aSupported;
}

//------------------------------------------------------------------------------
Any SAL_CALL OGridControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException)
{
	Any aReturn = OGridControlModel_BASE::queryInterface(_rType);

	if ( !aReturn.hasValue() )
	{
		aReturn = OControlModel::queryAggregation( _rType );
		if ( !aReturn.hasValue() )
		{
			aReturn = OInterfaceContainer::queryInterface( _rType );
			if ( !aReturn.hasValue() )
				aReturn = OErrorBroadcaster::queryInterface( _rType );
		}
	}
	return aReturn;
}

// XSQLErrorListener
//------------------------------------------------------------------------------
void SAL_CALL OGridControlModel::errorOccured( const SQLErrorEvent& _rEvent ) throw (RuntimeException)
{
	// forward the errors which happened to my columns to my own listeners
	onError( _rEvent );
}

// XRowSetSupplier
//------------------------------------------------------------------------------
Reference< XRowSet > SAL_CALL OGridControlModel::getRowSet(  ) throw (RuntimeException)
{
    return Reference< XRowSet >( getParent(), UNO_QUERY );
}

//------------------------------------------------------------------------------
void SAL_CALL OGridControlModel::setRowSet( const Reference< XRowSet >& /*_rxDataSource*/ ) throw (RuntimeException)
{
    OSL_ENSURE( false, "OGridControlModel::setRowSet: not supported!" );
}

//--------------------------------------------------------------------
void SAL_CALL OGridControlModel::addRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) throw (RuntimeException)
{
    if ( i_Listener.is() )
        m_aRowSetChangeListeners.addInterface( i_Listener );
}

//--------------------------------------------------------------------
void SAL_CALL OGridControlModel::removeRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) throw (RuntimeException)
{
    m_aRowSetChangeListeners.removeInterface( i_Listener );
}

// XChild
//------------------------------------------------------------------------------
void SAL_CALL OGridControlModel::setParent( const InterfaceRef& i_Parent ) throw(NoSupportException, RuntimeException)
{
    ::osl::ClearableMutexGuard aGuard( m_aMutex );
    if ( i_Parent == getParent() )
        return;

    OControlModel::setParent( i_Parent );

    EventObject aEvent( *this );
    aGuard.clear();
    m_aRowSetChangeListeners.notifyEach( &XRowSetChangeListener::onRowSetChanged, aEvent );
}

//------------------------------------------------------------------------------
Sequence< Type > SAL_CALL OGridControlModel::getTypes(	) throw(RuntimeException)
{
	return concatSequences(
		concatSequences(
			OControlModel::getTypes(),
			OInterfaceContainer::getTypes(),
			OErrorBroadcaster::getTypes()
		),
		OGridControlModel_BASE::getTypes()
	);
}

// OComponentHelper
//------------------------------------------------------------------------------
void OGridControlModel::disposing()
{
	OControlModel::disposing();
	OErrorBroadcaster::disposing();
	OInterfaceContainer::disposing();

	setParent(NULL);

	EventObject aEvt(static_cast<XWeak*>(this));
	m_aSelectListeners.disposeAndClear(aEvt);
	m_aResetListeners.disposeAndClear(aEvt);
    m_aRowSetChangeListeners.disposeAndClear(aEvt);
}

// XEventListener
//------------------------------------------------------------------------------
void OGridControlModel::disposing(const EventObject& _rEvent) throw( RuntimeException )
{
	OControlModel::disposing( _rEvent );
	OInterfaceContainer::disposing( _rEvent );
}

// XSelectionSupplier
//-----------------------------------------------------------------------------
sal_Bool SAL_CALL OGridControlModel::select(const Any& rElement) throw(IllegalArgumentException, RuntimeException)
{
    ::osl::ClearableMutexGuard aGuard( m_aMutex );

	Reference<XPropertySet> xSel;
	if (rElement.hasValue() && !::cppu::extractInterface(xSel, rElement))
	{
		throw IllegalArgumentException();
	}
	InterfaceRef xMe = static_cast<XWeak*>(this);

	if (xSel.is())
	{
		Reference<XChild> xAsChild(xSel, UNO_QUERY);
		if (!xAsChild.is() || (xAsChild->getParent() != xMe))
		{
			throw IllegalArgumentException();
		}
	}

	if ( xSel != m_xSelection )
    {
        m_xSelection = xSel;
        aGuard.clear();
        m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) );
        return sal_True;
    }
    return sal_False;
}

//-----------------------------------------------------------------------------
Any SAL_CALL OGridControlModel::getSelection() throw(RuntimeException)
{
	return makeAny(m_xSelection);
}

//-----------------------------------------------------------------------------
void OGridControlModel::addSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) throw( RuntimeException )
{
	m_aSelectListeners.addInterface(_rxListener);
}

//-----------------------------------------------------------------------------
void OGridControlModel::removeSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) throw( RuntimeException )
{
	m_aSelectListeners.removeInterface(_rxListener);
}

// XGridColumnFactory
//------------------------------------------------------------------------------
Reference<XPropertySet> SAL_CALL OGridControlModel::createColumn(const ::rtl::OUString& ColumnType) throw ( :: com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
	const Sequence< ::rtl::OUString >& rColumnTypes = frm::getColumnTypes();
	return createColumn( forms_detail::findPos( ColumnType, rColumnTypes ) );
}

//------------------------------------------------------------------------------
Reference<XPropertySet>  OGridControlModel::createColumn(sal_Int32 nTypeId) const
{
	Reference<XPropertySet>  xReturn;
	switch (nTypeId)
	{
		case TYPE_CHECKBOX: 		xReturn = new CheckBoxColumn( getContext() ); break;
		case TYPE_COMBOBOX: 		xReturn = new ComboBoxColumn( getContext() ); break;
		case TYPE_CURRENCYFIELD:	xReturn = new CurrencyFieldColumn( getContext() ); break;
		case TYPE_DATEFIELD:		xReturn = new DateFieldColumn( getContext() ); break;
		case TYPE_LISTBOX:			xReturn = new ListBoxColumn( getContext() ); break;
		case TYPE_NUMERICFIELD: 	xReturn = new NumericFieldColumn( getContext() ); break;
		case TYPE_PATTERNFIELD: 	xReturn = new PatternFieldColumn( getContext() ); break;
		case TYPE_TEXTFIELD:		xReturn = new TextFieldColumn( getContext() ); break;
		case TYPE_TIMEFIELD:		xReturn = new TimeFieldColumn( getContext() ); break;
		case TYPE_FORMATTEDFIELD:	xReturn = new FormattedFieldColumn( getContext() ); break;
		default:
			DBG_ERROR("OGridControlModel::createColumn: Unknown Column");
			break;
	}
	return xReturn;
}

//------------------------------------------------------------------------------
StringSequence SAL_CALL OGridControlModel::getColumnTypes() throw ( ::com::sun::star::uno::RuntimeException)
{
	return frm::getColumnTypes();
}

// XReset
//-----------------------------------------------------------------------------
void SAL_CALL OGridControlModel::reset() throw ( ::com::sun::star::uno::RuntimeException)
{
	::cppu::OInterfaceIteratorHelper aIter(m_aResetListeners);
	EventObject aEvt(static_cast<XWeak*>(this));
	sal_Bool bContinue = sal_True;
	while (aIter.hasMoreElements() && bContinue)
		bContinue =((XResetListener*)aIter.next())->approveReset(aEvt);

	if (bContinue)
	{
		_reset();
        m_aResetListeners.notifyEach( &XResetListener::resetted, aEvt );
	}
}

//-----------------------------------------------------------------------------
void SAL_CALL OGridControlModel::addResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException)
{
	m_aResetListeners.addInterface(_rxListener);
}

//-----------------------------------------------------------------------------
void SAL_CALL OGridControlModel::removeResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException)
{
	m_aResetListeners.removeInterface(_rxListener);
}

//-----------------------------------------------------------------------------
void OGridControlModel::_reset()
{
	Reference<XReset> xReset;
	sal_Int32 nCount = getCount();
	for (sal_Int32 nIndex=0; nIndex < nCount; nIndex++)
	{
		getByIndex( nIndex ) >>= xReset;
		if (xReset.is())
			xReset->reset();
	}
}

// XPropertySet
//------------------------------------------------------------------------------
void OGridControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
{
	BEGIN_DESCRIBE_BASE_PROPERTIES( 37 )
		DECL_PROP1(NAME,				::rtl::OUString,	BOUND);
		DECL_PROP2(CLASSID, 			sal_Int16,			READONLY, TRANSIENT);
		DECL_PROP1(TAG, 				::rtl::OUString,	BOUND);
		DECL_PROP1(TABINDEX,			sal_Int16,			BOUND);
		DECL_PROP3(TABSTOP, 			sal_Bool,			BOUND, MAYBEDEFAULT, MAYBEVOID);
		DECL_PROP2(HASNAVIGATION,		sal_Bool,			BOUND, MAYBEDEFAULT);
		DECL_PROP1(ENABLED, 			sal_Bool,			BOUND);
		DECL_PROP2(ENABLEVISIBLE,		sal_Bool,			BOUND, MAYBEDEFAULT);
		DECL_PROP1(BORDER,				sal_Int16,			BOUND);
		DECL_PROP2(BORDERCOLOR,	        sal_Int16,			BOUND, MAYBEVOID);
		DECL_PROP1(DEFAULTCONTROL,		::rtl::OUString,	BOUND);
		DECL_PROP3(TEXTCOLOR,			sal_Int32,			BOUND, MAYBEDEFAULT, MAYBEVOID);
		DECL_PROP3(BACKGROUNDCOLOR, 	sal_Int32,			BOUND, MAYBEDEFAULT, MAYBEVOID);
		DECL_PROP2(FONT,				FontDescriptor, 	BOUND, MAYBEDEFAULT);
		DECL_PROP3(ROWHEIGHT,			sal_Int32,			BOUND, MAYBEDEFAULT, MAYBEVOID);
		DECL_PROP1(HELPTEXT,			::rtl::OUString,	BOUND);
		DECL_PROP1(FONT_NAME,			::rtl::OUString,	MAYBEDEFAULT);
		DECL_PROP1(FONT_STYLENAME,		::rtl::OUString,	MAYBEDEFAULT);
		DECL_PROP1(FONT_FAMILY, 		sal_Int16,			MAYBEDEFAULT);
		DECL_PROP1(FONT_CHARSET,		sal_Int16,			MAYBEDEFAULT);
		DECL_PROP1(FONT_HEIGHT, 		float,				MAYBEDEFAULT);
		DECL_PROP1(FONT_WEIGHT, 		float,				MAYBEDEFAULT);
		DECL_PROP1(FONT_SLANT,			sal_Int16,			MAYBEDEFAULT);
		DECL_PROP1(FONT_UNDERLINE,		sal_Int16,			MAYBEDEFAULT);
		DECL_BOOL_PROP1(FONT_WORDLINEMODE,					MAYBEDEFAULT);
		DECL_PROP3(TEXTLINECOLOR,		sal_Int32,			BOUND, MAYBEDEFAULT, MAYBEVOID);
		DECL_PROP2(FONTEMPHASISMARK,	sal_Int16,			BOUND, MAYBEDEFAULT);
		DECL_PROP2(FONTRELIEF,			sal_Int16,			BOUND, MAYBEDEFAULT);
		DECL_PROP1(FONT_STRIKEOUT,		sal_Int16,			MAYBEDEFAULT);
		DECL_PROP2(RECORDMARKER,		sal_Bool,			BOUND, MAYBEDEFAULT );
		DECL_PROP2(PRINTABLE,			sal_Bool,			BOUND, MAYBEDEFAULT );
		DECL_PROP4(CURSORCOLOR, 		sal_Int32,			BOUND, MAYBEDEFAULT, MAYBEVOID , TRANSIENT);
		DECL_PROP3(ALWAYSSHOWCURSOR,	sal_Bool,			BOUND, MAYBEDEFAULT, TRANSIENT);
		DECL_PROP3(DISPLAYSYNCHRON, 	sal_Bool,			BOUND, MAYBEDEFAULT, TRANSIENT);
		DECL_PROP2(HELPURL, 			::rtl::OUString,	BOUND, MAYBEDEFAULT);
        DECL_PROP2(WRITING_MODE,        sal_Int16,          BOUND, MAYBEDEFAULT);
        DECL_PROP3(CONTEXT_WRITING_MODE,sal_Int16,          BOUND, MAYBEDEFAULT, TRANSIENT);
    END_DESCRIBE_PROPERTIES();
}

//------------------------------------------------------------------------------
void OGridControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
{
	switch (nHandle)
	{
        case PROPERTY_ID_CONTEXT_WRITING_MODE:
            rValue <<= m_nContextWritingMode;
            break;
        case PROPERTY_ID_WRITING_MODE:
            rValue <<= m_nWritingMode;
            break;
		case PROPERTY_ID_HELPTEXT:
			rValue <<= m_sHelpText;
			break;
		case PROPERTY_ID_HELPURL:
			rValue <<= m_sHelpURL;
			break;
		case PROPERTY_ID_DISPLAYSYNCHRON:
			setBOOL(rValue, m_bDisplaySynchron);
			break;
		case PROPERTY_ID_ALWAYSSHOWCURSOR:
			setBOOL(rValue, m_bAlwaysShowCursor);
			break;
		case PROPERTY_ID_CURSORCOLOR:
			rValue = m_aCursorColor;
			break;
		case PROPERTY_ID_PRINTABLE:
			setBOOL(rValue, m_bPrintable);
			break;
		case PROPERTY_ID_TABSTOP:
			rValue = m_aTabStop;
			break;
		case PROPERTY_ID_HASNAVIGATION:
			setBOOL(rValue, m_bNavigation);
			break;
		case PROPERTY_ID_RECORDMARKER:
			setBOOL(rValue, m_bRecordMarker);
			break;
		case PROPERTY_ID_ENABLED:
			setBOOL(rValue, m_bEnable);
			break;
		case PROPERTY_ID_ENABLEVISIBLE:
			setBOOL(rValue, m_bEnableVisible);
			break;
		case PROPERTY_ID_BORDER:
			rValue <<= (sal_Int16)m_nBorder;
			break;
		case PROPERTY_ID_BORDERCOLOR:
			rValue <<= m_aBorderColor;
			break;
		case PROPERTY_ID_DEFAULTCONTROL:
			rValue <<= m_aDefaultControl;
			break;
		case PROPERTY_ID_BACKGROUNDCOLOR:
			rValue = m_aBackgroundColor;
			break;
		case PROPERTY_ID_ROWHEIGHT:
			rValue = m_aRowHeight;
			break;

        default:
            if ( isFontRelatedProperty( nHandle ) )
                FontControlModel::getFastPropertyValue( rValue, nHandle );
            else
			    OControlModel::getFastPropertyValue( rValue, nHandle );
	}
}

//------------------------------------------------------------------------------
sal_Bool OGridControlModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
													sal_Int32 nHandle, const Any& rValue )throw( IllegalArgumentException )
{
	sal_Bool bModified(sal_False);
	switch (nHandle)
	{
        case PROPERTY_ID_CONTEXT_WRITING_MODE:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nContextWritingMode );
            break;
        case PROPERTY_ID_WRITING_MODE:
			bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nWritingMode );
            break;
		case PROPERTY_ID_HELPTEXT:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpText);
			break;
		case PROPERTY_ID_HELPURL:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpURL);
			break;
		case PROPERTY_ID_DISPLAYSYNCHRON:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDisplaySynchron);
			break;
		case PROPERTY_ID_ALWAYSSHOWCURSOR:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAlwaysShowCursor);
			break;
		case PROPERTY_ID_CURSORCOLOR:
			if (!rValue.hasValue() || !m_aCursorColor.hasValue())
			{
				if (rValue.hasValue() && (TypeClass_LONG != rValue.getValueType().getTypeClass()))
				{
					throw IllegalArgumentException();
				}
				rOldValue = m_aCursorColor;
				rConvertedValue = rValue;
				bModified = (rOldValue.getValue() != rConvertedValue.getValue());
			}
			else
				bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, getINT32(m_aCursorColor));
			break;
		case PROPERTY_ID_PRINTABLE:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bPrintable);
			break;
		case PROPERTY_ID_TABSTOP:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTabStop, ::getBooleanCppuType());
			break;
		case PROPERTY_ID_HASNAVIGATION:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bNavigation);
			break;
		case PROPERTY_ID_RECORDMARKER:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bRecordMarker);
			break;
		case PROPERTY_ID_ENABLED:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnable);
			break;
		case PROPERTY_ID_ENABLEVISIBLE:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnableVisible);
			break;
		case PROPERTY_ID_BORDER:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_nBorder);
			break;
		case PROPERTY_ID_BORDERCOLOR:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBorderColor, ::getCppuType((const sal_Int32*)NULL));
			break;
		case PROPERTY_ID_DEFAULTCONTROL:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultControl);
			break;
		case PROPERTY_ID_BACKGROUNDCOLOR:
			bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBackgroundColor, ::getCppuType((const sal_Int32*)NULL));
			break;
		case PROPERTY_ID_ROWHEIGHT:
			{
				bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aRowHeight, ::getCppuType((const sal_Int32*)NULL));

				sal_Int32 nNewVal( 0 );
				if ( ( rConvertedValue >>= nNewVal ) && ( nNewVal <= 0 ) )
				{
					rConvertedValue.clear();
					bModified = m_aRowHeight.hasValue();
				}
			}
			break;
		default:
            if ( isFontRelatedProperty( nHandle ) )
                bModified = FontControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
            else
			    bModified = OControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue);
	}
	return bModified;
}

//------------------------------------------------------------------------------
void OGridControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception)
{
	switch (nHandle)
	{
        case PROPERTY_ID_CONTEXT_WRITING_MODE:
            rValue >>= m_nContextWritingMode;
            break;
        case PROPERTY_ID_WRITING_MODE:
            rValue >>= m_nWritingMode;
            break;
		case PROPERTY_ID_HELPTEXT:
			rValue >>= m_sHelpText;
			break;
		case PROPERTY_ID_HELPURL:
			rValue >>= m_sHelpURL;
			break;
		case PROPERTY_ID_DISPLAYSYNCHRON:
			m_bDisplaySynchron = getBOOL(rValue);
			break;
		case PROPERTY_ID_ALWAYSSHOWCURSOR:
			m_bAlwaysShowCursor = getBOOL(rValue);
			break;
		case PROPERTY_ID_CURSORCOLOR:
			m_aCursorColor = rValue;
			break;
		case PROPERTY_ID_PRINTABLE:
			m_bPrintable = getBOOL(rValue);
			break;
		case PROPERTY_ID_TABSTOP:
			m_aTabStop = rValue;
			break;
		case PROPERTY_ID_HASNAVIGATION:
			m_bNavigation = getBOOL(rValue);
			break;
		case PROPERTY_ID_ENABLED:
			m_bEnable = getBOOL(rValue);
			break;
		case PROPERTY_ID_ENABLEVISIBLE:
			m_bEnableVisible = getBOOL(rValue);
			break;
		case PROPERTY_ID_RECORDMARKER:
			m_bRecordMarker = getBOOL(rValue);
			break;
		case PROPERTY_ID_BORDER:
			rValue >>= m_nBorder;
			break;
		case PROPERTY_ID_BORDERCOLOR:
			m_aBorderColor = rValue;
			break;
		case PROPERTY_ID_DEFAULTCONTROL:
			rValue >>= m_aDefaultControl;
			break;
		case PROPERTY_ID_BACKGROUNDCOLOR:
			m_aBackgroundColor = rValue;
			break;
        case PROPERTY_ID_ROWHEIGHT:
			m_aRowHeight = rValue;
			break;

        default:
            if ( isFontRelatedProperty( nHandle ) )
            {
                FontDescriptor aOldFont( getFont() );

                FontControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );

                if ( isFontAggregateProperty( nHandle ) )
	                firePropertyChange( PROPERTY_ID_FONT, makeAny( getFont() ), makeAny( aOldFont ) );
            }
            else
			    OControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
	}

}

//XPropertyState

//------------------------------------------------------------------------------
Any OGridControlModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
{
	Any aReturn;
	switch (nHandle)
	{
        case PROPERTY_ID_CONTEXT_WRITING_MODE:
        case PROPERTY_ID_WRITING_MODE:
            aReturn <<= WritingMode2::CONTEXT;
            break;

		case PROPERTY_ID_DEFAULTCONTROL:
			aReturn <<= ::rtl::OUString( STARDIV_ONE_FORM_CONTROL_GRID  );
			break;

		case PROPERTY_ID_PRINTABLE:
		case PROPERTY_ID_HASNAVIGATION:
		case PROPERTY_ID_RECORDMARKER:
		case PROPERTY_ID_DISPLAYSYNCHRON:
		case PROPERTY_ID_ENABLED:
		case PROPERTY_ID_ENABLEVISIBLE:
			aReturn = makeBoolAny(sal_True);
			break;

		case PROPERTY_ID_ALWAYSSHOWCURSOR:
			aReturn = makeBoolAny(sal_False);
			break;

		case PROPERTY_ID_HELPURL:
		case PROPERTY_ID_HELPTEXT:
			aReturn <<= ::rtl::OUString();
			break;

		case PROPERTY_ID_BORDER:
			aReturn <<= (sal_Int16)1;
			break;

		case PROPERTY_ID_BORDERCOLOR:
		case PROPERTY_ID_TABSTOP:
		case PROPERTY_ID_BACKGROUNDCOLOR:
		case PROPERTY_ID_ROWHEIGHT:
		case PROPERTY_ID_CURSORCOLOR:
			// void
			break;

		default:
            if ( isFontRelatedProperty( nHandle ) )
                aReturn = FontControlModel::getPropertyDefaultByHandle( nHandle );
            else
			    aReturn = OControlModel::getPropertyDefaultByHandle(nHandle);
	}
	return aReturn;
}

//------------------------------------------------------------------------------
OGridColumn* OGridControlModel::getColumnImplementation(const InterfaceRef& _rxIFace) const
{
	OGridColumn* pImplementation = NULL;
	Reference< XUnoTunnel > xUnoTunnel( _rxIFace, UNO_QUERY );
	if ( xUnoTunnel.is() )
		pImplementation = reinterpret_cast<OGridColumn*>(xUnoTunnel->getSomething(OGridColumn::getUnoTunnelImplementationId()));

	return pImplementation;
}

//------------------------------------------------------------------------------
void OGridControlModel::gotColumn( const Reference< XInterface >& _rxColumn )
{
	Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY );
	if ( xBroadcaster.is() )
		xBroadcaster->addSQLErrorListener( this );
}

//------------------------------------------------------------------------------
void OGridControlModel::lostColumn(const Reference< XInterface >& _rxColumn)
{
	if ( m_xSelection == _rxColumn )
	{	// the currently selected element was replaced
		m_xSelection.clear();
		EventObject aEvt( static_cast< XWeak* >( this ) );
        m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvt );
	}

    Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY );
	if ( xBroadcaster.is() )
		xBroadcaster->removeSQLErrorListener( this );
}

//------------------------------------------------------------------------------
void OGridControlModel::implRemoved(const InterfaceRef& _rxObject)
{
	OInterfaceContainer::implRemoved(_rxObject);
	lostColumn(_rxObject);
}

//------------------------------------------------------------------------------
void OGridControlModel::implInserted( const ElementDescription* _pElement )
{
	OInterfaceContainer::implInserted( _pElement );
	gotColumn( _pElement->xInterface );
}

//------------------------------------------------------------------------------
void OGridControlModel::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
{
    Reference< XInterface > xOldColumn( _rEvent.ReplacedElement, UNO_QUERY );
    Reference< XInterface > xNewColumn( _rEvent.Element, UNO_QUERY );

    bool bNewSelection = ( xOldColumn == m_xSelection );

    lostColumn( xOldColumn );
	gotColumn( xNewColumn );

    if ( bNewSelection )
        m_xSelection.set( xNewColumn, UNO_QUERY );

	OInterfaceContainer::impl_replacedElement( _rEvent, _rInstanceLock );
    // <<---- SYNCHRONIZED

    if ( bNewSelection )
    {
        m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) );
    }
}

//------------------------------------------------------------------------------
ElementDescription* OGridControlModel::createElementMetaData( )
{
	return new ColumnDescription;
}

//------------------------------------------------------------------------------
void OGridControlModel::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
{
	OGridColumn* pCol = getColumnImplementation( _rxObject );
	if ( !pCol )
		throw IllegalArgumentException();

	OInterfaceContainer::approveNewElement( _rxObject, _pElement );

	// if we're here, the object passed all tests
	if ( _pElement )
		static_cast< ColumnDescription* >( _pElement )->pColumn = pCol;
}

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

//------------------------------------------------------------------------------
void OGridControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException)
{
	OControlModel::write(_rxOutStream);

	Reference<XMarkableStream>	xMark(_rxOutStream, UNO_QUERY);

	// 1. Version
	_rxOutStream->writeShort(0x0008);

	// 2. Columns
	sal_Int32 nLen = getCount();
	_rxOutStream->writeLong(nLen);
	OGridColumn* pCol;
	for (sal_Int32 i = 0; i < nLen; i++)
	{
		// zuerst den Servicenamen fuer das darunterliegende Model
		pCol = getColumnImplementation(m_aItems[i]);
		DBG_ASSERT(pCol != NULL, "OGridControlModel::write : such items should never reach it into my container !");

		_rxOutStream << pCol->getModelName();

		// dann das Object selbst
		sal_Int32 nMark = xMark->createMark();
		sal_Int32 nObjLen = 0;
		_rxOutStream->writeLong(nObjLen);

		// schreiben der Col
		pCol->write(_rxOutStream);

		// feststellen der Laenge
		nObjLen = xMark->offsetToMark(nMark) - 4;
		xMark->jumpToMark(nMark);
		_rxOutStream->writeLong(nObjLen);
		xMark->jumpToFurthest();
		xMark->deleteMark(nMark);
	}

	// 3. Events
	writeEvents(_rxOutStream);

	// 4. Attribute
	// Maskierung fuer alle any Typen
	sal_uInt16 nAnyMask = 0;
	if (m_aRowHeight.getValueType().getTypeClass() == TypeClass_LONG)
		nAnyMask |= ROWHEIGHT;
	if ( getFont() != getDefaultFont() )
		nAnyMask |= FONTATTRIBS | FONTSIZE | FONTTYPE | FONTDESCRIPTOR;
	if (m_aTabStop.getValueType().getTypeClass() == TypeClass_BOOLEAN)
		nAnyMask |= TABSTOP;
	if ( hasTextColor() )
		nAnyMask |= TEXTCOLOR;
	if (m_aBackgroundColor.getValueType().getTypeClass() == TypeClass_LONG)
		nAnyMask |= BACKGROUNDCOLOR;
	if (!m_bRecordMarker)
		nAnyMask |= RECORDMARKER;

	_rxOutStream->writeShort(nAnyMask);

	if (nAnyMask & ROWHEIGHT)
		_rxOutStream->writeLong(getINT32(m_aRowHeight));

	// old structures
    const FontDescriptor& aFont = getFont();
	if ( nAnyMask & FONTDESCRIPTOR )
    {
		// Attrib
		_rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( VCLUnoHelper::ConvertFontWeight( aFont.Weight ) ) );
		_rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( aFont.Slant ) );
		_rxOutStream->writeShort( aFont.Underline );
		_rxOutStream->writeShort( aFont.Strikeout );
		_rxOutStream->writeShort( sal_Int16(aFont.Orientation * 10) );
		_rxOutStream->writeBoolean( aFont.Kerning );
		_rxOutStream->writeBoolean( aFont.WordLineMode );

		// Size
		_rxOutStream->writeLong( aFont.Width );
		_rxOutStream->writeLong( aFont.Height );
		_rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( VCLUnoHelper::ConvertFontWidth( aFont.CharacterWidth ) ) );

		// Type
		_rxOutStream->writeUTF( aFont.Name );
		_rxOutStream->writeUTF( aFont.StyleName );
		_rxOutStream->writeShort( aFont.Family );
		_rxOutStream->writeShort( aFont.CharSet );
		_rxOutStream->writeShort( aFont.Pitch );
    }

    _rxOutStream << m_aDefaultControl;

	_rxOutStream->writeShort(m_nBorder);
	_rxOutStream->writeBoolean(m_bEnable);

	if (nAnyMask & TABSTOP)
		_rxOutStream->writeBoolean(getBOOL(m_aTabStop));

	_rxOutStream->writeBoolean(m_bNavigation);

	if (nAnyMask & TEXTCOLOR)
		_rxOutStream->writeLong( getTextColor() );

	// neu ab Version 6
	_rxOutStream << m_sHelpText;

	if (nAnyMask & FONTDESCRIPTOR)
		_rxOutStream << getFont();

	if (nAnyMask & RECORDMARKER)
		_rxOutStream->writeBoolean(m_bRecordMarker);

	// neu ab Version 7
	_rxOutStream->writeBoolean(m_bPrintable);

	// new since 8
	if (nAnyMask & BACKGROUNDCOLOR)
		_rxOutStream->writeLong(getINT32(m_aBackgroundColor));
}

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

	Reference<XMarkableStream>	xMark(_rxInStream, UNO_QUERY);

	// 1. Version
	sal_Int16 nVersion = _rxInStream->readShort();

	// 2. Einlesen der Spalten
	sal_Int32 nLen = _rxInStream->readLong();
	if (nLen)
	{
		for (sal_Int32 i = 0; i < nLen; i++)
		{
			// Lesen des Modelnamen

			::rtl::OUString sModelName;
			_rxInStream >> sModelName;

			Reference<XPropertySet>  xCol(createColumn(getColumnTypeByModelName(sModelName)));
			DBG_ASSERT(xCol.is(), "OGridControlModel::read : unknown column type !");
			sal_Int32 nObjLen = _rxInStream->readLong();
			if (nObjLen)
			{
				sal_Int32 nMark = xMark->createMark();
				if (xCol.is())
				{
					OGridColumn* pCol = getColumnImplementation(xCol);
					pCol->read(_rxInStream);
				}
				xMark->jumpToMark(nMark);
				_rxInStream->skipBytes(nObjLen);
				xMark->deleteMark(nMark);
			}

			if ( xCol.is() )
				implInsert( i, xCol, sal_False, NULL, sal_False );
		}
	}

	// In der Basisimplementierung werden die Events nur gelesen, Elemente im Container existieren
	// da aber vor TF_ONE fuer das GridControl immer Events geschrieben wurden, muessen sie auch immer
	// mit gelesen werden
	sal_Int32 nObjLen = _rxInStream->readLong();
	if (nObjLen)
	{
		sal_Int32 nMark = xMark->createMark();
		Reference<XPersistObject>  xObj(m_xEventAttacher, UNO_QUERY);
		if (xObj.is())
			xObj->read(_rxInStream);
		xMark->jumpToMark(nMark);
		_rxInStream->skipBytes(nObjLen);
		xMark->deleteMark(nMark);
	}

	// Attachement lesen
	for (sal_Int32 i = 0; i < nLen; i++)
	{
		InterfaceRef  xIfc(m_aItems[i], UNO_QUERY);
		Reference<XPropertySet>  xSet(xIfc, UNO_QUERY);
		Any aHelper;
		aHelper <<= xSet;
		m_xEventAttacher->attach( i, xIfc, aHelper );
	}

	// 4. Einlesen der Attribute
	if (nVersion == 1)
		return;

	// Maskierung fuer any
	sal_uInt16 nAnyMask = _rxInStream->readShort();

	if (nAnyMask & ROWHEIGHT)
	{
		sal_Int32 nValue = _rxInStream->readLong();
		m_aRowHeight <<= (sal_Int32)nValue;
	}

    FontDescriptor aFont( getFont() );
	if ( nAnyMask & FONTATTRIBS )
	{
		aFont.Weight = (float)VCLUnoHelper::ConvertFontWeight( _rxInStream->readShort() );

		aFont.Slant = (FontSlant)_rxInStream->readShort();
		aFont.Underline = _rxInStream->readShort();
		aFont.Strikeout = _rxInStream->readShort();
		aFont.Orientation = ( (float)_rxInStream->readShort() ) / 10;
		aFont.Kerning = _rxInStream->readBoolean();
		aFont.WordLineMode = _rxInStream->readBoolean();
	}
	if ( nAnyMask & FONTSIZE )
	{
		aFont.Width = (sal_Int16)_rxInStream->readLong();
		aFont.Height = (sal_Int16)_rxInStream->readLong();
		aFont.CharacterWidth = (float)VCLUnoHelper::ConvertFontWidth( _rxInStream->readShort() );
	}
	if ( nAnyMask & FONTTYPE )
	{
		aFont.Name = _rxInStream->readUTF();
		aFont.StyleName = _rxInStream->readUTF();
		aFont.Family = _rxInStream->readShort();
		aFont.CharSet = _rxInStream->readShort();
		aFont.Pitch = _rxInStream->readShort();
	}

    if ( nAnyMask & ( FONTATTRIBS | FONTSIZE | FONTTYPE ) )
        setFont( aFont );

	// Name
	_rxInStream >> m_aDefaultControl;
	m_nBorder = _rxInStream->readShort();
	m_bEnable = _rxInStream->readBoolean();

	if (nAnyMask & TABSTOP)
	{
		m_aTabStop = makeBoolAny(_rxInStream->readBoolean());
	}

	if (nVersion > 3)
		m_bNavigation = _rxInStream->readBoolean();

	if (nAnyMask & TEXTCOLOR)
	{
		sal_Int32 nValue = _rxInStream->readLong();
        setTextColor( (sal_Int32)nValue );
	}

	// neu ab Version 6
	if (nVersion > 5)
		_rxInStream >> m_sHelpText;

	if (nAnyMask & FONTDESCRIPTOR)
	{
        FontDescriptor aUNOFont;
		_rxInStream >> aUNOFont;
        setFont( aFont );
	}

	if (nAnyMask & RECORDMARKER)
		m_bRecordMarker = _rxInStream->readBoolean();

	// neu ab Version 7
	if (nVersion > 6)
		m_bPrintable = _rxInStream->readBoolean();

	if (nAnyMask & BACKGROUNDCOLOR)
	{
		sal_Int32 nValue = _rxInStream->readLong();
		m_aBackgroundColor <<= (sal_Int32)nValue;
	}
}

//.........................................................................
}	// namespace frm
//.........................................................................

