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/form/ListSourceType.hpp>
29 #include <com/sun/star/awt/XItemListener.hpp>
30 #include <com/sun/star/awt/XFocusListener.hpp>
31 #include <com/sun/star/awt/XListBox.hpp>
32 #include <com/sun/star/form/XChangeBroadcaster.hpp>
34 #include <comphelper/asyncnotification.hxx>
35 #include <connectivity/FValue.hxx>
36 #include <cppuhelper/implbase4.hxx>
37 #include <vcl/timer.hxx>
38 #include <vcl/idle.hxx>
42 using namespace comphelper
;
44 /** ListBox is a bit confusing / different from other form components,
45 so here are a few notes:
47 The general design philosophy is that a ListBox is a mechanism
48 to translate back and forth between:
49 1) *display* values (strings that the user sees and chooses)
50 2) *binding* values, which is what the program (for a dialog),
51 the database, ... cares about.
53 A non-data aware ListBox exposes this mechanism through
54 com.sun.star.awt.XItemList (get|set)ItemData.
56 In a data-aware ListBox, this is naturally embodied by the
57 StringItemList on the one hand, and the ValueList on the other
58 hand (where, depending on ListSourceType, the ValueList is
59 possibly automatically filled from the BoundColumn of the
62 This source file implements data-aware ListBox, and the rest
63 of this comment applies to data-aware ListBox (only).
65 In all public APIs of the *model* (OListBoxModel),
66 the value of the control is the *binding* value.
67 That is what the bound database field gets,
68 that is what a validator validates,
69 that is what an external value binding
70 (com.sun.star.form.binding.XValueBinding)
71 exchanges with the control.
73 As an *implementation* choice, we keep the current value of the
74 ListBox as a sequence of *indices* in the value list, and do the
77 - ListBox's content property (or value property, sorry the
78 terminology is not always consistent) is SelectedItems which is
79 a sequence of *indices* in the value list.
81 - That is used to synchronise with our peer (UnoControlListBoxModel).
83 In particular, note that getCurrentValue() is a public API (and
84 deals with bound values), but getControlValue and
85 (do)setControlValue are *internal* implementation helpers that
88 Note that the *view* (OListBoxControl) presents a different story
89 than the model. E.g. the "SelectedItems" property is *display* *values*.
96 typedef ::std::vector
< ::connectivity::ORowSetValue
> ValueList
;
98 class OListBoxModel final
:public OBoundControlModel
99 ,public OEntryListHelper
100 ,public OErrorBroadcaster
103 CachedRowSet m_aListRowSet
; // the row set to fill the list
104 ::connectivity::ORowSetValue m_aSaveValue
;
107 css::form::ListSourceType m_eListSourceType
; // type of list source
108 css::uno::Any m_aBoundColumn
;
109 ValueList m_aListSourceValues
;
110 ValueList m_aBoundValues
; // do not write directly; use setBoundValues()
111 mutable ValueList m_aConvertedBoundValues
;
112 mutable sal_Int32 m_nConvertedBoundValuesType
;
113 css::uno::Sequence
<sal_Int16
> m_aDefaultSelectSeq
; // DefaultSelected
116 mutable sal_Int16 m_nNULLPos
; // position of the NULL value in our list
117 sal_Int32 m_nBoundColumnType
;
120 ::connectivity::ORowSetValue
getFirstSelectedValue() const;
122 virtual css::uno::Sequence
< css::uno::Type
> _getTypes() override
;
125 DECLARE_DEFAULT_LEAF_XTOR( OListBoxModel
);
128 OUString SAL_CALL
getImplementationName() override
129 { return "com.sun.star.form.OListBoxModel"; }
131 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
134 DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel
, OBoundControlModel
)
135 virtual css::uno::Any SAL_CALL
queryAggregation( const css::uno::Type
& _rType
) override
;
138 virtual void SAL_CALL
disposing() override
;
140 // OPropertySetHelper
141 virtual void SAL_CALL
getFastPropertyValue(css::uno::Any
& rValue
, sal_Int32 nHandle
) const override
;
142 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const css::uno::Any
& rValue
) override
;
143 virtual sal_Bool SAL_CALL
convertFastPropertyValue(
144 css::uno::Any
& _rConvertedValue
, css::uno::Any
& _rOldValue
, sal_Int32 _nHandle
, const css::uno::Any
& _rValue
) override
;
147 static const ::connectivity::ORowSetValue s_aEmptyValue
;
148 static const ::connectivity::ORowSetValue s_aEmptyStringValue
;
151 virtual void SAL_CALL
setPropertyValues(const css::uno::Sequence
< OUString
>& PropertyNames
, const css::uno::Sequence
< css::uno::Any
>& Values
) override
;
154 virtual OUString SAL_CALL
getServiceName() override
;
155 virtual void SAL_CALL
156 write(const css::uno::Reference
< css::io::XObjectOutputStream
>& _rxOutStream
) override
;
157 virtual void SAL_CALL
158 read(const css::uno::Reference
< css::io::XObjectInputStream
>& _rxInStream
) override
;
160 // OControlModel's property handling
161 virtual void describeFixedProperties(
162 css::uno::Sequence
< css::beans::Property
>& /* [out] */ _rProps
164 virtual void describeAggregateProperties(
165 css::uno::Sequence
< css::beans::Property
>& /* [out] */ _rAggregateProps
169 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
171 // OPropertyChangeListener
172 virtual void _propertyChanged( const css::beans::PropertyChangeEvent
& _rEvt
) override
;
174 // prevent method hiding
175 using OBoundControlModel::getFastPropertyValue
;
176 using OBoundControlModel::setPropertyValues
;
178 // OBoundControlModel overridables
179 virtual css::uno::Any
translateDbColumnToControlValue( ) override
;
180 virtual css::uno::Sequence
< css::uno::Type
>
181 getSupportedBindingTypes() override
;
182 virtual css::uno::Any
translateExternalValueToControlValue( const css::uno::Any
& _rExternalValue
) const override
;
183 virtual css::uno::Any
translateControlValueToExternalValue( ) const override
;
184 virtual css::uno::Any
translateControlValueToValidatableValue( ) const override
;
185 virtual bool commitControlValueToDbColumn( bool _bPostReset
) override
;
187 virtual void onConnectedDbColumn( const css::uno::Reference
< css::uno::XInterface
>& _rxForm
) override
;
188 virtual void onDisconnectedDbColumn() override
;
190 virtual css::uno::Any
getDefaultForReset() const override
;
191 virtual void resetNoBroadcast() override
;
193 virtual css::uno::Any
getCurrentFormComponentValue() const override
;
195 // OEntryListHelper overridables
196 virtual void stringItemListChanged( ControlModelLock
& _rInstanceLock
) override
;
197 virtual void refreshInternalEntryList() override
;
199 virtual css::uno::Reference
< css::util::XCloneable
> SAL_CALL
createClone( ) override
;
202 css::uno::Any
getCurrentSingleValue() const;
203 css::uno::Sequence
<css::uno::Any
> getCurrentMultiValue() const;
204 css::uno::Sequence
< sal_Int16
> translateBindingValuesToControlValue(
205 const css::uno::Sequence
< const css::uno::Any
> &i_aValues
)
207 css::uno::Sequence
< sal_Int16
> translateDbValueToControlValue(
208 const ::connectivity::ORowSetValue
&aValue
)
211 void loadData( bool _bForce
);
213 /** refreshes the list boxes list data
214 @precond we don't actually have an external list source
216 void impl_refreshDbEntryList( bool _bForce
);
218 void setBoundValues(const ValueList
&);
219 void clearBoundValues();
221 ValueList
impl_getValues() const;
223 sal_Int32
getValueType() const;
225 void convertBoundValues(sal_Int32 nType
) const;
231 typedef ::cppu::ImplHelper4
< css::awt::XFocusListener
232 , css::awt::XItemListener
234 , css::form::XChangeBroadcaster
235 > OListBoxControl_BASE
;
237 class OListBoxControl
:public OBoundControl
238 ,public OListBoxControl_BASE
239 ,public IEventProcessor
242 ::comphelper::OInterfaceContainerHelper2 m_aChangeListeners
;
243 ::comphelper::OInterfaceContainerHelper2 m_aItemListeners
;
245 css::uno::Any m_aCurrentSelection
;
248 css::uno::Reference
< css::awt::XListBox
>
251 ::rtl::Reference
< ::comphelper::AsyncEventNotifier
>
256 virtual css::uno::Sequence
< css::uno::Type
> _getTypes() override
;
259 explicit OListBoxControl(const css::uno::Reference
< css::uno::XComponentContext
>& _rxFactory
);
260 virtual ~OListBoxControl() override
;
263 DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl
, OBoundControl
)
264 virtual css::uno::Any SAL_CALL
queryAggregation( const css::uno::Type
& _rType
) override
;
267 OUString SAL_CALL
getImplementationName() override
268 { return "com.sun.star.form.OListBoxControl"; }
270 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
272 // XChangeBroadcaster
273 virtual void SAL_CALL
addChangeListener(const css::uno::Reference
< css::form::XChangeListener
>& _rxListener
) override
;
274 virtual void SAL_CALL
removeChangeListener(const css::uno::Reference
< css::form::XChangeListener
>& _rxListener
) override
;
277 virtual void SAL_CALL
focusGained(const css::awt::FocusEvent
& _rEvent
) override
;
278 virtual void SAL_CALL
focusLost(const css::awt::FocusEvent
& _rEvent
) override
;
281 virtual void SAL_CALL
itemStateChanged(const css::awt::ItemEvent
& _rEvent
) override
;
284 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
287 virtual void SAL_CALL
disposing() override
;
290 virtual void SAL_CALL
addItemListener( const css::uno::Reference
< css::awt::XItemListener
>& l
) override
;
291 virtual void SAL_CALL
removeItemListener( const css::uno::Reference
< css::awt::XItemListener
>& l
) override
;
292 virtual void SAL_CALL
addActionListener( const css::uno::Reference
< css::awt::XActionListener
>& l
) override
;
293 virtual void SAL_CALL
removeActionListener( const css::uno::Reference
< css::awt::XActionListener
>& l
) override
;
294 virtual void SAL_CALL
addItem( const OUString
& aItem
, ::sal_Int16 nPos
) override
;
295 virtual void SAL_CALL
addItems( const css::uno::Sequence
< OUString
>& aItems
, ::sal_Int16 nPos
) override
;
296 virtual void SAL_CALL
removeItems( ::sal_Int16 nPos
, ::sal_Int16 nCount
) override
;
297 virtual ::sal_Int16 SAL_CALL
getItemCount( ) override
;
298 virtual OUString SAL_CALL
getItem( ::sal_Int16 nPos
) override
;
299 virtual css::uno::Sequence
< OUString
> SAL_CALL
getItems( ) override
;
300 virtual ::sal_Int16 SAL_CALL
getSelectedItemPos( ) override
;
301 virtual css::uno::Sequence
< ::sal_Int16
> SAL_CALL
getSelectedItemsPos( ) override
;
302 virtual OUString SAL_CALL
getSelectedItem( ) override
;
303 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSelectedItems( ) override
;
304 virtual void SAL_CALL
selectItemPos( ::sal_Int16 nPos
, sal_Bool bSelect
) override
;
305 virtual void SAL_CALL
selectItemsPos( const css::uno::Sequence
< ::sal_Int16
>& aPositions
, sal_Bool bSelect
) override
;
306 virtual void SAL_CALL
selectItem( const OUString
& aItem
, sal_Bool bSelect
) override
;
307 virtual sal_Bool SAL_CALL
isMutipleMode( ) override
;
308 virtual void SAL_CALL
setMultipleMode( sal_Bool bMulti
) override
;
309 virtual ::sal_Int16 SAL_CALL
getDropDownLineCount( ) override
;
310 virtual void SAL_CALL
setDropDownLineCount( ::sal_Int16 nLines
) override
;
311 virtual void SAL_CALL
makeVisible( ::sal_Int16 nEntry
) override
;
315 virtual void processEvent( const ::comphelper::AnyEvent
& _rEvent
) override
;
318 DECL_LINK( OnTimeout
, Timer
*, void );
325 #endif // INCLUDED_FORMS_SOURCE_COMPONENT_LISTBOX_HXX
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */