1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "ListBox.hxx"
22 #include "property.hxx"
23 #include "property.hrc"
24 #include "services.hxx"
25 #include "frm_resource.hxx"
26 #include "frm_resource.hrc"
27 #include "BaseListBox.hxx"
28 #include "listenercontainers.hxx"
29 #include "componenttools.hxx"
31 #include <com/sun/star/util/XNumberFormatTypes.hpp>
32 #include <com/sun/star/sdbc/XRowSet.hpp>
33 #include <com/sun/star/container/XIndexAccess.hpp>
34 #include <com/sun/star/sdb/XSQLQueryComposerFactory.hpp>
35 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
36 #include <com/sun/star/util/NumberFormat.hpp>
37 #include <com/sun/star/awt/XWindow.hpp>
38 #include <com/sun/star/sdbc/XConnection.hpp>
39 #include <com/sun/star/sdb/CommandType.hpp>
41 #include <comphelper/basicio.hxx>
42 #include <comphelper/container.hxx>
43 #include <comphelper/numbers.hxx>
44 #include <comphelper/listenernotification.hxx>
45 #include <connectivity/dbtools.hxx>
46 #include <connectivity/formattedcolumnvalue.hxx>
47 #include <connectivity/dbconversion.hxx>
48 #include <cppuhelper/queryinterface.hxx>
49 #include <rtl/logfile.hxx>
50 #include <tools/debug.hxx>
51 #include <tools/diagnose_ex.h>
52 #include <unotools/sharedunocomponent.hxx>
53 #include <vcl/svapp.hxx>
55 #include <boost/optional.hpp>
62 //.........................................................................
65 using namespace ::com::sun::star::uno
;
66 using namespace ::com::sun::star::sdb
;
67 using namespace ::com::sun::star::sdbc
;
68 using namespace ::com::sun::star::sdbcx
;
69 using namespace ::com::sun::star::beans
;
70 using namespace ::com::sun::star::container
;
71 using namespace ::com::sun::star::form
;
72 using namespace ::com::sun::star::awt
;
73 using namespace ::com::sun::star::io
;
74 using namespace ::com::sun::star::lang
;
75 using namespace ::com::sun::star::util
;
76 using namespace ::com::sun::star::form::binding
;
77 using namespace ::dbtools
;
79 using ::connectivity::ORowSetValue
;
81 //==============================================================================
83 //==============================================================================
86 //--------------------------------------------------------------------------
87 struct RowSetValueToString
: public ::std::unary_function
< ORowSetValue
, OUString
>
89 OUString
operator()( const ORowSetValue
& _value
) const
91 return _value
.getString();
95 //--------------------------------------------------------------------------
96 struct AppendRowSetValueString
: public ::std::unary_function
< OUString
, void >
98 AppendRowSetValueString( OUString
& _string
)
103 void operator()( const OUString _append
)
112 //--------------------------------------------------------------------------
113 Sequence
< OUString
> lcl_convertToStringSequence( const ValueList
& _values
)
115 Sequence
< OUString
> aStrings( _values
.size() );
120 RowSetValueToString()
126 //==============================================================================
127 //= ItemEventDescription
128 //==============================================================================
129 typedef ::comphelper::EventHolder
< ItemEvent
> ItemEventDescription
;
131 //==============================================================================
133 //==============================================================================
134 //------------------------------------------------------------------
135 InterfaceRef SAL_CALL
OListBoxModel_CreateInstance(const Reference
<XMultiServiceFactory
>& _rxFactory
) throw (RuntimeException
)
137 return *(new OListBoxModel(_rxFactory
));
140 //------------------------------------------------------------------------------
141 Sequence
< Type
> OListBoxModel::_getTypes()
144 OBoundControlModel::_getTypes(),
145 OEntryListHelper::getTypes(),
146 OErrorBroadcaster::getTypes()
150 // stuff common to all constructors
151 void OListBoxModel::init()
153 startAggregatePropertyListening( PROPERTY_STRINGITEMLIST
);
156 DBG_NAME(OListBoxModel
);
157 //------------------------------------------------------------------
158 OListBoxModel::OListBoxModel(const Reference
<XMultiServiceFactory
>& _rxFactory
)
159 :OBoundControlModel( _rxFactory
, VCL_CONTROLMODEL_LISTBOX
, FRM_SUN_CONTROL_LISTBOX
, sal_True
, sal_True
, sal_True
)
160 // use the old control name for compatibility reasons
161 ,OEntryListHelper( (OControlModel
&)*this )
162 ,OErrorBroadcaster( OComponentHelper::rBHelper
)
163 ,m_aListRowSet( getContext() )
165 ,m_nBoundColumnType( DataType::SQLNULL
)
167 DBG_CTOR(OListBoxModel
,NULL
);
169 m_nClassId
= FormComponentType::LISTBOX
;
170 m_eListSourceType
= ListSourceType_VALUELIST
;
171 m_aBoundColumn
<<= (sal_Int16
)1;
172 initValueProperty( PROPERTY_SELECT_SEQ
, PROPERTY_ID_SELECT_SEQ
);
177 //------------------------------------------------------------------
178 OListBoxModel::OListBoxModel( const OListBoxModel
* _pOriginal
, const Reference
<XMultiServiceFactory
>& _rxFactory
)
179 :OBoundControlModel( _pOriginal
, _rxFactory
)
180 ,OEntryListHelper( *_pOriginal
, (OControlModel
&)*this )
181 ,OErrorBroadcaster( OComponentHelper::rBHelper
)
182 ,m_aListRowSet( getContext() )
183 ,m_eListSourceType( _pOriginal
->m_eListSourceType
)
184 ,m_aBoundColumn( _pOriginal
->m_aBoundColumn
)
185 ,m_aListSourceValues( _pOriginal
->m_aListSourceValues
)
186 ,m_aBoundValues( _pOriginal
->m_aBoundValues
)
187 ,m_aDefaultSelectSeq( _pOriginal
->m_aDefaultSelectSeq
)
189 ,m_nBoundColumnType( DataType::SQLNULL
)
191 DBG_CTOR(OListBoxModel
,NULL
);
196 //------------------------------------------------------------------
197 OListBoxModel::~OListBoxModel()
199 if (!OComponentHelper::rBHelper
.bDisposed
)
205 DBG_DTOR(OListBoxModel
,NULL
);
209 //------------------------------------------------------------------------------
210 IMPLEMENT_DEFAULT_CLONING( OListBoxModel
)
213 //------------------------------------------------------------------------------
214 StringSequence SAL_CALL
OListBoxModel::getSupportedServiceNames() throw(RuntimeException
)
216 StringSequence aSupported
= OBoundControlModel::getSupportedServiceNames();
218 sal_Int32 nOldLen
= aSupported
.getLength();
219 aSupported
.realloc( nOldLen
+ 8 );
220 OUString
* pStoreTo
= aSupported
.getArray() + nOldLen
;
222 *pStoreTo
++ = BINDABLE_CONTROL_MODEL
;
223 *pStoreTo
++ = DATA_AWARE_CONTROL_MODEL
;
224 *pStoreTo
++ = VALIDATABLE_CONTROL_MODEL
;
226 *pStoreTo
++ = BINDABLE_DATA_AWARE_CONTROL_MODEL
;
227 *pStoreTo
++ = VALIDATABLE_BINDABLE_CONTROL_MODEL
;
229 *pStoreTo
++ = FRM_SUN_COMPONENT_LISTBOX
;
230 *pStoreTo
++ = FRM_SUN_COMPONENT_DATABASE_LISTBOX
;
231 *pStoreTo
++ = BINDABLE_DATABASE_LIST_BOX
;
236 //------------------------------------------------------------------------------
237 Any SAL_CALL
OListBoxModel::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
239 Any aReturn
= OBoundControlModel::queryAggregation( _rType
);
240 if ( !aReturn
.hasValue() )
241 aReturn
= OEntryListHelper::queryInterface( _rType
);
242 if ( !aReturn
.hasValue() )
243 aReturn
= OErrorBroadcaster::queryInterface( _rType
);
248 //------------------------------------------------------------------------------
249 void OListBoxModel::disposing()
251 OBoundControlModel::disposing();
252 OEntryListHelper::disposing();
253 OErrorBroadcaster::disposing();
256 //------------------------------------------------------------------------------
257 void OListBoxModel::getFastPropertyValue(Any
& _rValue
, sal_Int32 _nHandle
) const
261 case PROPERTY_ID_BOUNDCOLUMN
:
262 _rValue
<<= m_aBoundColumn
;
265 case PROPERTY_ID_LISTSOURCETYPE
:
266 _rValue
<<= m_eListSourceType
;
269 case PROPERTY_ID_LISTSOURCE
:
270 _rValue
<<= lcl_convertToStringSequence( m_aListSourceValues
);
273 case PROPERTY_ID_VALUE_SEQ
:
274 _rValue
<<= lcl_convertToStringSequence( m_aBoundValues
);
277 case PROPERTY_ID_SELECT_VALUE_SEQ
:
278 _rValue
= getCurrentMultiValue();
281 case PROPERTY_ID_SELECT_VALUE
:
282 _rValue
= getCurrentSingleValue();
285 case PROPERTY_ID_DEFAULT_SELECT_SEQ
:
286 _rValue
<<= m_aDefaultSelectSeq
;
289 case PROPERTY_ID_STRINGITEMLIST
:
290 _rValue
<<= getStringItemList();
294 OBoundControlModel::getFastPropertyValue(_rValue
, _nHandle
);
298 //------------------------------------------------------------------------------
299 void OListBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle
, const Any
& _rValue
) throw (com::sun::star::uno::Exception
)
303 case PROPERTY_ID_BOUNDCOLUMN
:
304 DBG_ASSERT((_rValue
.getValueType().getTypeClass() == TypeClass_SHORT
) || (_rValue
.getValueType().getTypeClass() == TypeClass_VOID
),
305 "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
306 m_aBoundColumn
= _rValue
;
309 case PROPERTY_ID_LISTSOURCETYPE
:
310 DBG_ASSERT(_rValue
.getValueType().equals(::getCppuType(static_cast<ListSourceType
*>(0))),
311 "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
312 _rValue
>>= m_eListSourceType
;
315 case PROPERTY_ID_LISTSOURCE
:
318 Sequence
< OUString
> aListSource
;
319 OSL_VERIFY( _rValue
>>= aListSource
);
322 ValueList().swap(m_aListSourceValues
);
324 aListSource
.getConstArray(),
325 aListSource
.getConstArray() + aListSource
.getLength(),
326 ::std::insert_iterator
< ValueList
>( m_aListSourceValues
, m_aListSourceValues
.end() )
330 if ( m_eListSourceType
== ListSourceType_VALUELIST
)
332 setBoundValues(m_aListSourceValues
);
336 if ( m_xCursor
.is() && !hasField() && !hasExternalListSource() )
337 // listbox is already connected to a database, and no external list source
338 // data source changed -> refresh
344 case PROPERTY_ID_VALUE_SEQ
:
345 OSL_FAIL( "ValueItemList is read-only!" );
346 throw PropertyVetoException();
348 case PROPERTY_ID_SELECT_VALUE_SEQ
:
350 Sequence
< const Any
> v
;
352 Any
newSelectSeq(translateBindingValuesToControlValue(v
));
353 setControlValue( newSelectSeq
, eOther
);
357 case PROPERTY_ID_SELECT_VALUE
:
361 Any
newSelectSeq(translateDbValueToControlValue(v
));
362 setControlValue( newSelectSeq
, eOther
);
366 case PROPERTY_ID_DEFAULT_SELECT_SEQ
:
367 DBG_ASSERT(_rValue
.getValueType().equals(::getCppuType(static_cast< Sequence
<sal_Int16
>*>(0))),
368 "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
369 _rValue
>>= m_aDefaultSelectSeq
;
371 DBG_ASSERT(m_xAggregateFastSet
.is(), "OListBoxModel::setFastPropertyValue_NoBroadcast(DEFAULT_SELECT_SEQ) : invalid aggregate !");
372 if ( m_xAggregateFastSet
.is() )
373 setControlValue( _rValue
, eOther
);
376 case PROPERTY_ID_STRINGITEMLIST
:
378 ControlModelLock
aLock( *this );
379 setNewStringItemList( _rValue
, aLock
);
380 // TODO: this is bogus. setNewStringItemList expects a guard which has the *only*
381 // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with
382 // a lock - so we effectively has two locks here, of which setNewStringItemList can
389 OBoundControlModel::setFastPropertyValue_NoBroadcast(_nHandle
, _rValue
);
393 //------------------------------------------------------------------------------
394 sal_Bool
OListBoxModel::convertFastPropertyValue(
395 Any
& _rConvertedValue
, Any
& _rOldValue
, sal_Int32 _nHandle
, const Any
& _rValue
)
396 throw (IllegalArgumentException
)
398 sal_Bool
bModified(sal_False
);
401 case PROPERTY_ID_BOUNDCOLUMN
:
402 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_aBoundColumn
, ::getCppuType(static_cast<sal_Int16
*>(0)));
405 case PROPERTY_ID_LISTSOURCETYPE
:
406 bModified
= tryPropertyValueEnum(_rConvertedValue
, _rOldValue
, _rValue
, m_eListSourceType
);
409 case PROPERTY_ID_LISTSOURCE
:
410 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, lcl_convertToStringSequence( m_aListSourceValues
) );
413 case PROPERTY_ID_VALUE_SEQ
:
414 OSL_FAIL( "ValueItemList is read-only!" );
415 throw PropertyVetoException();
417 case PROPERTY_ID_SELECT_VALUE_SEQ
:
418 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, getCurrentMultiValue());
421 case PROPERTY_ID_SELECT_VALUE
:
422 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, getCurrentSingleValue());
425 case PROPERTY_ID_DEFAULT_SELECT_SEQ
:
426 bModified
= tryPropertyValue(_rConvertedValue
, _rOldValue
, _rValue
, m_aDefaultSelectSeq
);
429 case PROPERTY_ID_STRINGITEMLIST
:
430 bModified
= convertNewListSourceProperty( _rConvertedValue
, _rOldValue
, _rValue
);
434 return OBoundControlModel::convertFastPropertyValue(_rConvertedValue
, _rOldValue
, _nHandle
, _rValue
);
439 //------------------------------------------------------------------------------
440 void SAL_CALL
OListBoxModel::setPropertyValues( const Sequence
< OUString
>& _rPropertyNames
, const Sequence
< Any
>& _rValues
) throw(PropertyVetoException
, IllegalArgumentException
, WrappedTargetException
, RuntimeException
)
442 // if both SelectedItems and StringItemList are set, care for this
444 const Any
* pSelectSequenceValue
= NULL
;
446 const OUString
* pStartPos
= _rPropertyNames
.getConstArray();
447 const OUString
* pEndPos
= _rPropertyNames
.getConstArray() + _rPropertyNames
.getLength();
448 const OUString
* pSelectedItemsPos
= ::std::find_if(
450 ::std::bind2nd( ::std::equal_to
< OUString
>(), PROPERTY_SELECT_SEQ
)
452 const OUString
* pStringItemListPos
= ::std::find_if(
454 ::std::bind2nd( ::std::equal_to
< OUString
>(), PROPERTY_STRINGITEMLIST
)
456 if ( ( pSelectedItemsPos
!= pEndPos
) && ( pStringItemListPos
!= pEndPos
) )
458 // both properties are present
459 // -> remember the value for the select sequence
460 pSelectSequenceValue
= _rValues
.getConstArray() + ( pSelectedItemsPos
- pStartPos
);
463 OBoundControlModel::setPropertyValues( _rPropertyNames
, _rValues
);
465 if ( pSelectSequenceValue
)
467 setPropertyValue( PROPERTY_SELECT_SEQ
, *pSelectSequenceValue
);
468 // Note that this is the only reliable way, since one of the properties is implemented
469 // by ourself, and one is implemented by the aggregate, we cannot rely on any particular
470 // results when setting them both - too many undocumented behavior in all the involved
475 //------------------------------------------------------------------------------
476 void OListBoxModel::describeFixedProperties( Sequence
< Property
>& _rProps
) const
478 BEGIN_DESCRIBE_PROPERTIES( 9, OBoundControlModel
)
479 DECL_PROP1(TABINDEX
, sal_Int16
, BOUND
);
480 DECL_PROP2(BOUNDCOLUMN
, sal_Int16
, BOUND
, MAYBEVOID
);
481 DECL_PROP1(LISTSOURCETYPE
, ListSourceType
, BOUND
);
482 DECL_PROP1(LISTSOURCE
, StringSequence
, BOUND
);
483 DECL_PROP3(VALUE_SEQ
, StringSequence
, BOUND
, READONLY
, TRANSIENT
);
484 DECL_PROP2(SELECT_VALUE_SEQ
, Sequence
< Any
>, BOUND
, TRANSIENT
);
485 DECL_PROP2(SELECT_VALUE
, Any
, BOUND
, TRANSIENT
);
486 DECL_PROP1(DEFAULT_SELECT_SEQ
, Sequence
<sal_Int16
>, BOUND
);
487 DECL_PROP1(STRINGITEMLIST
, Sequence
< OUString
>, BOUND
);
488 END_DESCRIBE_PROPERTIES();
491 //------------------------------------------------------------------------------
492 void OListBoxModel::_propertyChanged( const PropertyChangeEvent
& i_rEvent
) throw ( RuntimeException
)
494 if ( i_rEvent
.PropertyName
== PROPERTY_STRINGITEMLIST
)
496 ControlModelLock
aLock( *this );
497 // SYNCHRONIZED ----->
498 // our aggregate internally changed its StringItemList property - reflect this in our "overridden"
499 // version of the property
500 setNewStringItemList( i_rEvent
.NewValue
, aLock
);
501 // <----- SYNCHRONIZED
504 OBoundControlModel::_propertyChanged( i_rEvent
);
507 //------------------------------------------------------------------------------
508 void OListBoxModel::describeAggregateProperties( Sequence
< Property
>& _rAggregateProps
) const
510 OBoundControlModel::describeAggregateProperties( _rAggregateProps
);
512 // superseded properties:
513 RemoveProperty( _rAggregateProps
, PROPERTY_STRINGITEMLIST
);
516 //------------------------------------------------------------------------------
517 OUString SAL_CALL
OListBoxModel::getServiceName() throw(RuntimeException
)
519 return OUString(FRM_COMPONENT_LISTBOX
); // old (non-sun) name for compatibility !
522 //------------------------------------------------------------------------------
523 void SAL_CALL
OListBoxModel::write(const Reference
<XObjectOutputStream
>& _rxOutStream
)
524 throw(IOException
, RuntimeException
)
526 OBoundControlModel::write(_rxOutStream
);
528 // Dummy sequence, to stay compatible if SelectSeq is not saved anymore
529 Sequence
<sal_Int16
> aDummySeq
;
532 // Version 0x0002: ListSource becomes StringSeq
533 _rxOutStream
->writeShort(0x0004);
536 sal_uInt16 nAnyMask
= 0;
537 if (m_aBoundColumn
.getValueType().getTypeClass() != TypeClass_VOID
)
538 nAnyMask
|= BOUNDCOLUMN
;
540 _rxOutStream
<< nAnyMask
;
542 _rxOutStream
<< lcl_convertToStringSequence( m_aListSourceValues
);
543 _rxOutStream
<< (sal_Int16
)m_eListSourceType
;
544 _rxOutStream
<< aDummySeq
;
545 _rxOutStream
<< m_aDefaultSelectSeq
;
547 if ((nAnyMask
& BOUNDCOLUMN
) == BOUNDCOLUMN
)
549 sal_Int16 nBoundColumn
= 0;
550 m_aBoundColumn
>>= nBoundColumn
;
551 _rxOutStream
<< nBoundColumn
;
553 writeHelpTextCompatibly(_rxOutStream
);
555 // from version 0x0004 : common properties
556 writeCommonProperties(_rxOutStream
);
559 //------------------------------------------------------------------------------
560 void SAL_CALL
OListBoxModel::read(const Reference
<XObjectInputStream
>& _rxInStream
) throw(IOException
, RuntimeException
)
562 // We need to respect dependencies for certain variables.
563 // Therefore, we need to set them explicitly via setPropertyValue().
565 OBoundControlModel::read(_rxInStream
);
566 ControlModelLock
aLock( *this );
568 // since we are "overwriting" the StringItemList of our aggregate (means we have
569 // an own place to store the value, instead of relying on our aggregate storing it),
570 // we need to respect what the aggregate just read for the StringItemList property.
573 if ( m_xAggregateSet
.is() )
574 setNewStringItemList( m_xAggregateSet
->getPropertyValue( PROPERTY_STRINGITEMLIST
), aLock
);
576 catch( const Exception
& )
578 OSL_FAIL( "OComboBoxModel::read: caught an exception while examining the aggregate's string item list!" );
582 sal_uInt16 nVersion
= _rxInStream
->readShort();
583 DBG_ASSERT(nVersion
> 0, "OListBoxModel::read : version 0 ? this should never have been written !");
585 if (nVersion
> 0x0004)
587 OSL_FAIL("OListBoxModel::read : invalid (means unknown) version !");
588 ValueList().swap(m_aListSourceValues
);
589 m_aBoundColumn
<<= (sal_Int16
)0;
591 m_eListSourceType
= ListSourceType_VALUELIST
;
592 m_aDefaultSelectSeq
.realloc(0);
593 defaultCommonProperties();
599 _rxInStream
>> nAnyMask
;
602 StringSequence aListSourceSeq
;
603 if (nVersion
== 0x0001)
605 // Create ListSourceSeq from String
606 OUString sListSource
;
607 _rxInStream
>> sListSource
;
609 sal_Int32 nTokens
= 1;
610 const sal_Unicode
* pStr
= sListSource
.getStr();
617 aListSourceSeq
.realloc( nTokens
);
618 for (sal_uInt16 i
=0; i
<nTokens
; ++i
)
621 aListSourceSeq
.getArray()[i
] = sListSource
.getToken(i
,';',nTmp
);
625 _rxInStream
>> aListSourceSeq
;
627 sal_Int16 nListSourceType
;
628 _rxInStream
>> nListSourceType
;
629 m_eListSourceType
= (ListSourceType
)nListSourceType
;
630 Any aListSourceSeqAny
;
631 aListSourceSeqAny
<<= aListSourceSeq
;
633 setFastPropertyValue(PROPERTY_ID_LISTSOURCE
, aListSourceSeqAny
);
635 // Dummy sequence, to stay compatible if SelectSeq is not saved anymore
636 Sequence
<sal_Int16
> aDummySeq
;
637 _rxInStream
>> aDummySeq
;
640 Sequence
<sal_Int16
> aDefaultSelectSeq
;
641 _rxInStream
>> aDefaultSelectSeq
;
642 Any aDefaultSelectSeqAny
;
643 aDefaultSelectSeqAny
<<= aDefaultSelectSeq
;
644 setFastPropertyValue(PROPERTY_ID_DEFAULT_SELECT_SEQ
, aDefaultSelectSeqAny
);
647 if ((nAnyMask
& BOUNDCOLUMN
) == BOUNDCOLUMN
)
650 _rxInStream
>> nValue
;
651 m_aBoundColumn
<<= nValue
;
653 else // the constructor initialises to 1, so if it is empty,
654 // we must explicitly set to empty
656 m_aBoundColumn
= Any();
660 readHelpTextCompatibly(_rxInStream
);
662 // if our string list is not filled from the value list, we must empty it
663 // this can be the case when somebody saves in alive mode
664 if ( ( m_eListSourceType
!= ListSourceType_VALUELIST
)
665 && !hasExternalListSource()
668 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST
, makeAny( StringSequence() ) );
672 readCommonProperties(_rxInStream
);
674 // Display the default values after reading
675 if ( !getControlSource().isEmpty() )
676 // (not if we don't have a control source - the "State" property acts like it is persistent, then
680 //------------------------------------------------------------------------------
681 void OListBoxModel::loadData( bool _bForce
)
683 RTL_LOGFILE_CONTEXT( aLogContext
, "OListBoxModel::loadData" );
684 DBG_ASSERT( m_eListSourceType
!= ListSourceType_VALUELIST
, "OListBoxModel::loadData: cannot load value list from DB!" );
685 DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::loadData: cannot load from DB when I have an external list source!" );
687 const sal_Int16
nNULLPosBackup( m_nNULLPos
);
688 const sal_Int32
nBoundColumnTypeBackup( m_nBoundColumnType
);
690 m_nBoundColumnType
= DataType::SQLNULL
;
694 Reference
< XConnection
> xConnection
;
695 // is the active connection of our form
696 Reference
< XPropertySet
> xFormProps( m_xCursor
, UNO_QUERY
);
697 if ( xFormProps
.is() )
698 xFormProps
->getPropertyValue( PROPERTY_ACTIVE_CONNECTION
) >>= xConnection
;
701 OUString sListSource
;
702 // if our list source type is no value list, we need to concatenate
703 // the single list source elements
705 m_aListSourceValues
.begin(),
706 m_aListSourceValues
.end(),
707 AppendRowSetValueString( sListSource
)
710 // outta here if we don't have all pre-requisites
711 if ( !xConnection
.is() || sListSource
.isEmpty() )
717 ::boost::optional
< sal_Int16
> aBoundColumn(0);
718 aBoundColumn
.reset();
719 if ( m_aBoundColumn
.getValueType().getTypeClass() == TypeClass_SHORT
)
721 sal_Int16
nBoundColumn( 0 );
722 m_aBoundColumn
>>= nBoundColumn
;
723 aBoundColumn
.reset( nBoundColumn
);
726 ::utl::SharedUNOComponent
< XResultSet
> xListCursor
;
729 m_aListRowSet
.setConnection( xConnection
);
731 sal_Bool bExecute
= sal_False
;
732 switch (m_eListSourceType
)
734 case ListSourceType_TABLEFIELDS
:
735 // don't work with a statement here, the fields will be collected below
738 case ListSourceType_TABLE
:
740 Reference
<XNameAccess
> xFieldsByName
= getTableFields(xConnection
, sListSource
);
741 Reference
<XIndexAccess
> xFieldsByIndex(xFieldsByName
, UNO_QUERY
);
743 // do we have a bound column if yes we have to select it
744 // and the displayed column is the first column othwhise we act as a combobox
746 OUString aBoundFieldName
;
748 if ( !!aBoundColumn
&& ( *aBoundColumn
>= 0 ) && xFieldsByIndex
.is() )
750 if ( *aBoundColumn
>= xFieldsByIndex
->getCount() )
753 Reference
<XPropertySet
> xFieldAsSet(xFieldsByIndex
->getByIndex( *aBoundColumn
),UNO_QUERY
);
754 assert(xFieldAsSet
.is());
755 xFieldAsSet
->getPropertyValue(PROPERTY_NAME
) >>= aBoundFieldName
;
756 aBoundColumn
.reset( 1 );
758 xFieldAsSet
.set(xFieldsByIndex
->getByIndex(0),UNO_QUERY
);
759 xFieldAsSet
->getPropertyValue(PROPERTY_NAME
) >>= aFieldName
;
761 else if (xFieldsByName
.is())
763 if ( xFieldsByName
->hasByName( getControlSource() ) )
764 aFieldName
= getControlSource();
767 // otherwise look for the alias
768 Reference
< XColumnsSupplier
> xSupplyFields
;
769 xFormProps
->getPropertyValue(OUString("SingleSelectQueryComposer")) >>= xSupplyFields
;
772 DBG_ASSERT(xSupplyFields
.is(), "OListBoxModel::loadData : invalid query composer !");
774 Reference
<XNameAccess
> xFieldNames
= xSupplyFields
->getColumns();
775 if ( xFieldNames
->hasByName( getControlSource() ) )
777 Reference
<XPropertySet
> xComposerFieldAsSet
;
778 xFieldNames
->getByName( getControlSource() ) >>= xComposerFieldAsSet
;
779 if (hasProperty(PROPERTY_FIELDSOURCE
, xComposerFieldAsSet
))
780 xComposerFieldAsSet
->getPropertyValue(PROPERTY_FIELDSOURCE
) >>= aFieldName
;
784 if (aFieldName
.isEmpty())
787 Reference
<XDatabaseMetaData
> xMeta
= xConnection
->getMetaData();
788 OUString aQuote
= xMeta
->getIdentifierQuoteString();
789 OUString
aStatement("SELECT ");
790 if (aBoundFieldName
.isEmpty()) // act like a combobox
791 aStatement
+= OUString("DISTINCT ");
793 aStatement
+= quoteName(aQuote
,aFieldName
);
794 if (!aBoundFieldName
.isEmpty())
796 aStatement
+= OUString(", ");
797 aStatement
+= quoteName(aQuote
, aBoundFieldName
);
799 aStatement
+= OUString(" FROM ");
801 OUString sCatalog
, sSchema
, sTable
;
802 qualifiedNameComponents( xMeta
, sListSource
, sCatalog
, sSchema
, sTable
, eInDataManipulation
);
803 aStatement
+= composeTableNameForSelect( xConnection
, sCatalog
, sSchema
, sTable
);
805 m_aListRowSet
.setEscapeProcessing( sal_False
);
806 m_aListRowSet
.setCommand( aStatement
);
811 case ListSourceType_QUERY
:
812 m_aListRowSet
.setCommandFromQuery( sListSource
);
817 m_aListRowSet
.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH
!= m_eListSourceType
);
818 m_aListRowSet
.setCommand( sListSource
);
825 if ( !_bForce
&& !m_aListRowSet
.isDirty() )
827 // if none of the settings of the row set changed, compared to the last
828 // invocation of loadData, then don't re-fill the list. Instead, assume
829 // the list entries are the same.
830 m_nNULLPos
= nNULLPosBackup
;
831 m_nBoundColumnType
= nBoundColumnTypeBackup
;
834 xListCursor
.reset( m_aListRowSet
.execute() );
837 catch(const SQLException
& eSQL
)
839 onError(eSQL
, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST
));
842 catch(const Exception
& eUnknown
)
848 // Fill display and value lists
849 ValueList aDisplayList
, aValueList
;
850 sal_Bool bUseNULL
= hasField() && !isRequired();
852 // empty BoundColumn is treated as BoundColumn=0,
858 OSL_ENSURE( xListCursor
.is() || ( ListSourceType_TABLEFIELDS
== m_eListSourceType
),
859 "OListBoxModel::loadData: logic error!" );
860 if ( !xListCursor
.is() && ( ListSourceType_TABLEFIELDS
!= m_eListSourceType
) )
863 switch (m_eListSourceType
)
865 case ListSourceType_SQL
:
866 case ListSourceType_SQLPASSTHROUGH
:
867 case ListSourceType_TABLE
:
868 case ListSourceType_QUERY
:
870 // Get field of the ResultSet's 1st column
871 Reference
<XColumnsSupplier
> xSupplyCols(xListCursor
, UNO_QUERY
);
872 DBG_ASSERT(xSupplyCols
.is(), "OListBoxModel::loadData : cursor supports the row set service but is no column supplier?!");
873 Reference
<XIndexAccess
> xColumns
;
874 if (xSupplyCols
.is())
876 xColumns
= Reference
<XIndexAccess
>(xSupplyCols
->getColumns(), UNO_QUERY
);
877 DBG_ASSERT(xColumns
.is(), "OListBoxModel::loadData : no columns supplied by the row set !");
880 Reference
< XPropertySet
> xDataField
;
882 xColumns
->getByIndex(0) >>= xDataField
;
883 if ( !xDataField
.is() )
886 ::dbtools::FormattedColumnValue
aValueFormatter( getContext(), m_xCursor
, xDataField
);
888 // Get the field of BoundColumn of the ResultSet
889 m_nBoundColumnType
= DataType::SQLNULL
;
890 if ( *aBoundColumn
>= 0 )
894 Reference
< XPropertySet
> xBoundField( xColumns
->getByIndex( *aBoundColumn
), UNO_QUERY_THROW
);
895 OSL_VERIFY( xBoundField
->getPropertyValue( OUString("Type") ) >>= m_nBoundColumnType
);
897 catch( const Exception
& )
899 DBG_UNHANDLED_EXCEPTION();
902 else if ( *aBoundColumn
== -1)
903 m_nBoundColumnType
= DataType::SMALLINT
;
905 // If the LB is bound to a field and empty entries are valid, we remember the position
906 // for an empty entry
907 RTL_LOGFILE_CONTEXT( aLogContext
, "OListBoxModel::loadData: string collection" );
909 sal_Int16 entryPos
= 0;
910 ORowSetValue aBoundValue
;
911 Reference
< XRow
> xCursorRow( xListCursor
, UNO_QUERY_THROW
);
912 while ( xListCursor
->next() && ( entryPos
++ < SHRT_MAX
) ) // SHRT_MAX is the maximum number of entries
914 aStr
= aValueFormatter
.getFormattedValue();
915 aDisplayList
.push_back( aStr
);
917 if(*aBoundColumn
>= 0)
918 aBoundValue
.fill( *aBoundColumn
+ 1, m_nBoundColumnType
, xCursorRow
);
920 // -1 because getRow() is 1-indexed, but ListBox positions are 0-indexed
921 aBoundValue
= static_cast<sal_Int16
>(xListCursor
->getRow()-1);
922 aValueList
.push_back( aBoundValue
);
924 if ( m_nNULLPos
== -1 && aBoundValue
.isNull() )
925 m_nNULLPos
= sal_Int16( aDisplayList
.size() - 1 );
926 if ( bUseNULL
&& ( m_nNULLPos
== -1 ) && aStr
.isEmpty() )
927 // There is already a non-NULL entry with empty display string;
928 // adding another one for NULL would make things confusing,
935 case ListSourceType_TABLEFIELDS
:
937 Reference
<XNameAccess
> xFieldNames
= getTableFields(xConnection
, sListSource
);
938 if (xFieldNames
.is())
940 StringSequence seqNames
= xFieldNames
->getElementNames();
942 seqNames
.getConstArray(),
943 seqNames
.getConstArray() + seqNames
.getLength(),
944 ::std::insert_iterator
< ValueList
>( aDisplayList
, aDisplayList
.end() )
946 if(*aBoundColumn
== -1)
948 // the type of i matters! It will be the type of the ORowSetValue pushed to aValueList!
949 for(sal_Int16 i
=0; static_cast<ValueList::size_type
>(i
) < aDisplayList
.size(); ++i
)
951 aValueList
.push_back(i
);
956 aValueList
= aDisplayList
;
962 OSL_FAIL( "OListBoxModel::loadData: unreachable!" );
966 catch(const SQLException
& eSQL
)
968 onError(eSQL
, FRM_RES_STRING(RID_BASELISTBOX_ERROR_FILLLIST
));
971 catch( const Exception
& )
973 DBG_UNHANDLED_EXCEPTION();
978 // Create Values sequence
980 if (bUseNULL
&& m_nNULLPos
== -1)
982 aValueList
.insert( aValueList
.begin(), ORowSetValue() );
984 aDisplayList
.insert( aDisplayList
.begin(), ORowSetValue( OUString() ) );
988 setBoundValues(aValueList
);
990 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST
, makeAny( lcl_convertToStringSequence( aDisplayList
) ) );
993 //------------------------------------------------------------------------------
994 void OListBoxModel::onConnectedDbColumn( const Reference
< XInterface
>& /*_rxForm*/ )
996 // list boxes which are bound to a db column don't have multi selection
997 // - this would be unable to reflect in the db column
1000 setFastPropertyValue( PROPERTY_ID_MULTISELECTION
, ::cppu::bool2any( ( sal_False
) ) );
1003 if ( !hasExternalListSource() )
1004 impl_refreshDbEntryList( false );
1007 //------------------------------------------------------------------------------
1008 void OListBoxModel::onDisconnectedDbColumn()
1010 if ( m_eListSourceType
!= ListSourceType_VALUELIST
)
1014 m_nBoundColumnType
= DataType::SQLNULL
;
1016 if ( !hasExternalListSource() )
1017 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST
, makeAny( StringSequence() ) );
1019 m_aListRowSet
.dispose();
1023 //------------------------------------------------------------------------------
1024 void OListBoxModel::setBoundValues(const ValueList
&l
)
1026 m_aConvertedBoundValues
.clear();
1030 //------------------------------------------------------------------------------
1031 void OListBoxModel::clearBoundValues()
1033 ValueList().swap(m_aConvertedBoundValues
);
1034 ValueList().swap(m_aBoundValues
);
1037 //------------------------------------------------------------------------------
1038 void OListBoxModel::convertBoundValues(const sal_Int32 nFieldType
) const
1040 m_aConvertedBoundValues
.resize(m_aBoundValues
.size());
1041 ValueList::const_iterator src
= m_aBoundValues
.begin();
1042 const ValueList::const_iterator end
= m_aBoundValues
.end();
1043 ValueList::iterator dst
= m_aConvertedBoundValues
.begin();
1044 for (; src
!= end
; ++src
, ++dst
)
1047 dst
->setTypeKind(nFieldType
);
1049 m_nConvertedBoundValuesType
= nFieldType
;
1050 OSL_ENSURE(dst
== m_aConvertedBoundValues
.end(), "OListBoxModel::convertBoundValues expected to have overwritten all of m_aConvertedBoundValues, but did not.");
1051 assert(dst
== m_aConvertedBoundValues
.end());
1053 //------------------------------------------------------------------------------
1054 sal_Int32
OListBoxModel::getValueType() const
1056 return impl_hasBoundComponent() ? m_nBoundColumnType
: getFieldType();
1058 //------------------------------------------------------------------------------
1059 ValueList
OListBoxModel::impl_getValues() const
1061 const sal_Int32 nFieldType
= getValueType();
1063 if ( !m_aConvertedBoundValues
.empty() && m_nConvertedBoundValuesType
== nFieldType
)
1064 return m_aConvertedBoundValues
;
1066 if ( !m_aBoundValues
.empty() )
1068 convertBoundValues(nFieldType
);
1069 return m_aConvertedBoundValues
;
1072 Sequence
< OUString
> aStringItems( getStringItemList() );
1073 ValueList
aValues( aStringItems
.getLength() );
1074 ValueList::iterator dst
= aValues
.begin();
1075 const OUString
*src (aStringItems
.getConstArray());
1076 const OUString
* const end
= src
+ aStringItems
.getLength();
1077 for (; src
< end
; ++src
, ++dst
)
1080 dst
->setTypeKind(nFieldType
);
1082 m_nConvertedBoundValuesType
= nFieldType
;
1083 OSL_ENSURE(dst
== aValues
.end(), "OListBoxModel::impl_getValues expected to have set all of aValues, but did not.");
1084 assert(dst
== aValues
.end());
1087 //------------------------------------------------------------------------------
1088 ORowSetValue
OListBoxModel::getFirstSelectedValue() const
1090 static const ORowSetValue s_aEmptyVaue
;
1092 DBG_ASSERT( m_xAggregateFastSet
.is(), "OListBoxModel::getFirstSelectedValue: invalid aggregate!" );
1093 if ( !m_xAggregateFastSet
.is() )
1094 return s_aEmptyVaue
;
1096 Sequence
< sal_Int16
> aSelectedIndices
;
1097 OSL_VERIFY( m_xAggregateFastSet
->getFastPropertyValue( getValuePropertyAggHandle() ) >>= aSelectedIndices
);
1098 if ( !aSelectedIndices
.getLength() )
1099 // nothing selected at all
1100 return s_aEmptyVaue
;
1102 if ( ( m_nNULLPos
!= -1 ) && ( aSelectedIndices
[0] == m_nNULLPos
) )
1103 // the dedicated "NULL" entry is selected
1104 return s_aEmptyVaue
;
1106 ValueList
aValues( impl_getValues() );
1108 size_t selectedValue
= aSelectedIndices
[0];
1109 if ( selectedValue
>= aValues
.size() )
1111 OSL_FAIL( "OListBoxModel::getFirstSelectedValue: inconsistent selection/valuelist!" );
1112 return s_aEmptyVaue
;
1115 return aValues
[ selectedValue
];
1118 //------------------------------------------------------------------------------
1119 sal_Bool
OListBoxModel::commitControlValueToDbColumn( bool /*_bPostReset*/ )
1121 // current selection list
1122 const ORowSetValue
aCurrentValue( getFirstSelectedValue() );
1123 if ( aCurrentValue
!= m_aSaveValue
)
1125 if ( aCurrentValue
.isNull() )
1126 m_xColumnUpdate
->updateNull();
1131 m_xColumnUpdate
->updateObject( aCurrentValue
.makeAny() );
1133 catch ( const Exception
& )
1138 m_aSaveValue
= aCurrentValue
;
1143 //------------------------------------------------------------------------------
1144 Sequence
< sal_Int16
> OListBoxModel::translateDbValueToControlValue(const ORowSetValue
&i_aValue
) const
1146 Sequence
< sal_Int16
> aSelectionIndicies
;
1148 // reset selection for NULL values
1149 if ( i_aValue
.isNull() )
1151 if ( m_nNULLPos
!= -1 )
1153 aSelectionIndicies
.realloc(1);
1154 aSelectionIndicies
[0] = m_nNULLPos
;
1159 ValueList
aValues( impl_getValues() );
1160 assert( m_nConvertedBoundValuesType
== getValueType());
1161 ORowSetValue
v(i_aValue
);
1162 v
.setTypeKind( m_nConvertedBoundValuesType
);
1163 ValueList::const_iterator curValuePos
= ::std::find( aValues
.begin(), aValues
.end(), v
);
1164 if ( curValuePos
!= aValues
.end() )
1166 aSelectionIndicies
.realloc( 1 );
1167 aSelectionIndicies
[0] = curValuePos
- aValues
.begin();
1171 return aSelectionIndicies
;
1173 //------------------------------------------------------------------------------
1174 Sequence
< sal_Int16
> OListBoxModel::translateBindingValuesToControlValue(const Sequence
< const Any
> &i_aValues
) const
1176 const ValueList
aValues( impl_getValues() );
1177 assert( m_nConvertedBoundValuesType
== getValueType());
1178 Sequence
< sal_Int16
> aSelectionIndicies(i_aValues
.getLength());
1179 sal_Int32
nCount(0);
1181 sal_Int16
*pIndex
= aSelectionIndicies
.getArray();
1182 const Any
*pValue
= i_aValues
.getConstArray();
1183 const Any
* const pValueEnd
= i_aValues
.getConstArray() + i_aValues
.getLength();
1184 for (;pValue
< pValueEnd
; ++pValue
)
1186 if ( pValue
->hasValue() )
1190 v
.setTypeKind( m_nConvertedBoundValuesType
);
1191 ValueList::const_iterator curValuePos
= ::std::find( aValues
.begin(), aValues
.end(), v
);
1192 if ( curValuePos
!= aValues
.end() )
1194 *pIndex
= curValuePos
- aValues
.begin();
1201 if ( m_nNULLPos
!= -1 )
1203 *pIndex
= m_nNULLPos
;
1209 assert(aSelectionIndicies
.getArray() + nCount
== pIndex
);
1210 aSelectionIndicies
.realloc(nCount
);
1211 return aSelectionIndicies
;
1213 //------------------------------------------------------------------------------
1214 Any
OListBoxModel::translateDbColumnToControlValue()
1216 Reference
< XPropertySet
> xBoundField( getField() );
1217 if ( !xBoundField
.is() )
1219 OSL_FAIL( "OListBoxModel::translateDbColumnToControlValue: no field? How could that happen?!" );
1223 ORowSetValue aCurrentValue
;
1224 aCurrentValue
.fill( getValueType(), m_xColumn
);
1226 m_aSaveValue
= aCurrentValue
;
1228 return makeAny( translateDbValueToControlValue(aCurrentValue
) );
1232 //------------------------------------------------------------------------------
1233 Any
OListBoxModel::getDefaultForReset() const
1236 if (m_aDefaultSelectSeq
.getLength())
1237 aValue
<<= m_aDefaultSelectSeq
;
1238 else if (m_nNULLPos
!= -1) // bound Listbox
1240 Sequence
<sal_Int16
> aSeq(1);
1241 aSeq
.getArray()[0] = m_nNULLPos
;
1246 Sequence
<sal_Int16
> aSeq
;
1253 //--------------------------------------------------------------------
1254 void OListBoxModel::resetNoBroadcast()
1256 OBoundControlModel::resetNoBroadcast();
1257 m_aSaveValue
.setNull();
1260 //--------------------------------------------------------------------
1261 void SAL_CALL
OListBoxModel::disposing( const EventObject
& _rSource
) throw ( RuntimeException
)
1263 if ( !OEntryListHelper::handleDisposing( _rSource
) )
1264 OBoundControlModel::disposing( _rSource
);
1267 //--------------------------------------------------------------------
1270 // The type of how we should transfer our selection to external value bindings
1273 eIndexList
, /// as list of indexes of selected entries
1274 eIndex
, /// as index of the selected entry
1275 eEntryList
, /// as list of string representations of selected *display* entries
1276 eEntry
, /// as string representation of the selected *display* entry
1277 eValueList
, /// as list of string representations of selected values
1278 eValue
/// as string representation of the selected value
1281 //--------------------------------------------------------------------
1282 ExchangeType
lcl_getCurrentExchangeType( const Type
& _rExchangeType
)
1284 switch ( _rExchangeType
.getTypeClass() )
1288 case TypeClass_STRING
:
1290 case TypeClass_LONG
:
1292 case TypeClass_SEQUENCE
:
1294 Type aElementType
= ::comphelper::getSequenceElementType( _rExchangeType
);
1295 switch ( aElementType
.getTypeClass() )
1299 case TypeClass_STRING
:
1301 case TypeClass_LONG
:
1310 OSL_FAIL( "lcl_getCurrentExchangeType: unsupported (unexpected) exchange type!" );
1315 //--------------------------------------------------------------------
1316 Any
OListBoxModel::translateExternalValueToControlValue( const Any
& _rExternalValue
) const
1318 Sequence
< sal_Int16
> aSelectIndexes
;
1320 switch ( lcl_getCurrentExchangeType( getExternalValueType() ) )
1324 Sequence
< const Any
> aExternalValues
;
1325 OSL_VERIFY( _rExternalValue
>>= aExternalValues
);
1326 aSelectIndexes
= translateBindingValuesToControlValue( aExternalValues
);
1333 v
.fill(_rExternalValue
);
1334 aSelectIndexes
= translateDbValueToControlValue(v
);
1340 // unfortunately, our select sequence is a sequence<short>, while the external binding
1341 // supplies sequence<int> only -> transform this
1342 Sequence
< sal_Int32
> aSelectIndexesPure
;
1343 OSL_VERIFY( _rExternalValue
>>= aSelectIndexesPure
);
1344 aSelectIndexes
.realloc( aSelectIndexesPure
.getLength() );
1346 aSelectIndexesPure
.getConstArray(),
1347 aSelectIndexesPure
.getConstArray() + aSelectIndexesPure
.getLength(),
1348 aSelectIndexes
.getArray()
1355 sal_Int32 nSelectIndex
= -1;
1356 OSL_VERIFY( _rExternalValue
>>= nSelectIndex
);
1357 if ( ( nSelectIndex
>= 0 ) && ( nSelectIndex
< getStringItemList().getLength() ) )
1359 aSelectIndexes
.realloc( 1 );
1360 aSelectIndexes
[ 0 ] = static_cast< sal_Int16
>( nSelectIndex
);
1367 // we can retrieve a string list from the binding for multiple selection
1368 Sequence
< OUString
> aSelectEntries
;
1369 OSL_VERIFY( _rExternalValue
>>= aSelectEntries
);
1371 ::std::set
< sal_Int16
> aSelectionSet
;
1373 // find the selection entries in our item list
1374 const OUString
* pSelectEntries
= aSelectEntries
.getArray();
1375 const OUString
* pSelectEntriesEnd
= pSelectEntries
+ aSelectEntries
.getLength();
1376 while ( pSelectEntries
!= pSelectEntriesEnd
)
1378 // the indexes where the current string appears in our string items
1379 Sequence
< sal_Int16
> aThisEntryIndexes
;
1380 aThisEntryIndexes
= findValue( getStringItemList(), *pSelectEntries
++, sal_False
);
1382 // insert all the indexes of this entry into our set
1384 aThisEntryIndexes
.getConstArray(),
1385 aThisEntryIndexes
.getConstArray() + aThisEntryIndexes
.getLength(),
1386 ::std::insert_iterator
< ::std::set
< sal_Int16
> >( aSelectionSet
, aSelectionSet
.begin() )
1390 // copy the indexes to the sequence
1391 aSelectIndexes
.realloc( aSelectionSet
.size() );
1393 aSelectionSet
.begin(),
1394 aSelectionSet
.end(),
1395 aSelectIndexes
.getArray()
1402 OUString sStringToSelect
;
1403 OSL_VERIFY( _rExternalValue
>>= sStringToSelect
);
1405 aSelectIndexes
= findValue( getStringItemList(), sStringToSelect
, sal_False
);
1410 return makeAny( aSelectIndexes
);
1413 //--------------------------------------------------------------------
1416 //................................................................
1417 struct ExtractStringFromSequence_Safe
: public ::std::unary_function
< sal_Int16
, OUString
>
1420 const Sequence
< OUString
>& m_rList
;
1423 ExtractStringFromSequence_Safe( const Sequence
< OUString
>& _rList
) : m_rList( _rList
) { }
1425 OUString
operator ()( sal_Int16 _nIndex
)
1427 OSL_ENSURE( _nIndex
< m_rList
.getLength(), "ExtractStringFromSequence_Safe: inconsistence!" );
1428 if ( _nIndex
< m_rList
.getLength() )
1429 return m_rList
[ _nIndex
];
1434 //................................................................
1435 Any
lcl_getSingleSelectedEntry( const Sequence
< sal_Int16
>& _rSelectSequence
, const Sequence
< OUString
>& _rStringList
)
1439 // by definition, multiple selected entries are transferred as NULL if the
1440 // binding does not support string lists
1441 if ( _rSelectSequence
.getLength() <= 1 )
1443 OUString sSelectedEntry
;
1445 if ( _rSelectSequence
.getLength() == 1 )
1446 sSelectedEntry
= ExtractStringFromSequence_Safe( _rStringList
)( _rSelectSequence
[0] );
1448 aReturn
<<= sSelectedEntry
;
1454 //................................................................
1455 Any
lcl_getMultiSelectedEntries( const Sequence
< sal_Int16
>& _rSelectSequence
, const Sequence
< OUString
>& _rStringList
)
1457 Sequence
< OUString
> aSelectedEntriesTexts( _rSelectSequence
.getLength() );
1459 _rSelectSequence
.getConstArray(),
1460 _rSelectSequence
.getConstArray() + _rSelectSequence
.getLength(),
1461 aSelectedEntriesTexts
.getArray(),
1462 ExtractStringFromSequence_Safe( _rStringList
)
1464 return makeAny( aSelectedEntriesTexts
);
1467 //................................................................
1468 struct ExtractAnyFromValueList_Safe
: public ::std::unary_function
< sal_Int16
, Any
>
1471 const ValueList
& m_rList
;
1474 ExtractAnyFromValueList_Safe( const ValueList
& _rList
) : m_rList( _rList
) { }
1476 Any
operator ()( sal_Int16 _nIndex
)
1478 OSL_ENSURE( static_cast<ValueList::size_type
>(_nIndex
) < m_rList
.size(), "ExtractAnyFromValueList: inconsistence!" );
1479 if ( static_cast<ValueList::size_type
>(_nIndex
) < m_rList
.size() )
1480 return m_rList
[ _nIndex
].makeAny();
1485 //................................................................
1486 Any
lcl_getSingleSelectedEntryAny( const Sequence
< sal_Int16
>& _rSelectSequence
, const ValueList
& _rStringList
)
1490 // by definition, multiple selected entries are transfered as NULL if the
1491 // binding does not support string lists
1492 if ( _rSelectSequence
.getLength() <= 1 )
1494 if ( _rSelectSequence
.getLength() == 1 )
1495 aReturn
= ExtractAnyFromValueList_Safe( _rStringList
)( _rSelectSequence
[0] );
1501 //................................................................
1502 Any
lcl_getMultiSelectedEntriesAny( const Sequence
< sal_Int16
>& _rSelectSequence
, const ValueList
& _rStringList
)
1504 Sequence
< Any
> aSelectedEntriesValues( _rSelectSequence
.getLength() );
1506 _rSelectSequence
.getConstArray(),
1507 _rSelectSequence
.getConstArray() + _rSelectSequence
.getLength(),
1508 aSelectedEntriesValues
.getArray(),
1509 ExtractAnyFromValueList_Safe( _rStringList
)
1511 return makeAny( aSelectedEntriesValues
);
1515 //--------------------------------------------------------------------
1516 Any
OListBoxModel::translateControlValueToExternalValue( ) const
1518 OSL_PRECOND( hasExternalValueBinding(), "OListBoxModel::translateControlValueToExternalValue: no binding!" );
1520 Sequence
< sal_Int16
> aSelectSequence
;
1521 OSL_VERIFY( getControlValue() >>= aSelectSequence
);
1524 switch ( lcl_getCurrentExchangeType( getExternalValueType() ) )
1527 aReturn
= getCurrentMultiValue();
1531 aReturn
= getCurrentSingleValue();
1536 // unfortunately, the select sequence is a sequence<short>, but our binding
1538 Sequence
< sal_Int32
> aTransformed( aSelectSequence
.getLength() );
1540 aSelectSequence
.getConstArray(),
1541 aSelectSequence
.getConstArray() + aSelectSequence
.getLength(),
1542 aTransformed
.getArray()
1544 aReturn
<<= aTransformed
;
1549 if ( aSelectSequence
.getLength() <= 1 )
1551 sal_Int32 nIndex
= -1;
1553 if ( aSelectSequence
.getLength() == 1 )
1554 nIndex
= aSelectSequence
[0];
1561 aReturn
= lcl_getMultiSelectedEntries( aSelectSequence
, getStringItemList() );
1565 aReturn
= lcl_getSingleSelectedEntry( aSelectSequence
, getStringItemList() );
1572 //------------------------------------------------------------------------------
1573 Any
OListBoxModel::translateControlValueToValidatableValue( ) const
1575 OSL_PRECOND( hasValidator(), "OListBoxModel::translateControlValueToValidatableValue: no validator, so why should I?" );
1576 return getCurrentFormComponentValue();
1579 //--------------------------------------------------------------------
1580 Any
OListBoxModel::getCurrentSingleValue() const
1586 Sequence
< sal_Int16
> aSelectSequence
;
1587 OSL_VERIFY( getControlValue() >>= aSelectSequence
);
1588 aCurrentValue
= lcl_getSingleSelectedEntryAny( aSelectSequence
, impl_getValues() );
1590 catch( const Exception
& )
1592 DBG_UNHANDLED_EXCEPTION();
1595 return aCurrentValue
;
1597 //--------------------------------------------------------------------
1598 Any
OListBoxModel::getCurrentMultiValue() const
1604 Sequence
< sal_Int16
> aSelectSequence
;
1605 OSL_VERIFY( getControlValue() >>= aSelectSequence
);
1606 aCurrentValue
= lcl_getMultiSelectedEntriesAny( aSelectSequence
, impl_getValues() );
1608 catch( const Exception
& )
1610 DBG_UNHANDLED_EXCEPTION();
1613 return aCurrentValue
;
1615 //--------------------------------------------------------------------
1616 Any
OListBoxModel::getCurrentFormComponentValue() const
1619 Reference
< com::sun::star::form::validation::XValidator
> vtor (const_cast<OListBoxModel
*>(this)->getValidator());
1620 Reference
< XValueBinding
> extBinding (const_cast<OListBoxModel
*>(this)->getValueBinding());
1621 if ( vtor
.is() && vtor
== extBinding
)
1622 return translateControlValueToExternalValue();
1629 sal_Bool
bMultiSelection( sal_False
);
1630 OSL_VERIFY( const_cast< OListBoxModel
* >( this )->getPropertyValue( PROPERTY_MULTISELECTION
) >>= bMultiSelection
);
1632 if ( bMultiSelection
)
1633 aCurrentValue
= getCurrentMultiValue();
1635 aCurrentValue
= getCurrentSingleValue();
1637 catch( const Exception
& )
1639 DBG_UNHANDLED_EXCEPTION();
1642 return aCurrentValue
;
1645 //--------------------------------------------------------------------
1646 Sequence
< Type
> OListBoxModel::getSupportedBindingTypes()
1648 Sequence
< Type
> aTypes(6);
1649 aTypes
[0] = ::getCppuType( static_cast< Sequence
< Any
>* >( NULL
) );
1650 aTypes
[1] = ::getCppuType( static_cast< Any
* >( NULL
) );
1651 aTypes
[2] = ::getCppuType( static_cast< Sequence
< sal_Int32
>* >( NULL
) );
1652 aTypes
[3] = ::getCppuType( static_cast< sal_Int32
* >( NULL
) );
1653 aTypes
[4] = ::getCppuType( static_cast< Sequence
< OUString
>* >( NULL
) );
1654 aTypes
[5] = ::getCppuType( static_cast< OUString
* >( NULL
) );
1658 //--------------------------------------------------------------------
1659 void OListBoxModel::stringItemListChanged( ControlModelLock
& _rInstanceLock
)
1661 if ( !m_xAggregateSet
.is() )
1664 suspendValueListening();
1667 m_xAggregateSet
->setPropertyValue( PROPERTY_STRINGITEMLIST
, makeAny( getStringItemList() ) );
1669 catch( const Exception
& )
1671 DBG_UNHANDLED_EXCEPTION();
1673 resumeValueListening();
1675 // update the selection here
1676 if ( hasExternalValueBinding( ) )
1677 transferExternalValueToControl( _rInstanceLock
);
1682 // TODO: update the selection in case we're bound to a database column
1686 if ( m_aDefaultSelectSeq
.getLength() )
1687 setControlValue( makeAny( m_aDefaultSelectSeq
), eOther
);
1692 //--------------------------------------------------------------------
1693 void OListBoxModel::connectedExternalListSource( )
1698 //--------------------------------------------------------------------
1699 void OListBoxModel::disconnectedExternalListSource( )
1701 // TODO: in case we're part of an already loaded form, we should probably simulate
1702 // an onConnectedDbColumn, so our list get's filled with the data as indicated
1703 // by our SQL-binding related properties
1706 //--------------------------------------------------------------------
1707 void OListBoxModel::impl_refreshDbEntryList( bool _bForce
)
1709 DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::impl_refreshDbEntryList: invalid call!" );
1711 if ( !hasExternalListSource( )
1712 && ( m_eListSourceType
!= ListSourceType_VALUELIST
)
1713 && ( m_xCursor
.is() )
1716 loadData( _bForce
);
1720 //--------------------------------------------------------------------
1721 void OListBoxModel::refreshInternalEntryList()
1723 impl_refreshDbEntryList( true );
1724 if ( hasField() && m_xCursor
.is() )
1725 initFromField( m_xCursor
);
1728 //==================================================================
1730 //==================================================================
1732 //------------------------------------------------------------------
1733 InterfaceRef SAL_CALL
OListBoxControl_CreateInstance(const Reference
<XMultiServiceFactory
>& _rxFactory
) throw (RuntimeException
)
1735 return *(new OListBoxControl(_rxFactory
));
1738 //------------------------------------------------------------------------------
1739 Sequence
< Type
> OListBoxControl::_getTypes()
1742 OBoundControl::_getTypes(),
1743 OListBoxControl_BASE::getTypes()
1747 //------------------------------------------------------------------
1748 Any SAL_CALL
OListBoxControl::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
1750 Any aReturn
= OListBoxControl_BASE::queryInterface( _rType
);
1752 if ( !aReturn
.hasValue()
1753 || _rType
.equals( XTypeProvider::static_type() )
1755 aReturn
= OBoundControl::queryAggregation( _rType
);
1760 DBG_NAME(OListBoxControl
);
1761 //------------------------------------------------------------------------------
1762 OListBoxControl::OListBoxControl(const Reference
<XMultiServiceFactory
>& _rxFactory
)
1763 :OBoundControl( _rxFactory
, VCL_CONTROL_LISTBOX
, sal_False
)
1764 ,m_aChangeListeners( m_aMutex
)
1765 ,m_aItemListeners( m_aMutex
)
1767 DBG_CTOR(OListBoxControl
,NULL
);
1769 increment(m_refCount
);
1771 // Register as FocusListener
1772 Reference
<XWindow
> xComp
;
1773 if (query_aggregation(m_xAggregate
, xComp
))
1774 xComp
->addFocusListener(this);
1776 // Register as ItemListener
1777 if ( query_aggregation( m_xAggregate
, m_xAggregateListBox
) )
1778 m_xAggregateListBox
->addItemListener(this);
1780 // Refcount at 2 for registered Listener
1781 decrement(m_refCount
);
1785 m_aChangeTimer
.SetTimeout(500);
1786 m_aChangeTimer
.SetTimeoutHdl(LINK(this,OListBoxControl
,OnTimeout
));
1789 //------------------------------------------------------------------------------
1790 OListBoxControl::~OListBoxControl()
1792 if (!OComponentHelper::rBHelper
.bDisposed
)
1799 m_xAggregateListBox
.clear();
1801 DBG_DTOR(OListBoxControl
,NULL
);
1804 //------------------------------------------------------------------------------
1805 StringSequence SAL_CALL
OListBoxControl::getSupportedServiceNames() throw(RuntimeException
)
1807 StringSequence aSupported
= OBoundControl::getSupportedServiceNames();
1808 aSupported
.realloc(aSupported
.getLength() + 1);
1810 OUString
* pArray
= aSupported
.getArray();
1811 pArray
[aSupported
.getLength()-1] = FRM_SUN_CONTROL_LISTBOX
;
1817 //------------------------------------------------------------------------------
1818 void SAL_CALL
OListBoxControl::focusGained(const FocusEvent
& /*_rEvent*/) throw(RuntimeException
)
1820 ::osl::MutexGuard
aGuard(m_aMutex
);
1821 if ( m_aChangeListeners
.getLength() ) // only if there are listeners
1823 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
1826 // memorize the current selection for posting the change event
1827 m_aCurrentSelection
= xSet
->getPropertyValue(PROPERTY_SELECT_SEQ
);
1832 //------------------------------------------------------------------------------
1833 void SAL_CALL
OListBoxControl::focusLost(const FocusEvent
& /*_rEvent*/) throw(RuntimeException
)
1835 m_aCurrentSelection
.clear();
1839 //------------------------------------------------------------------------------
1840 void SAL_CALL
OListBoxControl::itemStateChanged(const ItemEvent
& _rEvent
) throw(RuntimeException
)
1842 // forward this to our listeners
1843 Reference
< XChild
> xChild( getModel(), UNO_QUERY
);
1844 if ( xChild
.is() && xChild
->getParent().is() )
1846 ::osl::MutexGuard
aGuard( m_aMutex
);
1847 if ( m_aItemListeners
.getLength() )
1849 if ( !m_pItemBroadcaster
.is() )
1851 m_pItemBroadcaster
.set(
1852 new ::comphelper::AsyncEventNotifier("ListBox"));
1853 m_pItemBroadcaster
->launch();
1855 m_pItemBroadcaster
->addEvent( new ItemEventDescription( _rEvent
), this );
1859 m_aItemListeners
.notifyEach( &XItemListener::itemStateChanged
, _rEvent
);
1861 // and do the handling for the ChangeListeners
1862 ::osl::ClearableMutexGuard
aGuard(m_aMutex
);
1863 if ( m_aChangeTimer
.IsActive() )
1865 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
1866 m_aCurrentSelection
= xSet
->getPropertyValue(PROPERTY_SELECT_SEQ
);
1868 m_aChangeTimer
.Stop();
1869 m_aChangeTimer
.Start();
1873 if ( m_aChangeListeners
.getLength() && m_aCurrentSelection
.hasValue() )
1875 Reference
<XPropertySet
> xSet(getModel(), UNO_QUERY
);
1878 // Has the selection been changed?
1879 sal_Bool
bModified(sal_False
);
1880 Any aValue
= xSet
->getPropertyValue(PROPERTY_SELECT_SEQ
);
1882 Sequence
<sal_Int16
>& rSelection
= *(Sequence
<sal_Int16
> *)aValue
.getValue();
1883 Sequence
<sal_Int16
>& rOldSelection
= *(Sequence
<sal_Int16
> *)m_aCurrentSelection
.getValue();
1884 sal_Int32 nLen
= rSelection
.getLength();
1885 if (nLen
!= rOldSelection
.getLength())
1886 bModified
= sal_True
;
1889 const sal_Int16
* pVal
= rSelection
.getConstArray();
1890 const sal_Int16
* pCompVal
= rOldSelection
.getConstArray();
1892 while (nLen
-- && !bModified
)
1893 bModified
= pVal
[nLen
] != pCompVal
[nLen
];
1898 m_aCurrentSelection
= aValue
;
1899 m_aChangeTimer
.Start();
1903 else if (m_aCurrentSelection
.hasValue())
1904 m_aCurrentSelection
.clear();
1909 //------------------------------------------------------------------------------
1910 void SAL_CALL
OListBoxControl::disposing(const EventObject
& _rSource
) throw (RuntimeException
)
1912 OBoundControl::disposing(_rSource
);
1915 // XChangeBroadcaster
1916 //------------------------------------------------------------------------------
1917 void SAL_CALL
OListBoxControl::addChangeListener(const Reference
<XChangeListener
>& _rxListener
) throw(RuntimeException
)
1919 m_aChangeListeners
.addInterface( _rxListener
);
1922 //------------------------------------------------------------------------------
1923 void SAL_CALL
OListBoxControl::removeChangeListener(const Reference
<XChangeListener
>& _rxListener
) throw(RuntimeException
)
1925 m_aChangeListeners
.removeInterface( _rxListener
);
1929 //------------------------------------------------------------------------------
1930 void OListBoxControl::disposing()
1932 if (m_aChangeTimer
.IsActive())
1933 m_aChangeTimer
.Stop();
1935 EventObject
aEvent( *this );
1936 m_aChangeListeners
.disposeAndClear( aEvent
);
1937 m_aItemListeners
.disposeAndClear( aEvent
);
1939 rtl::Reference
< comphelper::AsyncEventNotifier
> t
;
1941 ::osl::MutexGuard
aGuard( m_aMutex
);
1942 if ( m_pItemBroadcaster
.is() )
1944 t
= m_pItemBroadcaster
;
1945 m_pItemBroadcaster
->removeEventsForProcessor( this );
1946 m_pItemBroadcaster
->terminate();
1947 m_pItemBroadcaster
= NULL
;
1954 OBoundControl::disposing();
1957 //------------------------------------------------------------------------------
1958 void OListBoxControl::processEvent( const AnyEvent
& _rEvent
)
1960 Reference
< XListBox
> xKeepAlive( this );
1962 ::osl::MutexGuard
aGuard( m_aMutex
);
1963 if ( OComponentHelper::rBHelper
.bDisposed
)
1966 const ItemEventDescription
& rItemEvent
= static_cast< const ItemEventDescription
& >( _rEvent
);
1967 m_aItemListeners
.notifyEach( &XItemListener::itemStateChanged
, rItemEvent
.getEventObject() );
1970 //------------------------------------------------------------------------------
1971 IMPL_LINK(OListBoxControl
, OnTimeout
, void*, /*EMPTYTAG*/)
1973 m_aChangeListeners
.notifyEach( &XChangeListener::changed
, EventObject( *this ) );
1977 //--------------------------------------------------------------------
1978 void SAL_CALL
OListBoxControl::addItemListener( const Reference
< XItemListener
>& l
) throw (RuntimeException
)
1980 m_aItemListeners
.addInterface( l
);
1983 //--------------------------------------------------------------------
1984 void SAL_CALL
OListBoxControl::removeItemListener( const Reference
< XItemListener
>& l
) throw (RuntimeException
)
1986 m_aItemListeners
.removeInterface( l
);
1989 //--------------------------------------------------------------------
1990 void SAL_CALL
OListBoxControl::addActionListener( const Reference
< XActionListener
>& l
) throw (RuntimeException
)
1992 if ( m_xAggregateListBox
.is() )
1993 m_xAggregateListBox
->addActionListener( l
);
1996 //--------------------------------------------------------------------
1997 void SAL_CALL
OListBoxControl::removeActionListener( const Reference
< XActionListener
>& l
) throw (RuntimeException
)
1999 if ( m_xAggregateListBox
.is() )
2000 m_xAggregateListBox
->removeActionListener( l
);
2003 //--------------------------------------------------------------------
2004 void SAL_CALL
OListBoxControl::addItem( const OUString
& aItem
, ::sal_Int16 nPos
) throw (RuntimeException
)
2006 if ( m_xAggregateListBox
.is() )
2007 m_xAggregateListBox
->addItem( aItem
, nPos
);
2010 //--------------------------------------------------------------------
2011 void SAL_CALL
OListBoxControl::addItems( const Sequence
< OUString
>& aItems
, ::sal_Int16 nPos
) throw (RuntimeException
)
2013 if ( m_xAggregateListBox
.is() )
2014 m_xAggregateListBox
->addItems( aItems
, nPos
);
2017 //--------------------------------------------------------------------
2018 void SAL_CALL
OListBoxControl::removeItems( ::sal_Int16 nPos
, ::sal_Int16 nCount
) throw (RuntimeException
)
2020 if ( m_xAggregateListBox
.is() )
2021 m_xAggregateListBox
->removeItems( nPos
, nCount
);
2024 //--------------------------------------------------------------------
2025 ::sal_Int16 SAL_CALL
OListBoxControl::getItemCount( ) throw (RuntimeException
)
2027 if ( m_xAggregateListBox
.is() )
2028 return m_xAggregateListBox
->getItemCount();
2032 //--------------------------------------------------------------------
2033 OUString SAL_CALL
OListBoxControl::getItem( ::sal_Int16 nPos
) throw (RuntimeException
)
2035 if ( m_xAggregateListBox
.is() )
2036 return m_xAggregateListBox
->getItem( nPos
);
2040 //--------------------------------------------------------------------
2041 Sequence
< OUString
> SAL_CALL
OListBoxControl::getItems( ) throw (RuntimeException
)
2043 if ( m_xAggregateListBox
.is() )
2044 return m_xAggregateListBox
->getItems();
2045 return Sequence
< OUString
>( );
2048 //--------------------------------------------------------------------
2049 ::sal_Int16 SAL_CALL
OListBoxControl::getSelectedItemPos( ) throw (RuntimeException
)
2051 if ( m_xAggregateListBox
.is() )
2052 return m_xAggregateListBox
->getSelectedItemPos();
2056 //--------------------------------------------------------------------
2057 Sequence
< ::sal_Int16
> SAL_CALL
OListBoxControl::getSelectedItemsPos( ) throw (RuntimeException
)
2059 if ( m_xAggregateListBox
.is() )
2060 return m_xAggregateListBox
->getSelectedItemsPos();
2061 return Sequence
< ::sal_Int16
>( );
2064 //--------------------------------------------------------------------
2065 OUString SAL_CALL
OListBoxControl::getSelectedItem( ) throw (RuntimeException
)
2067 if ( m_xAggregateListBox
.is() )
2068 return m_xAggregateListBox
->getSelectedItem();
2072 //--------------------------------------------------------------------
2073 Sequence
< OUString
> SAL_CALL
OListBoxControl::getSelectedItems( ) throw (RuntimeException
)
2075 if ( m_xAggregateListBox
.is() )
2076 return m_xAggregateListBox
->getSelectedItems();
2077 return Sequence
< OUString
>( );
2080 //--------------------------------------------------------------------
2081 void SAL_CALL
OListBoxControl::selectItemPos( ::sal_Int16 nPos
, ::sal_Bool bSelect
) throw (RuntimeException
)
2083 if ( m_xAggregateListBox
.is() )
2084 m_xAggregateListBox
->selectItemPos( nPos
, bSelect
);
2087 //--------------------------------------------------------------------
2088 void SAL_CALL
OListBoxControl::selectItemsPos( const Sequence
< ::sal_Int16
>& aPositions
, ::sal_Bool bSelect
) throw (RuntimeException
)
2090 if ( m_xAggregateListBox
.is() )
2091 m_xAggregateListBox
->selectItemsPos( aPositions
, bSelect
);
2094 //--------------------------------------------------------------------
2095 void SAL_CALL
OListBoxControl::selectItem( const OUString
& aItem
, ::sal_Bool bSelect
) throw (RuntimeException
)
2097 if ( m_xAggregateListBox
.is() )
2098 m_xAggregateListBox
->selectItem( aItem
, bSelect
);
2101 //--------------------------------------------------------------------
2102 ::sal_Bool SAL_CALL
OListBoxControl::isMutipleMode( ) throw (RuntimeException
)
2104 if ( m_xAggregateListBox
.is() )
2105 return m_xAggregateListBox
->isMutipleMode();
2109 //--------------------------------------------------------------------
2110 void SAL_CALL
OListBoxControl::setMultipleMode( ::sal_Bool bMulti
) throw (RuntimeException
)
2112 if ( m_xAggregateListBox
.is() )
2113 m_xAggregateListBox
->setMultipleMode( bMulti
);
2116 //--------------------------------------------------------------------
2117 ::sal_Int16 SAL_CALL
OListBoxControl::getDropDownLineCount( ) throw (RuntimeException
)
2119 if ( m_xAggregateListBox
.is() )
2120 return m_xAggregateListBox
->getDropDownLineCount();
2124 //--------------------------------------------------------------------
2125 void SAL_CALL
OListBoxControl::setDropDownLineCount( ::sal_Int16 nLines
) throw (RuntimeException
)
2127 if ( m_xAggregateListBox
.is() )
2128 m_xAggregateListBox
->setDropDownLineCount( nLines
);
2131 //--------------------------------------------------------------------
2132 void SAL_CALL
OListBoxControl::makeVisible( ::sal_Int16 nEntry
) throw (RuntimeException
)
2134 if ( m_xAggregateListBox
.is() )
2135 m_xAggregateListBox
->makeVisible( nEntry
);
2138 //.........................................................................
2140 //.........................................................................
2142 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */