1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_forms.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "ComboBox.hxx" 32*cdf0e10cSrcweir #include "property.hxx" 33*cdf0e10cSrcweir #include "property.hrc" 34*cdf0e10cSrcweir #include "services.hxx" 35*cdf0e10cSrcweir 36*cdf0e10cSrcweir #include "frm_resource.hxx" 37*cdf0e10cSrcweir #include "frm_resource.hrc" 38*cdf0e10cSrcweir #include "BaseListBox.hxx" 39*cdf0e10cSrcweir 40*cdf0e10cSrcweir /** === begin UNO includes === **/ 41*cdf0e10cSrcweir #include <com/sun/star/sdb/SQLErrorEvent.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/sdbc/XRowSet.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp> 45*cdf0e10cSrcweir #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp> 46*cdf0e10cSrcweir #include <com/sun/star/sdb/XQueriesSupplier.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/sdbc/XConnection.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/sdb/SQLContext.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/sdb/CommandType.hpp> 51*cdf0e10cSrcweir /** === end UNO includes === **/ 52*cdf0e10cSrcweir 53*cdf0e10cSrcweir #include <comphelper/numbers.hxx> 54*cdf0e10cSrcweir #include <comphelper/basicio.hxx> 55*cdf0e10cSrcweir #include <connectivity/dbtools.hxx> 56*cdf0e10cSrcweir #include <connectivity/dbconversion.hxx> 57*cdf0e10cSrcweir #include <cppuhelper/queryinterface.hxx> 58*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 59*cdf0e10cSrcweir #include <tools/debug.hxx> 60*cdf0e10cSrcweir #include <tools/diagnose_ex.h> 61*cdf0e10cSrcweir #include <unotools/sharedunocomponent.hxx> 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir #include <limits.h> 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir using namespace dbtools; 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir //......................................................................... 68*cdf0e10cSrcweir namespace frm 69*cdf0e10cSrcweir { 70*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 71*cdf0e10cSrcweir using namespace ::com::sun::star::sdb; 72*cdf0e10cSrcweir using namespace ::com::sun::star::sdbc; 73*cdf0e10cSrcweir using namespace ::com::sun::star::sdbcx; 74*cdf0e10cSrcweir using namespace ::com::sun::star::beans; 75*cdf0e10cSrcweir using namespace ::com::sun::star::container; 76*cdf0e10cSrcweir using namespace ::com::sun::star::form; 77*cdf0e10cSrcweir using namespace ::com::sun::star::awt; 78*cdf0e10cSrcweir using namespace ::com::sun::star::io; 79*cdf0e10cSrcweir using namespace ::com::sun::star::lang; 80*cdf0e10cSrcweir using namespace ::com::sun::star::util; 81*cdf0e10cSrcweir using namespace ::com::sun::star::form::binding; 82*cdf0e10cSrcweir 83*cdf0e10cSrcweir //======================================================================== 84*cdf0e10cSrcweir // class OComboBoxModel 85*cdf0e10cSrcweir //======================================================================== 86*cdf0e10cSrcweir //------------------------------------------------------------------ 87*cdf0e10cSrcweir InterfaceRef SAL_CALL OComboBoxModel_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir return (*new OComboBoxModel(_rxFactory)); 90*cdf0e10cSrcweir } 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir //------------------------------------------------------------------------------ 93*cdf0e10cSrcweir Sequence<Type> OComboBoxModel::_getTypes() 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir return ::comphelper::concatSequences( 96*cdf0e10cSrcweir OBoundControlModel::_getTypes(), 97*cdf0e10cSrcweir OEntryListHelper::getTypes(), 98*cdf0e10cSrcweir OErrorBroadcaster::getTypes() 99*cdf0e10cSrcweir ); 100*cdf0e10cSrcweir } 101*cdf0e10cSrcweir 102*cdf0e10cSrcweir // XServiceInfo 103*cdf0e10cSrcweir //------------------------------------------------------------------------------ 104*cdf0e10cSrcweir StringSequence SAL_CALL OComboBoxModel::getSupportedServiceNames() throw(RuntimeException) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir StringSequence aSupported = OBoundControlModel::getSupportedServiceNames(); 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir sal_Int32 nOldLen = aSupported.getLength(); 109*cdf0e10cSrcweir aSupported.realloc( nOldLen + 8 ); 110*cdf0e10cSrcweir ::rtl::OUString* pStoreTo = aSupported.getArray() + nOldLen; 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir *pStoreTo++ = BINDABLE_CONTROL_MODEL; 113*cdf0e10cSrcweir *pStoreTo++ = DATA_AWARE_CONTROL_MODEL; 114*cdf0e10cSrcweir *pStoreTo++ = VALIDATABLE_CONTROL_MODEL; 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir *pStoreTo++ = BINDABLE_DATA_AWARE_CONTROL_MODEL; 117*cdf0e10cSrcweir *pStoreTo++ = VALIDATABLE_BINDABLE_CONTROL_MODEL; 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir *pStoreTo++ = FRM_SUN_COMPONENT_COMBOBOX; 120*cdf0e10cSrcweir *pStoreTo++ = FRM_SUN_COMPONENT_DATABASE_COMBOBOX; 121*cdf0e10cSrcweir *pStoreTo++ = BINDABLE_DATABASE_COMBO_BOX; 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir return aSupported; 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir //------------------------------------------------------------------------------ 127*cdf0e10cSrcweir Any SAL_CALL OComboBoxModel::queryAggregation(const Type& _rType) throw (RuntimeException) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir Any aReturn = OBoundControlModel::queryAggregation( _rType ); 130*cdf0e10cSrcweir if ( !aReturn.hasValue() ) 131*cdf0e10cSrcweir aReturn = OEntryListHelper::queryInterface( _rType ); 132*cdf0e10cSrcweir if ( !aReturn.hasValue() ) 133*cdf0e10cSrcweir aReturn = OErrorBroadcaster::queryInterface( _rType ); 134*cdf0e10cSrcweir return aReturn; 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir //------------------------------------------------------------------ 138*cdf0e10cSrcweir DBG_NAME( OComboBoxModel ) 139*cdf0e10cSrcweir //------------------------------------------------------------------ 140*cdf0e10cSrcweir OComboBoxModel::OComboBoxModel(const Reference<XMultiServiceFactory>& _rxFactory) 141*cdf0e10cSrcweir :OBoundControlModel( _rxFactory, VCL_CONTROLMODEL_COMBOBOX, FRM_SUN_CONTROL_COMBOBOX, sal_True, sal_True, sal_True ) 142*cdf0e10cSrcweir // use the old control name for compytibility reasons 143*cdf0e10cSrcweir ,OEntryListHelper( (OControlModel&)*this ) 144*cdf0e10cSrcweir ,OErrorBroadcaster( OComponentHelper::rBHelper ) 145*cdf0e10cSrcweir ,m_aListRowSet( getContext() ) 146*cdf0e10cSrcweir ,m_eListSourceType(ListSourceType_TABLE) 147*cdf0e10cSrcweir ,m_bEmptyIsNull(sal_True) 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir DBG_CTOR( OComboBoxModel, NULL ); 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir m_nClassId = FormComponentType::COMBOBOX; 152*cdf0e10cSrcweir initValueProperty( PROPERTY_TEXT, PROPERTY_ID_TEXT ); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir //------------------------------------------------------------------ 156*cdf0e10cSrcweir OComboBoxModel::OComboBoxModel( const OComboBoxModel* _pOriginal, const Reference<XMultiServiceFactory>& _rxFactory ) 157*cdf0e10cSrcweir :OBoundControlModel( _pOriginal, _rxFactory ) 158*cdf0e10cSrcweir ,OEntryListHelper( *_pOriginal, (OControlModel&)*this ) 159*cdf0e10cSrcweir ,OErrorBroadcaster( OComponentHelper::rBHelper ) 160*cdf0e10cSrcweir ,m_aListRowSet( getContext() ) 161*cdf0e10cSrcweir ,m_aListSource( _pOriginal->m_aListSource ) 162*cdf0e10cSrcweir ,m_aDefaultText( _pOriginal->m_aDefaultText ) 163*cdf0e10cSrcweir ,m_eListSourceType( _pOriginal->m_eListSourceType ) 164*cdf0e10cSrcweir ,m_bEmptyIsNull( _pOriginal->m_bEmptyIsNull ) 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir DBG_CTOR( OComboBoxModel, NULL ); 167*cdf0e10cSrcweir } 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir //------------------------------------------------------------------ 170*cdf0e10cSrcweir OComboBoxModel::~OComboBoxModel() 171*cdf0e10cSrcweir { 172*cdf0e10cSrcweir if (!OComponentHelper::rBHelper.bDisposed) 173*cdf0e10cSrcweir { 174*cdf0e10cSrcweir acquire(); 175*cdf0e10cSrcweir dispose(); 176*cdf0e10cSrcweir } 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir DBG_DTOR( OComboBoxModel, NULL ); 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir 181*cdf0e10cSrcweir // XCloneable 182*cdf0e10cSrcweir //------------------------------------------------------------------------------ 183*cdf0e10cSrcweir IMPLEMENT_DEFAULT_CLONING( OComboBoxModel ) 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir //------------------------------------------------------------------------------ 186*cdf0e10cSrcweir void OComboBoxModel::disposing() 187*cdf0e10cSrcweir { 188*cdf0e10cSrcweir OBoundControlModel::disposing(); 189*cdf0e10cSrcweir OEntryListHelper::disposing(); 190*cdf0e10cSrcweir OErrorBroadcaster::disposing(); 191*cdf0e10cSrcweir m_xFormatter = NULL; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir //------------------------------------------------------------------------------ 195*cdf0e10cSrcweir void OComboBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir switch (_nHandle) 198*cdf0e10cSrcweir { 199*cdf0e10cSrcweir case PROPERTY_ID_LISTSOURCETYPE: 200*cdf0e10cSrcweir _rValue <<= m_eListSourceType; 201*cdf0e10cSrcweir break; 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir case PROPERTY_ID_LISTSOURCE: 204*cdf0e10cSrcweir _rValue <<= m_aListSource; 205*cdf0e10cSrcweir break; 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir case PROPERTY_ID_EMPTY_IS_NULL: 208*cdf0e10cSrcweir _rValue <<= m_bEmptyIsNull; 209*cdf0e10cSrcweir break; 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir case PROPERTY_ID_DEFAULT_TEXT: 212*cdf0e10cSrcweir _rValue <<= m_aDefaultText; 213*cdf0e10cSrcweir break; 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir case PROPERTY_ID_STRINGITEMLIST: 216*cdf0e10cSrcweir _rValue <<= getStringItemList(); 217*cdf0e10cSrcweir break; 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir default: 220*cdf0e10cSrcweir OBoundControlModel::getFastPropertyValue(_rValue, _nHandle); 221*cdf0e10cSrcweir } 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir //------------------------------------------------------------------------------ 225*cdf0e10cSrcweir void OComboBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) 226*cdf0e10cSrcweir throw (Exception) 227*cdf0e10cSrcweir { 228*cdf0e10cSrcweir switch (_nHandle) 229*cdf0e10cSrcweir { 230*cdf0e10cSrcweir case PROPERTY_ID_LISTSOURCETYPE : 231*cdf0e10cSrcweir DBG_ASSERT(_rValue.getValueType().equals(::getCppuType(reinterpret_cast<ListSourceType*>(NULL))), 232*cdf0e10cSrcweir "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" ); 233*cdf0e10cSrcweir _rValue >>= m_eListSourceType; 234*cdf0e10cSrcweir break; 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir case PROPERTY_ID_LISTSOURCE : 237*cdf0e10cSrcweir DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING, 238*cdf0e10cSrcweir "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" ); 239*cdf0e10cSrcweir _rValue >>= m_aListSource; 240*cdf0e10cSrcweir // die ListSource hat sich geaendert -> neu laden 241*cdf0e10cSrcweir if (ListSourceType_VALUELIST != m_eListSourceType) 242*cdf0e10cSrcweir { 243*cdf0e10cSrcweir if ( m_xCursor.is() && !hasField() && !hasExternalListSource() ) 244*cdf0e10cSrcweir // combo box is already connected to a database, and no external list source 245*cdf0e10cSrcweir // data source changed -> refresh 246*cdf0e10cSrcweir loadData( false ); 247*cdf0e10cSrcweir } 248*cdf0e10cSrcweir break; 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir case PROPERTY_ID_EMPTY_IS_NULL : 251*cdf0e10cSrcweir DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_BOOLEAN, 252*cdf0e10cSrcweir "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" ); 253*cdf0e10cSrcweir _rValue >>= m_bEmptyIsNull; 254*cdf0e10cSrcweir break; 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir case PROPERTY_ID_DEFAULT_TEXT : 257*cdf0e10cSrcweir DBG_ASSERT(_rValue.getValueType().getTypeClass() == TypeClass_STRING, 258*cdf0e10cSrcweir "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" ); 259*cdf0e10cSrcweir _rValue >>= m_aDefaultText; 260*cdf0e10cSrcweir resetNoBroadcast(); 261*cdf0e10cSrcweir break; 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir case PROPERTY_ID_STRINGITEMLIST: 264*cdf0e10cSrcweir { 265*cdf0e10cSrcweir ControlModelLock aLock( *this ); 266*cdf0e10cSrcweir setNewStringItemList( _rValue, aLock ); 267*cdf0e10cSrcweir // TODO: this is bogus. setNewStringItemList expects a guard which has the *only* 268*cdf0e10cSrcweir // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with 269*cdf0e10cSrcweir // a lock - so we effectively has two locks here, of which setNewStringItemList can 270*cdf0e10cSrcweir // only control one. 271*cdf0e10cSrcweir } 272*cdf0e10cSrcweir break; 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir default: 275*cdf0e10cSrcweir OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle, _rValue); 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir //------------------------------------------------------------------------------ 280*cdf0e10cSrcweir sal_Bool OComboBoxModel::convertFastPropertyValue( 281*cdf0e10cSrcweir Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue) 282*cdf0e10cSrcweir throw (IllegalArgumentException) 283*cdf0e10cSrcweir { 284*cdf0e10cSrcweir sal_Bool bModified(sal_False); 285*cdf0e10cSrcweir switch (_nHandle) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir case PROPERTY_ID_LISTSOURCETYPE : 288*cdf0e10cSrcweir bModified = tryPropertyValueEnum(_rConvertedValue, _rOldValue, _rValue, m_eListSourceType); 289*cdf0e10cSrcweir break; 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir case PROPERTY_ID_LISTSOURCE : 292*cdf0e10cSrcweir bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aListSource); 293*cdf0e10cSrcweir break; 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir case PROPERTY_ID_EMPTY_IS_NULL : 296*cdf0e10cSrcweir bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_bEmptyIsNull); 297*cdf0e10cSrcweir break; 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir case PROPERTY_ID_DEFAULT_TEXT : 300*cdf0e10cSrcweir bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aDefaultText); 301*cdf0e10cSrcweir break; 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir case PROPERTY_ID_STRINGITEMLIST: 304*cdf0e10cSrcweir bModified = convertNewListSourceProperty( _rConvertedValue, _rOldValue, _rValue ); 305*cdf0e10cSrcweir break; 306*cdf0e10cSrcweir 307*cdf0e10cSrcweir default: 308*cdf0e10cSrcweir bModified = OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue); 309*cdf0e10cSrcweir break; 310*cdf0e10cSrcweir } 311*cdf0e10cSrcweir return bModified; 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir 314*cdf0e10cSrcweir //------------------------------------------------------------------------------ 315*cdf0e10cSrcweir void OComboBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir BEGIN_DESCRIBE_PROPERTIES( 6, OBoundControlModel ) 318*cdf0e10cSrcweir DECL_PROP1(TABINDEX, sal_Int16, BOUND); 319*cdf0e10cSrcweir DECL_PROP1(LISTSOURCETYPE, ListSourceType, BOUND); 320*cdf0e10cSrcweir DECL_PROP1(LISTSOURCE, ::rtl::OUString, BOUND); 321*cdf0e10cSrcweir DECL_BOOL_PROP1(EMPTY_IS_NULL, BOUND); 322*cdf0e10cSrcweir DECL_PROP1(DEFAULT_TEXT, ::rtl::OUString, BOUND); 323*cdf0e10cSrcweir DECL_PROP1(STRINGITEMLIST, Sequence< ::rtl::OUString >,BOUND); 324*cdf0e10cSrcweir END_DESCRIBE_PROPERTIES(); 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir //------------------------------------------------------------------------------ 328*cdf0e10cSrcweir void OComboBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir OBoundControlModel::describeAggregateProperties( _rAggregateProps ); 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir // superseded properties: 333*cdf0e10cSrcweir RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST ); 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir 336*cdf0e10cSrcweir //------------------------------------------------------------------------------ 337*cdf0e10cSrcweir ::rtl::OUString SAL_CALL OComboBoxModel::getServiceName() throw(RuntimeException) 338*cdf0e10cSrcweir { 339*cdf0e10cSrcweir return FRM_COMPONENT_COMBOBOX; // old (non-sun) name for compatibility ! 340*cdf0e10cSrcweir } 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir //------------------------------------------------------------------------------ 343*cdf0e10cSrcweir void SAL_CALL OComboBoxModel::write(const Reference<stario::XObjectOutputStream>& _rxOutStream) 344*cdf0e10cSrcweir throw(stario::IOException, RuntimeException) 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir OBoundControlModel::write(_rxOutStream); 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir // Version 349*cdf0e10cSrcweir // Version 0x0002: EmptyIsNull 350*cdf0e10cSrcweir // Version 0x0003: ListSource->Seq 351*cdf0e10cSrcweir // Version 0x0004: DefaultText 352*cdf0e10cSrcweir // Version 0x0005: HelpText 353*cdf0e10cSrcweir _rxOutStream->writeShort(0x0006); 354*cdf0e10cSrcweir 355*cdf0e10cSrcweir // Maskierung fuer any 356*cdf0e10cSrcweir sal_uInt16 nAnyMask = 0; 357*cdf0e10cSrcweir if (m_aBoundColumn.getValueType().getTypeClass() == TypeClass_SHORT) 358*cdf0e10cSrcweir nAnyMask |= BOUNDCOLUMN; 359*cdf0e10cSrcweir _rxOutStream << nAnyMask; 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir StringSequence aListSourceSeq(&m_aListSource, 1); 362*cdf0e10cSrcweir _rxOutStream << aListSourceSeq; 363*cdf0e10cSrcweir _rxOutStream << (sal_Int16)m_eListSourceType; 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN) 366*cdf0e10cSrcweir { 367*cdf0e10cSrcweir sal_Int16 nBoundColumn = 0; 368*cdf0e10cSrcweir m_aBoundColumn >>= nBoundColumn; 369*cdf0e10cSrcweir _rxOutStream << nBoundColumn; 370*cdf0e10cSrcweir } 371*cdf0e10cSrcweir 372*cdf0e10cSrcweir _rxOutStream << (sal_Bool)m_bEmptyIsNull; 373*cdf0e10cSrcweir _rxOutStream << m_aDefaultText; 374*cdf0e10cSrcweir writeHelpTextCompatibly(_rxOutStream); 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir // from version 0x0006 : common properties 377*cdf0e10cSrcweir writeCommonProperties(_rxOutStream); 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir 380*cdf0e10cSrcweir //------------------------------------------------------------------------------ 381*cdf0e10cSrcweir void SAL_CALL OComboBoxModel::read(const Reference<stario::XObjectInputStream>& _rxInStream) throw(stario::IOException, RuntimeException) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir OBoundControlModel::read(_rxInStream); 384*cdf0e10cSrcweir ControlModelLock aLock( *this ); 385*cdf0e10cSrcweir 386*cdf0e10cSrcweir // since we are "overwriting" the StringItemList of our aggregate (means we have 387*cdf0e10cSrcweir // an own place to store the value, instead of relying on our aggregate storing it), 388*cdf0e10cSrcweir // we need to respect what the aggregate just read for the StringItemList property. 389*cdf0e10cSrcweir try 390*cdf0e10cSrcweir { 391*cdf0e10cSrcweir if ( m_xAggregateSet.is() ) 392*cdf0e10cSrcweir setNewStringItemList( m_xAggregateSet->getPropertyValue( PROPERTY_STRINGITEMLIST ), aLock ); 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir catch( const Exception& ) 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir OSL_ENSURE( sal_False, "OComboBoxModel::read: caught an exception while examining the aggregate's string item list!" ); 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir // Version 400*cdf0e10cSrcweir sal_uInt16 nVersion = _rxInStream->readShort(); 401*cdf0e10cSrcweir DBG_ASSERT(nVersion > 0, "OComboBoxModel::read : version 0 ? this should never have been written !"); 402*cdf0e10cSrcweir 403*cdf0e10cSrcweir if (nVersion > 0x0006) 404*cdf0e10cSrcweir { 405*cdf0e10cSrcweir DBG_ERROR("OComboBoxModel::read : invalid (means unknown) version !"); 406*cdf0e10cSrcweir m_aListSource = ::rtl::OUString(); 407*cdf0e10cSrcweir m_aBoundColumn <<= (sal_Int16)0; 408*cdf0e10cSrcweir m_aDefaultText = ::rtl::OUString(); 409*cdf0e10cSrcweir m_eListSourceType = ListSourceType_TABLE; 410*cdf0e10cSrcweir m_bEmptyIsNull = sal_True; 411*cdf0e10cSrcweir defaultCommonProperties(); 412*cdf0e10cSrcweir return; 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir // Maskierung fuer any 416*cdf0e10cSrcweir sal_uInt16 nAnyMask; 417*cdf0e10cSrcweir _rxInStream >> nAnyMask; 418*cdf0e10cSrcweir 419*cdf0e10cSrcweir // ListSource 420*cdf0e10cSrcweir if (nVersion < 0x0003) 421*cdf0e10cSrcweir { 422*cdf0e10cSrcweir ::rtl::OUString sListSource; 423*cdf0e10cSrcweir _rxInStream >> m_aListSource; 424*cdf0e10cSrcweir } 425*cdf0e10cSrcweir else // nVersion == 4 426*cdf0e10cSrcweir { 427*cdf0e10cSrcweir m_aListSource = ::rtl::OUString(); 428*cdf0e10cSrcweir StringSequence aListSource; 429*cdf0e10cSrcweir _rxInStream >> aListSource; 430*cdf0e10cSrcweir const ::rtl::OUString* pToken = aListSource.getConstArray(); 431*cdf0e10cSrcweir sal_Int32 nLen = aListSource.getLength(); 432*cdf0e10cSrcweir for (sal_Int32 i = 0; i < nLen; ++i, ++pToken) 433*cdf0e10cSrcweir m_aListSource += *pToken; 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir 436*cdf0e10cSrcweir sal_Int16 nListSourceType; 437*cdf0e10cSrcweir _rxInStream >> nListSourceType; 438*cdf0e10cSrcweir m_eListSourceType = (ListSourceType)nListSourceType; 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN) 441*cdf0e10cSrcweir { 442*cdf0e10cSrcweir sal_Int16 nValue; 443*cdf0e10cSrcweir _rxInStream >> nValue; 444*cdf0e10cSrcweir m_aBoundColumn <<= nValue; 445*cdf0e10cSrcweir } 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir if (nVersion > 0x0001) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir sal_Bool bNull; 450*cdf0e10cSrcweir _rxInStream >> bNull; 451*cdf0e10cSrcweir m_bEmptyIsNull = bNull; 452*cdf0e10cSrcweir } 453*cdf0e10cSrcweir 454*cdf0e10cSrcweir if (nVersion > 0x0003) // nVersion == 4 455*cdf0e10cSrcweir _rxInStream >> m_aDefaultText; 456*cdf0e10cSrcweir 457*cdf0e10cSrcweir // Stringliste muss geleert werden, wenn eine Listenquelle gesetzt ist 458*cdf0e10cSrcweir // dieses kann der Fall sein wenn im alive modus gespeichert wird 459*cdf0e10cSrcweir if ( m_aListSource.getLength() 460*cdf0e10cSrcweir && !hasExternalListSource() 461*cdf0e10cSrcweir ) 462*cdf0e10cSrcweir { 463*cdf0e10cSrcweir setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( StringSequence() ) ); 464*cdf0e10cSrcweir } 465*cdf0e10cSrcweir 466*cdf0e10cSrcweir if (nVersion > 0x0004) 467*cdf0e10cSrcweir readHelpTextCompatibly(_rxInStream); 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir if (nVersion > 0x0005) 470*cdf0e10cSrcweir readCommonProperties(_rxInStream); 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir // Nach dem Lesen die Defaultwerte anzeigen 473*cdf0e10cSrcweir if ( getControlSource().getLength() ) 474*cdf0e10cSrcweir { 475*cdf0e10cSrcweir // (not if we don't have a control source - the "State" property acts like it is persistent, then 476*cdf0e10cSrcweir resetNoBroadcast(); 477*cdf0e10cSrcweir } 478*cdf0e10cSrcweir } 479*cdf0e10cSrcweir 480*cdf0e10cSrcweir //------------------------------------------------------------------------------ 481*cdf0e10cSrcweir void OComboBoxModel::loadData( bool _bForce ) 482*cdf0e10cSrcweir { 483*cdf0e10cSrcweir DBG_ASSERT(m_eListSourceType != ListSourceType_VALUELIST, "OComboBoxModel::loadData : do not call for a value list !"); 484*cdf0e10cSrcweir DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::loadData: cannot load from DB when I have an external list source!" ); 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir if ( hasExternalListSource() ) 487*cdf0e10cSrcweir return; 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir // Connection holen 490*cdf0e10cSrcweir Reference<XRowSet> xForm(m_xCursor, UNO_QUERY); 491*cdf0e10cSrcweir if (!xForm.is()) 492*cdf0e10cSrcweir return; 493*cdf0e10cSrcweir Reference<XConnection> xConnection = getConnection(xForm); 494*cdf0e10cSrcweir if (!xConnection.is()) 495*cdf0e10cSrcweir return; 496*cdf0e10cSrcweir 497*cdf0e10cSrcweir Reference<XServiceInfo> xServiceInfo(xConnection, UNO_QUERY); 498*cdf0e10cSrcweir if (!xServiceInfo.is() || !xServiceInfo->supportsService(SRV_SDB_CONNECTION)) 499*cdf0e10cSrcweir { 500*cdf0e10cSrcweir DBG_ERROR("OComboBoxModel::loadData : invalid connection !"); 501*cdf0e10cSrcweir return; 502*cdf0e10cSrcweir } 503*cdf0e10cSrcweir 504*cdf0e10cSrcweir if (!m_aListSource.getLength() || m_eListSourceType == ListSourceType_VALUELIST) 505*cdf0e10cSrcweir return; 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir ::utl::SharedUNOComponent< XResultSet > xListCursor; 508*cdf0e10cSrcweir try 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir m_aListRowSet.setConnection( xConnection ); 511*cdf0e10cSrcweir 512*cdf0e10cSrcweir bool bExecuteRowSet( false ); 513*cdf0e10cSrcweir switch (m_eListSourceType) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir case ListSourceType_TABLEFIELDS: 516*cdf0e10cSrcweir // don't work with a statement here, the fields will be collected below 517*cdf0e10cSrcweir break; 518*cdf0e10cSrcweir case ListSourceType_TABLE: 519*cdf0e10cSrcweir { 520*cdf0e10cSrcweir // does the bound field belong to the table ? 521*cdf0e10cSrcweir // if we use an alias for the bound field, we won't find it 522*cdf0e10cSrcweir // in that case we use the first field of the table 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir Reference<XNameAccess> xFieldsByName = getTableFields(xConnection, m_aListSource); 525*cdf0e10cSrcweir Reference<XIndexAccess> xFieldsByIndex(xFieldsByName, UNO_QUERY); 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir ::rtl::OUString aFieldName; 528*cdf0e10cSrcweir if ( xFieldsByName.is() && xFieldsByName->hasByName( getControlSource() ) ) 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir aFieldName = getControlSource(); 531*cdf0e10cSrcweir } 532*cdf0e10cSrcweir else 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir // otherwise look for the alias 535*cdf0e10cSrcweir Reference<XPropertySet> xFormProp(xForm,UNO_QUERY); 536*cdf0e10cSrcweir Reference< XColumnsSupplier > xSupplyFields; 537*cdf0e10cSrcweir xFormProp->getPropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SingleSelectQueryComposer"))) >>= xSupplyFields; 538*cdf0e10cSrcweir 539*cdf0e10cSrcweir // search the field 540*cdf0e10cSrcweir DBG_ASSERT(xSupplyFields.is(), "OComboBoxModel::loadData : invalid query composer !"); 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir Reference< XNameAccess > xFieldNames = xSupplyFields->getColumns(); 543*cdf0e10cSrcweir if ( xFieldNames->hasByName( getControlSource() ) ) 544*cdf0e10cSrcweir { 545*cdf0e10cSrcweir Reference< XPropertySet > xComposerFieldAsSet; 546*cdf0e10cSrcweir xFieldNames->getByName( getControlSource() ) >>= xComposerFieldAsSet; 547*cdf0e10cSrcweir if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet)) 548*cdf0e10cSrcweir xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName; 549*cdf0e10cSrcweir } 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir 552*cdf0e10cSrcweir if (!aFieldName.getLength()) 553*cdf0e10cSrcweir break; 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData(); 556*cdf0e10cSrcweir OSL_ENSURE(xMeta.is(),"No database meta data!"); 557*cdf0e10cSrcweir if ( xMeta.is() ) 558*cdf0e10cSrcweir { 559*cdf0e10cSrcweir ::rtl::OUString aQuote = xMeta->getIdentifierQuoteString(); 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir ::rtl::OUString sCatalog, sSchema, sTable; 562*cdf0e10cSrcweir qualifiedNameComponents( xMeta, m_aListSource, sCatalog, sSchema, sTable, eInDataManipulation ); 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir ::rtl::OUStringBuffer aStatement; 565*cdf0e10cSrcweir aStatement.appendAscii( "SELECT DISTINCT " ); 566*cdf0e10cSrcweir aStatement.append ( quoteName( aQuote, aFieldName ) ); 567*cdf0e10cSrcweir aStatement.appendAscii( " FROM " ); 568*cdf0e10cSrcweir aStatement.append ( composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable ) ); 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir m_aListRowSet.setEscapeProcessing( sal_False ); 571*cdf0e10cSrcweir m_aListRowSet.setCommand( aStatement.makeStringAndClear() ); 572*cdf0e10cSrcweir bExecuteRowSet = true; 573*cdf0e10cSrcweir } 574*cdf0e10cSrcweir } break; 575*cdf0e10cSrcweir case ListSourceType_QUERY: 576*cdf0e10cSrcweir { 577*cdf0e10cSrcweir m_aListRowSet.setCommandFromQuery( m_aListSource ); 578*cdf0e10cSrcweir bExecuteRowSet = true; 579*cdf0e10cSrcweir } 580*cdf0e10cSrcweir break; 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir default: 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir m_aListRowSet.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH != m_eListSourceType ); 585*cdf0e10cSrcweir m_aListRowSet.setCommand( m_aListSource ); 586*cdf0e10cSrcweir bExecuteRowSet = true; 587*cdf0e10cSrcweir } 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir if ( bExecuteRowSet ) 591*cdf0e10cSrcweir { 592*cdf0e10cSrcweir if ( !_bForce && !m_aListRowSet.isDirty() ) 593*cdf0e10cSrcweir { 594*cdf0e10cSrcweir // if none of the settings of the row set changed, compared to the last 595*cdf0e10cSrcweir // invocation of loadData, then don't re-fill the list. Instead, assume 596*cdf0e10cSrcweir // the list entries are the same. 597*cdf0e10cSrcweir return; 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir xListCursor.reset( m_aListRowSet.execute() ); 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir catch(SQLException& eSQL) 603*cdf0e10cSrcweir { 604*cdf0e10cSrcweir onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST)); 605*cdf0e10cSrcweir return; 606*cdf0e10cSrcweir } 607*cdf0e10cSrcweir catch( const Exception& ) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 610*cdf0e10cSrcweir return; 611*cdf0e10cSrcweir } 612*cdf0e10cSrcweir 613*cdf0e10cSrcweir ::std::vector< ::rtl::OUString > aStringList; 614*cdf0e10cSrcweir aStringList.reserve(16); 615*cdf0e10cSrcweir try 616*cdf0e10cSrcweir { 617*cdf0e10cSrcweir OSL_ENSURE( xListCursor.is() || ( ListSourceType_TABLEFIELDS == m_eListSourceType ), 618*cdf0e10cSrcweir "OComboBoxModel::loadData: logic error!" ); 619*cdf0e10cSrcweir if ( !xListCursor.is() && ( ListSourceType_TABLEFIELDS != m_eListSourceType ) ) 620*cdf0e10cSrcweir return; 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir switch (m_eListSourceType) 623*cdf0e10cSrcweir { 624*cdf0e10cSrcweir case ListSourceType_SQL: 625*cdf0e10cSrcweir case ListSourceType_SQLPASSTHROUGH: 626*cdf0e10cSrcweir case ListSourceType_TABLE: 627*cdf0e10cSrcweir case ListSourceType_QUERY: 628*cdf0e10cSrcweir { 629*cdf0e10cSrcweir // die XDatabaseVAriant der ersten Spalte 630*cdf0e10cSrcweir Reference<XColumnsSupplier> xSupplyCols(xListCursor, UNO_QUERY); 631*cdf0e10cSrcweir DBG_ASSERT(xSupplyCols.is(), "OComboBoxModel::loadData : cursor supports the row set service but is no column supplier?!"); 632*cdf0e10cSrcweir Reference<XIndexAccess> xColumns; 633*cdf0e10cSrcweir if (xSupplyCols.is()) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir xColumns = Reference<XIndexAccess>(xSupplyCols->getColumns(), UNO_QUERY); 636*cdf0e10cSrcweir DBG_ASSERT(xColumns.is(), "OComboBoxModel::loadData : no columns supplied by the row set !"); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir Reference< XPropertySet > xDataField; 639*cdf0e10cSrcweir if ( xColumns.is() ) 640*cdf0e10cSrcweir xColumns->getByIndex(0) >>= xDataField; 641*cdf0e10cSrcweir if ( !xDataField.is() ) 642*cdf0e10cSrcweir return; 643*cdf0e10cSrcweir 644*cdf0e10cSrcweir ::dbtools::FormattedColumnValue aValueFormatter( getContext(), xForm, xDataField ); 645*cdf0e10cSrcweir 646*cdf0e10cSrcweir // Listen fuellen 647*cdf0e10cSrcweir sal_Int16 i = 0; 648*cdf0e10cSrcweir // per definitionem the list cursor is positioned _before_ the first row at the moment 649*cdf0e10cSrcweir while (xListCursor->next() && (i++<SHRT_MAX)) // max anzahl eintraege 650*cdf0e10cSrcweir { 651*cdf0e10cSrcweir aStringList.push_back( aValueFormatter.getFormattedValue() ); 652*cdf0e10cSrcweir } 653*cdf0e10cSrcweir } 654*cdf0e10cSrcweir break; 655*cdf0e10cSrcweir case ListSourceType_TABLEFIELDS: 656*cdf0e10cSrcweir { 657*cdf0e10cSrcweir Reference<XNameAccess> xFieldNames = getTableFields(xConnection, m_aListSource); 658*cdf0e10cSrcweir if (xFieldNames.is()) 659*cdf0e10cSrcweir { 660*cdf0e10cSrcweir StringSequence seqNames = xFieldNames->getElementNames(); 661*cdf0e10cSrcweir sal_Int32 nFieldsCount = seqNames.getLength(); 662*cdf0e10cSrcweir const ::rtl::OUString* pustrNames = seqNames.getConstArray(); 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir for (sal_Int32 k=0; k<nFieldsCount; ++k) 665*cdf0e10cSrcweir aStringList.push_back(pustrNames[k]); 666*cdf0e10cSrcweir } 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir break; 669*cdf0e10cSrcweir default: 670*cdf0e10cSrcweir OSL_ENSURE( false, "OComboBoxModel::loadData: unreachable!" ); 671*cdf0e10cSrcweir break; 672*cdf0e10cSrcweir } 673*cdf0e10cSrcweir } 674*cdf0e10cSrcweir catch(SQLException& eSQL) 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir onError(eSQL, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST)); 677*cdf0e10cSrcweir return; 678*cdf0e10cSrcweir } 679*cdf0e10cSrcweir catch( const Exception& ) 680*cdf0e10cSrcweir { 681*cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 682*cdf0e10cSrcweir return; 683*cdf0e10cSrcweir } 684*cdf0e10cSrcweir 685*cdf0e10cSrcweir // String-Sequence fuer ListBox erzeugen 686*cdf0e10cSrcweir StringSequence aStringSeq(aStringList.size()); 687*cdf0e10cSrcweir ::rtl::OUString* pStringAry = aStringSeq.getArray(); 688*cdf0e10cSrcweir for (sal_Int32 i = 0; i<aStringSeq.getLength(); ++i) 689*cdf0e10cSrcweir pStringAry[i] = aStringList[i]; 690*cdf0e10cSrcweir 691*cdf0e10cSrcweir // String-Sequence an ListBox setzen 692*cdf0e10cSrcweir setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringSeq ) ); 693*cdf0e10cSrcweir } 694*cdf0e10cSrcweir 695*cdf0e10cSrcweir //------------------------------------------------------------------------------ 696*cdf0e10cSrcweir void OComboBoxModel::onConnectedDbColumn( const Reference< XInterface >& _rxForm ) 697*cdf0e10cSrcweir { 698*cdf0e10cSrcweir Reference<XPropertySet> xField = getField(); 699*cdf0e10cSrcweir if ( xField.is() ) 700*cdf0e10cSrcweir m_pValueFormatter.reset( new ::dbtools::FormattedColumnValue( getContext(), Reference< XRowSet >( _rxForm, UNO_QUERY ), xField ) ); 701*cdf0e10cSrcweir getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= m_aDesignModeStringItems; 702*cdf0e10cSrcweir 703*cdf0e10cSrcweir // Daten nur laden, wenn eine Listenquelle angegeben wurde 704*cdf0e10cSrcweir if ( m_aListSource.getLength() && m_xCursor.is() && !hasExternalListSource() ) 705*cdf0e10cSrcweir loadData( false ); 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir //------------------------------------------------------------------------------ 709*cdf0e10cSrcweir void OComboBoxModel::onDisconnectedDbColumn() 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir m_pValueFormatter.reset(); 712*cdf0e10cSrcweir 713*cdf0e10cSrcweir // reset the string item list 714*cdf0e10cSrcweir if ( !hasExternalListSource() ) 715*cdf0e10cSrcweir setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( m_aDesignModeStringItems ) ); 716*cdf0e10cSrcweir 717*cdf0e10cSrcweir m_aListRowSet.dispose(); 718*cdf0e10cSrcweir } 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir //------------------------------------------------------------------------------ 721*cdf0e10cSrcweir void SAL_CALL OComboBoxModel::reloaded( const EventObject& aEvent ) throw(RuntimeException) 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir OBoundControlModel::reloaded(aEvent); 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir // reload data if we have a list source 726*cdf0e10cSrcweir if ( m_aListSource.getLength() && m_xCursor.is() && !hasExternalListSource() ) 727*cdf0e10cSrcweir loadData( false ); 728*cdf0e10cSrcweir } 729*cdf0e10cSrcweir 730*cdf0e10cSrcweir //------------------------------------------------------------------------------ 731*cdf0e10cSrcweir void OComboBoxModel::resetNoBroadcast() 732*cdf0e10cSrcweir { 733*cdf0e10cSrcweir OBoundControlModel::resetNoBroadcast(); 734*cdf0e10cSrcweir m_aLastKnownValue.clear(); 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir //----------------------------------------------------------------------------- 738*cdf0e10cSrcweir sal_Bool OComboBoxModel::commitControlValueToDbColumn( bool _bPostReset ) 739*cdf0e10cSrcweir { 740*cdf0e10cSrcweir Any aNewValue( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) ); 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir ::rtl::OUString sNewValue; 743*cdf0e10cSrcweir aNewValue >>= sNewValue; 744*cdf0e10cSrcweir 745*cdf0e10cSrcweir bool bModified = ( aNewValue != m_aLastKnownValue ); 746*cdf0e10cSrcweir if ( bModified ) 747*cdf0e10cSrcweir { 748*cdf0e10cSrcweir if ( !aNewValue.hasValue() 749*cdf0e10cSrcweir || ( !sNewValue.getLength() // an empty string 750*cdf0e10cSrcweir && m_bEmptyIsNull // which should be interpreted as NULL 751*cdf0e10cSrcweir ) 752*cdf0e10cSrcweir ) 753*cdf0e10cSrcweir { 754*cdf0e10cSrcweir m_xColumnUpdate->updateNull(); 755*cdf0e10cSrcweir } 756*cdf0e10cSrcweir else 757*cdf0e10cSrcweir { 758*cdf0e10cSrcweir try 759*cdf0e10cSrcweir { 760*cdf0e10cSrcweir OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::commitControlValueToDbColumn: no value formatter!" ); 761*cdf0e10cSrcweir if ( m_pValueFormatter.get() ) 762*cdf0e10cSrcweir { 763*cdf0e10cSrcweir if ( !m_pValueFormatter->setFormattedValue( sNewValue ) ) 764*cdf0e10cSrcweir return sal_False; 765*cdf0e10cSrcweir } 766*cdf0e10cSrcweir else 767*cdf0e10cSrcweir m_xColumnUpdate->updateString( sNewValue ); 768*cdf0e10cSrcweir } 769*cdf0e10cSrcweir catch ( const Exception& ) 770*cdf0e10cSrcweir { 771*cdf0e10cSrcweir return sal_False; 772*cdf0e10cSrcweir } 773*cdf0e10cSrcweir } 774*cdf0e10cSrcweir 775*cdf0e10cSrcweir m_aLastKnownValue = aNewValue; 776*cdf0e10cSrcweir } 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir // add the new value to the list 779*cdf0e10cSrcweir sal_Bool bAddToList = bModified && !_bPostReset; 780*cdf0e10cSrcweir // (only if this is not the "commit" triggered by a "reset") 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir if ( bAddToList ) 783*cdf0e10cSrcweir { 784*cdf0e10cSrcweir StringSequence aStringItemList; 785*cdf0e10cSrcweir if ( getPropertyValue( PROPERTY_STRINGITEMLIST ) >>= aStringItemList ) 786*cdf0e10cSrcweir { 787*cdf0e10cSrcweir const ::rtl::OUString* pStringItems = aStringItemList.getConstArray(); 788*cdf0e10cSrcweir sal_Int32 i; 789*cdf0e10cSrcweir for (i=0; i<aStringItemList.getLength(); ++i, ++pStringItems) 790*cdf0e10cSrcweir { 791*cdf0e10cSrcweir if ( pStringItems->equals( sNewValue ) ) 792*cdf0e10cSrcweir break; 793*cdf0e10cSrcweir } 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir // not found -> add 796*cdf0e10cSrcweir if (i >= aStringItemList.getLength()) 797*cdf0e10cSrcweir { 798*cdf0e10cSrcweir sal_Int32 nOldLen = aStringItemList.getLength(); 799*cdf0e10cSrcweir aStringItemList.realloc( nOldLen + 1 ); 800*cdf0e10cSrcweir aStringItemList.getArray()[ nOldLen ] = sNewValue; 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, makeAny( aStringItemList ) ); 803*cdf0e10cSrcweir } 804*cdf0e10cSrcweir } 805*cdf0e10cSrcweir } 806*cdf0e10cSrcweir 807*cdf0e10cSrcweir return sal_True; 808*cdf0e10cSrcweir } 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir // XPropertiesChangeListener 811*cdf0e10cSrcweir //------------------------------------------------------------------------------ 812*cdf0e10cSrcweir Any OComboBoxModel::translateDbColumnToControlValue() 813*cdf0e10cSrcweir { 814*cdf0e10cSrcweir OSL_PRECOND( m_pValueFormatter.get(), "OComboBoxModel::translateDbColumnToControlValue: no value formatter!" ); 815*cdf0e10cSrcweir if ( m_pValueFormatter.get() ) 816*cdf0e10cSrcweir { 817*cdf0e10cSrcweir ::rtl::OUString sValue( m_pValueFormatter->getFormattedValue() ); 818*cdf0e10cSrcweir if ( !sValue.getLength() 819*cdf0e10cSrcweir && m_pValueFormatter->getColumn().is() 820*cdf0e10cSrcweir && m_pValueFormatter->getColumn()->wasNull() 821*cdf0e10cSrcweir ) 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir m_aLastKnownValue.clear(); 824*cdf0e10cSrcweir } 825*cdf0e10cSrcweir else 826*cdf0e10cSrcweir { 827*cdf0e10cSrcweir 828*cdf0e10cSrcweir m_aLastKnownValue <<= sValue; 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir } 831*cdf0e10cSrcweir else 832*cdf0e10cSrcweir m_aLastKnownValue.clear(); 833*cdf0e10cSrcweir 834*cdf0e10cSrcweir return m_aLastKnownValue.hasValue() ? m_aLastKnownValue : makeAny( ::rtl::OUString() ); 835*cdf0e10cSrcweir // (m_aLastKnownValue is alllowed to be VOID, the control value isn't) 836*cdf0e10cSrcweir } 837*cdf0e10cSrcweir 838*cdf0e10cSrcweir //------------------------------------------------------------------------------ 839*cdf0e10cSrcweir Any OComboBoxModel::getDefaultForReset() const 840*cdf0e10cSrcweir { 841*cdf0e10cSrcweir return makeAny( m_aDefaultText ); 842*cdf0e10cSrcweir } 843*cdf0e10cSrcweir 844*cdf0e10cSrcweir //-------------------------------------------------------------------- 845*cdf0e10cSrcweir void OComboBoxModel::stringItemListChanged( ControlModelLock& /*_rInstanceLock*/ ) 846*cdf0e10cSrcweir { 847*cdf0e10cSrcweir if ( m_xAggregateSet.is() ) 848*cdf0e10cSrcweir m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, makeAny( getStringItemList() ) ); 849*cdf0e10cSrcweir } 850*cdf0e10cSrcweir 851*cdf0e10cSrcweir //-------------------------------------------------------------------- 852*cdf0e10cSrcweir void OComboBoxModel::connectedExternalListSource( ) 853*cdf0e10cSrcweir { 854*cdf0e10cSrcweir // TODO? 855*cdf0e10cSrcweir } 856*cdf0e10cSrcweir 857*cdf0e10cSrcweir //-------------------------------------------------------------------- 858*cdf0e10cSrcweir void OComboBoxModel::disconnectedExternalListSource( ) 859*cdf0e10cSrcweir { 860*cdf0e10cSrcweir // TODO? 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir 863*cdf0e10cSrcweir //-------------------------------------------------------------------- 864*cdf0e10cSrcweir void OComboBoxModel::refreshInternalEntryList() 865*cdf0e10cSrcweir { 866*cdf0e10cSrcweir DBG_ASSERT( !hasExternalListSource(), "OComboBoxModel::refreshInternalEntryList: invalid call!" ); 867*cdf0e10cSrcweir 868*cdf0e10cSrcweir if ( !hasExternalListSource( ) 869*cdf0e10cSrcweir && ( m_eListSourceType != ListSourceType_VALUELIST ) 870*cdf0e10cSrcweir && ( m_xCursor.is() ) 871*cdf0e10cSrcweir ) 872*cdf0e10cSrcweir { 873*cdf0e10cSrcweir loadData( true ); 874*cdf0e10cSrcweir } 875*cdf0e10cSrcweir } 876*cdf0e10cSrcweir 877*cdf0e10cSrcweir //-------------------------------------------------------------------- 878*cdf0e10cSrcweir void SAL_CALL OComboBoxModel::disposing( const EventObject& _rSource ) throw ( RuntimeException ) 879*cdf0e10cSrcweir { 880*cdf0e10cSrcweir if ( !OEntryListHelper::handleDisposing( _rSource ) ) 881*cdf0e10cSrcweir OBoundControlModel::disposing( _rSource ); 882*cdf0e10cSrcweir } 883*cdf0e10cSrcweir 884*cdf0e10cSrcweir //======================================================================== 885*cdf0e10cSrcweir //= OComboBoxControl 886*cdf0e10cSrcweir //======================================================================== 887*cdf0e10cSrcweir 888*cdf0e10cSrcweir //------------------------------------------------------------------ 889*cdf0e10cSrcweir InterfaceRef SAL_CALL OComboBoxControl_CreateInstance(const Reference<XMultiServiceFactory>& _rxFactory) throw (RuntimeException) 890*cdf0e10cSrcweir { 891*cdf0e10cSrcweir return *(new OComboBoxControl(_rxFactory)); 892*cdf0e10cSrcweir } 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir //------------------------------------------------------------------------------ 895*cdf0e10cSrcweir OComboBoxControl::OComboBoxControl(const Reference<XMultiServiceFactory>& _rxFactory) 896*cdf0e10cSrcweir :OBoundControl(_rxFactory, VCL_CONTROL_COMBOBOX) 897*cdf0e10cSrcweir { 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir 900*cdf0e10cSrcweir //------------------------------------------------------------------------------ 901*cdf0e10cSrcweir StringSequence SAL_CALL OComboBoxControl::getSupportedServiceNames() throw(RuntimeException) 902*cdf0e10cSrcweir { 903*cdf0e10cSrcweir StringSequence aSupported = OBoundControl::getSupportedServiceNames(); 904*cdf0e10cSrcweir aSupported.realloc(aSupported.getLength() + 1); 905*cdf0e10cSrcweir 906*cdf0e10cSrcweir ::rtl::OUString* pArray = aSupported.getArray(); 907*cdf0e10cSrcweir pArray[aSupported.getLength()-1] = FRM_SUN_CONTROL_COMBOBOX; 908*cdf0e10cSrcweir return aSupported; 909*cdf0e10cSrcweir } 910*cdf0e10cSrcweir 911*cdf0e10cSrcweir //......................................................................... 912*cdf0e10cSrcweir } 913*cdf0e10cSrcweir //......................................................................... 914*cdf0e10cSrcweir 915