LCOV - code coverage report
Current view: top level - forms/source/component - ListBox.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 436 947 46.0 %
Date: 2015-06-13 12:38:46 Functions: 58 103 56.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11