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 INCLUDED_FORMS_SOURCE_COMPONENT_LISTBOX_HXX
21 #define INCLUDED_FORMS_SOURCE_COMPONENT_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>
42 #include <vcl/idle.hxx>
46 /** ListBox is a bit confusing / different from other form components,
47 so here are a few notes:
49 The general design philosophy is that a ListBox is a mechanism
50 to translate back and forth between:
51 1) *display* values (strings that the user sees and chooses)
52 2) *binding* values, which is what the program (for a dialog),
53 the database, ... cares about.
55 A non-data aware ListBox exposes this mechanism through
56 com.sun.star.awt.XItemList (get|set)ItemData.
58 In a data-aware ListBox, this is naturally embodied by the
59 StringItemList on the one hand, and the ValueList on the other
60 hand (where, depending on ListSourceType, the ValueList is
61 possibly automatically filled from the BoundColumn of the
64 This source file implements data-aware ListBox, and the rest
65 of this comment applies to data-aware ListBox (only).
67 In all public APIs of the *model* (OListBoxModel),
68 the value of the control is the *binding* value.
69 That is what the bound database field gets,
70 that is what a validator validates,
71 that is what an external value binding
72 (com.sun.star.form.binding.XValueBinding)
73 exchanges with the control.
75 As an *implementation* choice, we keep the current value of the
76 ListBox as a sequence of *indices* in the value list, and do the
79 - ListBox's content propery (or value property, sorry the
80 terminology is not always consistent) is SelectedItems which is
81 a sequence of *indices* in the value list.
83 - That is used to synchronise with our peer (UnoControlListBoxModel).
85 In particular, note that getCurrentValue() is a public API (and
86 deals with bound values), but getControlValue and
87 (do)setControlValue are *internal* implementation helpers that
90 Note that the *view* (OListBoxControl) presents a different story
91 than the model. E.g. the "SelectedItems" property is *display* *values*.
98 typedef ::std::vector
< ::connectivity::ORowSetValue
> ValueList
;
100 class OListBoxModel
:public OBoundControlModel
101 ,public OEntryListHelper
102 ,public OErrorBroadcaster
105 CachedRowSet m_aListRowSet
; // the row set to fill the list
106 ::connectivity::ORowSetValue m_aSaveValue
;
109 ::com::sun::star::form::ListSourceType m_eListSourceType
; // type der list source
110 ::com::sun::star::uno::Any m_aBoundColumn
;
111 ValueList m_aListSourceValues
;
112 ValueList m_aBoundValues
; // do not write directly; use setBoundValues()
113 mutable ValueList m_aConvertedBoundValues
;
114 mutable sal_Int32 m_nConvertedBoundValuesType
;
115 ::com::sun::star::uno::Sequence
<sal_Int16
> m_aDefaultSelectSeq
; // DefaultSelected
118 mutable sal_Int16 m_nNULLPos
; // position of the NULL value in our list
119 sal_Int32 m_nBoundColumnType
;
122 ::connectivity::ORowSetValue
getFirstSelectedValue() const;
124 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
> _getTypes() SAL_OVERRIDE
;
127 DECLARE_DEFAULT_LEAF_XTOR( OListBoxModel
);
130 OUString SAL_CALL
getImplementationName()
131 throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
132 { return OUString("com.sun.star.form.OListBoxModel"); }
134 virtual StringSequence SAL_CALL
getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
137 DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel
, OBoundControlModel
)
138 virtual ::com::sun::star::uno::Any SAL_CALL
queryAggregation( const ::com::sun::star::uno::Type
& _rType
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
141 virtual void SAL_CALL
disposing() SAL_OVERRIDE
;
143 // OPropertySetHelper
144 virtual void SAL_CALL
getFastPropertyValue(::com::sun::star::uno::Any
& rValue
, sal_Int32 nHandle
) const SAL_OVERRIDE
;
145 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const ::com::sun::star::uno::Any
& rValue
)
146 throw (::com::sun::star::uno::Exception
, std::exception
) SAL_OVERRIDE
;
147 virtual sal_Bool SAL_CALL
convertFastPropertyValue(
148 ::com::sun::star::uno::Any
& _rConvertedValue
, ::com::sun::star::uno::Any
& _rOldValue
, sal_Int32 _nHandle
, const ::com::sun::star::uno::Any
& _rValue
)
149 throw (::com::sun::star::lang::IllegalArgumentException
) SAL_OVERRIDE
;
152 static const ::connectivity::ORowSetValue s_aEmptyValue
;
153 static const ::connectivity::ORowSetValue s_aEmptyStringValue
;
156 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
, std::exception
) SAL_OVERRIDE
;
159 virtual OUString SAL_CALL
getServiceName() throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
160 virtual void SAL_CALL
161 write(const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectOutputStream
>& _rxOutStream
) throw(::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
162 virtual void SAL_CALL
163 read(const ::com::sun::star::uno::Reference
< ::com::sun::star::io::XObjectInputStream
>& _rxInStream
) throw(::com::sun::star::io::IOException
, ::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
165 // OControlModel's property handling
166 virtual void describeFixedProperties(
167 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::Property
>& /* [out] */ _rProps
168 ) const SAL_OVERRIDE
;
169 virtual void describeAggregateProperties(
170 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::Property
>& /* [out] */ _rAggregateProps
171 ) const SAL_OVERRIDE
;
174 virtual void SAL_CALL
disposing(const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
176 // OPropertyChangeListener
177 virtual void _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent
& _rEvt
) throw ( ::com::sun::star::uno::RuntimeException
) SAL_OVERRIDE
;
179 // prevent method hiding
180 using OBoundControlModel::getFastPropertyValue
;
181 using OBoundControlModel::setPropertyValues
;
184 // OBoundControlModel overridables
185 virtual ::com::sun::star::uno::Any
186 translateDbColumnToControlValue( ) SAL_OVERRIDE
;
187 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
>
188 getSupportedBindingTypes() SAL_OVERRIDE
;
189 virtual ::com::sun::star::uno::Any
190 translateExternalValueToControlValue( const ::com::sun::star::uno::Any
& _rExternalValue
) const SAL_OVERRIDE
;
191 virtual ::com::sun::star::uno::Any
192 translateControlValueToExternalValue( ) const SAL_OVERRIDE
;
193 virtual ::com::sun::star::uno::Any
194 translateControlValueToValidatableValue( ) const SAL_OVERRIDE
;
195 virtual bool commitControlValueToDbColumn( bool _bPostReset
) SAL_OVERRIDE
;
197 virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& _rxForm
) SAL_OVERRIDE
;
198 virtual void onDisconnectedDbColumn() SAL_OVERRIDE
;
200 virtual ::com::sun::star::uno::Any
201 getDefaultForReset() const SAL_OVERRIDE
;
202 virtual void resetNoBroadcast() SAL_OVERRIDE
;
204 virtual ::com::sun::star::uno::Any
205 getCurrentFormComponentValue() const SAL_OVERRIDE
;
207 // OEntryListHelper overridables
208 virtual void stringItemListChanged( ControlModelLock
& _rInstanceLock
) SAL_OVERRIDE
;
209 virtual void connectedExternalListSource( ) SAL_OVERRIDE
;
210 virtual void disconnectedExternalListSource( ) SAL_OVERRIDE
;
211 virtual void refreshInternalEntryList() SAL_OVERRIDE
;
214 virtual css::uno::Reference
< css::util::XCloneable
> SAL_CALL
createClone( ) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
217 ::com::sun::star::uno::Any
getCurrentSingleValue() const;
218 ::com::sun::star::uno::Any
getCurrentMultiValue() const;
219 ::com::sun::star::uno::Sequence
< sal_Int16
> translateBindingValuesToControlValue(
220 const ::com::sun::star::uno::Sequence
< const ::com::sun::star::uno::Any
> &i_aValues
)
222 ::com::sun::star::uno::Sequence
< sal_Int16
> translateDbValueToControlValue(
223 const ::connectivity::ORowSetValue
&aValue
)
228 void loadData( bool _bForce
);
230 /** refreshes the list boxes list data
231 @precond we don't actually have an external list source
233 void impl_refreshDbEntryList( bool _bForce
);
235 void setBoundValues(const ValueList
&);
236 void clearBoundValues();
238 ValueList
impl_getValues() const;
240 sal_Int32
getValueType() const;
242 void convertBoundValues(sal_Int32 nType
) const;
244 bool impl_hasBoundComponent() const { return m_nBoundColumnType
!= ::com::sun::star::sdbc::DataType::SQLNULL
; }
250 typedef ::cppu::ImplHelper4
< ::com::sun::star::awt::XFocusListener
251 , ::com::sun::star::awt::XItemListener
252 , ::com::sun::star::awt::XListBox
253 , ::com::sun::star::form::XChangeBroadcaster
254 > OListBoxControl_BASE
;
256 class OListBoxControl
:public OBoundControl
257 ,public OListBoxControl_BASE
258 ,public IEventProcessor
261 ::cppu::OInterfaceContainerHelper m_aChangeListeners
;
262 ::cppu::OInterfaceContainerHelper m_aItemListeners
;
264 ::com::sun::star::uno::Any m_aCurrentSelection
;
267 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XListBox
>
270 ::rtl::Reference
< ::comphelper::AsyncEventNotifier
>
275 virtual ::com::sun::star::uno::Sequence
< ::com::sun::star::uno::Type
> _getTypes() SAL_OVERRIDE
;
278 OListBoxControl(const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XComponentContext
>& _rxFactory
);
279 virtual ~OListBoxControl();
282 DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl
, OBoundControl
)
283 virtual ::com::sun::star::uno::Any SAL_CALL
queryAggregation( const ::com::sun::star::uno::Type
& _rType
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
286 OUString SAL_CALL
getImplementationName()
287 throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
288 { return OUString("com.sun.star.form.OListBoxControl"); }
290 virtual StringSequence SAL_CALL
getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
292 // XChangeBroadcaster
293 virtual void SAL_CALL
addChangeListener(const ::com::sun::star::uno::Reference
< ::com::sun::star::form::XChangeListener
>& _rxListener
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
294 virtual void SAL_CALL
removeChangeListener(const ::com::sun::star::uno::Reference
< ::com::sun::star::form::XChangeListener
>& _rxListener
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
297 virtual void SAL_CALL
focusGained(const ::com::sun::star::awt::FocusEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
298 virtual void SAL_CALL
focusLost(const ::com::sun::star::awt::FocusEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
301 virtual void SAL_CALL
itemStateChanged(const ::com::sun::star::awt::ItemEvent
& _rEvent
) throw(::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
304 virtual void SAL_CALL
disposing(const ::com::sun::star::lang::EventObject
& Source
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
307 virtual void SAL_CALL
disposing() SAL_OVERRIDE
;
310 virtual void SAL_CALL
addItemListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XItemListener
>& l
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
311 virtual void SAL_CALL
removeItemListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XItemListener
>& l
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
312 virtual void SAL_CALL
addActionListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XActionListener
>& l
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
313 virtual void SAL_CALL
removeActionListener( const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XActionListener
>& l
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
314 virtual void SAL_CALL
addItem( const OUString
& aItem
, ::sal_Int16 nPos
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
315 virtual void SAL_CALL
addItems( const ::com::sun::star::uno::Sequence
< OUString
>& aItems
, ::sal_Int16 nPos
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
316 virtual void SAL_CALL
removeItems( ::sal_Int16 nPos
, ::sal_Int16 nCount
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
317 virtual ::sal_Int16 SAL_CALL
getItemCount( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
318 virtual OUString SAL_CALL
getItem( ::sal_Int16 nPos
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
319 virtual ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
getItems( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
320 virtual ::sal_Int16 SAL_CALL
getSelectedItemPos( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
321 virtual ::com::sun::star::uno::Sequence
< ::sal_Int16
> SAL_CALL
getSelectedItemsPos( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
322 virtual OUString SAL_CALL
getSelectedItem( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
323 virtual ::com::sun::star::uno::Sequence
< OUString
> SAL_CALL
getSelectedItems( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
324 virtual void SAL_CALL
selectItemPos( ::sal_Int16 nPos
, sal_Bool bSelect
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
325 virtual void SAL_CALL
selectItemsPos( const ::com::sun::star::uno::Sequence
< ::sal_Int16
>& aPositions
, sal_Bool bSelect
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
326 virtual void SAL_CALL
selectItem( const OUString
& aItem
, sal_Bool bSelect
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
327 virtual sal_Bool SAL_CALL
isMutipleMode( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
328 virtual void SAL_CALL
setMultipleMode( sal_Bool bMulti
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
329 virtual ::sal_Int16 SAL_CALL
getDropDownLineCount( ) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
330 virtual void SAL_CALL
setDropDownLineCount( ::sal_Int16 nLines
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
331 virtual void SAL_CALL
makeVisible( ::sal_Int16 nEntry
) throw (::com::sun::star::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
;
335 virtual void processEvent( const ::comphelper::AnyEvent
& _rEvent
) SAL_OVERRIDE
;
338 DECL_LINK_TYPED( OnTimeout
, Idle
*, void );
345 #endif // INCLUDED_FORMS_SOURCE_COMPONENT_LISTBOX_HXX
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */