1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef _FORMS_LISTBOX_HXX_
21 #define _FORMS_LISTBOX_HXX_
23 #include "FormComponent.hxx"
24 #include "cachedrowset.hxx"
25 #include "errorbroadcaster.hxx"
26 #include "entrylisthelper.hxx"
28 #include <com/sun/star/util/XNumberFormatter.hpp>
29 #include <com/sun/star/sdb/XSQLErrorBroadcaster.hpp>
30 #include <com/sun/star/form/ListSourceType.hpp>
31 #include <com/sun/star/awt/XItemListener.hpp>
32 #include <com/sun/star/awt/XFocusListener.hpp>
33 #include <com/sun/star/awt/XListBox.hpp>
34 #include <com/sun/star/form/XChangeBroadcaster.hpp>
35 #include <com/sun/star/sdbc/DataType.hpp>
37 #include <comphelper/asyncnotification.hxx>
38 #include <connectivity/FValue.hxx>
39 #include <cppuhelper/interfacecontainer.hxx>
40 #include <cppuhelper/implbase1.hxx>
41 #include <vcl/timer.hxx>
45 /** ListBox is a bit confusing / different from other form components,
46 so here are a few notes:
48 The general design philosophy is that a ListBox is a mechanism
49 to translate back and forth between:
50 1) *display* values (strings that the user sees and chooses)
51 2) *binding* values, which is what the program (for a dialog),
52 the database, ... cares about.
54 A non-data aware ListBox exposes this mechanism through
55 com.sun.star.awt.XItemList (get|set)ItemData.
57 In a data-aware ListBox, this is naturally embodied by the
58 StringItemList on the one hand, and the ValueList on the other
59 hand (where, depending on ListSourceType, the ValueList is
60 possibly automatically filled from the BoundColumn of the
63 This source file implements data-aware ListBox, and the rest
64 of this comment applies to data-aware ListBox (only).
66 In all public APIs of the *model* (OListBoxModel),
67 the value of the control is the *binding* value.
68 That is what the bound database field gets,
69 that is what a validator validates,
70 that is what an external value binding
71 (com.sun.star.form.binding.XValueBinding)
72 exchanges with the control.
74 As an *implementation* choice, we keep the current value of the
75 ListBox as a sequence of *indices* in the value list, and do the
78 - ListBox's content propery (or value property, sorry the
79 terminology is not always consistent) is SelectedItems which is
80 a sequence of *indices* in the value list.
82 - That is used to synchronise with our peer (UnoControlListBoxModel).
84 In particular, note that getCurrentValue() is a public API (and
85 deals with bound values), but getControlValue and
86 (do)setControlValue are *internal* implementation helpers that
89 Note that the *view* (OListBoxControl) presents a different story
90 than the model. E.g. the "SelectedItems" property is *display* *values*.
93 //.........................................................................
97 //==================================================================
99 //==================================================================
100 typedef ::std::vector
< ::connectivity::ORowSetValue
> ValueList
;
102 class OListBoxModel
:public OBoundControlModel
103 ,public OEntryListHelper
104 ,public OErrorBroadcaster
107 CachedRowSet m_aListRowSet
; // the row set to fill the list
108 ::connectivity::ORowSetValue m_aSaveValue
;
111 ::com::sun::star::form::ListSourceType m_eListSourceType
; // type der list source
112 ::com::sun::star::uno::Any m_aBoundColumn
;
113 ValueList m_aListSourceValues
;
114 ValueList m_aBoundValues
; // do not write directly; use setBoundValues()
115 mutable ValueList m_aConvertedBoundValues
;
116 mutable sal_Int32 m_nConvertedBoundValuesType
;
117 ::com::sun::star::uno::Sequence
<sal_Int16
> m_aDefaultSelectSeq
; // DefaultSelected
120 sal_Int16 m_nNULLPos
; // position of the NULL value in our list
121 sal_Int32 m_nBoundColumnType
;
124 ::connectivity::ORowSetValue
getFirstSelectedValue() const;
126 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
> _getTypes();
129 DECLARE_DEFAULT_LEAF_XTOR( OListBoxModel
);
132 IMPLEMENTATION_NAME(OListBoxModel
);
133 virtual StringSequence SAL_CALL
getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException
);
136 DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel
, OBoundControlModel
);
137 virtual ::com::sun::star::uno::Any SAL_CALL
queryAggregation( const ::com::sun::star::uno::Type
& _rType
) throw (::com::sun::star::uno::RuntimeException
);
140 virtual void SAL_CALL
disposing();
142 // OPropertySetHelper
143 virtual void SAL_CALL
getFastPropertyValue(::com::sun::star::uno::Any
& rValue
, sal_Int32 nHandle
) const;
144 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const ::com::sun::star::uno::Any
& rValue
)
145 throw (::com::sun::star::uno::Exception
);
146 virtual sal_Bool SAL_CALL
convertFastPropertyValue(
147 ::com::sun::star::uno::Any
& _rConvertedValue
, ::com::sun::star::uno::Any
& _rOldValue
, sal_Int32 _nHandle
, const ::com::sun::star::uno::Any
& _rValue
)
148 throw (::com::sun::star::lang::IllegalArgumentException
);
152 virtual void SAL_CALL
setPropertyValues(const ::com::sun::star::uno::Sequence
< OUString
>& PropertyNames
, const ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Any
>& Values
) throw(::com::sun::star::beans::PropertyVetoException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
);
155 virtual OUString SAL_CALL
getServiceName() throw(::com::sun::star::uno::RuntimeException
);
156 virtual void SAL_CALL
157 write(const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectOutputStream
>& _rxOutStream
) throw(::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
);
158 virtual void SAL_CALL
159 read(const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectInputStream
>& _rxInStream
) throw(::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
);
161 // OControlModel's property handling
162 virtual void describeFixedProperties(
163 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::Property
>& /* [out] */ _rProps
165 virtual void describeAggregateProperties(
166 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::Property
>& /* [out] */ _rAggregateProps
170 virtual void SAL_CALL
disposing(const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
172 // OPropertyChangeListener
173 virtual void _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent
& _rEvt
) throw ( ::com::sun::star::uno::RuntimeException
);
175 // prevent method hiding
176 using OBoundControlModel::getFastPropertyValue
;
177 using OBoundControlModel::setPropertyValues
;
180 // OBoundControlModel overridables
181 virtual ::com::sun::star::uno::Any
182 translateDbColumnToControlValue( );
183 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
>
184 getSupportedBindingTypes();
185 virtual ::com::sun::star::uno::Any
186 translateExternalValueToControlValue( const ::com::sun::star::uno::Any
& _rExternalValue
) const;
187 virtual ::com::sun::star::uno::Any
188 translateControlValueToExternalValue( ) const;
189 virtual ::com::sun::star::uno::Any
190 translateControlValueToValidatableValue( ) const;
191 virtual sal_Bool
commitControlValueToDbColumn( bool _bPostReset
);
193 virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _rxForm
);
194 virtual void onDisconnectedDbColumn();
196 virtual ::com::sun::star::uno::Any
197 getDefaultForReset() const;
198 virtual void resetNoBroadcast();
200 virtual ::com::sun::star::uno::Any
201 getCurrentFormComponentValue() const;
203 // OEntryListHelper overridables
204 virtual void stringItemListChanged( ControlModelLock
& _rInstanceLock
);
205 virtual void connectedExternalListSource( );
206 virtual void disconnectedExternalListSource( );
207 virtual void refreshInternalEntryList();
210 DECLARE_XCLONEABLE();
213 ::com::sun::star::uno::Any
getCurrentSingleValue() const;
214 ::com::sun::star::uno::Any
getCurrentMultiValue() const;
215 ::com::sun::star::uno::Sequence
< sal_Int16
> translateBindingValuesToControlValue(
216 const ::com::sun::star::uno::Sequence
< const ::com::sun::star::uno::Any
> &i_aValues
)
218 ::com::sun::star::uno::Sequence
< sal_Int16
> translateDbValueToControlValue(
219 const ::connectivity::ORowSetValue
&aValue
)
224 void loadData( bool _bForce
);
226 /** refreshes the list boxes list data
227 @precond we don't actually have an external list source
229 void impl_refreshDbEntryList( bool _bForce
);
231 void setBoundValues(const ValueList
&);
232 void clearBoundValues();
234 ValueList
impl_getValues() const;
236 sal_Int32
getValueType() const;
238 void convertBoundValues(sal_Int32 nType
) const;
240 bool impl_hasBoundComponent() const { return m_nBoundColumnType
!= ::com::sun::star::sdbc::DataType::SQLNULL
; }
243 //==================================================================
245 //==================================================================
246 typedef ::cppu::ImplHelper4
< ::com::sun::star::awt::XFocusListener
247 , ::com::sun::star::awt::XItemListener
248 , ::com::sun::star::awt::XListBox
249 , ::com::sun::star::form::XChangeBroadcaster
250 > OListBoxControl_BASE
;
252 class OListBoxControl
:public OBoundControl
253 ,public OListBoxControl_BASE
254 ,public IEventProcessor
257 ::cppu::OInterfaceContainerHelper m_aChangeListeners
;
258 ::cppu::OInterfaceContainerHelper m_aItemListeners
;
260 ::com::sun::star::uno::Any m_aCurrentSelection
;
261 Timer m_aChangeTimer
;
263 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XListBox
>
266 ::rtl::Reference
< ::comphelper::AsyncEventNotifier
>
271 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
> _getTypes();
274 OListBoxControl(const ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XMultiServiceFactory
>& _rxFactory
);
275 virtual ~OListBoxControl();
278 DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl
, OBoundControl
);
279 virtual ::com::sun::star::uno::Any SAL_CALL
queryAggregation( const ::com::sun::star::uno::Type
& _rType
) throw (::com::sun::star::uno::RuntimeException
);
282 IMPLEMENTATION_NAME(OListBoxControl
);
283 virtual StringSequence SAL_CALL
getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException
);
285 // XChangeBroadcaster
286 virtual void SAL_CALL
addChangeListener(const ::com::sun::star::uno::Reference
< ::com::sun::star::form::XChangeListener
>& _rxListener
) throw(::com::sun::star::uno::RuntimeException
);
287 virtual void SAL_CALL
removeChangeListener(const ::com::sun::star::uno::Reference
< ::com::sun::star::form::XChangeListener
>& _rxListener
) throw(::com::sun::star::uno::RuntimeException
);
290 virtual void SAL_CALL
focusGained(const ::com::sun::star::awt::FocusEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
291 virtual void SAL_CALL
focusLost(const ::com::sun::star::awt::FocusEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
294 virtual void SAL_CALL
itemStateChanged(const ::com::sun::star::awt::ItemEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
);
297 virtual void SAL_CALL
disposing(const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
);
300 virtual void SAL_CALL
disposing();
303 virtual void SAL_CALL
addItemListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XItemListener
>& l
) throw (::com::sun::star::uno::RuntimeException
);
304 virtual void SAL_CALL
removeItemListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XItemListener
>& l
) throw (::com::sun::star::uno::RuntimeException
);
305 virtual void SAL_CALL
addActionListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XActionListener
>& l
) throw (::com::sun::star::uno::RuntimeException
);
306 virtual void SAL_CALL
removeActionListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XActionListener
>& l
) throw (::com::sun::star::uno::RuntimeException
);
307 virtual void SAL_CALL
addItem( const OUString
& aItem
, ::sal_Int16 nPos
) throw (::com::sun::star::uno::RuntimeException
);
308 virtual void SAL_CALL
addItems( const ::com::sun::star::uno::Sequence
< OUString
>& aItems
, ::sal_Int16 nPos
) throw (::com::sun::star::uno::RuntimeException
);
309 virtual void SAL_CALL
removeItems( ::sal_Int16 nPos
, ::sal_Int16 nCount
) throw (::com::sun::star::uno::RuntimeException
);
310 virtual ::sal_Int16 SAL_CALL
getItemCount( ) throw (::com::sun::star::uno::RuntimeException
);
311 virtual OUString SAL_CALL
getItem( ::sal_Int16 nPos
) throw (::com::sun::star::uno::RuntimeException
);
312 virtual ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
getItems( ) throw (::com::sun::star::uno::RuntimeException
);
313 virtual ::sal_Int16 SAL_CALL
getSelectedItemPos( ) throw (::com::sun::star::uno::RuntimeException
);
314 virtual ::com::sun::star::uno::Sequence
< ::sal_Int16
> SAL_CALL
getSelectedItemsPos( ) throw (::com::sun::star::uno::RuntimeException
);
315 virtual OUString SAL_CALL
getSelectedItem( ) throw (::com::sun::star::uno::RuntimeException
);
316 virtual ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
getSelectedItems( ) throw (::com::sun::star::uno::RuntimeException
);
317 virtual void SAL_CALL
selectItemPos( ::sal_Int16 nPos
, ::sal_Bool bSelect
) throw (::com::sun::star::uno::RuntimeException
);
318 virtual void SAL_CALL
selectItemsPos( const ::com::sun::star::uno::Sequence
< ::sal_Int16
>& aPositions
, ::sal_Bool bSelect
) throw (::com::sun::star::uno::RuntimeException
);
319 virtual void SAL_CALL
selectItem( const OUString
& aItem
, ::sal_Bool bSelect
) throw (::com::sun::star::uno::RuntimeException
);
320 virtual ::sal_Bool SAL_CALL
isMutipleMode( ) throw (::com::sun::star::uno::RuntimeException
);
321 virtual void SAL_CALL
setMultipleMode( ::sal_Bool bMulti
) throw (::com::sun::star::uno::RuntimeException
);
322 virtual ::sal_Int16 SAL_CALL
getDropDownLineCount( ) throw (::com::sun::star::uno::RuntimeException
);
323 virtual void SAL_CALL
setDropDownLineCount( ::sal_Int16 nLines
) throw (::com::sun::star::uno::RuntimeException
);
324 virtual void SAL_CALL
makeVisible( ::sal_Int16 nEntry
) throw (::com::sun::star::uno::RuntimeException
);
328 virtual void processEvent( const ::comphelper::AnyEvent
& _rEvent
);
331 DECL_LINK( OnTimeout
, void* );
334 //.........................................................................
336 //.........................................................................
338 #endif // _FORMS_LISTBOX_HXX_
340 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */