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 .
22 #include <FormComponent.hxx>
23 #include "cachedrowset.hxx"
24 #include "errorbroadcaster.hxx"
25 #include "entrylisthelper.hxx"
27 #include <com/sun/star/form/ListSourceType.hpp>
28 #include <com/sun/star/awt/XItemListener.hpp>
29 #include <com/sun/star/awt/XFocusListener.hpp>
30 #include <com/sun/star/awt/XListBox.hpp>
31 #include <com/sun/star/form/XChangeBroadcaster.hpp>
33 #include <comphelper/asyncnotification.hxx>
34 #include <connectivity/FValue.hxx>
35 #include <cppuhelper/implbase4.hxx>
36 #include <vcl/timer.hxx>
37 #include <vcl/idle.hxx>
41 using namespace comphelper
;
43 /** ListBox is a bit confusing / different from other form components,
44 so here are a few notes:
46 The general design philosophy is that a ListBox is a mechanism
47 to translate back and forth between:
48 1) *display* values (strings that the user sees and chooses)
49 2) *binding* values, which is what the program (for a dialog),
50 the database, ... cares about.
52 A non-data aware ListBox exposes this mechanism through
53 com.sun.star.awt.XItemList (get|set)ItemData.
55 In a data-aware ListBox, this is naturally embodied by the
56 StringItemList on the one hand, and the ValueList on the other
57 hand (where, depending on ListSourceType, the ValueList is
58 possibly automatically filled from the BoundColumn of the
61 This source file implements data-aware ListBox, and the rest
62 of this comment applies to data-aware ListBox (only).
64 In all public APIs of the *model* (OListBoxModel),
65 the value of the control is the *binding* value.
66 That is what the bound database field gets,
67 that is what a validator validates,
68 that is what an external value binding
69 (com.sun.star.form.binding.XValueBinding)
70 exchanges with the control.
72 As an *implementation* choice, we keep the current value of the
73 ListBox as a sequence of *indices* in the value list, and do the
76 - ListBox's content property (or value property, sorry the
77 terminology is not always consistent) is SelectedItems which is
78 a sequence of *indices* in the value list.
80 - That is used to synchronise with our peer (UnoControlListBoxModel).
82 In particular, note that getCurrentValue() is a public API (and
83 deals with bound values), but getControlValue and
84 (do)setControlValue are *internal* implementation helpers that
87 Note that the *view* (OListBoxControl) presents a different story
88 than the model. E.g. the "SelectedItems" property is *display* *values*.
95 typedef ::std::vector
< ::connectivity::ORowSetValue
> ValueList
;
97 class OListBoxModel final
:public OBoundControlModel
98 ,public OEntryListHelper
99 ,public OErrorBroadcaster
102 CachedRowSet m_aListRowSet
; // the row set to fill the list
103 ::connectivity::ORowSetValue m_aSaveValue
;
106 css::form::ListSourceType m_eListSourceType
; // type of list source
107 css::uno::Any m_aBoundColumn
;
108 ValueList m_aListSourceValues
;
109 ValueList m_aBoundValues
; // do not write directly; use setBoundValues()
110 mutable ValueList m_aConvertedBoundValues
;
111 mutable sal_Int32 m_nConvertedBoundValuesType
;
112 css::uno::Sequence
<sal_Int16
> m_aDefaultSelectSeq
; // DefaultSelected
115 mutable sal_Int16 m_nNULLPos
; // position of the NULL value in our list
116 sal_Int32 m_nBoundColumnType
;
119 ::connectivity::ORowSetValue
getFirstSelectedValue() const;
121 virtual css::uno::Sequence
< css::uno::Type
> _getTypes() override
;
125 const css::uno::Reference
< css::uno::XComponentContext
>& _rxFactory
128 const OListBoxModel
* _pOriginal
,
129 const css::uno::Reference
< css::uno::XComponentContext
>& _rxFactory
131 virtual ~OListBoxModel() override
;
134 OUString SAL_CALL
getImplementationName() override
135 { return "com.sun.star.form.OListBoxModel"; }
137 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
140 DECLARE_UNO3_AGG_DEFAULTS(OListBoxModel
, OBoundControlModel
)
141 virtual css::uno::Any SAL_CALL
queryAggregation( const css::uno::Type
& _rType
) override
;
144 virtual void SAL_CALL
disposing() override
;
146 // OPropertySetHelper
147 virtual void SAL_CALL
getFastPropertyValue(css::uno::Any
& rValue
, sal_Int32 nHandle
) const override
;
148 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const css::uno::Any
& rValue
) override
;
149 virtual sal_Bool SAL_CALL
convertFastPropertyValue(
150 css::uno::Any
& _rConvertedValue
, css::uno::Any
& _rOldValue
, sal_Int32 _nHandle
, const css::uno::Any
& _rValue
) override
;
153 static const ::connectivity::ORowSetValue s_aEmptyValue
;
154 static const ::connectivity::ORowSetValue s_aEmptyStringValue
;
157 virtual void SAL_CALL
setPropertyValues(const css::uno::Sequence
< OUString
>& PropertyNames
, const css::uno::Sequence
< css::uno::Any
>& Values
) override
;
160 virtual OUString SAL_CALL
getServiceName() override
;
161 virtual void SAL_CALL
162 write(const css::uno::Reference
< css::io::XObjectOutputStream
>& _rxOutStream
) override
;
163 virtual void SAL_CALL
164 read(const css::uno::Reference
< css::io::XObjectInputStream
>& _rxInStream
) override
;
166 // OControlModel's property handling
167 virtual void describeFixedProperties(
168 css::uno::Sequence
< css::beans::Property
>& /* [out] */ _rProps
170 virtual void describeAggregateProperties(
171 css::uno::Sequence
< css::beans::Property
>& /* [out] */ _rAggregateProps
175 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
177 // OPropertyChangeListener
178 virtual void _propertyChanged( const css::beans::PropertyChangeEvent
& _rEvt
) override
;
180 // prevent method hiding
181 using OBoundControlModel::getFastPropertyValue
;
182 using OBoundControlModel::setPropertyValues
;
184 // OBoundControlModel overridables
185 virtual css::uno::Any
translateDbColumnToControlValue( ) override
;
186 virtual css::uno::Sequence
< css::uno::Type
>
187 getSupportedBindingTypes() override
;
188 virtual css::uno::Any
translateExternalValueToControlValue( const css::uno::Any
& _rExternalValue
) const override
;
189 virtual css::uno::Any
translateControlValueToExternalValue( ) const override
;
190 virtual css::uno::Any
translateControlValueToValidatableValue( ) const override
;
191 virtual bool commitControlValueToDbColumn( bool _bPostReset
) override
;
193 virtual void onConnectedDbColumn( const css::uno::Reference
< css::uno::XInterface
>& _rxForm
) override
;
194 virtual void onDisconnectedDbColumn() override
;
196 virtual css::uno::Any
getDefaultForReset() const override
;
197 virtual void resetNoBroadcast() override
;
199 virtual css::uno::Any
getCurrentFormComponentValue() const override
;
201 // OEntryListHelper overridables
202 virtual void stringItemListChanged( ControlModelLock
& _rInstanceLock
) override
;
203 virtual void refreshInternalEntryList() override
;
205 virtual css::uno::Reference
< css::util::XCloneable
> SAL_CALL
createClone( ) override
;
208 css::uno::Any
getCurrentSingleValue() const;
209 css::uno::Sequence
<css::uno::Any
> getCurrentMultiValue() const;
210 css::uno::Sequence
< sal_Int16
> translateBindingValuesToControlValue(
211 const css::uno::Sequence
< const css::uno::Any
> &i_aValues
)
213 css::uno::Sequence
< sal_Int16
> translateDbValueToControlValue(
214 const ::connectivity::ORowSetValue
&aValue
)
217 void loadData( bool _bForce
);
219 /** refreshes the list boxes list data
220 @precond we don't actually have an external list source
222 void impl_refreshDbEntryList( bool _bForce
);
224 void setBoundValues(ValueList
&&);
225 void clearBoundValues();
227 ValueList
impl_getValues() const;
229 sal_Int32
getValueType() const;
231 void convertBoundValues(sal_Int32 nType
) const;
237 typedef ::cppu::ImplHelper4
< css::awt::XFocusListener
238 , css::awt::XItemListener
240 , css::form::XChangeBroadcaster
241 > OListBoxControl_BASE
;
243 class OListBoxControl
:public OBoundControl
244 ,public OListBoxControl_BASE
245 ,public IEventProcessor
248 ::comphelper::OInterfaceContainerHelper2 m_aChangeListeners
;
249 ::comphelper::OInterfaceContainerHelper2 m_aItemListeners
;
251 css::uno::Any m_aCurrentSelection
;
254 css::uno::Reference
< css::awt::XListBox
>
257 ::rtl::Reference
< ::comphelper::AsyncEventNotifier
>
262 virtual css::uno::Sequence
< css::uno::Type
> _getTypes() override
;
265 explicit OListBoxControl(const css::uno::Reference
< css::uno::XComponentContext
>& _rxFactory
);
266 virtual ~OListBoxControl() override
;
269 DECLARE_UNO3_AGG_DEFAULTS(OListBoxControl
, OBoundControl
)
270 virtual css::uno::Any SAL_CALL
queryAggregation( const css::uno::Type
& _rType
) override
;
273 OUString SAL_CALL
getImplementationName() override
274 { return "com.sun.star.form.OListBoxControl"; }
276 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
;
278 // XChangeBroadcaster
279 virtual void SAL_CALL
addChangeListener(const css::uno::Reference
< css::form::XChangeListener
>& _rxListener
) override
;
280 virtual void SAL_CALL
removeChangeListener(const css::uno::Reference
< css::form::XChangeListener
>& _rxListener
) override
;
283 virtual void SAL_CALL
focusGained(const css::awt::FocusEvent
& _rEvent
) override
;
284 virtual void SAL_CALL
focusLost(const css::awt::FocusEvent
& _rEvent
) override
;
287 virtual void SAL_CALL
itemStateChanged(const css::awt::ItemEvent
& _rEvent
) override
;
290 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
293 virtual void SAL_CALL
disposing() override
;
296 virtual void SAL_CALL
addItemListener( const css::uno::Reference
< css::awt::XItemListener
>& l
) override
;
297 virtual void SAL_CALL
removeItemListener( const css::uno::Reference
< css::awt::XItemListener
>& l
) override
;
298 virtual void SAL_CALL
addActionListener( const css::uno::Reference
< css::awt::XActionListener
>& l
) override
;
299 virtual void SAL_CALL
removeActionListener( const css::uno::Reference
< css::awt::XActionListener
>& l
) override
;
300 virtual void SAL_CALL
addItem( const OUString
& aItem
, ::sal_Int16 nPos
) override
;
301 virtual void SAL_CALL
addItems( const css::uno::Sequence
< OUString
>& aItems
, ::sal_Int16 nPos
) override
;
302 virtual void SAL_CALL
removeItems( ::sal_Int16 nPos
, ::sal_Int16 nCount
) override
;
303 virtual ::sal_Int16 SAL_CALL
getItemCount( ) override
;
304 virtual OUString SAL_CALL
getItem( ::sal_Int16 nPos
) override
;
305 virtual css::uno::Sequence
< OUString
> SAL_CALL
getItems( ) override
;
306 virtual ::sal_Int16 SAL_CALL
getSelectedItemPos( ) override
;
307 virtual css::uno::Sequence
< ::sal_Int16
> SAL_CALL
getSelectedItemsPos( ) override
;
308 virtual OUString SAL_CALL
getSelectedItem( ) override
;
309 virtual css::uno::Sequence
< OUString
> SAL_CALL
getSelectedItems( ) override
;
310 virtual void SAL_CALL
selectItemPos( ::sal_Int16 nPos
, sal_Bool bSelect
) override
;
311 virtual void SAL_CALL
selectItemsPos( const css::uno::Sequence
< ::sal_Int16
>& aPositions
, sal_Bool bSelect
) override
;
312 virtual void SAL_CALL
selectItem( const OUString
& aItem
, sal_Bool bSelect
) override
;
313 virtual sal_Bool SAL_CALL
isMutipleMode( ) override
;
314 virtual void SAL_CALL
setMultipleMode( sal_Bool bMulti
) override
;
315 virtual ::sal_Int16 SAL_CALL
getDropDownLineCount( ) override
;
316 virtual void SAL_CALL
setDropDownLineCount( ::sal_Int16 nLines
) override
;
317 virtual void SAL_CALL
makeVisible( ::sal_Int16 nEntry
) override
;
321 virtual void processEvent( const ::comphelper::AnyEvent
& _rEvent
) override
;
324 DECL_LINK( OnTimeout
, Timer
*, void );
331 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */