diff --git a/forms/source/component/ListBox.cxx b/forms/source/component/ListBox.cxx index d13971befb91..55945fba0870 100644 --- a/forms/source/component/ListBox.cxx +++ b/forms/source/component/ListBox.cxx @@ -1,63 +1,63 @@ /************************************************************************* - * - * $RCSfile: ListBox.cxx,v $ - * - * $Revision: 1.28 $ - * - * last change: $Author: obo $ $Date: 2003-10-21 08:59:07 $ - * - * The Contents of this file are made available subject to the terms of - * either of the following licenses - * - * - GNU Lesser General Public License Version 2.1 - * - Sun Industry Standards Source License Version 1.1 - * - * Sun Microsystems Inc., October, 2000 - * - * GNU Lesser General Public License Version 2.1 - * ============================================= - * Copyright 2000 by Sun Microsystems, Inc. - * 901 San Antonio Road, Palo Alto, CA 94303, USA - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License version 2.1, as published by the Free Software Foundation. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * - * Sun Industry Standards Source License Version 1.1 - * ================================================= - * The contents of this file are subject to the Sun Industry Standards - * Source License Version 1.1 (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.openoffice.org/license.html. - * - * Software provided under this License is provided on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, - * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. - * See the License for the specific provisions governing your rights and - * obligations concerning the Software. - * - * The Initial Developer of the Original Code is: Sun Microsystems, Inc. - * - * Copyright: 2000 by Sun Microsystems, Inc. - * - * All Rights Reserved. - * - * Contributor(s): _______________________________________ - * - * - ************************************************************************/ +* +* $RCSfile: ListBox.cxx,v $ +* +* $Revision: 1.29 $ +* +* last change: $Author: kz $ $Date: 2003-12-11 12:29:45 $ +* +* The Contents of this file are made available subject to the terms of +* either of the following licenses +* +* - GNU Lesser General Public License Version 2.1 +* - Sun Industry Standards Source License Version 1.1 +* +* Sun Microsystems Inc., October, 2000 +* +* GNU Lesser General Public License Version 2.1 +* ============================================= +* Copyright 2000 by Sun Microsystems, Inc. +* 901 San Antonio Road, Palo Alto, CA 94303, USA +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software Foundation. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, +* MA 02111-1307 USA +* +* +* Sun Industry Standards Source License Version 1.1 +* ================================================= +* The contents of this file are subject to the Sun Industry Standards +* Source License Version 1.1 (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.openoffice.org/license.html. +* +* Software provided under this License is provided on an "AS IS" basis, +* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, +* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. +* See the License for the specific provisions governing your rights and +* obligations concerning the Software. +* +* The Initial Developer of the Original Code is: Sun Microsystems, Inc. +* +* Copyright: 2000 by Sun Microsystems, Inc. +* +* All Rights Reserved. +* +* Contributor(s): _______________________________________ +* +* +************************************************************************/ #ifndef _FORMS_LISTBOX_HXX_ #include "ListBox.hxx" @@ -157,164 +157,164 @@ //......................................................................... 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 ::drafts::com::sun::star::form; -using namespace ::dbtools; + 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 ::drafts::com::sun::star::form; + using namespace ::dbtools; -//================================================================== -//= OListBoxModel -//================================================================== -//------------------------------------------------------------------ -InterfaceRef SAL_CALL OListBoxModel_CreateInstance(const Reference& _rxFactory) throw (RuntimeException) -{ - return *(new OListBoxModel(_rxFactory)); -} + //================================================================== + //= OListBoxModel + //================================================================== + //------------------------------------------------------------------ + InterfaceRef SAL_CALL OListBoxModel_CreateInstance(const Reference& _rxFactory) throw (RuntimeException) + { + return *(new OListBoxModel(_rxFactory)); + } -//------------------------------------------------------------------------------ -Sequence< Type> OListBoxModel::_getTypes() -{ - return ::comphelper::concatSequences( - ::comphelper::concatSequences( + //------------------------------------------------------------------------------ + Sequence< Type> OListBoxModel::_getTypes() + { + return ::comphelper::concatSequences( + ::comphelper::concatSequences( OBoundControlModel::_getTypes(), OListBoxModel_BASE::getTypes(), OEntryListHelper::getTypes() - ), - OErrorBroadcaster::getTypes() - ); -} - - -DBG_NAME(OListBoxModel); -//------------------------------------------------------------------ -OListBoxModel::OListBoxModel(const Reference& _rxFactory) - :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_LISTBOX, FRM_CONTROL_LISTBOX, sal_True, sal_True ) - // use the old control name for compytibility reasons - ,OEntryListHelper( m_aMutex ) - ,OErrorBroadcaster( OComponentHelper::rBHelper ) - ,m_aRefreshListeners(m_aMutex) - ,m_bBoundComponent(sal_False) - ,m_eTransferSelectionAs( tsEntry ) - ,m_nNULLPos(-1) -{ - DBG_CTOR(OListBoxModel,NULL); - - m_nClassId = FormComponentType::LISTBOX; - m_eListSourceType = ListSourceType_VALUELIST; - m_aBoundColumn <<= (sal_Int16)1; - initValueProperty( PROPERTY_SELECT_SEQ, PROPERTY_ID_SELECT_SEQ); -} - -//------------------------------------------------------------------ -OListBoxModel::OListBoxModel( const OListBoxModel* _pOriginal, const Reference& _rxFactory ) - :OBoundControlModel( _pOriginal, _rxFactory ) - ,OEntryListHelper( m_aMutex ) - ,OErrorBroadcaster( OComponentHelper::rBHelper ) - ,m_aRefreshListeners( m_aMutex ) - ,m_bBoundComponent(sal_False) - ,m_eTransferSelectionAs( tsEntry ) - ,m_nNULLPos(-1) -{ - DBG_CTOR(OListBoxModel,NULL); - m_eListSourceType = _pOriginal->m_eListSourceType; - m_aBoundColumn = _pOriginal->m_aBoundColumn; -} - -//------------------------------------------------------------------ -OListBoxModel::~OListBoxModel() -{ - if (!OComponentHelper::rBHelper.bDisposed) - { - acquire(); - dispose(); + ), + OErrorBroadcaster::getTypes() + ); } - DBG_DTOR(OListBoxModel,NULL); -} -// XCloneable -//------------------------------------------------------------------------------ -IMPLEMENT_DEFAULT_CLONING( OListBoxModel ) - -// XServiceInfo -//------------------------------------------------------------------------------ -StringSequence SAL_CALL OListBoxModel::getSupportedServiceNames() throw(RuntimeException) -{ - StringSequence aSupported = OBoundControlModel::getSupportedServiceNames(); - aSupported.realloc(aSupported.getLength() + 3); - - ::rtl::OUString* pArray = aSupported.getArray(); - pArray[aSupported.getLength()-3] = FRM_SUN_COMPONENT_BINDDB_LISTBOX; - pArray[aSupported.getLength()-2] = FRM_SUN_COMPONENT_DATABASE_LISTBOX; - pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_LISTBOX; - return aSupported; -} - -//------------------------------------------------------------------------------ -Any SAL_CALL OListBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException) -{ - Any aReturn = OBoundControlModel::queryAggregation( _rType ); - if ( !aReturn.hasValue() ) - aReturn = OListBoxModel_BASE::queryInterface( _rType ); - if ( !aReturn.hasValue() ) - aReturn = OEntryListHelper::queryInterface( _rType ); - if ( !aReturn.hasValue() ) - aReturn = OErrorBroadcaster::queryInterface( _rType ); - return aReturn; -} - -// OComponentHelper -//------------------------------------------------------------------------------ -void OListBoxModel::disposing() -{ - EventObject aEvt( static_cast< XWeak* >( this ) ); - m_aRefreshListeners.disposeAndClear(aEvt); - - OBoundControlModel::disposing(); - OEntryListHelper::disposing(); - OErrorBroadcaster::disposing(); -} - -// XRefreshable -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxModel::addRefreshListener(const Reference& _rxListener) throw(RuntimeException) -{ - m_aRefreshListeners.addInterface(_rxListener); -} - -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxModel::removeRefreshListener(const Reference& _rxListener) throw(RuntimeException) -{ - m_aRefreshListeners.removeInterface(_rxListener); -} - -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxModel::refresh() throw(RuntimeException) -{ + DBG_NAME(OListBoxModel); + //------------------------------------------------------------------ + OListBoxModel::OListBoxModel(const Reference& _rxFactory) + :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_LISTBOX, FRM_CONTROL_LISTBOX, sal_True, sal_True ) + // use the old control name for compytibility reasons + ,OEntryListHelper( m_aMutex ) + ,OErrorBroadcaster( OComponentHelper::rBHelper ) + ,m_aRefreshListeners(m_aMutex) + ,m_bBoundComponent(sal_False) + ,m_eTransferSelectionAs( tsEntry ) + ,m_nNULLPos(-1) { - ::osl::MutexGuard aGuard( m_aMutex ); - if ( !hasExternalListSource() ) - implRefreshListFromDbBinding( ); + DBG_CTOR(OListBoxModel,NULL); + + m_nClassId = FormComponentType::LISTBOX; + m_eListSourceType = ListSourceType_VALUELIST; + m_aBoundColumn <<= (sal_Int16)1; + initValueProperty( PROPERTY_SELECT_SEQ, PROPERTY_ID_SELECT_SEQ); } - EventObject aEvt(static_cast< XWeak*>(this)); - NOTIFY_LISTENERS(m_aRefreshListeners, XRefreshListener, refreshed, aEvt); -} - -//------------------------------------------------------------------------------ -void OListBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const -{ - switch (_nHandle) + //------------------------------------------------------------------ + OListBoxModel::OListBoxModel( const OListBoxModel* _pOriginal, const Reference& _rxFactory ) + :OBoundControlModel( _pOriginal, _rxFactory ) + ,OEntryListHelper( m_aMutex ) + ,OErrorBroadcaster( OComponentHelper::rBHelper ) + ,m_aRefreshListeners( m_aMutex ) + ,m_bBoundComponent(sal_False) + ,m_eTransferSelectionAs( tsEntry ) + ,m_nNULLPos(-1) { + DBG_CTOR(OListBoxModel,NULL); + m_eListSourceType = _pOriginal->m_eListSourceType; + m_aBoundColumn = _pOriginal->m_aBoundColumn; + } + + //------------------------------------------------------------------ + OListBoxModel::~OListBoxModel() + { + if (!OComponentHelper::rBHelper.bDisposed) + { + acquire(); + dispose(); + } + + DBG_DTOR(OListBoxModel,NULL); + } + + // XCloneable + //------------------------------------------------------------------------------ + IMPLEMENT_DEFAULT_CLONING( OListBoxModel ) + + // XServiceInfo + //------------------------------------------------------------------------------ + StringSequence SAL_CALL OListBoxModel::getSupportedServiceNames() throw(RuntimeException) + { + StringSequence aSupported = OBoundControlModel::getSupportedServiceNames(); + aSupported.realloc(aSupported.getLength() + 3); + + ::rtl::OUString* pArray = aSupported.getArray(); + pArray[aSupported.getLength()-3] = FRM_SUN_COMPONENT_BINDDB_LISTBOX; + pArray[aSupported.getLength()-2] = FRM_SUN_COMPONENT_DATABASE_LISTBOX; + pArray[aSupported.getLength()-1] = FRM_SUN_COMPONENT_LISTBOX; + return aSupported; + } + + //------------------------------------------------------------------------------ + Any SAL_CALL OListBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException) + { + Any aReturn = OBoundControlModel::queryAggregation( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OListBoxModel_BASE::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OEntryListHelper::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OErrorBroadcaster::queryInterface( _rType ); + return aReturn; + } + + // OComponentHelper + //------------------------------------------------------------------------------ + void OListBoxModel::disposing() + { + EventObject aEvt( static_cast< XWeak* >( this ) ); + m_aRefreshListeners.disposeAndClear(aEvt); + + OBoundControlModel::disposing(); + OEntryListHelper::disposing(); + OErrorBroadcaster::disposing(); + } + + // XRefreshable + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxModel::addRefreshListener(const Reference& _rxListener) throw(RuntimeException) + { + m_aRefreshListeners.addInterface(_rxListener); + } + + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxModel::removeRefreshListener(const Reference& _rxListener) throw(RuntimeException) + { + m_aRefreshListeners.removeInterface(_rxListener); + } + + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxModel::refresh() throw(RuntimeException) + { + { + ::osl::MutexGuard aGuard( m_aMutex ); + if ( !hasExternalListSource() ) + implRefreshListFromDbBinding( ); + } + + EventObject aEvt(static_cast< XWeak*>(this)); + NOTIFY_LISTENERS(m_aRefreshListeners, XRefreshListener, refreshed, aEvt); + } + + //------------------------------------------------------------------------------ + void OListBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const + { + switch (_nHandle) + { case PROPERTY_ID_BOUNDCOLUMN: _rValue <<= m_aBoundColumn; break; @@ -341,14 +341,14 @@ void OListBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const default: OBoundControlModel::getFastPropertyValue(_rValue, _nHandle); + } } -} -//------------------------------------------------------------------------------ -void OListBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (com::sun::star::uno::Exception) -{ - switch (_nHandle) + //------------------------------------------------------------------------------ + void OListBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (com::sun::star::uno::Exception) { + switch (_nHandle) + { case PROPERTY_ID_BOUNDCOLUMN : DBG_ASSERT((_rValue.getValueType().getTypeClass() == TypeClass_SHORT) || (_rValue.getValueType().getTypeClass() == TypeClass_VOID), "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" ); @@ -398,17 +398,17 @@ void OListBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const A default: OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue); + } } -} -//------------------------------------------------------------------------------ -sal_Bool OListBoxModel::convertFastPropertyValue( - Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue) - throw (IllegalArgumentException) -{ - sal_Bool bModified(sal_False); - switch (_nHandle) + //------------------------------------------------------------------------------ + sal_Bool OListBoxModel::convertFastPropertyValue( + Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue) + throw (IllegalArgumentException) { + sal_Bool bModified(sal_False); + switch (_nHandle) + { case PROPERTY_ID_BOUNDCOLUMN : bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aBoundColumn, ::getCppuType(reinterpret_cast(NULL))); break; @@ -435,1206 +435,1211 @@ sal_Bool OListBoxModel::convertFastPropertyValue( default: return OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue); + } + return bModified; } - return bModified; -} -//------------------------------------------------------------------------------ -Reference SAL_CALL OListBoxModel::getPropertySetInfo() throw(RuntimeException) -{ + //------------------------------------------------------------------------------ + Reference SAL_CALL OListBoxModel::getPropertySetInfo() throw(RuntimeException) + { Reference xInfo( createPropertySetInfo( getInfoHelper() ) ); - return xInfo; -} - -//------------------------------------------------------------------------------ -cppu::IPropertyArrayHelper& OListBoxModel::getInfoHelper() -{ - return *const_cast(this)->getArrayHelper(); -} - -//------------------------------------------------------------------------------ -void OListBoxModel::fillProperties( - Sequence< Property >& _rProps, - Sequence< Property >& _rAggregateProps ) const -{ - FRM_BEGIN_PROP_HELPER(14) - RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST ); - // we want to "override" this property - - DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT); - DECL_PROP1(NAME, ::rtl::OUString, BOUND); - DECL_PROP1(TAG, ::rtl::OUString, BOUND); - DECL_PROP1(TABINDEX, sal_Int16, BOUND); - DECL_PROP2(BOUNDCOLUMN, sal_Int16, BOUND, MAYBEVOID); - DECL_PROP1(LISTSOURCETYPE, ListSourceType, BOUND); - DECL_PROP1(LISTSOURCE, StringSequence, BOUND); - DECL_PROP3(VALUE_SEQ, StringSequence, BOUND, READONLY, TRANSIENT); - DECL_PROP1(DEFAULT_SELECT_SEQ, Sequence, BOUND); - DECL_PROP1(CONTROLSOURCE, ::rtl::OUString, BOUND); - DECL_IFACE_PROP3(BOUNDFIELD, XPropertySet, BOUND,READONLY, TRANSIENT); - DECL_IFACE_PROP2(CONTROLLABEL, XPropertySet, BOUND, MAYBEVOID); - DECL_PROP2(CONTROLSOURCEPROPERTY, rtl::OUString, READONLY, TRANSIENT); - DECL_PROP1(STRINGITEMLIST, Sequence< ::rtl::OUString >, BOUND); - FRM_END_PROP_HELPER(); -} - -//------------------------------------------------------------------------------ -::rtl::OUString SAL_CALL OListBoxModel::getServiceName() throw(RuntimeException) -{ - return FRM_COMPONENT_LISTBOX; // old (non-sun) name for compatibility ! -} - -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxModel::write(const Reference& _rxOutStream) - throw(stario::IOException, RuntimeException) -{ - OBoundControlModel::write(_rxOutStream); - - // Dummy-Seq, um Kompatible zu bleiben, wenn SelectSeq nicht mehr gespeichert wird - Sequence aDummySeq; - - // Version - // Version 0x0002: ListSource wird StringSeq - _rxOutStream->writeShort(0x0004); - - // Maskierung fuer any - sal_uInt16 nAnyMask = 0; - if (m_aBoundColumn.getValueType().getTypeClass() != TypeClass_VOID) - nAnyMask |= BOUNDCOLUMN; - - _rxOutStream << nAnyMask; - - _rxOutStream << m_aListSourceSeq; - _rxOutStream << (sal_Int16)m_eListSourceType; - _rxOutStream << aDummySeq; - _rxOutStream << m_aDefaultSelectSeq; - - if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN) - { - sal_Int16 nBoundColumn; - m_aBoundColumn >>= nBoundColumn; - _rxOutStream << nBoundColumn; - } - writeHelpTextCompatibly(_rxOutStream); - - // from version 0x0004 : common properties - writeCommonProperties(_rxOutStream); -} - -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxModel::read(const Reference& _rxInStream) throw(stario::IOException, RuntimeException) -{ - // Bei manchen Variblen muessen Abhaengigkeiten beruecksichtigt werden. - // Deshalb muessen sie explizit ueber setPropertyValue() gesetzt werden. - - OBoundControlModel::read(_rxInStream); - ::osl::MutexGuard aGuard(m_aMutex); - - // Version - sal_uInt16 nVersion = _rxInStream->readShort(); - DBG_ASSERT(nVersion > 0, "OListBoxModel::read : version 0 ? this should never have been written !"); - - if (nVersion > 0x0004) - { - DBG_ERROR("OListBoxModel::read : invalid (means unknown) version !"); - m_aListSourceSeq.realloc(0); - m_aBoundColumn <<= (sal_Int16)0; - m_aValueSeq.realloc(0); - m_eListSourceType = ListSourceType_VALUELIST; - m_aDefaultSelectSeq.realloc(0); - defaultCommonProperties(); - return; + return xInfo; } - // Maskierung fuer any - sal_uInt16 nAnyMask; - _rxInStream >> nAnyMask; - - // ListSourceSeq - StringSequence aListSourceSeq; - if (nVersion == 0x0001) + //------------------------------------------------------------------------------ + cppu::IPropertyArrayHelper& OListBoxModel::getInfoHelper() { - // ListSourceSeq aus String zusammenstellen; - ::rtl::OUString sListSource; - _rxInStream >> sListSource; + return *const_cast(this)->getArrayHelper(); + } - sal_Int32 nTokens = 1; - const sal_Unicode* pStr = sListSource.getStr(); - while ( *pStr ) + //------------------------------------------------------------------------------ + void OListBoxModel::fillProperties( + Sequence< Property >& _rProps, + Sequence< Property >& _rAggregateProps ) const + { + FRM_BEGIN_PROP_HELPER(14) + RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST ); + // we want to "override" this property + + DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT); + DECL_PROP1(NAME, ::rtl::OUString, BOUND); + DECL_PROP1(TAG, ::rtl::OUString, BOUND); + DECL_PROP1(TABINDEX, sal_Int16, BOUND); + DECL_PROP2(BOUNDCOLUMN, sal_Int16, BOUND, MAYBEVOID); + DECL_PROP1(LISTSOURCETYPE, ListSourceType, BOUND); + DECL_PROP1(LISTSOURCE, StringSequence, BOUND); + DECL_PROP3(VALUE_SEQ, StringSequence, BOUND, READONLY, TRANSIENT); + DECL_PROP1(DEFAULT_SELECT_SEQ, Sequence, BOUND); + DECL_PROP1(CONTROLSOURCE, ::rtl::OUString, BOUND); + DECL_IFACE_PROP3(BOUNDFIELD, XPropertySet, BOUND,READONLY, TRANSIENT); + DECL_IFACE_PROP2(CONTROLLABEL, XPropertySet, BOUND, MAYBEVOID); + DECL_PROP2(CONTROLSOURCEPROPERTY, rtl::OUString, READONLY, TRANSIENT); + DECL_PROP1(STRINGITEMLIST, Sequence< ::rtl::OUString >, BOUND); + FRM_END_PROP_HELPER(); + } + + //------------------------------------------------------------------------------ + ::rtl::OUString SAL_CALL OListBoxModel::getServiceName() throw(RuntimeException) + { + return FRM_COMPONENT_LISTBOX; // old (non-sun) name for compatibility ! + } + + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxModel::write(const Reference& _rxOutStream) + throw(stario::IOException, RuntimeException) + { + OBoundControlModel::write(_rxOutStream); + + // Dummy-Seq, um Kompatible zu bleiben, wenn SelectSeq nicht mehr gespeichert wird + Sequence aDummySeq; + + // Version + // Version 0x0002: ListSource wird StringSeq + _rxOutStream->writeShort(0x0004); + + // Maskierung fuer any + sal_uInt16 nAnyMask = 0; + if (m_aBoundColumn.getValueType().getTypeClass() != TypeClass_VOID) + nAnyMask |= BOUNDCOLUMN; + + _rxOutStream << nAnyMask; + + _rxOutStream << m_aListSourceSeq; + _rxOutStream << (sal_Int16)m_eListSourceType; + _rxOutStream << aDummySeq; + _rxOutStream << m_aDefaultSelectSeq; + + if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN) { - if ( *pStr == ';' ) - nTokens++; - pStr++; + sal_Int16 nBoundColumn; + m_aBoundColumn >>= nBoundColumn; + _rxOutStream << nBoundColumn; } - aListSourceSeq.realloc( nTokens ); - for (sal_uInt16 i=0; i& _rxInStream) throw(stario::IOException, RuntimeException) + { + // Bei manchen Variblen muessen Abhaengigkeiten beruecksichtigt werden. + // Deshalb muessen sie explizit ueber setPropertyValue() gesetzt werden. + + OBoundControlModel::read(_rxInStream); + ::osl::MutexGuard aGuard(m_aMutex); + + // Version + sal_uInt16 nVersion = _rxInStream->readShort(); + DBG_ASSERT(nVersion > 0, "OListBoxModel::read : version 0 ? this should never have been written !"); + + if (nVersion > 0x0004) { - sal_Int32 nTmp = 0; - aListSourceSeq.getArray()[i] = sListSource.getToken(i,';',nTmp); + DBG_ERROR("OListBoxModel::read : invalid (means unknown) version !"); + m_aListSourceSeq.realloc(0); + m_aBoundColumn <<= (sal_Int16)0; + m_aValueSeq.realloc(0); + m_eListSourceType = ListSourceType_VALUELIST; + m_aDefaultSelectSeq.realloc(0); + defaultCommonProperties(); + return; } + + // Maskierung fuer any + sal_uInt16 nAnyMask; + _rxInStream >> nAnyMask; + + // ListSourceSeq + StringSequence aListSourceSeq; + if (nVersion == 0x0001) + { + // ListSourceSeq aus String zusammenstellen; + ::rtl::OUString sListSource; + _rxInStream >> sListSource; + + sal_Int32 nTokens = 1; + const sal_Unicode* pStr = sListSource.getStr(); + while ( *pStr ) + { + if ( *pStr == ';' ) + nTokens++; + pStr++; + } + aListSourceSeq.realloc( nTokens ); + for (sal_uInt16 i=0; i> aListSourceSeq; + + sal_Int16 nListSourceType; + _rxInStream >> nListSourceType; + m_eListSourceType = (ListSourceType)nListSourceType; + Any aListSourceSeqAny; + aListSourceSeqAny <<= aListSourceSeq; + + setFastPropertyValue(PROPERTY_ID_LISTSOURCE, aListSourceSeqAny ); + + // Dummy-Seq, um Kompatible zu bleiben, wenn SelectSeq nicht mehr gespeichert wird + Sequence aDummySeq; + _rxInStream >> aDummySeq; + + // DefaultSelectSeq + Sequence aDefaultSelectSeq; + _rxInStream >> aDefaultSelectSeq; + Any aDefaultSelectSeqAny; + aDefaultSelectSeqAny <<= aDefaultSelectSeq; + setFastPropertyValue(PROPERTY_ID_DEFAULT_SELECT_SEQ, aDefaultSelectSeqAny); + + // BoundColumn + if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN) + { + sal_Int16 nValue; + _rxInStream >> nValue; + m_aBoundColumn <<= nValue; + } + + if (nVersion > 2) + readHelpTextCompatibly(_rxInStream); + + // if our string list is not filled from the value list, we must empty it + // this can be the case when somebody saves in alive mode + if ( ( m_eListSourceType != ListSourceType_VALUELIST ) + && !hasExternalListSource() + ) + { + setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) ); + } + + if (nVersion > 3) + readCommonProperties(_rxInStream); + + // Nach dem Lesen die Defaultwerte anzeigen + if (m_aControlSource.getLength()) + // (not if we don't have a control source - the "State" property acts like it is persistent, then + resetNoBroadcast(); } - else - _rxInStream >> aListSourceSeq; - sal_Int16 nListSourceType; - _rxInStream >> nListSourceType; - m_eListSourceType = (ListSourceType)nListSourceType; - Any aListSourceSeqAny; - aListSourceSeqAny <<= aListSourceSeq; - - setFastPropertyValue(PROPERTY_ID_LISTSOURCE, aListSourceSeqAny ); - - // Dummy-Seq, um Kompatible zu bleiben, wenn SelectSeq nicht mehr gespeichert wird - Sequence aDummySeq; - _rxInStream >> aDummySeq; - - // DefaultSelectSeq - Sequence aDefaultSelectSeq; - _rxInStream >> aDefaultSelectSeq; - Any aDefaultSelectSeqAny; - aDefaultSelectSeqAny <<= aDefaultSelectSeq; - setFastPropertyValue(PROPERTY_ID_DEFAULT_SELECT_SEQ, aDefaultSelectSeqAny); - - // BoundColumn - if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN) + //------------------------------------------------------------------------------ + void OListBoxModel::loadData() { - sal_Int16 nValue; - _rxInStream >> nValue; - m_aBoundColumn <<= nValue; - } + DBG_ASSERT( m_eListSourceType != ListSourceType_VALUELIST, "OListBoxModel::loadData: cannot load value list from DB!" ); + DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::loadData: cannot load from DB when I have an external list source!" ); - if (nVersion > 2) - readHelpTextCompatibly(_rxInStream); + m_nNULLPos = -1; + m_bBoundComponent = sal_False; - // if our string list is not filled from the value list, we must empty it - // this can be the case when somebody saves in alive mode - if ( ( m_eListSourceType != ListSourceType_VALUELIST ) - && !hasExternalListSource() - ) - { - setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) ); - } + // Connection holen + Reference xForm(m_xCursor, UNO_QUERY); + if (!xForm.is()) + return; + Reference xConnection = getConnection(xForm); + if (!xConnection.is()) + return; - if (nVersion > 3) - readCommonProperties(_rxInStream); - - // Nach dem Lesen die Defaultwerte anzeigen - if (m_aControlSource.getLength()) - // (not if we don't have a control source - the "State" property acts like it is persistent, then - resetNoBroadcast(); -} - -//------------------------------------------------------------------------------ -void OListBoxModel::loadData() -{ - DBG_ASSERT( m_eListSourceType != ListSourceType_VALUELIST, "OListBoxModel::loadData: cannot load value list from DB!" ); - DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::loadData: cannot load from DB when I have an external list source!" ); - - m_nNULLPos = -1; - m_bBoundComponent = sal_False; - - // Connection holen - Reference xForm(m_xCursor, UNO_QUERY); - if (!xForm.is()) - return; - Reference xConnection = getConnection(xForm); - if (!xConnection.is()) - return; - - // we need a com::sun::star::sdb::Connection for some of the code below ... + // we need a com::sun::star::sdb::Connection for some of the code below ... Reference xServiceInfo(xConnection, UNO_QUERY); - if (!xServiceInfo.is() || !xServiceInfo->supportsService(SRV_SDB_CONNECTION)) - { - DBG_ERROR("OListBoxModel::loadData : invalid connection !"); - return; - } - - Reference< XRowSet > xContentRowSet(m_xServiceFactory->createInstance(SRV_SDB_ROWSET), UNO_QUERY); - Reference< XPropertySet > xContentSetProperties(xContentRowSet, UNO_QUERY); - Reference xListCursor(xContentSetProperties, UNO_QUERY); - if (!xListCursor.is()) - { - DBG_ERROR("OListBoxModel::loadData: could not instantiate a RowSet!"); - return; - } - - // Wenn der ListSourceType keine Werteliste ist, - // muss die String-Seq zu einem String zusammengefasst werden - ::rtl::OUString sListSource; - const ::rtl::OUString* pustrListSouceStrings = m_aListSourceSeq.getConstArray(); - sal_Int32 i; - for (i=0; i>= nBoundColumn; - - try - { - sal_Bool bExecute = sal_False; - switch (m_eListSourceType) + if (!xServiceInfo.is() || !xServiceInfo->supportsService(SRV_SDB_CONNECTION)) { + DBG_ERROR("OListBoxModel::loadData : invalid connection !"); + return; + } + + Reference< XRowSet > xContentRowSet(m_xServiceFactory->createInstance(SRV_SDB_ROWSET), UNO_QUERY); + Reference< XPropertySet > xContentSetProperties(xContentRowSet, UNO_QUERY); + Reference xListCursor(xContentSetProperties, UNO_QUERY); + if (!xListCursor.is()) + { + DBG_ERROR("OListBoxModel::loadData: could not instantiate a RowSet!"); + return; + } + + // Wenn der ListSourceType keine Werteliste ist, + // muss die String-Seq zu einem String zusammengefasst werden + ::rtl::OUString sListSource; + const ::rtl::OUString* pustrListSouceStrings = m_aListSourceSeq.getConstArray(); + sal_Int32 i; + for (i=0; i>= nBoundColumn; + + try + { + sal_Bool bExecute = sal_False; + switch (m_eListSourceType) + { case ListSourceType_TABLEFIELDS: // don't work with a statement here, the fields will be collected below break; + case ListSourceType_TABLE: - { - Reference xFieldsByName = getTableFields(xConnection, sListSource); - Reference xFieldsByIndex(xFieldsByName, UNO_QUERY); - - // do we have a bound column if yes we have to select it - // and the displayed column is the first column othwhise we act as a combobox - ::rtl::OUString aFieldName; - ::rtl::OUString aBoundFieldName; - - if ((nBoundColumn > 0) && xFieldsByIndex.is()) { - if (xFieldsByIndex->getCount() <= nBoundColumn) + Reference xFieldsByName = getTableFields(xConnection, sListSource); + Reference xFieldsByIndex(xFieldsByName, UNO_QUERY); + + // do we have a bound column if yes we have to select it + // and the displayed column is the first column othwhise we act as a combobox + ::rtl::OUString aFieldName; + ::rtl::OUString aBoundFieldName; + + if ((nBoundColumn > 0) && xFieldsByIndex.is()) + { + if (xFieldsByIndex->getCount() <= nBoundColumn) + break; + + Reference xFieldAsSet; + xFieldsByIndex->getByIndex(nBoundColumn) >>= xFieldAsSet; + xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aBoundFieldName; + nBoundColumn = 1; + + xFieldsByIndex->getByIndex(0) >>= xFieldAsSet; + xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aFieldName; + } + else if (xFieldsByName.is()) + { + if (xFieldsByName->hasByName(m_aControlSource)) + aFieldName = m_aControlSource; + else + { + // otherwise look for the alias + Reference xFactory(xConnection, UNO_QUERY); + if (!xFactory.is()) + break; + + Reference xComposer = xFactory->createQueryComposer(); + try + { + Reference xFormAsSet(xForm, UNO_QUERY); + ::rtl::OUString aStatement; + xFormAsSet->getPropertyValue(PROPERTY_ACTIVECOMMAND) >>= aStatement; + xComposer->setQuery(aStatement); + } + catch(Exception&) + { + disposeComponent(xComposer); + break; + } + + // search the field + Reference xSupplyFields(xComposer, UNO_QUERY); + DBG_ASSERT(xSupplyFields.is(), "OListBoxModel::loadData : invalid query composer !"); + + Reference xFieldNames = xSupplyFields->getColumns(); + if (xFieldNames->hasByName(m_aControlSource)) + { + Reference xComposerFieldAsSet; + xFieldNames->getByName(m_aControlSource) >>= xComposerFieldAsSet; + if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet)) + xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName; + } + disposeComponent(xComposer); + } + } + if (!aFieldName.getLength()) break; - Reference xFieldAsSet; - xFieldsByIndex->getByIndex(nBoundColumn) >>= xFieldAsSet; - xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aBoundFieldName; - nBoundColumn = 1; + Reference xMeta = xConnection->getMetaData(); + ::rtl::OUString aQuote = xMeta->getIdentifierQuoteString(); + ::rtl::OUString aStatement = ::rtl::OUString::createFromAscii("SELECT "); + if (!aBoundFieldName.getLength()) // act like a combobox + aStatement += ::rtl::OUString::createFromAscii("DISTINCT "); - xFieldsByIndex->getByIndex(0) >>= xFieldAsSet; - xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aFieldName; - } - else if (xFieldsByName.is()) - { - if (xFieldsByName->hasByName(m_aControlSource)) - aFieldName = m_aControlSource; - else + aStatement += quoteName(aQuote,aFieldName); + if (aBoundFieldName.getLength()) { - // otherwise look for the alias - Reference xFactory(xConnection, UNO_QUERY); - if (!xFactory.is()) - break; - - Reference xComposer = xFactory->createQueryComposer(); - try - { - Reference xFormAsSet(xForm, UNO_QUERY); - ::rtl::OUString aStatement; - xFormAsSet->getPropertyValue(PROPERTY_ACTIVECOMMAND) >>= aStatement; - xComposer->setQuery(aStatement); - } - catch(Exception&) - { - disposeComponent(xComposer); - break; - } - - // search the field - Reference xSupplyFields(xComposer, UNO_QUERY); - DBG_ASSERT(xSupplyFields.is(), "OListBoxModel::loadData : invalid query composer !"); - - Reference xFieldNames = xSupplyFields->getColumns(); - if (xFieldNames->hasByName(m_aControlSource)) - { - Reference xComposerFieldAsSet; - xFieldNames->getByName(m_aControlSource) >>= xComposerFieldAsSet; - if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet)) - xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName; - } - disposeComponent(xComposer); + aStatement += ::rtl::OUString::createFromAscii(", "); + aStatement += quoteName(aQuote, aBoundFieldName); } + aStatement += ::rtl::OUString::createFromAscii(" FROM "); + aStatement += quoteTableName(xMeta, sListSource,::dbtools::eInDataManipulation); + + xContentSetProperties->setPropertyValue(PROPERTY_COMMAND, makeAny(aStatement)); + bExecute = sal_True; } - if (!aFieldName.getLength()) - break; + break; - Reference xMeta = xConnection->getMetaData(); - ::rtl::OUString aQuote = xMeta->getIdentifierQuoteString(); - ::rtl::OUString aStatement = ::rtl::OUString::createFromAscii("SELECT "); - if (!aBoundFieldName.getLength()) // act like a combobox - aStatement += ::rtl::OUString::createFromAscii("DISTINCT "); - - aStatement += quoteName(aQuote,aFieldName); - if (aBoundFieldName.getLength()) - { - aStatement += ::rtl::OUString::createFromAscii(", "); - aStatement += quoteName(aQuote, aBoundFieldName); - } - aStatement += ::rtl::OUString::createFromAscii(" FROM "); - aStatement += quoteTableName(xMeta, sListSource,::dbtools::eInDataManipulation); - - xContentSetProperties->setPropertyValue(PROPERTY_COMMAND, makeAny(aStatement)); - bExecute = sal_True; - } break; case ListSourceType_QUERY: - { - Reference xSupplyQueries(xConnection, UNO_QUERY); - Reference xQuery(*(InterfaceRef*)xSupplyQueries->getQueries()->getByName(sListSource).getValue(), UNO_QUERY); - xContentSetProperties->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, xQuery->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)); + { + Reference xSupplyQueries(xConnection, UNO_QUERY); + Reference xQuery(*(InterfaceRef*)xSupplyQueries->getQueries()->getByName(sListSource).getValue(), UNO_QUERY); + xContentSetProperties->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, xQuery->getPropertyValue(PROPERTY_ESCAPE_PROCESSING)); + + xContentSetProperties->setPropertyValue(PROPERTY_COMMAND, xQuery->getPropertyValue(PROPERTY_COMMAND)); + bExecute = sal_True; + } + break; - xContentSetProperties->setPropertyValue(PROPERTY_COMMAND, xQuery->getPropertyValue(PROPERTY_COMMAND)); - bExecute = sal_True; - } break; default: + { + if (ListSourceType_SQLPASSTHROUGH == m_eListSourceType) + xContentSetProperties->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any((sal_False))); + xContentSetProperties->setPropertyValue(PROPERTY_COMMAND, makeAny(sListSource)); + bExecute = sal_True; + } + } + + if (bExecute) { - if (ListSourceType_SQLPASSTHROUGH == m_eListSourceType) - xContentSetProperties->setPropertyValue(PROPERTY_ESCAPE_PROCESSING, ::cppu::bool2any((sal_False))); - xContentSetProperties->setPropertyValue(PROPERTY_COMMAND, makeAny(sListSource)); - bExecute = sal_True; + Reference< XPropertySet > xFormProps(xForm, UNO_QUERY); + + xContentSetProperties->setPropertyValue( PROPERTY_COMMANDTYPE, makeAny( CommandType::COMMAND ) ); + xContentSetProperties->setPropertyValue( PROPERTY_DATASOURCE, xFormProps->getPropertyValue( PROPERTY_DATASOURCE ) ); + + // try to give the row set the connection of our form - this saves the rowset from creating an own one + xContentSetProperties->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, xFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) ); + + xContentRowSet->execute(); } } - - if (bExecute) + catch(SQLException& eSQL) { - Reference< XPropertySet > xFormProps(xForm, UNO_QUERY); - - xContentSetProperties->setPropertyValue( PROPERTY_COMMANDTYPE, makeAny( CommandType::COMMAND ) ); - xContentSetProperties->setPropertyValue( PROPERTY_DATASOURCE, xFormProps->getPropertyValue( PROPERTY_DATASOURCE ) ); - - // try to give the row set the connection of our form - this saves the rowset from creating an own one - xContentSetProperties->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, xFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) ); - - xContentRowSet->execute(); + onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST)); + disposeComponent(xListCursor); + return; } - } - catch(SQLException& eSQL) - { - onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST)); - disposeComponent(xListCursor); - return; - } - catch(Exception& eUnknown) - { - eUnknown; - disposeComponent(xListCursor); - return; - } - - if (ListSourceType_TABLEFIELDS != m_eListSourceType && !xListCursor.is()) - // something went wrong ... - return; - - // Anzeige- und Werteliste fuellen - vector< ::rtl::OUString > aValueList, aStringList; - aValueList.reserve(16); - aStringList.reserve(16); - sal_Bool bUseNULL = getField().is() && !m_bRequired; - try - { - switch (m_eListSourceType) + catch(Exception& eUnknown) { + eUnknown; + disposeComponent(xListCursor); + return; + } + + if (ListSourceType_TABLEFIELDS != m_eListSourceType && !xListCursor.is()) + // something went wrong ... + return; + + // Anzeige- und Werteliste fuellen + vector< ::rtl::OUString > aValueList, aStringList; + aValueList.reserve(16); + aStringList.reserve(16); + sal_Bool bUseNULL = getField().is() && !m_bRequired; + try + { + switch (m_eListSourceType) + { case ListSourceType_SQL: case ListSourceType_SQLPASSTHROUGH: case ListSourceType_TABLE: case ListSourceType_QUERY: + { + // Feld der 1. Column des ResultSets holen + Reference xSupplyCols(xListCursor, UNO_QUERY); + DBG_ASSERT(xSupplyCols.is(), "OListBoxModel::loadData : cursor supports the row set service but is no column supplier ??!"); + Reference xColumns; + if (xSupplyCols.is()) + { + xColumns = Reference(xSupplyCols->getColumns(), UNO_QUERY); + DBG_ASSERT(xColumns.is(), "OListBoxModel::loadData : no columns supplied by the row set !"); + } + Reference xDataField; + if (xColumns.is()) + xColumns->getByIndex(0) >>= xDataField; + if (!xDataField.is()) + { + disposeComponent(xListCursor); + return; + } + + Reference xSupplier = getNumberFormats(xConnection, sal_False, m_xServiceFactory); + + ::com::sun::star::util::Date aNullDate(DBTypeConversion::getStandardDate()); + sal_Int32 nFormatKey = 0; + sal_Int32 nFieldType = DataType::OTHER; + sal_Int16 nKeyType = NumberFormat::UNDEFINED; + sal_Bool bHaveFormat = sal_False; + Reference xFieldAsSet(xDataField, UNO_QUERY); + try + { + xFieldAsSet->getPropertyValue(PROPERTY_FIELDTYPE) >>= nFieldType; + bHaveFormat = (xFieldAsSet->getPropertyValue(PROPERTY_FORMATKEY) >>= nFormatKey); + } + catch(Exception&) + { + DBG_ERROR("OListBoxModel::loadData: could not obtain the field type and/or format key of the bound column!"); + } + + if (!bHaveFormat) + { + Locale aAppLanguage = Application::GetSettings().GetUILocale(); + if (xSupplier.is()) + { + Reference< XNumberFormatTypes > xNumTypes(xSupplier->getNumberFormats(), UNO_QUERY); + if (xNumTypes.is()) + nFormatKey = getDefaultNumberFormat(xFieldAsSet, xNumTypes, aAppLanguage); + } + } + + Reference xFormatter; + if (xSupplier.is()) + { + xFormatter = Reference( + m_xServiceFactory->createInstance(FRM_NUMBER_FORMATTER), + UNO_QUERY + ); + if (xFormatter.is()) + { + xFormatter->attachNumberFormatsSupplier(xSupplier); + xFormatter->getNumberFormatsSupplier()->getNumberFormatSettings()->getPropertyValue( + ::rtl::OUString::createFromAscii("NullDate")) >>= aNullDate; + nKeyType = getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey); + } + } + + // Feld der BoundColumn des ResultSets holen + Reference xBoundField; + if ((nBoundColumn > 0) && m_xColumn.is()) + // don't look for a bound column if we're not connected to a field + xColumns->getByIndex(nBoundColumn) >>= xBoundField; + m_bBoundComponent = xBoundField.is(); + + // Ist die LB an ein Feld gebunden und sind Leereinträge zulaessig + // dann wird die Position fuer einen Leereintrag gemerkt + + ::rtl::OUString aStr; + sal_Int16 i = 0; + // per definitionem the list cursor is positioned _before_ the first row at the moment + while (xListCursor->next() && (i++getString(); + aValueList.push_back(aStr); + } + + if (bUseNULL && (m_nNULLPos == -1) && !aStr.getLength()) + m_nNULLPos = (sal_Int16)aStringList.size() - 1; + } + } + break; + + case ListSourceType_TABLEFIELDS: + { + Reference xFieldNames = getTableFields(xConnection, sListSource); + if (xFieldNames.is()) + { + StringSequence seqNames = xFieldNames->getElementNames(); + sal_Int32 nFieldsCount = seqNames.getLength(); + const ::rtl::OUString* pustrNames = seqNames.getConstArray(); + + for (sal_Int32 k=0; k& _rxForm ) + { + // list boxes which are bound to a db column don't have multi selection + // - this would be unable to reflect in the db column + if ( getField().is() ) + { + setFastPropertyValue( PROPERTY_ID_MULTISELECTION, ::cppu::bool2any( ( sal_False ) ) ); + } + + if ( !hasExternalListSource() ) + implRefreshListFromDbBinding( ); + } + + //------------------------------------------------------------------------------ + void OListBoxModel::onDisconnectedDbColumn() + { + if (m_eListSourceType != ListSourceType_VALUELIST) + { + m_aValueSeq = StringSequence(); + m_nNULLPos = -1; + m_bBoundComponent = sal_False; + + if ( !hasExternalListSource() ) + setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) ); + } + } + + //------------------------------------------------------------------------------ + StringSequence OListBoxModel::GetCurValueSeq() const + { + StringSequence aCurValues; + + // Aus den selektierten Indizes Werte-Sequence aufbauen + DBG_ASSERT(m_xAggregateFastSet.is(), "OListBoxModel::GetCurValueSeq : invalid aggregate !"); + if (!m_xAggregateFastSet.is()) + return aCurValues; + + Any aTmp = m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ); + + Sequence aSelectSeq; aTmp >>= aSelectSeq; + const sal_Int16 *pSels = aSelectSeq.getConstArray(); + sal_uInt32 nSelCount = aSelectSeq.getLength(); + + if (nSelCount) + { + StringSequence aValues; + if ( m_aValueSeq.getLength() ) { - // Feld der 1. Column des ResultSets holen - Reference xSupplyCols(xListCursor, UNO_QUERY); - DBG_ASSERT(xSupplyCols.is(), "OListBoxModel::loadData : cursor supports the row set service but is no column supplier ??!"); - Reference xColumns; - if (xSupplyCols.is()) - { - xColumns = Reference(xSupplyCols->getColumns(), UNO_QUERY); - DBG_ASSERT(xColumns.is(), "OListBoxModel::loadData : no columns supplied by the row set !"); - } - Reference xDataField; - if (xColumns.is()) - xColumns->getByIndex(0) >>= xDataField; - if (!xDataField.is()) - { - disposeComponent(xListCursor); - return; - } + aValues = m_aValueSeq; + } + else + { + aValues = getStringItemList(); + } - Reference xSupplier = getNumberFormats(xConnection, sal_False, m_xServiceFactory); + const ::rtl::OUString *pVals = aValues.getConstArray(); + sal_Int32 nValCnt = aValues.getLength(); - ::com::sun::star::util::Date aNullDate(DBTypeConversion::getStandardDate()); - sal_Int32 nFormatKey = 0; - sal_Int32 nFieldType = DataType::OTHER; - sal_Int16 nKeyType = NumberFormat::UNDEFINED; - sal_Bool bHaveFormat = sal_False; - Reference xFieldAsSet(xDataField, UNO_QUERY); + if (nSelCount > 1) + { + // Einfach- oder Mehrfach-Selektion + sal_Bool bMultiSel; + const_cast(this)->OPropertySetAggregationHelper::getFastPropertyValue(PROPERTY_ID_MULTISELECTION) >>= bMultiSel; + if (bMultiSel) + nSelCount = 1; + } + + // ist der Eintrag fuer NULL selektiert ? + // dann leere Selektion liefern + if (m_nNULLPos != -1 && nSelCount == 1 && pSels[0] == m_nNULLPos) + nSelCount = 0; + + aCurValues.realloc(nSelCount); + ::rtl::OUString *pCurVals = aCurValues.getArray(); + + for (sal_uInt16 i = 0; i < nSelCount; i++) + { + if (pSels[i] < nValCnt) + pCurVals[i] = pVals[pSels[i]]; + } + } + return aCurValues; + } + + //------------------------------------------------------------------------------ + sal_Bool OListBoxModel::commitControlValueToDbColumn( bool _bPostReset ) + { + // current selektion list + Any aCurrentValue; + StringSequence aCurValueSeq = GetCurValueSeq(); + if ( aCurValueSeq.getLength() ) + aCurrentValue <<= aCurValueSeq.getConstArray()[0]; + + if ( !compare( aCurrentValue, m_aSaveValue ) ) + { + if ( !aCurrentValue.hasValue() ) + m_xColumnUpdate->updateNull(); + else + { try { - xFieldAsSet->getPropertyValue(PROPERTY_FIELDTYPE) >>= nFieldType; - bHaveFormat = (xFieldAsSet->getPropertyValue(PROPERTY_FORMATKEY) >>= nFormatKey); + ::rtl::OUString sNewValue; + aCurrentValue >>= sNewValue; + m_xColumnUpdate->updateString( sNewValue ); } catch(Exception&) { - DBG_ERROR("OListBoxModel::loadData: could not obtain the field type and/or format key of the bound column!"); - } - - if (!bHaveFormat) - { - Locale aAppLanguage = Application::GetSettings().GetUILocale(); - if (xSupplier.is()) - { - Reference< XNumberFormatTypes > xNumTypes(xSupplier->getNumberFormats(), UNO_QUERY); - if (xNumTypes.is()) - nFormatKey = getDefaultNumberFormat(xFieldAsSet, xNumTypes, aAppLanguage); - } - } - - Reference xFormatter; - if (xSupplier.is()) - { - xFormatter = Reference( - m_xServiceFactory->createInstance(FRM_NUMBER_FORMATTER), - UNO_QUERY - ); - if (xFormatter.is()) - { - xFormatter->attachNumberFormatsSupplier(xSupplier); - xFormatter->getNumberFormatsSupplier()->getNumberFormatSettings()->getPropertyValue( - ::rtl::OUString::createFromAscii("NullDate")) >>= aNullDate; - nKeyType = getNumberFormatType(xFormatter->getNumberFormatsSupplier()->getNumberFormats(), nFormatKey); - } - } - - // Feld der BoundColumn des ResultSets holen - Reference xBoundField; - if ((nBoundColumn > 0) && m_xColumn.is()) - // don't look for a bound column if we're not connected to a field - xColumns->getByIndex(nBoundColumn) >>= xBoundField; - m_bBoundComponent = xBoundField.is(); - - // Ist die LB an ein Feld gebunden und sind Leereinträge zulaessig - // dann wird die Position fuer einen Leereintrag gemerkt - - ::rtl::OUString aStr; - sal_Int16 i = 0; - // per definitionem the list cursor is positioned _before_ the first row at the moment - while (xListCursor->next() && (i++getString(); - aValueList.push_back(aStr); - } - - if (bUseNULL && (m_nNULLPos == -1) && !aStr.getLength()) - m_nNULLPos = (sal_Int16)aStringList.size() - 1; + return sal_False; } } - break; - - case ListSourceType_TABLEFIELDS: - { - Reference xFieldNames = getTableFields(xConnection, sListSource); - if (xFieldNames.is()) - { - StringSequence seqNames = xFieldNames->getElementNames(); - sal_Int32 nFieldsCount = seqNames.getLength(); - const ::rtl::OUString* pustrNames = seqNames.getConstArray(); - - for (sal_Int32 k=0; k aSelSeq; - m_aValueSeq.realloc(aValueList.size()); - ::rtl::OUString* pustrValues = m_aValueSeq.getArray(); - for (i = 0; i < (sal_Int32)aValueList.size(); ++i) - pustrValues[i] = aValueList[i]; - - // String-Sequence fuer ListBox erzeugen - StringSequence aStringSeq(aStringList.size()); - ::rtl::OUString* pustrStrings = aStringSeq.getArray(); - for (i = 0; i < (sal_Int32)aStringList.size(); ++i) - pustrStrings[i] = aStringList[i]; - - setFastPropertyValue(PROPERTY_ID_STRINGITEMLIST, makeAny(aStringSeq)); - - // Statement + Cursor zerstoeren - disposeComponent(xListCursor); -} - -//------------------------------------------------------------------------------ -void OListBoxModel::implRefreshListFromDbBinding( ) -{ - DBG_ASSERT( !hasExternalListSource( ), "OListBoxModel::implRefreshListFromDbBinding: invalid call!" ); - - if ( m_eListSourceType != ListSourceType_VALUELIST ) - { - if ( getField().is() ) - m_aValueSeq = StringSequence(); - - if ( m_xCursor.is() ) - loadData(); - } -} - -//------------------------------------------------------------------------------ -void OListBoxModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) -{ - // list boxes which are bound to a db column don't have multi selection - // - this would be unable to reflect in the db column - if ( getField().is() ) - { - setFastPropertyValue( PROPERTY_ID_MULTISELECTION, ::cppu::bool2any( ( sal_False ) ) ); - } - - if ( !hasExternalListSource() ) - implRefreshListFromDbBinding( ); -} - -//------------------------------------------------------------------------------ -void OListBoxModel::onDisconnectedDbColumn() -{ - if (m_eListSourceType != ListSourceType_VALUELIST) - { - m_aValueSeq = StringSequence(); - m_nNULLPos = -1; - m_bBoundComponent = sal_False; - - if ( !hasExternalListSource() ) - setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) ); - } -} - -//------------------------------------------------------------------------------ -StringSequence OListBoxModel::GetCurValueSeq() const -{ - StringSequence aCurValues; - - // Aus den selektierten Indizes Werte-Sequence aufbauen - DBG_ASSERT(m_xAggregateFastSet.is(), "OListBoxModel::GetCurValueSeq : invalid aggregate !"); - if (!m_xAggregateFastSet.is()) - return aCurValues; - - Any aTmp = m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ); - - Sequence aSelectSeq; aTmp >>= aSelectSeq; - const sal_Int16 *pSels = aSelectSeq.getConstArray(); - sal_uInt32 nSelCount = aSelectSeq.getLength(); - - if (nSelCount) - { - StringSequence aValues; - if ( m_aValueSeq.getLength() ) + // Bei NULL-Eintraegen Selektion aufheben! + ::rtl::OUString sValue = m_xColumn->getString(); + if (m_xColumn->wasNull()) { - aValues = m_aValueSeq; + m_aSaveValue.clear(); + if (m_nNULLPos != -1) + { + aSelSeq.realloc(1); + aSelSeq.getArray()[0] = m_nNULLPos; + } } else { - aValues = getStringItemList(); - } + m_aSaveValue <<= sValue; - const ::rtl::OUString *pVals = aValues.getConstArray(); - sal_Int32 nValCnt = aValues.getLength(); - - if (nSelCount > 1) - { - // Einfach- oder Mehrfach-Selektion - sal_Bool bMultiSel; - const_cast(this)->OPropertySetAggregationHelper::getFastPropertyValue(PROPERTY_ID_MULTISELECTION) >>= bMultiSel; - if (bMultiSel) - nSelCount = 1; - } - - // ist der Eintrag fuer NULL selektiert ? - // dann leere Selektion liefern - if (m_nNULLPos != -1 && nSelCount == 1 && pSels[0] == m_nNULLPos) - nSelCount = 0; - - aCurValues.realloc(nSelCount); - ::rtl::OUString *pCurVals = aCurValues.getArray(); - - for (sal_uInt16 i = 0; i < nSelCount; i++) - { - if (pSels[i] < nValCnt) - pCurVals[i] = pVals[pSels[i]]; - } - } - return aCurValues; -} - -//------------------------------------------------------------------------------ -sal_Bool OListBoxModel::commitControlValueToDbColumn( bool _bPostReset ) -{ - // current selektion list - Any aCurrentValue; - StringSequence aCurValueSeq = GetCurValueSeq(); - if ( aCurValueSeq.getLength() ) - aCurrentValue <<= aCurValueSeq.getConstArray()[0]; - - if ( !compare( aCurrentValue, m_aSaveValue ) ) - { - if ( !aCurrentValue.hasValue() ) - m_xColumnUpdate->updateNull(); - else - { - try + // In der Werteliste nur einzelne Werte suchen, wenn das Control mit einem Datenbankfeld verbunden ist + if ( m_aValueSeq.getLength() ) // value list { - ::rtl::OUString sNewValue; - aCurrentValue >>= sNewValue; - m_xColumnUpdate->updateString( sNewValue ); + aSelSeq = findValue( m_aValueSeq, sValue, m_bBoundComponent ); } - catch(Exception&) + else { - return sal_False; + aSelSeq = findValue( getStringItemList(), sValue, m_bBoundComponent ); } } - m_aSaveValue = aCurrentValue; + return makeAny( aSelSeq ); } - return sal_True; -} -// XPropertiesChangeListener -//------------------------------------------------------------------------------ -Any OListBoxModel::translateDbColumnToControlValue() -{ - DBG_ASSERT( m_xAggregateFastSet.is() && m_xAggregateSet.is(), "OListBoxModel::translateDbColumnToControlValue: invalid aggregate !" ); - if ( !m_xAggregateFastSet.is() || !m_xAggregateSet.is() ) - return Any(); - - Sequence aSelSeq; - - // Bei NULL-Eintraegen Selektion aufheben! - ::rtl::OUString sValue = m_xColumn->getString(); - if (m_xColumn->wasNull()) + // XReset + //------------------------------------------------------------------------------ + Any OListBoxModel::getDefaultForReset() const { - m_aSaveValue.clear(); - if (m_nNULLPos != -1) + Any aValue; + if (m_aDefaultSelectSeq.getLength()) + aValue <<= m_aDefaultSelectSeq; + else if (m_nNULLPos != -1) // gebundene Listbox { - aSelSeq.realloc(1); - aSelSeq.getArray()[0] = m_nNULLPos; - } - } - else - { - m_aSaveValue <<= sValue; - - // In der Werteliste nur einzelne Werte suchen, wenn das Control mit einem Datenbankfeld verbunden ist - if ( m_aValueSeq.getLength() ) // value list - { - aSelSeq = findValue( m_aValueSeq, sValue, m_bBoundComponent ); + Sequence aSeq(1); + aSeq.getArray()[0] = m_nNULLPos; + aValue <<= aSeq; } else { - aSelSeq = findValue( getStringItemList(), sValue, m_bBoundComponent ); + Sequence aSeq; + aValue <<= aSeq; } - } - return makeAny( aSelSeq ); -} -// XReset -//------------------------------------------------------------------------------ -Any OListBoxModel::getDefaultForReset() const -{ - Any aValue; - if (m_aDefaultSelectSeq.getLength()) - aValue <<= m_aDefaultSelectSeq; - else if (m_nNULLPos != -1) // gebundene Listbox - { - Sequence aSeq(1); - aSeq.getArray()[0] = m_nNULLPos; - aValue <<= aSeq; - } - else - { - Sequence aSeq; - aValue <<= aSeq; + return aValue; } - return aValue; -} - -//-------------------------------------------------------------------- -void SAL_CALL OListBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException ) -{ - if ( !OEntryListHelper::handleDisposing( _rSource ) ) - OBoundControlModel::disposing( _rSource ); -} - -//-------------------------------------------------------------------- -Any OListBoxModel::translateExternalValueToControlValue( ) -{ - OSL_PRECOND( hasExternalValueBinding(), - "OListBoxModel::translateExternalValueToControlValue: precondition not met!" ); - - Sequence< sal_Int16 > aSelectIndexes; - if ( m_xExternalBinding.is() ) + //-------------------------------------------------------------------- + void SAL_CALL OListBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException ) { + if ( !OEntryListHelper::handleDisposing( _rSource ) ) + OBoundControlModel::disposing( _rSource ); + } + + //-------------------------------------------------------------------- + Any OListBoxModel::translateExternalValueToControlValue( ) + { + OSL_PRECOND( hasExternalValueBinding(), + "OListBoxModel::translateExternalValueToControlValue: precondition not met!" ); + + Sequence< sal_Int16 > aSelectIndexes; + if ( m_xExternalBinding.is() ) + { + switch ( m_eTransferSelectionAs ) + { + case tsIndexList: + { + // unfortunately, our select sequence is a sequence, while the external binding + // supplies sequence only -> transform this + Sequence< sal_Int32 > aSelectIndexesPure; + m_xExternalBinding->getValue( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ) >>= aSelectIndexesPure; + aSelectIndexes.realloc( aSelectIndexesPure.getLength() ); + ::std::copy( + aSelectIndexesPure.getConstArray(), + aSelectIndexesPure.getConstArray() + aSelectIndexesPure.getLength(), + aSelectIndexes.getArray() + ); + } + break; + + case tsIndex: + { + sal_Int32 nSelectIndex = -1; + m_xExternalBinding->getValue( ::getCppuType( static_cast< sal_Int32* >( NULL ) ) ) >>= nSelectIndex; + if ( ( nSelectIndex >= 0 ) && ( nSelectIndex < getStringItemList().getLength() ) ) + { + aSelectIndexes.realloc( 1 ); + aSelectIndexes[ 0 ] = static_cast< sal_Int16 >( nSelectIndex ); + } + } + break; + + case tsEntryList: + { + // we can retrieve a string list from the binding for multiple selection + Sequence< ::rtl::OUString > aSelectEntries; + m_xExternalBinding->getValue( ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) ) ) >>= aSelectEntries; + + ::std::set< sal_Int16 > aSelectionSet; + + // find the selection entries in our item list + const ::rtl::OUString* pSelectEntries = aSelectEntries.getArray(); + const ::rtl::OUString* pSelectEntriesEnd = pSelectEntries + aSelectEntries.getLength(); + while ( pSelectEntries != pSelectEntriesEnd ) + { + // the indexes where the current string appears in our string items + Sequence< sal_Int16 > aThisEntryIndexes; + aThisEntryIndexes = findValue( getStringItemList(), *pSelectEntries++, sal_False ); + + // insert all the indexes of this entry into our set + ::std::copy( + aThisEntryIndexes.getConstArray(), + aThisEntryIndexes.getConstArray() + aThisEntryIndexes.getLength(), + insert_iterator< ::std::set< sal_Int16 > >( aSelectionSet, aSelectionSet.begin() ) + ); + } + + // copy the indexes to the sequence + aSelectIndexes.realloc( aSelectionSet.size() ); + ::std::copy( + aSelectionSet.begin(), + aSelectionSet.end(), + aSelectIndexes.getArray() + ); + } + break; + + case tsEntry: + { + ::rtl::OUString sStringToSelect; + m_xExternalBinding->getValue( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ) >>= sStringToSelect; + + aSelectIndexes = findValue( getStringItemList(), sStringToSelect, sal_False ); + } + break; + } + } + + return makeAny( aSelectIndexes ); + } + + //-------------------------------------------------------------------- + void OListBoxModel::onConnectedExternalValue( ) + { + OSL_ENSURE( hasExternalValueBinding(), "OListBoxModel::onConnectedExternalValue: no external value binding!" ); + + // if the binding supports string sequences, we prefer this + if ( m_xExternalBinding.is() ) + { + if ( m_xExternalBinding->supportsType( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ) ) + { + m_eTransferSelectionAs = tsIndexList; + } + else if ( m_xExternalBinding->supportsType( ::getCppuType( static_cast< sal_Int32* >( NULL ) ) ) ) + { + m_eTransferSelectionAs = tsIndex; + } + else if ( m_xExternalBinding->supportsType( ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) ) ) ) + { + m_eTransferSelectionAs = tsEntryList; + } + else + { + OSL_ENSURE( m_xExternalBinding->supportsType( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ), + "OListBoxModel::onConnectedExternalValue: this should not have survived approveValueBinding!" ); + m_eTransferSelectionAs = tsEntry; + } + } + + OBoundControlModel::onConnectedExternalValue( ); + } + + //.................................................................... + namespace + { + struct ExtractStringFromSequence_Safe : public ::std::unary_function< sal_Int16, ::rtl::OUString > + { + protected: + const Sequence< ::rtl::OUString >& m_rList; + + public: + ExtractStringFromSequence_Safe( const Sequence< ::rtl::OUString >& _rList ) : m_rList( _rList ) { } + + ::rtl::OUString operator ()( sal_Int16 _nIndex ) + { + OSL_ENSURE( _nIndex < m_rList.getLength(), "ExtractStringFromSequence_Safe: inconsistence!" ); + if ( _nIndex < m_rList.getLength() ) + return m_rList[ _nIndex ]; + return ::rtl::OUString(); + } + }; + } + + //-------------------------------------------------------------------- + Any OListBoxModel::translateControlValueToExternalValue( ) + { + OSL_PRECOND( hasExternalValueBinding(), "OListBoxModel::translateControlValueToExternalValue: no binding!" ); + + Sequence< sal_Int16 > aSelectSequence; + getPropertyValue( PROPERTY_SELECT_SEQ ) >>= aSelectSequence; + + Any aReturn; switch ( m_eTransferSelectionAs ) { case tsIndexList: - { - // unfortunately, our select sequence is a sequence, while the external binding - // supplies sequence only -> transform this - Sequence< sal_Int32 > aSelectIndexesPure; - m_xExternalBinding->getValue( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ) >>= aSelectIndexesPure; - aSelectIndexes.realloc( aSelectIndexesPure.getLength() ); - ::std::copy( - aSelectIndexesPure.getConstArray(), - aSelectIndexesPure.getConstArray() + aSelectIndexesPure.getLength(), - aSelectIndexes.getArray() - ); - } - break; + { + OSL_ENSURE( m_xExternalBinding->supportsType( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ), + "OListBoxModel::translateControlValueToExternalValue: how this? It does not support string sequences!" ); + // unfortunately, the select sequence is a sequence, but our binding + // expects int's + Sequence< sal_Int32 > aTransformed( aSelectSequence.getLength() ); + ::std::copy( + aSelectSequence.getConstArray(), + aSelectSequence.getConstArray() + aSelectSequence.getLength(), + aTransformed.getArray() + ); + aReturn <<= aTransformed; + } + break; case tsIndex: - { - sal_Int32 nSelectIndex = -1; - m_xExternalBinding->getValue( ::getCppuType( static_cast< sal_Int32* >( NULL ) ) ) >>= nSelectIndex; - if ( ( nSelectIndex >= 0 ) && ( nSelectIndex < getStringItemList().getLength() ) ) + if ( aSelectSequence.getLength() <= 1 ) { - aSelectIndexes.realloc( 1 ); - aSelectIndexes[ 0 ] = static_cast< sal_Int16 >( nSelectIndex ); + sal_Int32 nIndex = -1; + + if ( aSelectSequence.getLength() == 1 ) + nIndex = aSelectSequence[0]; + + aReturn <<= nIndex; } - } - break; + break; case tsEntryList: - { - // we can retrieve a string list from the binding for multiple selection - Sequence< ::rtl::OUString > aSelectEntries; - m_xExternalBinding->getValue( ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) ) ) >>= aSelectEntries; - - ::std::set< sal_Int16 > aSelectionSet; - - // find the selection entries in our item list - const ::rtl::OUString* pSelectEntries = aSelectEntries.getArray(); - const ::rtl::OUString* pSelectEntriesEnd = pSelectEntries + aSelectEntries.getLength(); - while ( pSelectEntries != pSelectEntriesEnd ) { - // the indexes where the current string appears in our string items - Sequence< sal_Int16 > aThisEntryIndexes; - aThisEntryIndexes = findValue( getStringItemList(), *pSelectEntries++, sal_False ); - - // insert all the indexes of this entry into our set - ::std::copy( - aThisEntryIndexes.getConstArray(), - aThisEntryIndexes.getConstArray() + aThisEntryIndexes.getLength(), - insert_iterator< ::std::set< sal_Int16 > >( aSelectionSet, aSelectionSet.begin() ) - ); + Sequence< ::rtl::OUString > aSelectedEntriesTexts( aSelectSequence.getLength() ); + ::std::transform( + aSelectSequence.getConstArray(), + aSelectSequence.getConstArray() + aSelectSequence.getLength(), + aSelectedEntriesTexts.getArray(), + ExtractStringFromSequence_Safe( getStringItemList() ) + ); } - - // copy the indexes to the sequence - aSelectIndexes.realloc( aSelectionSet.size() ); - ::std::copy( - aSelectionSet.begin(), - aSelectionSet.end(), - aSelectIndexes.getArray() - ); - } - break; + break; case tsEntry: - { - ::rtl::OUString sStringToSelect; - m_xExternalBinding->getValue( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ) >>= sStringToSelect; + // by definition, multiple selected entries are transfered as NULL if the + // binding does not support string lists + if ( aSelectSequence.getLength() <= 1 ) + { + ::rtl::OUString sSelectedEntry; - aSelectIndexes = findValue( getStringItemList(), sStringToSelect, sal_False ); - } - break; + if ( aSelectSequence.getLength() == 1 ) + sSelectedEntry = ExtractStringFromSequence_Safe( getStringItemList() )( aSelectSequence[0] ); + + aReturn <<= sSelectedEntry; + } + break; } + + return aReturn; } - return makeAny( aSelectIndexes ); -} - -//-------------------------------------------------------------------- -void OListBoxModel::onConnectedExternalValue( ) -{ - OSL_ENSURE( hasExternalValueBinding(), "OListBoxModel::onConnectedExternalValue: no external value binding!" ); - - // if the binding supports string sequences, we prefer this - if ( m_xExternalBinding.is() ) + //-------------------------------------------------------------------- + sal_Bool OListBoxModel::approveValueBinding( const Reference< XValueBinding >& _rxBinding ) { - if ( m_xExternalBinding->supportsType( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ) ) - { - m_eTransferSelectionAs = tsIndexList; - } - else if ( m_xExternalBinding->supportsType( ::getCppuType( static_cast< sal_Int32* >( NULL ) ) ) ) - { - m_eTransferSelectionAs = tsIndex; - } - else if ( m_xExternalBinding->supportsType( ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) ) ) ) - { - m_eTransferSelectionAs = tsEntryList; - } - else - { - OSL_ENSURE( m_xExternalBinding->supportsType( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ), - "OListBoxModel::onConnectedExternalValue: this should not have survived approveValueBinding!" ); - m_eTransferSelectionAs = tsEntry; - } - } + OSL_PRECOND( _rxBinding.is(), "OListBoxModel::approveValueBinding: precondition not met!" ); - OBoundControlModel::onConnectedExternalValue( ); -} - -//.................................................................... -namespace -{ - struct ExtractStringFromSequence_Safe : public ::std::unary_function< sal_Int16, ::rtl::OUString > - { - protected: - const Sequence< ::rtl::OUString >& m_rList; - - public: - ExtractStringFromSequence_Safe( const Sequence< ::rtl::OUString >& _rList ) : m_rList( _rList ) { } - - ::rtl::OUString operator ()( sal_Int16 _nIndex ) - { - OSL_ENSURE( _nIndex < m_rList.getLength(), "ExtractStringFromSequence_Safe: inconsistence!" ); - if ( _nIndex < m_rList.getLength() ) - return m_rList[ _nIndex ]; - return ::rtl::OUString(); - } - }; -} - -//-------------------------------------------------------------------- -Any OListBoxModel::translateControlValueToExternalValue( ) -{ - OSL_PRECOND( hasExternalValueBinding(), "OListBoxModel::translateControlValueToExternalValue: no binding!" ); - - Sequence< sal_Int16 > aSelectSequence; - getPropertyValue( PROPERTY_SELECT_SEQ ) >>= aSelectSequence; - - Any aReturn; - switch ( m_eTransferSelectionAs ) - { - case tsIndexList: - { - OSL_ENSURE( m_xExternalBinding->supportsType( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ), - "OListBoxModel::translateControlValueToExternalValue: how this? It does not support string sequences!" ); - // unfortunately, the select sequence is a sequence, but our binding - // expects int's - Sequence< sal_Int32 > aTransformed( aSelectSequence.getLength() ); - ::std::copy( - aSelectSequence.getConstArray(), - aSelectSequence.getConstArray() + aSelectSequence.getLength(), - aTransformed.getArray() - ); - aReturn <<= aTransformed; - } - break; - - case tsIndex: - if ( aSelectSequence.getLength() <= 1 ) - { - sal_Int32 nIndex = -1; - - if ( aSelectSequence.getLength() == 1 ) - nIndex = aSelectSequence[0]; - - aReturn <<= nIndex; - } - break; - - case tsEntryList: - { - Sequence< ::rtl::OUString > aSelectedEntriesTexts( aSelectSequence.getLength() ); - ::std::transform( - aSelectSequence.getConstArray(), - aSelectSequence.getConstArray() + aSelectSequence.getLength(), - aSelectedEntriesTexts.getArray(), - ExtractStringFromSequence_Safe( getStringItemList() ) - ); - } - break; - - case tsEntry: - // by definition, multiple selected entries are transfered as NULL if the - // binding does not support string lists - if ( aSelectSequence.getLength() <= 1 ) - { - ::rtl::OUString sSelectedEntry; - - if ( aSelectSequence.getLength() == 1 ) - sSelectedEntry = ExtractStringFromSequence_Safe( getStringItemList() )( aSelectSequence[0] ); - - aReturn <<= sSelectedEntry; - } - break; - } - - return aReturn; -} - -//-------------------------------------------------------------------- -sal_Bool OListBoxModel::approveValueBinding( const Reference< XValueBinding >& _rxBinding ) -{ - OSL_PRECOND( _rxBinding.is(), "OListBoxModel::approveValueBinding: precondition not met!" ); - - // only strings are accepted for simplicity - return _rxBinding.is() - && ( _rxBinding->supportsType( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ) + // only strings are accepted for simplicity + return _rxBinding.is() + && ( _rxBinding->supportsType( ::getCppuType( static_cast< ::rtl::OUString* >( NULL ) ) ) || _rxBinding->supportsType( ::getCppuType( static_cast< Sequence< ::rtl::OUString >* >( NULL ) ) ) || _rxBinding->supportsType( ::getCppuType( static_cast< sal_Int32* >( NULL ) ) ) || _rxBinding->supportsType( ::getCppuType( static_cast< Sequence< sal_Int32 >* >( NULL ) ) ) ); -} - -//-------------------------------------------------------------------- -void OListBoxModel::stringItemListChanged( ) -{ - if ( m_xAggregateSet.is() ) - { - suspendValueListening(); - try - { - m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) ); - } - catch( const Exception& ) - { - OSL_ENSURE( sal_False, "OListBoxModel::stringItemListChanged: caught an exception!" ); - } - resumeValueListening(); - - // update the selection here - if ( hasExternalValueBinding( ) ) - transferExternalValueToControl( ); - else - { - // TODO: update the selection in case we're bound to a database column - } - } -} - -//-------------------------------------------------------------------- -void OListBoxModel::connectedExternalListSource( ) -{ - // TODO? -} - -//-------------------------------------------------------------------- -void OListBoxModel::disconnectedExternalListSource( ) -{ - // TODO: in case we're part of an already loaded form, we should probably simulate - // an onConnectedDbColumn, so our list get's filled with the data as indicated - // by our SQL-binding related properties -} - -//================================================================== -// OListBoxControl -//================================================================== - -//------------------------------------------------------------------ -InterfaceRef SAL_CALL OListBoxControl_CreateInstance(const Reference& _rxFactory) throw (RuntimeException) -{ - return *(new OListBoxControl(_rxFactory)); -} - -//------------------------------------------------------------------------------ -Sequence< Type> OListBoxControl::_getTypes() -{ - return concatSequences( - OBoundControl::_getTypes(), - OListBoxControl_BASE::getTypes() - ); -} - -//------------------------------------------------------------------ -Any SAL_CALL OListBoxControl::queryAggregation(const Type& _rType) throw (RuntimeException) -{ - Any aReturn = OBoundControl::queryAggregation(_rType); - if (!aReturn.hasValue()) - aReturn = OListBoxControl_BASE::queryInterface(_rType); - - return aReturn; -} - -DBG_NAME(OListBoxControl); -//------------------------------------------------------------------------------ -OListBoxControl::OListBoxControl(const Reference& _rxFactory) - :OBoundControl(_rxFactory, VCL_CONTROL_LISTBOX) - ,m_aChangeListeners(m_aMutex) -{ - DBG_CTOR(OListBoxControl,NULL); - - increment(m_refCount); - { - // als FocusListener anmelden - Reference xComp; - if (query_aggregation(m_xAggregate, xComp)) - xComp->addFocusListener(this); - - // als ItemListener anmelden - Reference xListbox; - if (query_aggregation(m_xAggregate, xListbox)) - xListbox->addItemListener(this); - } - // Refcount bei 2 fuer angemeldete Listener - decrement(m_refCount); - - m_aChangeTimer.SetTimeout(500); - m_aChangeTimer.SetTimeoutHdl(LINK(this,OListBoxControl,OnTimeout)); -} - -//------------------------------------------------------------------------------ -OListBoxControl::~OListBoxControl() -{ - if (!OComponentHelper::rBHelper.bDisposed) - { - acquire(); - dispose(); } - DBG_DTOR(OListBoxControl,NULL); -} - -//------------------------------------------------------------------------------ -StringSequence SAL_CALL OListBoxControl::getSupportedServiceNames() throw(RuntimeException) -{ - StringSequence aSupported = OBoundControl::getSupportedServiceNames(); - aSupported.realloc(aSupported.getLength() + 1); - - ::rtl::OUString* pArray = aSupported.getArray(); - pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_LISTBOX; - return aSupported; -} - - -// XFocusListener -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxControl::focusGained(const FocusEvent& _rEvent) throw(RuntimeException) -{ - ::osl::MutexGuard aGuard(m_aMutex); - if (m_aChangeListeners.getLength()) // only if there are listeners + //-------------------------------------------------------------------- + void OListBoxModel::stringItemListChanged( ) { - Reference xSet(getModel(), UNO_QUERY); - if (xSet.is()) + if ( m_xAggregateSet.is() ) { - // memorize the current selection for posting the change event - m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ); + suspendValueListening(); + try + { + m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "OListBoxModel::stringItemListChanged: caught an exception!" ); + } + resumeValueListening(); + + // update the selection here + if ( hasExternalValueBinding( ) ) + transferExternalValueToControl( ); + else + { + // TODO: update the selection in case we're bound to a database column + } } } -} -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxControl::focusLost(const FocusEvent& _rEvent) throw(RuntimeException) -{ - m_aCurrentSelection.clear(); -} + //-------------------------------------------------------------------- + void OListBoxModel::connectedExternalListSource( ) + { + // TODO? + } -// XItemListener -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxControl::itemStateChanged(const ItemEvent& _rEvent) throw(RuntimeException) -{ - // call the changelistener delayed - ::osl::ClearableMutexGuard aGuard(m_aMutex); - if (m_aChangeTimer.IsActive()) - { - Reference xSet(getModel(), UNO_QUERY); - m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ); + //-------------------------------------------------------------------- + void OListBoxModel::disconnectedExternalListSource( ) + { + // TODO: in case we're part of an already loaded form, we should probably simulate + // an onConnectedDbColumn, so our list get's filled with the data as indicated + // by our SQL-binding related properties + } - m_aChangeTimer.Stop(); - m_aChangeTimer.Start(); - } - else - { - if (m_aChangeListeners.getLength() && m_aCurrentSelection.hasValue()) - { + //================================================================== + // OListBoxControl + //================================================================== + + //------------------------------------------------------------------ + InterfaceRef SAL_CALL OListBoxControl_CreateInstance(const Reference& _rxFactory) throw (RuntimeException) + { + return *(new OListBoxControl(_rxFactory)); + } + + //------------------------------------------------------------------------------ + Sequence< Type> OListBoxControl::_getTypes() + { + return concatSequences( + OBoundControl::_getTypes(), + OListBoxControl_BASE::getTypes() + ); + } + + //------------------------------------------------------------------ + Any SAL_CALL OListBoxControl::queryAggregation(const Type& _rType) throw (RuntimeException) + { + Any aReturn = OBoundControl::queryAggregation(_rType); + if (!aReturn.hasValue()) + aReturn = OListBoxControl_BASE::queryInterface(_rType); + + return aReturn; + } + + DBG_NAME(OListBoxControl); + //------------------------------------------------------------------------------ + OListBoxControl::OListBoxControl(const Reference& _rxFactory) + :OBoundControl(_rxFactory, VCL_CONTROL_LISTBOX) + ,m_aChangeListeners(m_aMutex) + { + DBG_CTOR(OListBoxControl,NULL); + + increment(m_refCount); + { + // als FocusListener anmelden + Reference xComp; + if (query_aggregation(m_xAggregate, xComp)) + xComp->addFocusListener(this); + + // als ItemListener anmelden + Reference xListbox; + if (query_aggregation(m_xAggregate, xListbox)) + xListbox->addItemListener(this); + } + // Refcount bei 2 fuer angemeldete Listener + decrement(m_refCount); + + m_aChangeTimer.SetTimeout(500); + m_aChangeTimer.SetTimeoutHdl(LINK(this,OListBoxControl,OnTimeout)); + } + + //------------------------------------------------------------------------------ + OListBoxControl::~OListBoxControl() + { + if (!OComponentHelper::rBHelper.bDisposed) + { + acquire(); + dispose(); + } + + DBG_DTOR(OListBoxControl,NULL); + } + + //------------------------------------------------------------------------------ + StringSequence SAL_CALL OListBoxControl::getSupportedServiceNames() throw(RuntimeException) + { + StringSequence aSupported = OBoundControl::getSupportedServiceNames(); + aSupported.realloc(aSupported.getLength() + 1); + + ::rtl::OUString* pArray = aSupported.getArray(); + pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_LISTBOX; + return aSupported; + } + + + // XFocusListener + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxControl::focusGained(const FocusEvent& _rEvent) throw(RuntimeException) + { + ::osl::MutexGuard aGuard(m_aMutex); + if (m_aChangeListeners.getLength()) // only if there are listeners + { Reference xSet(getModel(), UNO_QUERY); if (xSet.is()) { - // Has the selection been changed? - sal_Bool bModified(sal_False); - Any aValue = xSet->getPropertyValue(PROPERTY_SELECT_SEQ); - - Sequence& rSelection = *(Sequence *)aValue.getValue(); - Sequence& rOldSelection = *(Sequence *)m_aCurrentSelection.getValue(); - sal_Int32 nLen = rSelection.getLength(); - if (nLen != rOldSelection.getLength()) - bModified = sal_True; - else - { - const sal_Int16* pVal = rSelection.getConstArray(); - const sal_Int16* pCompVal = rOldSelection.getConstArray(); - - while (nLen-- && !bModified) - bModified = pVal[nLen] != pCompVal[nLen]; - } - - if (bModified) - { - m_aCurrentSelection = aValue; - m_aChangeTimer.Start(); - } + // memorize the current selection for posting the change event + m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ); } } - else if (m_aCurrentSelection.hasValue()) - m_aCurrentSelection.clear(); - } -} + } -// XEventListener -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxControl::disposing(const EventObject& _rSource) throw (RuntimeException) -{ - OBoundControl::disposing(_rSource); -} + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxControl::focusLost(const FocusEvent& _rEvent) throw(RuntimeException) + { + m_aCurrentSelection.clear(); + } -// XChangeBroadcaster -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxControl::addChangeListener(const Reference& _rxListener) throw(RuntimeException) -{ - m_aChangeListeners.addInterface(_rxListener); -} + // XItemListener + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxControl::itemStateChanged(const ItemEvent& _rEvent) throw(RuntimeException) + { + // call the changelistener delayed + ::osl::ClearableMutexGuard aGuard(m_aMutex); + if (m_aChangeTimer.IsActive()) + { + Reference xSet(getModel(), UNO_QUERY); + m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ); -//------------------------------------------------------------------------------ -void SAL_CALL OListBoxControl::removeChangeListener(const Reference& _rxListener) throw(RuntimeException) -{ - m_aChangeListeners.removeInterface(_rxListener); -} + m_aChangeTimer.Stop(); + m_aChangeTimer.Start(); + } + else + { + if (m_aChangeListeners.getLength() && m_aCurrentSelection.hasValue()) + { + Reference xSet(getModel(), UNO_QUERY); + if (xSet.is()) + { + // Has the selection been changed? + sal_Bool bModified(sal_False); + Any aValue = xSet->getPropertyValue(PROPERTY_SELECT_SEQ); -// OComponentHelper -//------------------------------------------------------------------------------ -void OListBoxControl::disposing() -{ - if (m_aChangeTimer.IsActive()) - m_aChangeTimer.Stop(); + Sequence& rSelection = *(Sequence *)aValue.getValue(); + Sequence& rOldSelection = *(Sequence *)m_aCurrentSelection.getValue(); + sal_Int32 nLen = rSelection.getLength(); + if (nLen != rOldSelection.getLength()) + bModified = sal_True; + else + { + const sal_Int16* pVal = rSelection.getConstArray(); + const sal_Int16* pCompVal = rOldSelection.getConstArray(); - EventObject aEvt(static_cast< XWeak*>(this)); - m_aChangeListeners.disposeAndClear(aEvt); + while (nLen-- && !bModified) + bModified = pVal[nLen] != pCompVal[nLen]; + } - OBoundControl::disposing(); -} + if (bModified) + { + m_aCurrentSelection = aValue; + m_aChangeTimer.Start(); + } + } + } + else if (m_aCurrentSelection.hasValue()) + m_aCurrentSelection.clear(); + } + } -//------------------------------------------------------------------------------ -IMPL_LINK(OListBoxControl, OnTimeout, void*, EMPTYTAG) -{ - EventObject aEvt(static_cast< XWeak*>(this)); - NOTIFY_LISTENERS(m_aChangeListeners, XChangeListener, changed, aEvt); - return 1; -} + // XEventListener + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxControl::disposing(const EventObject& _rSource) throw (RuntimeException) + { + OBoundControl::disposing(_rSource); + } + + // XChangeBroadcaster + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxControl::addChangeListener(const Reference& _rxListener) throw(RuntimeException) + { + m_aChangeListeners.addInterface(_rxListener); + } + + //------------------------------------------------------------------------------ + void SAL_CALL OListBoxControl::removeChangeListener(const Reference& _rxListener) throw(RuntimeException) + { + m_aChangeListeners.removeInterface(_rxListener); + } + + // OComponentHelper + //------------------------------------------------------------------------------ + void OListBoxControl::disposing() + { + if (m_aChangeTimer.IsActive()) + m_aChangeTimer.Stop(); + + EventObject aEvt(static_cast< XWeak*>(this)); + m_aChangeListeners.disposeAndClear(aEvt); + + OBoundControl::disposing(); + } + + //------------------------------------------------------------------------------ + IMPL_LINK(OListBoxControl, OnTimeout, void*, EMPTYTAG) + { + EventObject aEvt(static_cast< XWeak*>(this)); + NOTIFY_LISTENERS(m_aChangeListeners, XChangeListener, changed, aEvt); + return 1; + } //......................................................................... }