LibreOffice Module forms (master) 1
ListBox.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <config_features.h>
21#include <config_fuzzers.h>
22
23#include "ListBox.hxx"
24#include <property.hxx>
25#include <services.hxx>
26#include <frm_resource.hxx>
27#include <strings.hrc>
28#include "BaseListBox.hxx"
29#include <componenttools.hxx>
30
31#include <com/sun/star/beans/PropertyAttribute.hpp>
32#include <com/sun/star/form/FormComponentType.hpp>
33#include <com/sun/star/container/XIndexAccess.hpp>
34#include <com/sun/star/sdbc/XRow.hpp>
35#include <com/sun/star/awt/XWindow.hpp>
36#include <com/sun/star/sdbc/XConnection.hpp>
37
41#include <comphelper/string.hxx>
42#include <comphelper/types.hxx>
45#include <o3tl/any.hxx>
46#include <o3tl/safeint.hxx>
47#include <tools/debug.hxx>
49#include <sal/log.hxx>
51
52#include <optional>
53
54#include <algorithm>
55#include <iterator>
56#include <climits>
57
58namespace frm
59{
60 using namespace ::com::sun::star::uno;
61 using namespace ::com::sun::star::sdb;
62 using namespace ::com::sun::star::sdbc;
63 using namespace ::com::sun::star::sdbcx;
64 using namespace ::com::sun::star::beans;
65 using namespace ::com::sun::star::container;
66 using namespace ::com::sun::star::form;
67 using namespace ::com::sun::star::awt;
68 using namespace ::com::sun::star::io;
69 using namespace ::com::sun::star::lang;
70 using namespace ::com::sun::star::util;
71 using namespace ::com::sun::star::form::binding;
72 using namespace ::dbtools;
73
74 using ::connectivity::ORowSetValue;
75
76 const ::connectivity::ORowSetValue OListBoxModel::s_aEmptyValue;
77 const ::connectivity::ORowSetValue OListBoxModel::s_aEmptyStringValue = OUString();
78
79 //= helper
80
81 namespace
82 {
83
84 struct RowSetValueToString
85 {
86 OUString operator()( const ORowSetValue& _value ) const
87 {
88 return _value.getString();
89 }
90 };
91
92
93 struct AppendRowSetValueString
94 {
95 explicit AppendRowSetValueString( OUString& _string )
96 :m_string( _string )
97 {
98 }
99
100 void operator()( const ORowSetValue& _append )
101 {
102 m_string += _append.getString();
103 }
104
105 private:
106 OUString& m_string;
107 };
108
109
110 Sequence< OUString > lcl_convertToStringSequence( const ValueList& _values )
111 {
112 Sequence< OUString > aStrings( _values.size() );
113 ::std::transform(
114 _values.begin(),
115 _values.end(),
116 aStrings.getArray(),
117 RowSetValueToString()
118 );
119 return aStrings;
120 }
121 }
122
123
124 //= ItemEventDescription
125
126 typedef ::comphelper::EventHolder< ItemEvent > ItemEventDescription;
127
128
129 //= OListBoxModel
130
131 Sequence< Type> OListBoxModel::_getTypes()
132 {
133 return TypeBag(
137 ).getTypes();
138 }
139
140 // stuff common to all constructors
142 {
145 }
146
147
148 OListBoxModel::OListBoxModel(const Reference<XComponentContext>& _rxFactory)
150 // use the old control name for compatibility reasons
151 ,OEntryListHelper( static_cast<OControlModel&>(*this) )
152 ,OErrorBroadcaster( OComponentHelper::rBHelper )
153 ,m_nConvertedBoundValuesType(0)
154 ,m_nNULLPos(-1)
155 ,m_nBoundColumnType( DataType::SQLNULL )
156 {
157
158 m_nClassId = FormComponentType::LISTBOX;
159 m_eListSourceType = ListSourceType_VALUELIST;
160 m_aBoundColumn <<= sal_Int16(1);
162
163 init();
164 }
165
166
167 OListBoxModel::OListBoxModel( const OListBoxModel* _pOriginal, const Reference<XComponentContext>& _rxFactory )
168 :OBoundControlModel( _pOriginal, _rxFactory )
169 ,OEntryListHelper( *_pOriginal, static_cast<OControlModel&>(*this) )
170 ,OErrorBroadcaster( OComponentHelper::rBHelper )
171 ,m_eListSourceType( _pOriginal->m_eListSourceType )
172 ,m_aBoundColumn( _pOriginal->m_aBoundColumn )
173 ,m_aListSourceValues( _pOriginal->m_aListSourceValues )
174 ,m_aBoundValues( _pOriginal->m_aBoundValues )
175 ,m_nConvertedBoundValuesType(0)
176 ,m_aDefaultSelectSeq( _pOriginal->m_aDefaultSelectSeq )
177 ,m_nNULLPos(-1)
178 ,m_nBoundColumnType( DataType::SQLNULL )
179 {
180
181 init();
182 }
183
184
186 {
187 if (!OComponentHelper::rBHelper.bDisposed)
188 {
189 acquire();
190 dispose();
191 }
192
193 }
194
195 // XCloneable
196
197 css::uno::Reference< css::util::XCloneable > SAL_CALL OListBoxModel::createClone()
198{
200 pClone->clonedFrom(this);
201 return pClone;
202}
203
204 // XServiceInfo
205
206 css::uno::Sequence<OUString> SAL_CALL OListBoxModel::getSupportedServiceNames()
207 {
208 css::uno::Sequence<OUString> aSupported = OBoundControlModel::getSupportedServiceNames();
209
210 sal_Int32 nOldLen = aSupported.getLength();
211 aSupported.realloc( nOldLen + 9 );
212 OUString* pStoreTo = aSupported.getArray() + nOldLen;
213
214 *pStoreTo++ = BINDABLE_CONTROL_MODEL;
215 *pStoreTo++ = DATA_AWARE_CONTROL_MODEL;
216 *pStoreTo++ = VALIDATABLE_CONTROL_MODEL;
217
220
221 *pStoreTo++ = FRM_SUN_COMPONENT_LISTBOX;
223 *pStoreTo++ = BINDABLE_DATABASE_LIST_BOX;
224
225 *pStoreTo++ = FRM_COMPONENT_LISTBOX;
226
227 return aSupported;
228 }
229
230
232 {
233 Any aReturn = OBoundControlModel::queryAggregation( _rType );
234 if ( !aReturn.hasValue() )
235 aReturn = OEntryListHelper::queryInterface( _rType );
236 if ( !aReturn.hasValue() )
237 aReturn = OErrorBroadcaster::queryInterface( _rType );
238 return aReturn;
239 }
240
241 // OComponentHelper
242
244 {
248 }
249
250
251 void OListBoxModel::getFastPropertyValue(Any& _rValue, sal_Int32 _nHandle) const
252 {
253 switch (_nHandle)
254 {
256 _rValue = m_aBoundColumn;
257 break;
258
260 _rValue <<= m_eListSourceType;
261 break;
262
264 _rValue <<= lcl_convertToStringSequence( m_aListSourceValues );
265 break;
266
268 _rValue <<= lcl_convertToStringSequence( m_aBoundValues );
269 break;
270
272 _rValue <<= getCurrentMultiValue();
273 break;
274
276 _rValue = getCurrentSingleValue();
277 break;
278
280 _rValue <<= m_aDefaultSelectSeq;
281 break;
282
285 break;
286
288 _rValue <<= getTypedItemList();
289 break;
290
291 default:
293 }
294 }
295
296
297 void OListBoxModel::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue)
298 {
299 switch (_nHandle)
300 {
302 DBG_ASSERT((_rValue.getValueType().getTypeClass() == TypeClass_SHORT) || (_rValue.getValueType().getTypeClass() == TypeClass_VOID),
303 "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
304 m_aBoundColumn = _rValue;
305 break;
306
308 DBG_ASSERT(_rValue.getValueType().equals(::cppu::UnoType<ListSourceType>::get()),
309 "OComboBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
310 _rValue >>= m_eListSourceType;
311 break;
312
314 {
315 // extract
316 Sequence< OUString > aListSource;
317 OSL_VERIFY( _rValue >>= aListSource );
318
319 // copy to member
322 std::cbegin(aListSource),
323 std::cend(aListSource),
324 ::std::insert_iterator< ValueList >( m_aListSourceValues, m_aListSourceValues.end() )
325 );
326
327 // propagate
328 if ( m_eListSourceType == ListSourceType_VALUELIST )
329 {
331 }
332 else
333 {
334 if ( m_xCursor.is() && !hasField() && !hasExternalListSource() )
335 // listbox is already connected to a database, and no external list source
336 // data source changed -> refresh
337 loadData( false );
338 }
339 }
340 break;
341
343 SAL_WARN( "forms.component", "ValueItemList is read-only!" );
344 throw PropertyVetoException();
345
347 {
348 Sequence< const Any > v;
349 _rValue >>= v;
351 setControlValue( newSelectSeq, eOther );
352 }
353 break;
354
355#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
357 {
358 ORowSetValue v;
359 v.fill(_rValue);
360 Any newSelectSeq(translateDbValueToControlValue(v));
361 setControlValue( newSelectSeq, eOther );
362 }
363 break;
364#endif
366 DBG_ASSERT(_rValue.getValueType().equals(cppu::UnoType<Sequence<sal_Int16>>::get()),
367 "OListBoxModel::setFastPropertyValue_NoBroadcast : invalid type !" );
368 _rValue >>= m_aDefaultSelectSeq;
369
370 DBG_ASSERT(m_xAggregateFastSet.is(), "OListBoxModel::setFastPropertyValue_NoBroadcast(DEFAULT_SELECT_SEQ) : invalid aggregate !");
371 if ( m_xAggregateFastSet.is() )
372 setControlValue( _rValue, eOther );
373 break;
374
376 {
377 ControlModelLock aLock( *this );
378 setNewStringItemList( _rValue, aLock );
379 // TODO: this is bogus. setNewStringItemList expects a guard which has the *only*
380 // lock to the mutex, but setFastPropertyValue_NoBroadcast is already called with
381 // a lock - so we effectively has two locks here, of which setNewStringItemList can
382 // only control one.
383 }
385 break;
386
388 {
389 ControlModelLock aLock( *this );
390 setNewTypedItemList( _rValue, aLock );
391 // Same TODO as above.
392 }
394 break;
395
396 default:
398 }
399 }
400
401
403 Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue)
404 {
405 bool bModified(false);
406 switch (_nHandle)
407 {
409 bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aBoundColumn, ::cppu::UnoType<sal_Int16>::get());
410 break;
411
413 bModified = tryPropertyValueEnum(_rConvertedValue, _rOldValue, _rValue, m_eListSourceType);
414 break;
415
417 bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, lcl_convertToStringSequence( m_aListSourceValues ) );
418 break;
419
421 SAL_WARN( "forms.component", "ValueItemList is read-only!" );
422 throw IllegalArgumentException();
423
425 bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, getCurrentMultiValue());
426 break;
427
429 {
430 // Any from connectivity::ORowSetValue
431 Any _rCurrentValue = getCurrentSingleValue();
432 if (_rCurrentValue != _rValue)
433 {
434 _rOldValue = _rCurrentValue;
435 _rConvertedValue = _rValue;
436 bModified = true;
437 }
438 break;
439 }
441 bModified = tryPropertyValue(_rConvertedValue, _rOldValue, _rValue, m_aDefaultSelectSeq);
442 break;
443
445 bModified = convertNewListSourceProperty( _rConvertedValue, _rOldValue, _rValue );
446 break;
447
450 throw IllegalArgumentException();
451 bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, getTypedItemList());
452 break;
453
454 default:
455 return OBoundControlModel::convertFastPropertyValue(_rConvertedValue, _rOldValue, _nHandle, _rValue);
456 }
457 return bModified;
458 }
459
460
461 void SAL_CALL OListBoxModel::setPropertyValues( const Sequence< OUString >& _rPropertyNames, const Sequence< Any >& _rValues )
462 {
463 // if both SelectedItems and StringItemList are set, care for this
464 // #i27024#
465 const Any* pSelectSequenceValue = nullptr;
466
467 const OUString* pSelectedItemsPos = std::find(
468 _rPropertyNames.begin(), _rPropertyNames.end(), PROPERTY_SELECT_SEQ
469 );
470 auto aStringItemListExists = std::any_of(
471 _rPropertyNames.begin(), _rPropertyNames.end(),
472 [](OUString const & s) { return s == PROPERTY_STRINGITEMLIST; }
473 );
474 if ( ( pSelectedItemsPos != _rPropertyNames.end() ) && aStringItemListExists )
475 {
476 if (_rPropertyNames.getLength() != _rValues.getLength())
477 throw css::lang::IllegalArgumentException("lengths do not match",
478 static_cast<cppu::OWeakObject*>(this), -1);
479
480 // both properties are present
481 // -> remember the value for the select sequence
482 pSelectSequenceValue = _rValues.getConstArray() + ( pSelectedItemsPos - _rPropertyNames.begin() );
483 }
484
485 OBoundControlModel::setPropertyValues( _rPropertyNames, _rValues );
486
487 if ( pSelectSequenceValue )
488 {
489 setPropertyValue( PROPERTY_SELECT_SEQ, *pSelectSequenceValue );
490 // Note that this is the only reliable way, since one of the properties is implemented
491 // by ourself, and one is implemented by the aggregate, we cannot rely on any particular
492 // results when setting them both - too many undocumented behavior in all the involved
493
494 }
495 }
496
497
498 void OListBoxModel::describeFixedProperties( Sequence< Property >& _rProps ) const
499 {
501 sal_Int32 nOldCount = _rProps.getLength();
502 _rProps.realloc( nOldCount + 10);
503 css::beans::Property* pProperties = _rProps.getArray() + nOldCount;
504 *pProperties++ = css::beans::Property(PROPERTY_TABINDEX, PROPERTY_ID_TABINDEX, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND);
505 *pProperties++ = css::beans::Property(PROPERTY_BOUNDCOLUMN, PROPERTY_ID_BOUNDCOLUMN, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEVOID);
506 *pProperties++ = css::beans::Property(PROPERTY_LISTSOURCETYPE, PROPERTY_ID_LISTSOURCETYPE, cppu::UnoType<ListSourceType>::get(), css::beans::PropertyAttribute::BOUND);
507 *pProperties++ = css::beans::Property(PROPERTY_LISTSOURCE, PROPERTY_ID_LISTSOURCE, cppu::UnoType<css::uno::Sequence<OUString>>::get(), css::beans::PropertyAttribute::BOUND);
508 *pProperties++ = css::beans::Property(PROPERTY_VALUE_SEQ, PROPERTY_ID_VALUE_SEQ, cppu::UnoType<css::uno::Sequence<OUString>>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::READONLY | css::beans::PropertyAttribute::TRANSIENT);
509 *pProperties++ = css::beans::Property(PROPERTY_SELECT_VALUE_SEQ, PROPERTY_ID_SELECT_VALUE_SEQ, cppu::UnoType<Sequence< Any >>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::TRANSIENT);
510 *pProperties++ = css::beans::Property(PROPERTY_SELECT_VALUE, PROPERTY_ID_SELECT_VALUE, cppu::UnoType<Any>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::TRANSIENT);
511 *pProperties++ = css::beans::Property(PROPERTY_DEFAULT_SELECT_SEQ, PROPERTY_ID_DEFAULT_SELECT_SEQ, cppu::UnoType<Sequence<sal_Int16>>::get(), css::beans::PropertyAttribute::BOUND);
512 *pProperties++ = css::beans::Property(PROPERTY_STRINGITEMLIST, PROPERTY_ID_STRINGITEMLIST, cppu::UnoType<Sequence< OUString >>::get(), css::beans::PropertyAttribute::BOUND);
513 *pProperties++ = css::beans::Property(PROPERTY_TYPEDITEMLIST, PROPERTY_ID_TYPEDITEMLIST, cppu::UnoType<Sequence< Any >>::get(), css::beans::PropertyAttribute::OPTIONAL);
514 DBG_ASSERT( pProperties == _rProps.getArray() + _rProps.getLength(), "<...>::describeFixedProperties/getInfoHelper: forgot to adjust the count ?");
515 }
516
517
518 void OListBoxModel::_propertyChanged( const PropertyChangeEvent& i_rEvent )
519 {
520 if ( i_rEvent.PropertyName == PROPERTY_STRINGITEMLIST )
521 {
522 ControlModelLock aLock( *this );
523 // SYNCHRONIZED ----->
524 // our aggregate internally changed its StringItemList property - reflect this in our "overridden"
525 // version of the property
526 setNewStringItemList( i_rEvent.NewValue, aLock );
527 // <----- SYNCHRONIZED
528 return;
529 }
530 else if ( i_rEvent.PropertyName == PROPERTY_TYPEDITEMLIST )
531 {
532 ControlModelLock aLock( *this );
533 // SYNCHRONIZED ----->
534 // our aggregate internally changed its TypedItemList property - reflect this in our "overridden"
535 // version of the property
536 setNewTypedItemList( i_rEvent.NewValue, aLock );
537 // <----- SYNCHRONIZED
538 return;
539 }
541 }
542
543
544 void OListBoxModel::describeAggregateProperties( Sequence< Property >& _rAggregateProps ) const
545 {
547
548 // superseded properties:
549 RemoveProperty( _rAggregateProps, PROPERTY_STRINGITEMLIST );
550 RemoveProperty( _rAggregateProps, PROPERTY_TYPEDITEMLIST );
551 }
552
553
555 {
556 return FRM_COMPONENT_LISTBOX; // old (non-sun) name for compatibility !
557 }
558
559
560 void SAL_CALL OListBoxModel::write(const Reference<XObjectOutputStream>& _rxOutStream)
561 {
562 OBoundControlModel::write(_rxOutStream);
563
564 // Dummy sequence, to stay compatible if SelectSeq is not saved anymore
565 Sequence<sal_Int16> aDummySeq;
566
567 // Version
568 // Version 0x0002: ListSource becomes StringSeq
569 _rxOutStream->writeShort(0x0004);
570
571 // Masking for any
572 sal_uInt16 nAnyMask = 0;
573 if (m_aBoundColumn.getValueType().getTypeClass() != TypeClass_VOID)
574 nAnyMask |= BOUNDCOLUMN;
575
576 _rxOutStream << nAnyMask;
577
578 _rxOutStream << lcl_convertToStringSequence( m_aListSourceValues );
579 _rxOutStream << static_cast<sal_Int16>(m_eListSourceType);
580 _rxOutStream << aDummySeq;
581 _rxOutStream << m_aDefaultSelectSeq;
582
583 if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
584 {
585 sal_Int16 nBoundColumn = 0;
586 m_aBoundColumn >>= nBoundColumn;
587 _rxOutStream << nBoundColumn;
588 }
589 writeHelpTextCompatibly(_rxOutStream);
590
591 // from version 0x0004 : common properties
592 writeCommonProperties(_rxOutStream);
593 }
594
595
596 void SAL_CALL OListBoxModel::read(const Reference<XObjectInputStream>& _rxInStream)
597 {
598 // We need to respect dependencies for certain variables.
599 // Therefore, we need to set them explicitly via setPropertyValue().
600
601 OBoundControlModel::read(_rxInStream);
602 ControlModelLock aLock( *this );
603
604 // since we are "overwriting" the StringItemList of our aggregate (means we have
605 // an own place to store the value, instead of relying on our aggregate storing it),
606 // we need to respect what the aggregate just read for the StringItemList property.
607 try
608 {
609 if ( m_xAggregateSet.is() )
610 setNewStringItemList( m_xAggregateSet->getPropertyValue( PROPERTY_STRINGITEMLIST ), aLock );
611 }
612 catch( const Exception& )
613 {
614 TOOLS_WARN_EXCEPTION( "forms.component", "OComboBoxModel::read: caught an exception while examining the aggregate's string item list" );
615 }
616
617 // Version
618 sal_uInt16 nVersion = _rxInStream->readShort();
619 DBG_ASSERT(nVersion > 0, "OListBoxModel::read : version 0 ? this should never have been written !");
620
621 if (nVersion > 0x0004)
622 {
623 SAL_WARN( "forms.component", "OListBoxModel::read : invalid (means unknown) version !");
625 m_aBoundColumn <<= sal_Int16(0);
627 m_eListSourceType = ListSourceType_VALUELIST;
628 m_aDefaultSelectSeq.realloc(0);
630 return;
631 }
632
633 // Masking for any
634 sal_uInt16 nAnyMask;
635 _rxInStream >> nAnyMask;
636
637 // ListSourceSeq
638 css::uno::Sequence<OUString> aListSourceSeq;
639 if (nVersion == 0x0001)
640 {
641 // Create ListSourceSeq from String
642 OUString sListSource;
643 _rxInStream >> sListSource;
644
645 const sal_Int32 nTokens{ comphelper::string::getTokenCount(sListSource, ';') };
646 aListSourceSeq.realloc( nTokens );
647 sal_Int32 nIdx{ 0 };
648 for (sal_Int32 i=0; i<nTokens; ++i)
649 {
650 aListSourceSeq.getArray()[i] = sListSource.getToken(0, ';', nIdx);
651 }
652 }
653 else
654 _rxInStream >> aListSourceSeq;
655
656 sal_Int16 nListSourceType;
657 _rxInStream >> nListSourceType;
658 m_eListSourceType = static_cast<ListSourceType>(nListSourceType);
659 Any aListSourceSeqAny;
660 aListSourceSeqAny <<= aListSourceSeq;
661
662 setFastPropertyValue(PROPERTY_ID_LISTSOURCE, aListSourceSeqAny );
663
664 // Dummy sequence, to stay compatible if SelectSeq is not saved anymore
665 Sequence<sal_Int16> aDummySeq;
666 _rxInStream >> aDummySeq;
667
668 // DefaultSelectSeq
669 Sequence<sal_Int16> aDefaultSelectSeq;
670 _rxInStream >> aDefaultSelectSeq;
671 Any aDefaultSelectSeqAny;
672 aDefaultSelectSeqAny <<= aDefaultSelectSeq;
673 setFastPropertyValue(PROPERTY_ID_DEFAULT_SELECT_SEQ, aDefaultSelectSeqAny);
674
675 // BoundColumn
676 if ((nAnyMask & BOUNDCOLUMN) == BOUNDCOLUMN)
677 {
678 sal_Int16 nValue;
679 _rxInStream >> nValue;
681 }
682 else // the constructor initialises to 1, so if it is empty,
683 // we must explicitly set to empty
684 {
686 }
687
688 if (nVersion > 2)
689 readHelpTextCompatibly(_rxInStream);
690
691 // if our string list is not filled from the value list, we must empty it
692 // this can be the case when somebody saves in alive mode
693 if ( ( m_eListSourceType != ListSourceType_VALUELIST )
695 )
696 {
697 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, Any( css::uno::Sequence<OUString>() ) );
698 setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, Any( css::uno::Sequence<css::uno::Any>() ) );
699 }
700
701 if (nVersion > 3)
702 readCommonProperties(_rxInStream);
703
704 // Display the default values after reading
705 if ( !getControlSource().isEmpty() )
706 // (not if we don't have a control source - the "State" property acts like it is persistent, then
708 }
709
710
711 void OListBoxModel::loadData( bool _bForce )
712 {
713 SAL_INFO( "forms.component", "OListBoxModel::loadData" );
714 DBG_ASSERT( m_eListSourceType != ListSourceType_VALUELIST, "OListBoxModel::loadData: cannot load value list from DB!" );
715 DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::loadData: cannot load from DB when I have an external list source!" );
716
717 const sal_Int16 nNULLPosBackup( m_nNULLPos );
718 const sal_Int32 nBoundColumnTypeBackup( m_nBoundColumnType );
719 m_nNULLPos = -1;
720 m_nBoundColumnType = DataType::SQLNULL;
721
722 // pre-requisites:
723 // PRE1: connection
724 Reference< XConnection > xConnection;
725 // is the active connection of our form
726 Reference< XPropertySet > xFormProps( m_xCursor, UNO_QUERY );
727 if ( xFormProps.is() )
728 xFormProps->getPropertyValue( PROPERTY_ACTIVE_CONNECTION ) >>= xConnection;
729
730 // PRE2: list source
731 OUString sListSource;
732 // if our list source type is no value list, we need to concatenate
733 // the single list source elements
734 ::std::for_each(
735 m_aListSourceValues.begin(),
737 AppendRowSetValueString( sListSource )
738 );
739
740 // outta here if we don't have all pre-requisites
741 if ( !xConnection.is() || sListSource.isEmpty() )
742 {
744 return;
745 }
746
747 ::std::optional< sal_Int16 > aBoundColumn(std::nullopt);
748 if ( m_aBoundColumn.getValueType().getTypeClass() == TypeClass_SHORT )
749 {
750 sal_Int16 nBoundColumn( 0 );
751 m_aBoundColumn >>= nBoundColumn;
752 aBoundColumn = nBoundColumn;
753 }
754
756 try
757 {
758 m_aListRowSet.setConnection( xConnection );
759
760 bool bExecute = false;
761 switch (m_eListSourceType)
762 {
763 case ListSourceType_TABLEFIELDS:
764 // don't work with a statement here, the fields will be collected below
765 break;
766
767 case ListSourceType_TABLE:
768 {
769 Reference<XNameAccess> xFieldsByName = getTableFields(xConnection, sListSource);
770 Reference<XIndexAccess> xFieldsByIndex(xFieldsByName, UNO_QUERY);
771
772 // do we have a bound column if yes we have to select it
773 // and the displayed column is the first column otherwise we act as a combobox
774 OUString aFieldName;
775 OUString aBoundFieldName;
776
777 if ( !!aBoundColumn && ( *aBoundColumn >= 0 ) && xFieldsByIndex.is() )
778 {
779 if ( *aBoundColumn >= xFieldsByIndex->getCount() )
780 break;
781
782 Reference<XPropertySet> xFieldAsSet(xFieldsByIndex->getByIndex( *aBoundColumn ),UNO_QUERY);
783 assert(xFieldAsSet.is());
784 xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aBoundFieldName;
785 aBoundColumn = 1;
786
787 xFieldAsSet.set(xFieldsByIndex->getByIndex(0),UNO_QUERY);
788 xFieldAsSet->getPropertyValue(PROPERTY_NAME) >>= aFieldName;
789 }
790 else if (xFieldsByName.is())
791 {
792 if ( xFieldsByName->hasByName( getControlSource() ) )
793 aFieldName = getControlSource();
794 else
795 {
796 // otherwise look for the alias
797 Reference< XColumnsSupplier > xSupplyFields;
798 xFormProps->getPropertyValue("SingleSelectQueryComposer") >>= xSupplyFields;
799
800 // search the field
801 DBG_ASSERT(xSupplyFields.is(), "OListBoxModel::loadData : invalid query composer !");
802
803 Reference<XNameAccess> xFieldNames = xSupplyFields->getColumns();
804 if ( xFieldNames->hasByName( getControlSource() ) )
805 {
806 Reference<XPropertySet> xComposerFieldAsSet;
807 xFieldNames->getByName( getControlSource() ) >>= xComposerFieldAsSet;
808 if (hasProperty(PROPERTY_FIELDSOURCE, xComposerFieldAsSet))
809 xComposerFieldAsSet->getPropertyValue(PROPERTY_FIELDSOURCE) >>= aFieldName;
810 }
811 }
812 }
813 if (aFieldName.isEmpty())
814 break;
815
816 Reference<XDatabaseMetaData> xMeta = xConnection->getMetaData();
817 OUString aQuote = xMeta->getIdentifierQuoteString();
818 OUString aStatement("SELECT ");
819 if (aBoundFieldName.isEmpty()) // act like a combobox
820 aStatement += "DISTINCT ";
821
822 aStatement += quoteName(aQuote,aFieldName);
823 if (!aBoundFieldName.isEmpty())
824 {
825 aStatement += ", " + quoteName(aQuote, aBoundFieldName);
826 }
827 aStatement += " FROM ";
828
829 OUString sCatalog, sSchema, sTable;
830 qualifiedNameComponents( xMeta, sListSource, sCatalog, sSchema, sTable, EComposeRule::InDataManipulation );
831 aStatement += composeTableNameForSelect( xConnection, sCatalog, sSchema, sTable );
832
834 m_aListRowSet.setCommand( aStatement );
835 bExecute = true;
836 }
837 break;
838
839 case ListSourceType_QUERY:
840 m_aListRowSet.setCommandFromQuery( sListSource );
841 bExecute = true;
842 break;
843
844 default:
845 m_aListRowSet.setEscapeProcessing( ListSourceType_SQLPASSTHROUGH != m_eListSourceType );
846 m_aListRowSet.setCommand( sListSource );
847 bExecute = true;
848 break;
849 }
850
851 if (bExecute)
852 {
853 if ( !_bForce && !m_aListRowSet.isDirty() )
854 {
855 // if none of the settings of the row set changed, compared to the last
856 // invocation of loadData, then don't re-fill the list. Instead, assume
857 // the list entries are the same.
858 m_nNULLPos = nNULLPosBackup;
859 m_nBoundColumnType = nBoundColumnTypeBackup;
860 return;
861 }
862 xListCursor.reset( m_aListRowSet.execute() );
863 }
864 }
865 catch(const SQLException& eSQL)
866 {
867 onError(eSQL, ResourceManager::loadString(RID_BASELISTBOX_ERROR_FILLLIST));
868 return;
869 }
870 catch(const Exception&)
871 {
872 return;
873 }
874
875 // Fill display and value lists
876 ValueList aDisplayList, aValueList;
877 bool bUseNULL = hasField() && !isRequired();
878
879 // empty BoundColumn is treated as BoundColumn==0,
880 if(!aBoundColumn)
881 aBoundColumn = 0;
882
883 try
884 {
885 OSL_ENSURE( xListCursor.is() || ( ListSourceType_TABLEFIELDS == m_eListSourceType ),
886 "OListBoxModel::loadData: logic error!" );
887 if ( !xListCursor.is() && ( ListSourceType_TABLEFIELDS != m_eListSourceType ) )
888 return;
889
890 switch (m_eListSourceType)
891 {
892#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
893 case ListSourceType_SQL:
894 case ListSourceType_SQLPASSTHROUGH:
895 case ListSourceType_TABLE:
896 case ListSourceType_QUERY:
897 {
898 // Get field of the ResultSet's 1st column
899 Reference<XColumnsSupplier> xSupplyCols(xListCursor, UNO_QUERY);
900 DBG_ASSERT(xSupplyCols.is(), "OListBoxModel::loadData : cursor supports the row set service but is no column supplier?!");
901 Reference<XIndexAccess> xColumns;
902 if (xSupplyCols.is())
903 {
904 xColumns.set(xSupplyCols->getColumns(), UNO_QUERY);
905 DBG_ASSERT(xColumns.is(), "OListBoxModel::loadData : no columns supplied by the row set !");
906 }
907
908 Reference< XPropertySet > xDataField;
909 if ( xColumns.is() )
910 xColumns->getByIndex(0) >>= xDataField;
911 if ( !xDataField.is() )
912 return;
913
914 ::dbtools::FormattedColumnValue aValueFormatter( getContext(), m_xCursor, xDataField );
915
916 // Get the field of BoundColumn of the ResultSet
917 m_nBoundColumnType = DataType::SQLNULL;
918 if ( *aBoundColumn >= 0 )
919 {
920 try
921 {
922 Reference< XPropertySet > xBoundField( xColumns->getByIndex( *aBoundColumn ), UNO_QUERY_THROW );
923 OSL_VERIFY( xBoundField->getPropertyValue("Type") >>= m_nBoundColumnType );
924 }
925 catch( const Exception& )
926 {
927 DBG_UNHANDLED_EXCEPTION("forms.component");
928 }
929 }
930 else if ( *aBoundColumn == -1)
931 m_nBoundColumnType = DataType::SMALLINT;
932
933 // If the LB is bound to a field and empty entries are valid, we remember the position
934 // for an empty entry
935 SAL_INFO( "forms.component", "OListBoxModel::loadData: string collection" );
936 OUString aStr;
937 sal_Int16 entryPos = 0;
938 ORowSetValue aBoundValue;
939 Reference< XRow > xCursorRow( xListCursor, UNO_QUERY_THROW );
940 while ( xListCursor->next() && ( entryPos++ < SHRT_MAX ) ) // SHRT_MAX is the maximum number of entries
941 {
942 aStr = aValueFormatter.getFormattedValue();
943 aDisplayList.emplace_back(aStr );
944
945 if(*aBoundColumn >= 0)
946 aBoundValue.fill( *aBoundColumn + 1, m_nBoundColumnType, xCursorRow );
947 else
948 // -1 because getRow() is 1-indexed, but ListBox positions are 0-indexed
949 aBoundValue = static_cast<sal_Int16>(xListCursor->getRow()-1);
950 aValueList.push_back( aBoundValue );
951
952 if ( m_nNULLPos == -1 && aBoundValue.isNull() )
953 m_nNULLPos = sal_Int16( aDisplayList.size() - 1 );
954 if ( bUseNULL && ( m_nNULLPos == -1 ) && aStr.isEmpty() )
955 // There is already a non-NULL entry with empty display string;
956 // adding another one for NULL would make things confusing,
957 // so back off.
958 bUseNULL = false;
959 }
960 }
961 break;
962#endif
963 case ListSourceType_TABLEFIELDS:
964 {
965 Reference<XNameAccess> xFieldNames = getTableFields(xConnection, sListSource);
966 if (xFieldNames.is())
967 {
968 const css::uno::Sequence<OUString> seqNames = xFieldNames->getElementNames();
970 seqNames.begin(),
971 seqNames.end(),
972 ::std::insert_iterator< ValueList >( aDisplayList, aDisplayList.end() )
973 );
974 if(*aBoundColumn == -1)
975 {
976 // the type of i matters! It will be the type of the ORowSetValue pushed to aValueList!
977 for(size_t i=0; i < aDisplayList.size(); ++i)
978 {
979 aValueList.emplace_back(sal_Int16(i));
980 }
981 }
982 else
983 {
984 aValueList = aDisplayList;
985 }
986 }
987 }
988 break;
989 default:
990 SAL_WARN( "forms.component", "OListBoxModel::loadData: unreachable!" );
991 break;
992 }
993 }
994 catch(const SQLException& eSQL)
995 {
996 onError(eSQL, ResourceManager::loadString(RID_BASELISTBOX_ERROR_FILLLIST));
997 return;
998 }
999 catch( const Exception& )
1000 {
1001 DBG_UNHANDLED_EXCEPTION("forms.component");
1002 return;
1003 }
1004
1005
1006 // Create Values sequence
1007 // Add NULL entry
1008 if (bUseNULL && m_nNULLPos == -1)
1009 {
1010 aValueList.insert( aValueList.begin(), ORowSetValue() );
1011
1012 aDisplayList.insert( aDisplayList.begin(), ORowSetValue( OUString() ) );
1013 m_nNULLPos = 0;
1014 }
1015
1016 setBoundValues(std::move(aValueList));
1017
1018 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, Any( lcl_convertToStringSequence( aDisplayList ) ) );
1019 setFastPropertyValue( PROPERTY_ID_TYPEDITEMLIST, Any( css::uno::Sequence<css::uno::Any>() ) );
1020 }
1021
1022
1023 void OListBoxModel::onConnectedDbColumn( const Reference< XInterface >& /*_rxForm*/ )
1024 {
1025 // list boxes which are bound to a db column don't have multi selection
1026 // - this would be unable to reflect in the db column
1027 if ( hasField() )
1028 {
1029 setFastPropertyValue( PROPERTY_ID_MULTISELECTION, css::uno::Any(false) );
1030 }
1031
1032 if ( !hasExternalListSource() )
1033 impl_refreshDbEntryList( false );
1034 }
1035
1036
1038 {
1040 m_nNULLPos = -1;
1041 m_nBoundColumnType = DataType::SQLNULL;
1042
1043 if ( m_eListSourceType != ListSourceType_VALUELIST )
1044 {
1045 if ( !hasExternalListSource() )
1046 setFastPropertyValue( PROPERTY_ID_STRINGITEMLIST, Any( css::uno::Sequence<OUString>() ) );
1047
1049 }
1050 }
1051
1052
1054 {
1056 m_aBoundValues = std::move(l);
1057 }
1058
1059
1061 {
1063 ValueList().swap(m_aBoundValues);
1064 }
1065
1066
1067 void OListBoxModel::convertBoundValues(const sal_Int32 nFieldType) const
1068 {
1069 assert(s_aEmptyValue.isNull());
1070 m_nNULLPos = -1;
1072 ValueList::iterator dst = m_aConvertedBoundValues.begin();
1073 sal_Int16 nPos = 0;
1074 for (auto const& src : m_aBoundValues)
1075 {
1076 if(m_nNULLPos == -1 &&
1077 !isRequired() &&
1078 (src == s_aEmptyStringValue || src == s_aEmptyValue || src.isNull()) )
1079 {
1080 m_nNULLPos = nPos;
1081 dst->setNull();
1082 }
1083 else
1084 {
1085 *dst = src;
1086 }
1087 dst->setTypeKind(nFieldType);
1088 ++dst;
1089 ++nPos;
1090 }
1091 m_nConvertedBoundValuesType = nFieldType;
1092 OSL_ENSURE(dst == m_aConvertedBoundValues.end(), "OListBoxModel::convertBoundValues expected to have overwritten all of m_aConvertedBoundValues, but did not.");
1093 assert(dst == m_aConvertedBoundValues.end());
1094 }
1095
1097 {
1098 return (m_nBoundColumnType != css::sdbc::DataType::SQLNULL) ?
1100 ( hasField() ? getFieldType() : DataType::VARCHAR);
1101 }
1102
1104 {
1105 const sal_Int32 nFieldType = getValueType();
1106
1107 if ( !m_aConvertedBoundValues.empty() && m_nConvertedBoundValuesType == nFieldType )
1109
1110 if ( !m_aBoundValues.empty() )
1111 {
1112 convertBoundValues(nFieldType);
1114 }
1115
1116 const std::vector< OUString >& aStringItems( getStringItemList() );
1117 ValueList aValues( aStringItems.size() );
1118 ValueList::iterator dst = aValues.begin();
1119 for (auto const& src : aStringItems)
1120 {
1121 *dst = src;
1122 dst->setTypeKind(nFieldType);
1123 ++dst;
1124 }
1125 m_nConvertedBoundValuesType = nFieldType;
1126 OSL_ENSURE(dst == aValues.end(), "OListBoxModel::impl_getValues expected to have set all of aValues, but did not.");
1127 assert(dst == aValues.end());
1128 return aValues;
1129 }
1130
1132 {
1133 DBG_ASSERT( m_xAggregateFastSet.is(), "OListBoxModel::getFirstSelectedValue: invalid aggregate!" );
1134 if ( !m_xAggregateFastSet.is() )
1135 return s_aEmptyValue;
1136
1137 Sequence< sal_Int16 > aSelectedIndices;
1138 OSL_VERIFY( m_xAggregateFastSet->getFastPropertyValue( getValuePropertyAggHandle() ) >>= aSelectedIndices );
1139 if ( !aSelectedIndices.hasElements() )
1140 // nothing selected at all
1141 return s_aEmptyValue;
1142
1143 if ( ( m_nNULLPos != -1 ) && ( aSelectedIndices[0] == m_nNULLPos ) )
1144 // the dedicated "NULL" entry is selected
1145 return s_aEmptyValue;
1146
1147 ValueList aValues( impl_getValues() );
1148
1149 size_t selectedValue = aSelectedIndices[0];
1150 if ( selectedValue >= aValues.size() )
1151 {
1152 SAL_WARN( "forms.component", "OListBoxModel::getFirstSelectedValue: inconsistent selection/valuelist!" );
1153 return s_aEmptyValue;
1154 }
1155
1156 return aValues[ selectedValue ];
1157 }
1158
1159
1161 {
1162 // current selection list
1163 const ORowSetValue aCurrentValue( getFirstSelectedValue() );
1164 if ( aCurrentValue != m_aSaveValue )
1165 {
1166 if ( aCurrentValue.isNull() )
1167 m_xColumnUpdate->updateNull();
1168 else
1169 {
1170 try
1171 {
1172 m_xColumnUpdate->updateObject( aCurrentValue.makeAny() );
1173 }
1174 catch ( const Exception& )
1175 {
1176 return false;
1177 }
1178 }
1179 m_aSaveValue = aCurrentValue;
1180 }
1181 return true;
1182 }
1183
1184
1185 Sequence< sal_Int16 > OListBoxModel::translateDbValueToControlValue(const ORowSetValue &i_aValue) const
1186 {
1187 Sequence< sal_Int16 > aSelectionIndicies;
1188
1189 // reset selection for NULL values
1190 if ( i_aValue.isNull() )
1191 {
1192 if ( m_nNULLPos != -1 )
1193 {
1194 aSelectionIndicies = { m_nNULLPos };
1195 }
1196 }
1197 else
1198 {
1199 ValueList aValues( impl_getValues() );
1201 ORowSetValue v(i_aValue);
1202 v.setTypeKind( m_nConvertedBoundValuesType );
1203 ValueList::const_iterator curValuePos = ::std::find( aValues.begin(), aValues.end(), v );
1204 if ( curValuePos != aValues.end() )
1205 {
1206 aSelectionIndicies = { o3tl::narrowing<sal_Int16>(curValuePos - aValues.begin()) };
1207 }
1208 }
1209
1210 return aSelectionIndicies;
1211 }
1212
1213 Sequence< sal_Int16 > OListBoxModel::translateBindingValuesToControlValue(const Sequence< const Any > &i_aValues) const
1214 {
1215 const ValueList aValues( impl_getValues() );
1217 Sequence< sal_Int16 > aSelectionIndicies(i_aValues.getLength());
1218
1219 sal_Int32 nCount(0);
1220
1221#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1222 sal_Int16 *pIndex = aSelectionIndicies.getArray();
1223 for ( auto const & value : i_aValues)
1224 {
1225 if ( value.hasValue() )
1226 {
1227 ORowSetValue v;
1228 v.fill(value);
1229 v.setTypeKind( m_nConvertedBoundValuesType );
1230 ValueList::const_iterator curValuePos = ::std::find( aValues.begin(), aValues.end(), v );
1231 if ( curValuePos != aValues.end() )
1232 {
1233 *pIndex = curValuePos - aValues.begin();
1234 ++pIndex;
1235 ++nCount;
1236 }
1237 }
1238 else
1239 {
1240 if ( m_nNULLPos != -1 )
1241 {
1242 *pIndex = m_nNULLPos;
1243 ++pIndex;
1244 ++nCount;
1245 }
1246 }
1247 }
1248 assert(aSelectionIndicies.getArray() + nCount == pIndex);
1249#endif
1250 aSelectionIndicies.realloc(nCount);
1251 return aSelectionIndicies;
1252 }
1253
1255 {
1256#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1257 Reference< XPropertySet > xBoundField( getField() );
1258 if ( !xBoundField.is() )
1259 {
1260 SAL_WARN( "forms.component", "OListBoxModel::translateDbColumnToControlValue: no field? How could that happen?!" );
1261 return Any();
1262 }
1263
1264 ORowSetValue aCurrentValue;
1265 aCurrentValue.fill( getValueType(), m_xColumn );
1266
1267 m_aSaveValue = aCurrentValue;
1268
1269 return Any( translateDbValueToControlValue(aCurrentValue) );
1270#else
1271 return Any();
1272#endif
1273 }
1274
1275 // XReset
1276
1278 {
1279 Any aValue;
1280 if (m_aDefaultSelectSeq.hasElements())
1281 aValue <<= m_aDefaultSelectSeq;
1282 else if (m_nNULLPos != -1) // bound Listbox
1283 {
1284 Sequence<sal_Int16> aSeq { m_nNULLPos };
1285 aValue <<= aSeq;
1286 }
1287 else
1288 {
1289 Sequence<sal_Int16> aSeq;
1290 aValue <<= aSeq;
1291 }
1292
1293 return aValue;
1294 }
1295
1296
1298 {
1301 }
1302
1303
1304 void SAL_CALL OListBoxModel::disposing( const EventObject& _rSource )
1305 {
1306 if ( !OEntryListHelper::handleDisposing( _rSource ) )
1308 }
1309
1310
1311 namespace
1312 {
1313 // The type of how we should transfer our selection to external value bindings
1314 enum ExchangeType
1315 {
1316 eIndexList,
1317 eIndex,
1318 eEntryList,
1319 eEntry,
1320 eValueList,
1321 eValue
1322 };
1323
1324
1325 ExchangeType lcl_getCurrentExchangeType( const Type& _rExchangeType )
1326 {
1327 switch ( _rExchangeType.getTypeClass() )
1328 {
1329 case TypeClass_ANY:
1330 return eValue;
1331 case TypeClass_STRING:
1332 return eEntry;
1333 case TypeClass_LONG:
1334 return eIndex;
1335 case TypeClass_SEQUENCE:
1336 {
1337 Type aElementType = ::comphelper::getSequenceElementType( _rExchangeType );
1338 switch ( aElementType.getTypeClass() )
1339 {
1340 case TypeClass_ANY:
1341 return eValueList;
1342 case TypeClass_STRING:
1343 return eEntryList;
1344 case TypeClass_LONG:
1345 return eIndexList;
1346 default:
1347 break;
1348 }
1349 break;
1350 }
1351 default:
1352 break;
1353 }
1354 SAL_WARN( "forms.component", "lcl_getCurrentExchangeType: unsupported (unexpected) exchange type!" );
1355 return eEntry;
1356 }
1357 }
1358
1359
1361 {
1362 Sequence< sal_Int16 > aSelectIndexes;
1363
1364 switch ( lcl_getCurrentExchangeType( getExternalValueType() ) )
1365 {
1366 case eValueList:
1367 {
1368 Sequence< const Any > aExternalValues;
1369 OSL_VERIFY( _rExternalValue >>= aExternalValues );
1370 aSelectIndexes = translateBindingValuesToControlValue( aExternalValues );
1371 }
1372 break;
1373
1374 case eValue:
1375#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS
1376 {
1377 ORowSetValue v;
1378 v.fill(_rExternalValue);
1379 aSelectIndexes = translateDbValueToControlValue(v);
1380 }
1381#endif
1382 break;
1383
1384 case eIndexList:
1385 {
1386 // unfortunately, our select sequence is a sequence<short>, while the external binding
1387 // supplies sequence<int> only -> transform this
1388 Sequence< sal_Int32 > aSelectIndexesPure;
1389 OSL_VERIFY( _rExternalValue >>= aSelectIndexesPure );
1390 aSelectIndexes.realloc( aSelectIndexesPure.getLength() );
1392 std::cbegin(aSelectIndexesPure),
1393 std::cend(aSelectIndexesPure),
1394 aSelectIndexes.getArray()
1395 );
1396 }
1397 break;
1398
1399 case eIndex:
1400 {
1401 sal_Int32 nSelectIndex = -1;
1402 OSL_VERIFY( _rExternalValue >>= nSelectIndex );
1403 if ( ( nSelectIndex >= 0 ) && ( o3tl::make_unsigned(nSelectIndex) < getStringItemList().size() ) )
1404 {
1405 aSelectIndexes = { o3tl::narrowing<sal_Int16>(nSelectIndex) };
1406 }
1407 }
1408 break;
1409
1410 case eEntryList:
1411 {
1412 // we can retrieve a string list from the binding for multiple selection
1413 Sequence< OUString > aSelectEntries;
1414 OSL_VERIFY( _rExternalValue >>= aSelectEntries );
1415
1416 ::std::set< sal_Int16 > aSelectionSet;
1417
1418 // find the selection entries in our item list
1419 for ( OUString const & selectEntry : std::as_const(aSelectEntries) )
1420 {
1421 int idx = 0;
1422 for(const OUString& s : getStringItemList())
1423 {
1424 if (s==selectEntry)
1425 aSelectionSet.insert(idx);
1426 ++idx;
1427 }
1428 }
1429
1430 // copy the indexes to the sequence
1431 aSelectIndexes = comphelper::containerToSequence( aSelectionSet );
1432 }
1433 break;
1434
1435 case eEntry:
1436 {
1437 OUString sStringToSelect;
1438 OSL_VERIFY( _rExternalValue >>= sStringToSelect );
1439 ::std::set< sal_Int16 > aSelectionSet;
1440 int idx = 0;
1441 for(const OUString& s : getStringItemList())
1442 {
1443 if (s==sStringToSelect)
1444 aSelectionSet.insert(idx);
1445 ++idx;
1446 }
1447
1448 aSelectIndexes = comphelper::containerToSequence( aSelectionSet );
1449 }
1450 break;
1451 }
1452
1453 return Any( aSelectIndexes );
1454 }
1455
1456
1457 namespace
1458 {
1459
1460 struct ExtractStringFromSequence_Safe
1461 {
1462 protected:
1463 const std::vector< OUString >& m_rList;
1464
1465 public:
1466 explicit ExtractStringFromSequence_Safe( const std::vector< OUString >& _rList ) : m_rList( _rList ) { }
1467
1468 OUString operator ()( sal_Int16 _nIndex )
1469 {
1470 OSL_ENSURE( _nIndex < static_cast<sal_Int32>(m_rList.size()), "ExtractStringFromSequence_Safe: inconsistence!" );
1471 if ( _nIndex < static_cast<sal_Int32>(m_rList.size()) )
1472 return m_rList[ _nIndex ];
1473 return OUString();
1474 }
1475 };
1476
1477
1478 Any lcl_getSingleSelectedEntryTyped( const Sequence< sal_Int16 >& _rSelectSequence, const Sequence<Any>& _rTypedList )
1479 {
1480 Any aReturn;
1481
1482 // by definition, multiple selected entries are transferred as NULL if the
1483 // binding does not support lists
1484 if ( _rSelectSequence.getLength() <= 1 )
1485 {
1486 if ( _rSelectSequence.getLength() == 1 )
1487 {
1488 sal_Int32 nIndex = _rSelectSequence[0];
1489 if (0 <= nIndex && nIndex < _rTypedList.getLength())
1490 aReturn = _rTypedList[nIndex];
1491 }
1492 }
1493
1494 return aReturn;
1495 }
1496
1497
1498 Any lcl_getSingleSelectedEntry( const Sequence< sal_Int16 >& _rSelectSequence, const std::vector< OUString >& _rStringList )
1499 {
1500 Any aReturn;
1501
1502 // by definition, multiple selected entries are transferred as NULL if the
1503 // binding does not support string lists
1504 if ( _rSelectSequence.getLength() <= 1 )
1505 {
1506 OUString sSelectedEntry;
1507
1508 if ( _rSelectSequence.getLength() == 1 )
1509 sSelectedEntry = ExtractStringFromSequence_Safe( _rStringList )( _rSelectSequence[0] );
1510
1511 aReturn <<= sSelectedEntry;
1512 }
1513
1514 return aReturn;
1515 }
1516
1517
1518 Any lcl_getMultiSelectedEntries( const Sequence< sal_Int16 >& _rSelectSequence, const std::vector< OUString >& _rStringList )
1519 {
1520 Sequence< OUString > aSelectedEntriesTexts( _rSelectSequence.getLength() );
1521 ::std::transform(
1522 _rSelectSequence.begin(),
1523 _rSelectSequence.end(),
1524 aSelectedEntriesTexts.getArray(),
1525 ExtractStringFromSequence_Safe( _rStringList )
1526 );
1527 return Any( aSelectedEntriesTexts );
1528 }
1529
1530
1531 struct ExtractAnyFromValueList_Safe
1532 {
1533 protected:
1534 const ValueList& m_rList;
1535
1536 public:
1537 explicit ExtractAnyFromValueList_Safe( const ValueList& _rList ) : m_rList( _rList ) { }
1538
1539 Any operator ()( sal_Int16 _nIndex )
1540 {
1541 OSL_ENSURE( o3tl::make_unsigned(_nIndex) < m_rList.size(), "ExtractAnyFromValueList: inconsistence!" );
1542 if ( o3tl::make_unsigned(_nIndex) < m_rList.size() )
1543 return m_rList[ _nIndex ].makeAny();
1544 return Any();
1545 }
1546 };
1547
1548
1549 Any lcl_getSingleSelectedEntryAny( const Sequence< sal_Int16 >& _rSelectSequence, const ValueList& _rStringList )
1550 {
1551 Any aReturn;
1552
1553 // by definition, multiple selected entries are transferred as NULL if the
1554 // binding does not support string lists
1555 if ( _rSelectSequence.getLength() <= 1 )
1556 {
1557 if ( _rSelectSequence.getLength() == 1 )
1558 aReturn = ExtractAnyFromValueList_Safe( _rStringList )( _rSelectSequence[0] );
1559 }
1560
1561 return aReturn;
1562 }
1563
1564
1565 Sequence< Any > lcl_getMultiSelectedEntriesAny( const Sequence< sal_Int16 >& _rSelectSequence, const ValueList& _rStringList )
1566 {
1567 Sequence< Any > aSelectedEntriesValues( _rSelectSequence.getLength() );
1568 ::std::transform(
1569 _rSelectSequence.begin(),
1570 _rSelectSequence.end(),
1571 aSelectedEntriesValues.getArray(),
1572 ExtractAnyFromValueList_Safe( _rStringList )
1573 );
1574 return aSelectedEntriesValues;
1575 }
1576 }
1577
1578
1580 {
1581 OSL_PRECOND( hasExternalValueBinding(), "OListBoxModel::translateControlValueToExternalValue: no binding!" );
1582
1583 Sequence< sal_Int16 > aSelectSequence;
1584 OSL_VERIFY( getControlValue() >>= aSelectSequence );
1585
1586 Any aReturn;
1587 switch ( lcl_getCurrentExchangeType( getExternalValueType() ) )
1588 {
1589 case eValueList:
1590 aReturn <<= getCurrentMultiValue();
1591 break;
1592
1593 case eValue:
1594 aReturn = getCurrentSingleValue();
1595 break;
1596
1597 case eIndexList:
1598 {
1599 // unfortunately, the select sequence is a sequence<short>, but our binding
1600 // expects int's
1601 Sequence< sal_Int32 > aTransformed( aSelectSequence.getLength() );
1603 std::cbegin(aSelectSequence),
1604 std::cend(aSelectSequence),
1605 aTransformed.getArray()
1606 );
1607 aReturn <<= aTransformed;
1608 }
1609 break;
1610
1611 case eIndex:
1612 if ( aSelectSequence.getLength() <= 1 )
1613 {
1614 sal_Int32 nIndex = -1;
1615
1616 if ( aSelectSequence.getLength() == 1 )
1617 nIndex = aSelectSequence[0];
1618
1619 aReturn <<= nIndex;
1620 }
1621 break;
1622
1623 case eEntryList:
1624 aReturn = lcl_getMultiSelectedEntries( aSelectSequence, getStringItemList() );
1625 break;
1626
1627 case eEntry:
1628 {
1629 const std::vector<OUString>& rStrings = getStringItemList();
1630 const Sequence<Any>& rValues = getTypedItemList();
1631 if (rStrings.size() == static_cast<size_t>(rValues.getLength()))
1632 aReturn = lcl_getSingleSelectedEntryTyped( aSelectSequence, rValues );
1633 else
1634 aReturn = lcl_getSingleSelectedEntry( aSelectSequence, rStrings );
1635 }
1636 break;
1637 }
1638
1639 return aReturn;
1640 }
1641
1642
1644 {
1645 OSL_PRECOND( hasValidator(), "OListBoxModel::translateControlValueToValidatableValue: no validator, so why should I?" );
1647 }
1648
1649
1651 {
1652 Any aCurrentValue;
1653
1654 try
1655 {
1656 Sequence< sal_Int16 > aSelectSequence;
1657 OSL_VERIFY( getControlValue() >>= aSelectSequence );
1658 aCurrentValue = lcl_getSingleSelectedEntryAny( aSelectSequence, impl_getValues() );
1659 }
1660 catch( const Exception& )
1661 {
1662 DBG_UNHANDLED_EXCEPTION("forms.component");
1663 }
1664
1665 return aCurrentValue;
1666 }
1667
1669 {
1670 Sequence< Any > aCurrentValue;
1671
1672 try
1673 {
1674 Sequence< sal_Int16 > aSelectSequence;
1675 OSL_VERIFY( getControlValue() >>= aSelectSequence );
1676 aCurrentValue = lcl_getMultiSelectedEntriesAny( aSelectSequence, impl_getValues() );
1677 }
1678 catch( const Exception& )
1679 {
1680 DBG_UNHANDLED_EXCEPTION("forms.component");
1681 }
1682
1683 return aCurrentValue;
1684 }
1685
1687 {
1688 {
1689 Reference< css::form::validation::XValidator > vtor (const_cast<OListBoxModel*>(this)->getValidator());
1690 Reference< XValueBinding > extBinding (const_cast<OListBoxModel*>(this)->getValueBinding());
1691 if ( vtor.is() && vtor == extBinding )
1693 }
1694
1695 Any aCurrentValue;
1696
1697 try
1698 {
1699 bool bMultiSelection( false );
1700 OSL_VERIFY( const_cast< OListBoxModel* >( this )->getPropertyValue( PROPERTY_MULTISELECTION ) >>= bMultiSelection );
1701
1702 if ( bMultiSelection )
1703 aCurrentValue <<= getCurrentMultiValue();
1704 else
1705 aCurrentValue = getCurrentSingleValue();
1706 }
1707 catch( const Exception& )
1708 {
1709 DBG_UNHANDLED_EXCEPTION("forms.component");
1710 }
1711
1712 return aCurrentValue;
1713 }
1714
1715
1717 {
1718 return
1719 {
1726 };
1727 }
1728
1729
1731 {
1732 if ( !m_xAggregateSet.is() )
1733 return;
1734
1736 try
1737 {
1738 m_xAggregateSet->setPropertyValue( PROPERTY_STRINGITEMLIST, Any( comphelper::containerToSequence(getStringItemList()) ) );
1739 m_xAggregateSet->setPropertyValue( PROPERTY_TYPEDITEMLIST, Any( getTypedItemList() ) );
1740 }
1741 catch( const Exception& )
1742 {
1743 DBG_UNHANDLED_EXCEPTION("forms.component");
1744 }
1746
1747 // update the selection here
1748 if ( hasExternalValueBinding( ) )
1749 transferExternalValueToControl( _rInstanceLock );
1750 else
1751 {
1752 if ( hasField() )
1753 {
1754 // TODO: update the selection in case we're bound to a database column
1755 }
1756 else
1757 {
1758 if ( m_aDefaultSelectSeq.hasElements() )
1760 }
1761 }
1762 }
1763
1764
1766 {
1767 DBG_ASSERT( !hasExternalListSource(), "OListBoxModel::impl_refreshDbEntryList: invalid call!" );
1768
1769 if ( !hasExternalListSource( )
1770 && ( m_eListSourceType != ListSourceType_VALUELIST )
1771 && ( m_xCursor.is() )
1772 )
1773 {
1774 loadData( _bForce );
1775 }
1776 }
1777
1778
1780 {
1782 if ( hasField() && m_xCursor.is() )
1784 }
1785
1786
1787 // OListBoxControl
1788
1790 {
1791 return TypeBag(
1794 ).getTypes();
1795 }
1796
1797
1799 {
1800 Any aReturn = OListBoxControl_BASE::queryInterface( _rType );
1801
1802 if ( !aReturn.hasValue()
1803 || _rType.equals( cppu::UnoType<XTypeProvider>::get() )
1804 )
1805 aReturn = OBoundControl::queryAggregation( _rType );
1806
1807 return aReturn;
1808 }
1809
1810
1811 OListBoxControl::OListBoxControl(const Reference<XComponentContext>& _rxFactory)
1812 :OBoundControl( _rxFactory, VCL_CONTROL_LISTBOX, false )
1813 ,m_aChangeListeners( m_aMutex )
1814 ,m_aItemListeners( m_aMutex )
1815 ,m_aChangeIdle("forms OListBoxControl m_aChangedIdle")
1816 {
1817
1818 osl_atomic_increment(&m_refCount);
1819 {
1820 // Register as FocusListener
1821 Reference<XWindow> xComp;
1822 if (query_aggregation(m_xAggregate, xComp))
1823 xComp->addFocusListener(this);
1824
1825 // Register as ItemListener
1827 m_xAggregateListBox->addItemListener(this);
1828 }
1829 // Refcount at 2 for registered Listener
1830 osl_atomic_decrement(&m_refCount);
1831
1833
1834 m_aChangeIdle.SetPriority(TaskPriority::LOWEST);
1836 }
1837
1838
1840 {
1841 if (!OComponentHelper::rBHelper.bDisposed)
1842 {
1843 acquire();
1844 dispose();
1845 }
1846
1848 m_xAggregateListBox.clear();
1849
1850 }
1851
1852
1853 css::uno::Sequence<OUString> SAL_CALL OListBoxControl::getSupportedServiceNames()
1854 {
1855 css::uno::Sequence<OUString> aSupported = OBoundControl::getSupportedServiceNames();
1856 aSupported.realloc(aSupported.getLength() + 2);
1857
1858 OUString* pArray = aSupported.getArray();
1859 pArray[aSupported.getLength()-2] = FRM_SUN_CONTROL_LISTBOX;
1860 pArray[aSupported.getLength()-1] = STARDIV_ONE_FORM_CONTROL_LISTBOX;
1861 return aSupported;
1862 }
1863
1864
1865 // XFocusListener
1866
1867 void SAL_CALL OListBoxControl::focusGained(const FocusEvent& /*_rEvent*/)
1868 {
1869 ::osl::MutexGuard aGuard(m_aMutex);
1870 if ( m_aChangeListeners.getLength() ) // only if there are listeners
1871 {
1872 Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
1873 if (xSet.is())
1874 {
1875 // memorize the current selection for posting the change event
1876 m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ);
1877 }
1878 }
1879 }
1880
1881
1882 void SAL_CALL OListBoxControl::focusLost(const FocusEvent& /*_rEvent*/)
1883 {
1884 m_aCurrentSelection.clear();
1885 }
1886
1887 // XItemListener
1888
1889 void SAL_CALL OListBoxControl::itemStateChanged(const ItemEvent& _rEvent)
1890 {
1891 // forward this to our listeners
1892 Reference< XChild > xChild( getModel(), UNO_QUERY );
1893 if ( xChild.is() && xChild->getParent().is() )
1894 {
1895 ::osl::MutexGuard aGuard( m_aMutex );
1897 {
1898 if ( !m_pItemBroadcaster.is() )
1899 {
1901 new ::comphelper::AsyncEventNotifier("ListBox"));
1902 m_pItemBroadcaster->launch();
1903 }
1904 m_pItemBroadcaster->addEvent( new ItemEventDescription( _rEvent ), this );
1905 }
1906 }
1907 else
1908 m_aItemListeners.notifyEach( &XItemListener::itemStateChanged, _rEvent );
1909
1910 // and do the handling for the ChangeListeners
1911 osl::MutexGuard aGuard(m_aMutex);
1912 if ( m_aChangeIdle.IsActive() )
1913 {
1914 Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
1915 m_aCurrentSelection = xSet->getPropertyValue(PROPERTY_SELECT_SEQ);
1916
1919 }
1920 else
1921 {
1922 if ( m_aChangeListeners.getLength() && m_aCurrentSelection.hasValue() )
1923 {
1924 Reference<XPropertySet> xSet(getModel(), UNO_QUERY);
1925 if (xSet.is())
1926 {
1927 // Has the selection been changed?
1928 bool bModified(false);
1929 Any aValue = xSet->getPropertyValue(PROPERTY_SELECT_SEQ);
1930
1931 Sequence<sal_Int16> const & rSelection = *o3tl::doAccess<Sequence<sal_Int16>>(aValue);
1932 Sequence<sal_Int16> const & rOldSelection = *o3tl::doAccess<Sequence<sal_Int16>>(m_aCurrentSelection);
1933 sal_Int32 nLen = rSelection.getLength();
1934 if (nLen != rOldSelection.getLength())
1935 bModified = true;
1936 else
1937 {
1938 const sal_Int16* pVal = rSelection.getConstArray();
1939 const sal_Int16* pCompVal = rOldSelection.getConstArray();
1940
1941 while (nLen-- && !bModified)
1942 bModified = pVal[nLen] != pCompVal[nLen];
1943 }
1944
1945 if (bModified)
1946 {
1947 m_aCurrentSelection = aValue;
1949 }
1950 }
1951 }
1952 else if (m_aCurrentSelection.hasValue())
1953 m_aCurrentSelection.clear();
1954 }
1955 }
1956
1957 // XEventListener
1958
1959 void SAL_CALL OListBoxControl::disposing(const EventObject& _rSource)
1960 {
1961 OBoundControl::disposing(_rSource);
1962 }
1963
1964 // XChangeBroadcaster
1965
1966 void SAL_CALL OListBoxControl::addChangeListener(const Reference<XChangeListener>& _rxListener)
1967 {
1968 m_aChangeListeners.addInterface( _rxListener );
1969 }
1970
1971
1972 void SAL_CALL OListBoxControl::removeChangeListener(const Reference<XChangeListener>& _rxListener)
1973 {
1974 m_aChangeListeners.removeInterface( _rxListener );
1975 }
1976
1977 // OComponentHelper
1978
1980 {
1981 if (m_aChangeIdle.IsActive())
1983
1984 EventObject aEvent( *this );
1987
1989 {
1990 ::osl::MutexGuard aGuard( m_aMutex );
1991 if ( m_pItemBroadcaster.is() )
1992 {
1994 m_pItemBroadcaster->removeEventsForProcessor( this );
1995 m_pItemBroadcaster->terminate();
1996 m_pItemBroadcaster = nullptr;
1997 }
1998 }
1999 if (t.is()) {
2000 t->join();
2001 }
2002
2004 }
2005
2006
2008 {
2009 Reference< XListBox > xKeepAlive( this );
2010 {
2011 ::osl::MutexGuard aGuard( m_aMutex );
2012 if ( OComponentHelper::rBHelper.bDisposed )
2013 return;
2014 }
2015 const ItemEventDescription& rItemEvent = static_cast< const ItemEventDescription& >( _rEvent );
2016 m_aItemListeners.notifyEach( &XItemListener::itemStateChanged, rItemEvent.getEventObject() );
2017 }
2018
2019
2021 {
2022 m_aChangeListeners.notifyEach( &XChangeListener::changed, EventObject( *this ) );
2023 }
2024
2025
2026 void SAL_CALL OListBoxControl::addItemListener( const Reference< XItemListener >& l )
2027 {
2029 }
2030
2031
2032 void SAL_CALL OListBoxControl::removeItemListener( const Reference< XItemListener >& l )
2033 {
2035 }
2036
2037
2038 void SAL_CALL OListBoxControl::addActionListener( const Reference< XActionListener >& l )
2039 {
2040 if ( m_xAggregateListBox.is() )
2041 m_xAggregateListBox->addActionListener( l );
2042 }
2043
2044
2045 void SAL_CALL OListBoxControl::removeActionListener( const Reference< XActionListener >& l )
2046 {
2047 if ( m_xAggregateListBox.is() )
2048 m_xAggregateListBox->removeActionListener( l );
2049 }
2050
2051
2052 void SAL_CALL OListBoxControl::addItem( const OUString& aItem, ::sal_Int16 nPos )
2053 {
2054 if ( m_xAggregateListBox.is() )
2055 m_xAggregateListBox->addItem( aItem, nPos );
2056 }
2057
2058
2059 void SAL_CALL OListBoxControl::addItems( const Sequence< OUString >& aItems, ::sal_Int16 nPos )
2060 {
2061 if ( m_xAggregateListBox.is() )
2062 m_xAggregateListBox->addItems( aItems, nPos );
2063 }
2064
2065
2066 void SAL_CALL OListBoxControl::removeItems( ::sal_Int16 nPos, ::sal_Int16 nCount )
2067 {
2068 if ( m_xAggregateListBox.is() )
2069 m_xAggregateListBox->removeItems( nPos, nCount );
2070 }
2071
2072
2073 ::sal_Int16 SAL_CALL OListBoxControl::getItemCount( )
2074 {
2075 if ( m_xAggregateListBox.is() )
2076 return m_xAggregateListBox->getItemCount();
2077 return 0;
2078 }
2079
2080
2081 OUString SAL_CALL OListBoxControl::getItem( ::sal_Int16 nPos )
2082 {
2083 if ( m_xAggregateListBox.is() )
2084 return m_xAggregateListBox->getItem( nPos );
2085 return OUString( );
2086 }
2087
2088
2089 Sequence< OUString > SAL_CALL OListBoxControl::getItems( )
2090 {
2091 if ( m_xAggregateListBox.is() )
2092 return m_xAggregateListBox->getItems();
2093 return Sequence< OUString >( );
2094 }
2095
2096
2098 {
2099 if ( m_xAggregateListBox.is() )
2100 return m_xAggregateListBox->getSelectedItemPos();
2101 return 0;
2102 }
2103
2104
2105 Sequence< ::sal_Int16 > SAL_CALL OListBoxControl::getSelectedItemsPos( )
2106 {
2107 if ( m_xAggregateListBox.is() )
2108 return m_xAggregateListBox->getSelectedItemsPos();
2109 return Sequence< ::sal_Int16 >( );
2110 }
2111
2112
2114 {
2115 if ( m_xAggregateListBox.is() )
2116 return m_xAggregateListBox->getSelectedItem();
2117 return OUString( );
2118 }
2119
2120
2121 Sequence< OUString > SAL_CALL OListBoxControl::getSelectedItems( )
2122 {
2123 if ( m_xAggregateListBox.is() )
2124 return m_xAggregateListBox->getSelectedItems();
2125 return Sequence< OUString >( );
2126 }
2127
2128
2129 void SAL_CALL OListBoxControl::selectItemPos( ::sal_Int16 nPos, sal_Bool bSelect )
2130 {
2131 if ( m_xAggregateListBox.is() )
2132 m_xAggregateListBox->selectItemPos( nPos, bSelect );
2133 }
2134
2135
2136 void SAL_CALL OListBoxControl::selectItemsPos( const Sequence< ::sal_Int16 >& aPositions, sal_Bool bSelect )
2137 {
2138 if ( m_xAggregateListBox.is() )
2139 m_xAggregateListBox->selectItemsPos( aPositions, bSelect );
2140 }
2141
2142
2143 void SAL_CALL OListBoxControl::selectItem( const OUString& aItem, sal_Bool bSelect )
2144 {
2145 if ( m_xAggregateListBox.is() )
2146 m_xAggregateListBox->selectItem( aItem, bSelect );
2147 }
2148
2149
2151 {
2152 if ( m_xAggregateListBox.is() )
2153 return m_xAggregateListBox->isMutipleMode();
2154 return false;
2155 }
2156
2157
2159 {
2160 if ( m_xAggregateListBox.is() )
2161 m_xAggregateListBox->setMultipleMode( bMulti );
2162 }
2163
2164
2166 {
2167 if ( m_xAggregateListBox.is() )
2168 return m_xAggregateListBox->getDropDownLineCount();
2169 return 0;
2170 }
2171
2172
2173 void SAL_CALL OListBoxControl::setDropDownLineCount( ::sal_Int16 nLines )
2174 {
2175 if ( m_xAggregateListBox.is() )
2176 m_xAggregateListBox->setDropDownLineCount( nLines );
2177 }
2178
2179
2180 void SAL_CALL OListBoxControl::makeVisible( ::sal_Int16 nEntry )
2181 {
2182 if ( m_xAggregateListBox.is() )
2183 m_xAggregateListBox->makeVisible( nEntry );
2184 }
2185
2186}
2187
2188extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
2189com_sun_star_form_OListBoxModel_get_implementation(css::uno::XComponentContext* component,
2190 css::uno::Sequence<css::uno::Any> const &)
2191{
2192 return cppu::acquire(new frm::OListBoxModel(component));
2193}
2194
2195extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
2196com_sun_star_form_OListBoxControl_get_implementation(css::uno::XComponentContext* component,
2197 css::uno::Sequence<css::uno::Any> const &)
2198{
2199 return cppu::acquire(new frm::OListBoxControl(component));
2200}
2201
2202/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sSchema
OptionalString sCatalog
const std::vector< OUString > & m_rList
Definition: ListBox.cxx:1463
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_form_OListBoxModel_get_implementation(css::uno::XComponentContext *component, css::uno::Sequence< css::uno::Any > const &)
Definition: ListBox.cxx:2189
OUString & m_string
Definition: ListBox.cxx:106
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_form_OListBoxControl_get_implementation(css::uno::XComponentContext *component, css::uno::Sequence< css::uno::Any > const &)
Definition: ListBox.cxx:2196
XPropertyListType t
AnyEventRef aEvent
virtual void Start(bool bStartTimer=true) override
bool IsActive() const
void SetPriority(TaskPriority ePriority)
void Stop()
void SetInvokeHandler(const Link< Timer *, void > &rLink)
const EventObjectType & getEventObject() const
virtual void SAL_CALL acquire() noexcept=0
sal_Int32 addInterface(const css::uno::Reference< ListenerT > &rxIFace)
void disposeAndClear(const css::lang::EventObject &rEvt)
sal_Int32 removeInterface(const css::uno::Reference< ListenerT > &rxIFace)
void notifyEach(void(SAL_CALL ListenerT::*NotificationMethod)(const EventT &), const EventT &Event)
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(css::uno::Type const &rType) SAL_OVERRIDE
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() SAL_OVERRIDE
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
virtual void SAL_CALL dispose() SAL_OVERRIDE
oslInterlockedCount m_refCount
css::uno::Type const & get()
OUString getFormattedValue() const
void setCommand(const OUString &_rCommand)
void setCommandFromQuery(const OUString &_rQueryName)
sets the command of a query as command to be executed
css::uno::Reference< css::sdbc::XResultSet > execute()
executes the statement
void dispose()
disposes the instance and frees all associated resources
bool isDirty() const
determines whether the row set properties are dirty, i.e. have changed since the last call to execute
void setConnection(const css::uno::Reference< css::sdbc::XConnection > &_rxConnection)
void setEscapeProcessing(const bool _bEscapeProcessing)
class whose instances lock an OControlModel
void writeCommonProperties(const css::uno::Reference< css::io::XObjectOutputStream > &_rxOutStream)
We can't write (new) common properties in this base class, as the file format doesn't allow this (unf...
sal_Int32 getValuePropertyAggHandle() const
sal_Int32 getFieldType() const
bool hasExternalValueBinding() const
checks whether we currently have an external value binding in place
const css::uno::Type & getExternalValueType() const
returns the type which should be used to exchange data with our external value binding
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
virtual css::uno::Reference< css::form::validation::XValidator > SAL_CALL getValidator() override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void setControlValue(const css::uno::Any &_rValue, ValueChangeInstigator _eInstigator)
sets the given value as new current value for the control
void initFromField(const css::uno::Reference< css::sdbc::XRowSet > &_rxForm)
initializes the control from m_xField
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
virtual void SAL_CALL disposing() override
void initValueProperty(const OUString &_rValuePropertyName, sal_Int32 _nValuePropertyExternalHandle)
initializes the part of the class which is related to the control value.
css::uno::Reference< css::sdb::XColumn > m_xColumn
virtual void describeFixedProperties(css::uno::Sequence< css::beans::Property > &_rProps) const override
describes the properties provided by this class, or its respective derived class
virtual void resetNoBroadcast()
called to reset the control to some kind of default.
const OUString & getControlSource() const
virtual css::uno::Sequence< css::uno::Type > _getTypes() override
virtual void SAL_CALL write(const css::uno::Reference< css::io::XObjectOutputStream > &OutStream) override
virtual void SAL_CALL getFastPropertyValue(css::uno::Any &rValue, sal_Int32 nHandle) const override
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &_rConvertedValue, css::uno::Any &_rOldValue, sal_Int32 _nHandle, const css::uno::Any &_rValue) override
virtual void SAL_CALL read(const css::uno::Reference< css::io::XObjectInputStream > &InStream) override
void readCommonProperties(const css::uno::Reference< css::io::XObjectInputStream > &_rxInStream)
void resumeValueListening()
resumes listening at the value property
css::uno::Reference< css::sdbc::XRowSet > m_xCursor
void transferExternalValueToControl(ControlModelLock &_rInstanceLock)
transfers the current value of the active external binding to the control @precond we do have an acti...
void suspendValueListening()
suspends listening at the value property
const css::uno::Reference< css::beans::XPropertySet > & getField() const
css::uno::Reference< css::sdb::XColumnUpdate > m_xColumnUpdate
void startAggregatePropertyListening(const OUString &_rPropertyName)
starts listening at the aggregate, for changes in the given property
virtual css::uno::Reference< css::form::binding::XValueBinding > SAL_CALL getValueBinding() override
virtual css::uno::Any getControlValue() const
retrieves the current value of the control
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &_rEvt) override
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
virtual void SAL_CALL disposing() override
virtual css::uno::Sequence< css::uno::Type > _getTypes() override
const css::uno::Reference< css::uno::XComponentContext > & getContext() const
virtual void describeAggregateProperties(css::uno::Sequence< css::beans::Property > &_rAggregateProps) const
describes the properties of our aggregate
void writeHelpTextCompatibly(const css::uno::Reference< css::io::XObjectOutputStream > &_rxOutStream)
virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< css::beans::PropertyValue > &aProps) override
void readHelpTextCompatibly(const css::uno::Reference< css::io::XObjectInputStream > &_rxInStream)
css::uno::Reference< css::uno::XAggregation > m_xAggregate
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void doSetDelegator()
sets the control as delegator at the aggregate
void doResetDelegator()
virtual css::uno::Reference< css::awt::XControlModel > SAL_CALL getModel() override
::osl::Mutex m_aMutex
virtual void SAL_CALL dispose() override
bool convertNewListSourceProperty(css::uno::Any &_rConvertedValue, css::uno::Any &_rOldValue, const css::uno::Any &_rValue)
helper for implementing convertFastPropertyValue( StringItemList )
void setNewStringItemList(const css::uno::Any &_rValue, ControlModelLock &_rInstanceLock)
helper for implementing setFastPropertyValueNoBroadcast
void disposing()
to be called by derived classes' instances when they're being disposed
void setNewTypedItemList(const css::uno::Any &_rValue, ControlModelLock &_rInstanceLock)
helper for implementing setFastPropertyValueNoBroadcast
const css::uno::Sequence< css::uno::Any > & getTypedItemList() const
returns the current typed item list
bool handleDisposing(const css::lang::EventObject &_rEvent)
handling the XEventListener::disposing call for the case where our list source is being disposed
bool hasExternalListSource() const
determines whether we actually have an external list source
const std::vector< OUString > & getStringItemList() const
returns the current string item list
void onError(const css::sdbc::SQLException &_rException, const OUString &_rContextDescription)
virtual OUString SAL_CALL getSelectedItem() override
Definition: ListBox.cxx:2113
virtual void SAL_CALL setMultipleMode(sal_Bool bMulti) override
Definition: ListBox.cxx:2158
virtual void SAL_CALL addItems(const css::uno::Sequence< OUString > &aItems, ::sal_Int16 nPos) override
Definition: ListBox.cxx:2059
virtual void SAL_CALL disposing() override
Definition: ListBox.cxx:1979
virtual void SAL_CALL focusLost(const css::awt::FocusEvent &_rEvent) override
Definition: ListBox.cxx:1882
virtual css::uno::Sequence< OUString > SAL_CALL getItems() override
Definition: ListBox.cxx:2089
virtual void SAL_CALL addActionListener(const css::uno::Reference< css::awt::XActionListener > &l) override
Definition: ListBox.cxx:2038
css::uno::Reference< css::awt::XListBox > m_xAggregateListBox
Definition: ListBox.hxx:256
virtual void SAL_CALL focusGained(const css::awt::FocusEvent &_rEvent) override
Definition: ListBox.cxx:1867
virtual void SAL_CALL makeVisible(::sal_Int16 nEntry) override
Definition: ListBox.cxx:2180
virtual ~OListBoxControl() override
Definition: ListBox.cxx:1839
virtual void SAL_CALL selectItemPos(::sal_Int16 nPos, sal_Bool bSelect) override
Definition: ListBox.cxx:2129
virtual css::uno::Sequence< ::sal_Int16 > SAL_CALL getSelectedItemsPos() override
Definition: ListBox.cxx:2105
virtual void SAL_CALL itemStateChanged(const css::awt::ItemEvent &_rEvent) override
Definition: ListBox.cxx:1889
::comphelper::OInterfaceContainerHelper3< css::form::XChangeListener > m_aChangeListeners
Definition: ListBox.hxx:249
virtual void SAL_CALL removeItems(::sal_Int16 nPos, ::sal_Int16 nCount) override
Definition: ListBox.cxx:2066
virtual ::sal_Int16 SAL_CALL getDropDownLineCount() override
Definition: ListBox.cxx:2165
virtual void SAL_CALL setDropDownLineCount(::sal_Int16 nLines) override
Definition: ListBox.cxx:2173
::rtl::Reference< ::comphelper::AsyncEventNotifier > m_pItemBroadcaster
Definition: ListBox.hxx:259
virtual void SAL_CALL addChangeListener(const css::uno::Reference< css::form::XChangeListener > &_rxListener) override
Definition: ListBox.cxx:1966
virtual OUString SAL_CALL getItem(::sal_Int16 nPos) override
Definition: ListBox.cxx:2081
OListBoxControl(const css::uno::Reference< css::uno::XComponentContext > &_rxFactory)
Definition: ListBox.cxx:1811
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: ListBox.cxx:1853
virtual void processEvent(const ::comphelper::AnyEvent &_rEvent) override
Definition: ListBox.cxx:2007
virtual sal_Bool SAL_CALL isMutipleMode() override
Definition: ListBox.cxx:2150
virtual void SAL_CALL selectItem(const OUString &aItem, sal_Bool bSelect) override
Definition: ListBox.cxx:2143
virtual void SAL_CALL addItemListener(const css::uno::Reference< css::awt::XItemListener > &l) override
Definition: ListBox.cxx:2026
css::uno::Any m_aCurrentSelection
Definition: ListBox.hxx:252
virtual ::sal_Int16 SAL_CALL getItemCount() override
Definition: ListBox.cxx:2073
virtual void SAL_CALL selectItemsPos(const css::uno::Sequence< ::sal_Int16 > &aPositions, sal_Bool bSelect) override
Definition: ListBox.cxx:2136
virtual void SAL_CALL removeActionListener(const css::uno::Reference< css::awt::XActionListener > &l) override
Definition: ListBox.cxx:2045
virtual css::uno::Sequence< css::uno::Type > _getTypes() override
Definition: ListBox.cxx:1789
virtual void SAL_CALL addItem(const OUString &aItem, ::sal_Int16 nPos) override
Definition: ListBox.cxx:2052
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
Definition: ListBox.cxx:1798
virtual css::uno::Sequence< OUString > SAL_CALL getSelectedItems() override
Definition: ListBox.cxx:2121
virtual ::sal_Int16 SAL_CALL getSelectedItemPos() override
Definition: ListBox.cxx:2097
virtual void SAL_CALL removeItemListener(const css::uno::Reference< css::awt::XItemListener > &l) override
Definition: ListBox.cxx:2032
virtual void SAL_CALL removeChangeListener(const css::uno::Reference< css::form::XChangeListener > &_rxListener) override
Definition: ListBox.cxx:1972
::comphelper::OInterfaceContainerHelper3< css::awt::XItemListener > m_aItemListeners
Definition: ListBox.hxx:250
virtual void resetNoBroadcast() override
called to reset the control to some kind of default.
Definition: ListBox.cxx:1297
virtual bool commitControlValueToDbColumn(bool _bPostReset) override
commits the current control value to the database column we're bound to @precond we're properly bound...
Definition: ListBox.cxx:1160
virtual css::uno::Any translateControlValueToExternalValue() const override
commits the current control value to our external value binding
Definition: ListBox.cxx:1579
ValueList m_aListSourceValues
Definition: ListBox.hxx:109
virtual ~OListBoxModel() override
Definition: ListBox.cxx:185
virtual void _propertyChanged(const css::beans::PropertyChangeEvent &_rEvt) override
Definition: ListBox.cxx:518
CachedRowSet m_aListRowSet
Definition: ListBox.hxx:103
static const ::connectivity::ORowSetValue s_aEmptyStringValue
Definition: ListBox.hxx:155
virtual void onDisconnectedDbColumn() override
called whenever a connection to a database column has been suspended
Definition: ListBox.cxx:1037
virtual void SAL_CALL getFastPropertyValue(css::uno::Any &rValue, sal_Int32 nHandle) const override
Definition: ListBox.cxx:251
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &_rConvertedValue, css::uno::Any &_rOldValue, sal_Int32 _nHandle, const css::uno::Any &_rValue) override
Definition: ListBox.cxx:402
ValueList impl_getValues() const
Definition: ListBox.cxx:1103
css::form::ListSourceType m_eListSourceType
Definition: ListBox.hxx:107
void setBoundValues(ValueList &&)
Definition: ListBox.cxx:1053
::connectivity::ORowSetValue m_aSaveValue
Definition: ListBox.hxx:104
virtual void onConnectedDbColumn(const css::uno::Reference< css::uno::XInterface > &_rxForm) override
called whenever a connection to a database column has been established
Definition: ListBox.cxx:1023
sal_Int32 m_nConvertedBoundValuesType
Definition: ListBox.hxx:112
virtual OUString SAL_CALL getServiceName() override
Definition: ListBox.cxx:554
virtual css::uno::Reference< css::util::XCloneable > SAL_CALL createClone() override
Definition: ListBox.cxx:197
css::uno::Any getCurrentSingleValue() const
Definition: ListBox.cxx:1650
::connectivity::ORowSetValue getFirstSelectedValue() const
Definition: ListBox.cxx:1131
ValueList m_aBoundValues
Definition: ListBox.hxx:110
virtual css::uno::Any getCurrentFormComponentValue() const override
retrieves the current value of the form component
Definition: ListBox.cxx:1686
css::uno::Sequence< css::uno::Any > getCurrentMultiValue() const
Definition: ListBox.cxx:1668
void clearBoundValues()
Definition: ListBox.cxx:1060
virtual css::uno::Any translateExternalValueToControlValue(const css::uno::Any &_rExternalValue) const override
translates the given value, which was obtained from the current external value binding,...
Definition: ListBox.cxx:1360
virtual void SAL_CALL disposing() override
Definition: ListBox.cxx:243
ValueList m_aConvertedBoundValues
Definition: ListBox.hxx:111
virtual void refreshInternalEntryList() override
called when XRefreshable::refresh has been called, and we do not have an external list source
Definition: ListBox.cxx:1779
static const ::connectivity::ORowSetValue s_aEmptyValue
Definition: ListBox.hxx:154
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue) override
Definition: ListBox.cxx:297
virtual css::uno::Sequence< css::uno::Type > getSupportedBindingTypes() override
returns the data types which the control could use to exchange data with an external value binding
Definition: ListBox.cxx:1716
virtual css::uno::Any translateDbColumnToControlValue() override
translates a db column value into a control value.
Definition: ListBox.cxx:1254
virtual css::uno::Any getDefaultForReset() const override
returns the default which should be used when resetting the control
Definition: ListBox.cxx:1277
css::uno::Any m_aBoundColumn
Definition: ListBox.hxx:108
sal_Int32 getValueType() const
Definition: ListBox.cxx:1096
sal_Int16 m_nNULLPos
Definition: ListBox.hxx:116
css::uno::Sequence< sal_Int16 > m_aDefaultSelectSeq
Definition: ListBox.hxx:113
void impl_refreshDbEntryList(bool _bForce)
refreshes the list boxes list data @precond we don't actually have an external list source
Definition: ListBox.cxx:1765
sal_Int32 m_nBoundColumnType
Definition: ListBox.hxx:117
void convertBoundValues(sal_Int32 nType) const
Definition: ListBox.cxx:1067
virtual void describeFixedProperties(css::uno::Sequence< css::beans::Property > &_rProps) const override
describes the properties provided by this class, or its respective derived class
Definition: ListBox.cxx:498
virtual void stringItemListChanged(ControlModelLock &_rInstanceLock) override
announces that the list of entries has changed.
Definition: ListBox.cxx:1730
void loadData(bool _bForce)
Definition: ListBox.cxx:711
virtual void SAL_CALL setPropertyValues(const css::uno::Sequence< OUString > &PropertyNames, const css::uno::Sequence< css::uno::Any > &Values) override
Definition: ListBox.cxx:461
virtual css::uno::Any translateControlValueToValidatableValue() const override
retrieves the current value of the control, in a shape which can be used with our external validator.
Definition: ListBox.cxx:1643
virtual void SAL_CALL read(const css::uno::Reference< css::io::XObjectInputStream > &_rxInStream) override
Definition: ListBox.cxx:596
virtual css::uno::Any SAL_CALL queryAggregation(const css::uno::Type &_rType) override
Definition: ListBox.cxx:231
virtual css::uno::Sequence< css::uno::Type > _getTypes() override
Definition: ListBox.cxx:131
virtual void SAL_CALL write(const css::uno::Reference< css::io::XObjectOutputStream > &_rxOutStream) override
Definition: ListBox.cxx:560
OListBoxModel(const css::uno::Reference< css::uno::XComponentContext > &_rxFactory)
css::uno::Sequence< sal_Int16 > translateBindingValuesToControlValue(const css::uno::Sequence< const css::uno::Any > &i_aValues) const
Definition: ListBox.cxx:1213
css::uno::Sequence< sal_Int16 > translateDbValueToControlValue(const ::connectivity::ORowSetValue &aValue) const
Definition: ListBox.cxx:1185
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: ListBox.cxx:206
virtual void describeAggregateProperties(css::uno::Sequence< css::beans::Property > &_rAggregateProps) const override
describes the properties of our aggregate
Definition: ListBox.cxx:544
a helper class which merges sequences of <type scope="css::uno">Type</type>s, so that the resulting s...
TypeSequence getTypes() const
returns the types represented by this bag
void reset(const css::uno::Reference< INTERFACE > &_rxComponent, AssignmentMode _eMode=TakeOwnership)
Any value
int nCount
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
float v
sal_Int16 nVersion
sal_Int16 nValue
constexpr OUStringLiteral PROPERTY_SELECT_VALUE
Definition: frm_strings.hxx:81
constexpr OUStringLiteral PROPERTY_TABINDEX
Definition: frm_strings.hxx:26
constexpr OUStringLiteral PROPERTY_NAME
Definition: frm_strings.hxx:28
constexpr OUStringLiteral PROPERTY_SELECT_SEQ
Definition: frm_strings.hxx:78
constexpr OUStringLiteral PROPERTY_SELECT_VALUE_SEQ
Definition: frm_strings.hxx:80
constexpr OUStringLiteral PROPERTY_LISTSOURCETYPE
Definition: frm_strings.hxx:76
constexpr OUStringLiteral PROPERTY_TYPEDITEMLIST
Definition: frm_strings.hxx:63
constexpr OUStringLiteral PROPERTY_VALUE_SEQ
Definition: frm_strings.hxx:79
constexpr OUStringLiteral PROPERTY_BOUNDCOLUMN
constexpr OUStringLiteral PROPERTY_STRINGITEMLIST
Definition: frm_strings.hxx:62
constexpr OUStringLiteral PROPERTY_LISTSOURCE
Definition: frm_strings.hxx:77
constexpr OUStringLiteral PROPERTY_FIELDSOURCE
constexpr OUStringLiteral PROPERTY_MULTISELECTION
Definition: frm_strings.hxx:83
constexpr OUStringLiteral PROPERTY_ACTIVE_CONNECTION
constexpr OUStringLiteral PROPERTY_DEFAULT_SELECT_SEQ
Definition: frm_strings.hxx:82
std::mutex m_aMutex
const sal_uInt16 idx[]
sal_Int32 nIndex
sal_uInt16 nPos
Sequence< sal_Int8 > aSeq
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
size
@ Exception
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
bool hasProperty(const OUString &_rName, const Reference< XPropertySet > &_rxSet)
bool query_aggregation(const css::uno::Reference< css::uno::XAggregation > &_rxAggregate, css::uno::Reference< iface > &_rxOut)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
bool tryPropertyValue(Any &_rConvertedValue, Any &_rOldValue, const Any &_rValueToSet, const Any &_rCurrentValue, const Type &_rExpectedType)
std::enable_if< std::is_enum< ENUMTYPE >::value, bool >::type tryPropertyValueEnum(css::uno::Any &_rConvertedValue, css::uno::Any &_rOldValue, const css::uno::Any &_rValueToSet, const ENUMTYPE &_rCurrentValue)
void RemoveProperty(Sequence< Property > &_rProps, const OUString &_rPropName)
Type
void qualifiedNameComponents(const Reference< XDatabaseMetaData > &_rxConnMetaData, const OUString &_rQualifiedName, OUString &_rCatalog, OUString &_rSchema, OUString &_rName, EComposeRule _eComposeRule)
OUString composeTableNameForSelect(const Reference< XConnection > &_rxConnection, const OUString &_rCatalog, const OUString &_rSchema, const OUString &_rName)
OUString quoteName(std::u16string_view _rQuote, const OUString &_rName)
Reference< XNameAccess > getTableFields(const Reference< XConnection > &_rxConn, const OUString &_rName)
OUString loadString(TranslateId aResId)
loads the string with the specified resource id from the FormLayer mo file
ListBox is a bit confusing / different from other form components, so here are a few notes:
Definition: BaseListBox.hxx:25
::std::vector< ::connectivity::ORowSetValue > ValueList
Definition: ListBox.hxx:96
const sal_uInt16 BOUNDCOLUMN
Definition: BaseListBox.hxx:27
IMPL_LINK_NOARG(OButtonControl, OnClick, void *, void)
Definition: Button.cxx:440
::comphelper::EventHolder< ItemEvent > ItemEventDescription
Definition: ListBox.cxx:126
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
VBAHELPER_DLLPUBLIC bool setPropertyValue(css::uno::Sequence< css::beans::PropertyValue > &aProp, const OUString &aName, const css::uno::Any &aValue)
DataType
bool getPropertyValue(ValueType &rValue, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, OUString const &propName)
void copy(const css::uno::Reference< css::beans::XPropertySet > &, css::uno::Reference< css::beans::XPropertySet > const &)
copy the properties from one PropertySet into the next
#define PROPERTY_ID_DEFAULT_SELECT_SEQ
Definition: property.hxx:127
#define PROPERTY_ID_TYPEDITEMLIST
Definition: property.hxx:304
#define PROPERTY_ID_SELECT_SEQ
Definition: property.hxx:126
#define PROPERTY_ID_STRINGITEMLIST
Definition: property.hxx:84
#define PROPERTY_ID_BOUNDCOLUMN
Definition: property.hxx:79
#define PROPERTY_ID_SELECT_VALUE
Definition: property.hxx:115
#define PROPERTY_ID_LISTSOURCETYPE
Definition: property.hxx:80
#define PROPERTY_ID_VALUE_SEQ
Definition: property.hxx:113
#define PROPERTY_ID_MULTISELECTION
Definition: property.hxx:128
#define PROPERTY_ID_SELECT_VALUE_SEQ
Definition: property.hxx:116
#define PROPERTY_ID_LISTSOURCE
Definition: property.hxx:81
#define PROPERTY_ID_TABINDEX
Definition: property.hxx:41
constexpr OUStringLiteral VALIDATABLE_BINDABLE_CONTROL_MODEL
Definition: services.hxx:184
constexpr OUStringLiteral VCL_CONTROLMODEL_LISTBOX
Definition: services.hxx:40
constexpr OUStringLiteral STARDIV_ONE_FORM_CONTROL_LISTBOX
Definition: services.hxx:93
constexpr OUStringLiteral BINDABLE_DATA_AWARE_CONTROL_MODEL
Definition: services.hxx:181
constexpr OUStringLiteral FRM_SUN_CONTROL_LISTBOX
Definition: services.hxx:151
constexpr OUStringLiteral DATA_AWARE_CONTROL_MODEL
Definition: services.hxx:182
constexpr OUStringLiteral FRM_SUN_COMPONENT_DATABASE_LISTBOX
Definition: services.hxx:140
constexpr OUStringLiteral VALIDATABLE_CONTROL_MODEL
Definition: services.hxx:183
constexpr OUStringLiteral FRM_SUN_COMPONENT_LISTBOX
Definition: services.hxx:114
constexpr OUStringLiteral BINDABLE_DATABASE_LIST_BOX
Definition: services.hxx:172
constexpr OUStringLiteral BINDABLE_CONTROL_MODEL
Definition: services.hxx:179
constexpr OUStringLiteral FRM_COMPONENT_LISTBOX
Definition: services.hxx:67
constexpr OUStringLiteral VCL_CONTROL_LISTBOX
Definition: services.hxx:24
unsigned char sal_Bool