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

Generated by: LCOV version 1.10