LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/forms/source/component - ListBox.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 419 938 44.7 %
Date: 2013-07-09 Functions: 57 103 55.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10