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