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

Generated by: LCOV version 1.10