Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
21 : #define INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
22 :
23 : #include "cloneable.hxx"
24 : #include "property.hrc"
25 : #include "property.hxx"
26 : #include "propertybaghelper.hxx"
27 : #include "resettable.hxx"
28 : #include "services.hxx"
29 : #include "windowstateguard.hxx"
30 :
31 : #include <com/sun/star/awt/XControl.hpp>
32 : #include <com/sun/star/beans/XPropertyAccess.hpp>
33 : #include <com/sun/star/beans/XPropertyContainer.hpp>
34 : #include <com/sun/star/container/XChild.hpp>
35 : #include <com/sun/star/container/XNamed.hpp>
36 : #include <com/sun/star/form/binding/XBindableValue.hpp>
37 : #include <com/sun/star/form/FormComponentType.hpp>
38 : #include <com/sun/star/form/validation/XValidatableFormComponent.hpp>
39 : #include <com/sun/star/form/validation/XValidityConstraintListener.hpp>
40 : #include <com/sun/star/form/XBoundComponent.hpp>
41 : #include <com/sun/star/form/XBoundControl.hpp>
42 : #include <com/sun/star/form/XFormComponent.hpp>
43 : #include <com/sun/star/form/XLoadListener.hpp>
44 : #include <com/sun/star/form/XReset.hpp>
45 : #include <com/sun/star/io/XMarkableStream.hpp>
46 : #include <com/sun/star/io/XPersistObject.hpp>
47 : #include <com/sun/star/lang/DisposedException.hpp>
48 : #include <com/sun/star/lang/XEventListener.hpp>
49 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 : #include <com/sun/star/lang/XServiceInfo.hpp>
51 : #include <com/sun/star/sdb/XColumn.hpp>
52 : #include <com/sun/star/sdb/XColumnUpdate.hpp>
53 : #include <com/sun/star/sdb/XRowSetChangeListener.hpp>
54 : #include <com/sun/star/sdbc/XRowSet.hpp>
55 : #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
56 : #include <com/sun/star/uno/XAggregation.hpp>
57 : #include <com/sun/star/util/XCloneable.hpp>
58 : #include <com/sun/star/util/XModifyListener.hpp>
59 : #include <com/sun/star/form/XLoadable.hpp>
60 :
61 : #include <comphelper/propagg.hxx>
62 : #include <comphelper/propertybag.hxx>
63 : #include <comphelper/propmultiplex.hxx>
64 : #include <comphelper/sequence.hxx>
65 : #include <comphelper/uno3.hxx>
66 : #include <cppuhelper/component.hxx>
67 : #include <cppuhelper/implbase1.hxx>
68 : #include <cppuhelper/implbase2.hxx>
69 : #include <cppuhelper/implbase3.hxx>
70 : #include <cppuhelper/implbase4.hxx>
71 : #include <cppuhelper/implbase7.hxx>
72 : #include <osl/mutex.hxx>
73 : #include <rtl/ustring.hxx>
74 :
75 :
76 : namespace frm
77 : {
78 :
79 :
80 : // default tab index for components
81 : const sal_Int16 FRM_DEFAULT_TABINDEX = 0;
82 :
83 : // macros for quickly declaring/implementing XServiceInfo
84 : #define DECLARE_XPERSISTOBJECT() \
85 : virtual OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE; \
86 : virtual void SAL_CALL 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; \
87 : virtual void SAL_CALL 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;
88 :
89 : class OControlModel;
90 :
91 :
92 : //= ControlModelLock
93 :
94 : /** class whose instances lock a OControlModel
95 :
96 : Locking here merely means locking the OControlModel's mutex.
97 :
98 : In addition to the locking facility, the class is also able to fire property
99 : change notifications. This happens when the last ControlModelLock instance on a stack
100 : dies.
101 : */
102 : class ControlModelLock
103 : {
104 : public:
105 1419 : ControlModelLock( OControlModel& _rModel )
106 : :m_rModel( _rModel )
107 1419 : ,m_bLocked( false )
108 : {
109 1419 : acquire();
110 1419 : }
111 :
112 1419 : ~ControlModelLock()
113 1419 : {
114 1419 : if ( m_bLocked )
115 1389 : release();
116 1419 : }
117 : inline void acquire();
118 : inline void release();
119 :
120 781 : inline OControlModel& getModel() const { return m_rModel; };
121 :
122 : /** adds a property change notification, which is to be fired when the last lock on the model
123 : (in the current thread) is released.
124 : */
125 : void addPropertyNotification(
126 : const sal_Int32 _nHandle,
127 : const ::com::sun::star::uno::Any& _rOldValue,
128 : const ::com::sun::star::uno::Any& _rNewValue
129 : );
130 :
131 : private:
132 : void impl_notifyAll_nothrow();
133 :
134 : private:
135 : OControlModel& m_rModel;
136 : bool m_bLocked;
137 : ::com::sun::star::uno::Sequence< sal_Int32 > m_aHandles;
138 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > m_aOldValues;
139 : ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > m_aNewValues;
140 :
141 : private:
142 : ControlModelLock( const ControlModelLock& ) SAL_DELETED_FUNCTION;
143 : ControlModelLock& operator=( const ControlModelLock& ) SAL_DELETED_FUNCTION;
144 : };
145 :
146 :
147 : //= OControl
148 : //= base class for form layer controls
149 :
150 : typedef ::cppu::ImplHelper3 < ::com::sun::star::awt::XControl
151 : , ::com::sun::star::lang::XEventListener
152 : , ::com::sun::star::lang::XServiceInfo
153 : > OControl_BASE;
154 :
155 : class OControl :public ::cppu::OComponentHelper
156 : ,public OControl_BASE
157 : {
158 : protected:
159 : ::osl::Mutex m_aMutex;
160 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControl >
161 : m_xControl;
162 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XAggregation>
163 : m_xAggregate;
164 :
165 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >
166 : m_xContext;
167 : WindowStateGuard m_aWindowStateGuard;
168 :
169 : public:
170 : /** constructs a control
171 :
172 : @param _rFactory
173 : the service factory for this control
174 : @param _rAggregateService
175 : the service name of the component to aggregate
176 : @param _bSetDelegator
177 : set this to <FALSE/> if you don't want the constructor to set the delegator at
178 : the aggregate. In this case, you <em>have</em> to call doSetDelegator within your
179 : own constructor.
180 :
181 : This is helpful, if your derived class wants to cache an interface of the aggregate.
182 : In this case, the aggregate needs to be queried for this interface <b>before</b> the
183 : <member scope="com::sun::star::uno">XAggregation::setDelegator</member> call.
184 :
185 : In such a case, pass <FALSE/> to this parameter. Then, cache the aggregate's interface(s)
186 : as needed. Afterwards, call <member>doSetDelegator</member>.
187 :
188 : In your destructor, you need to call <member>doResetDelegator</member> before
189 : resetting the cached interfaces. This will reset the aggregates delegator to <NULL/>,
190 : which will ensure that the <member scope="com::sun::star::uno">XInterface::release</member>
191 : calls on the cached interfaces are really applied to the aggregate, instead of
192 : the <type>OControl</type> itself.
193 : */
194 : OControl(
195 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rFactory,
196 : const OUString& _rAggregateService,
197 : const bool _bSetDelegator = true
198 : );
199 :
200 : protected:
201 : virtual ~OControl();
202 :
203 : /** sets the control as delegator at the aggregate
204 :
205 : This has to be called from within your derived class' constructor, if and only
206 : if you passed <FALSE/> to the <arg>_bSetDelegator</arg> parameter of the
207 : <type>OControl</type> constructor.
208 : */
209 : void doSetDelegator();
210 : void doResetDelegator();
211 :
212 : // UNO
213 720967 : DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
214 : 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;
215 :
216 : // XTypeProvider
217 : virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
218 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
219 :
220 : // OComponentHelper
221 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
222 :
223 : // XComponent (as base of XControl)
224 305 : virtual void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
225 305 : { OComponentHelper::dispose(); }
226 262 : virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
227 262 : { OComponentHelper::addEventListener(_rxListener); }
228 249 : virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener>& _rxListener) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE
229 249 : { OComponentHelper::removeEventListener(_rxListener); }
230 :
231 : // XEventListener
232 : virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
233 :
234 : // XServiceInfo
235 : virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
236 : virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
237 : virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE = 0;
238 :
239 : // XServiceInfo - static version
240 : static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
241 :
242 : // XControl
243 : virtual void SAL_CALL setContext(const InterfaceRef& Context) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
244 : virtual InterfaceRef SAL_CALL getContext() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
245 : virtual void SAL_CALL createPeer(const ::com::sun::star::uno::Reference<css::awt::XToolkit>& Toolkit, const ::com::sun::star::uno::Reference<css::awt::XWindowPeer>& Parent) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
246 : virtual ::com::sun::star::uno::Reference<css::awt::XWindowPeer> SAL_CALL getPeer() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
247 : virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference<css::awt::XControlModel>& Model) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
248 : virtual ::com::sun::star::uno::Reference<css::awt::XControlModel> SAL_CALL getModel() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
249 : virtual ::com::sun::star::uno::Reference<css::awt::XView> SAL_CALL getView() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
250 : virtual void SAL_CALL setDesignMode(sal_Bool bOn) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
251 : virtual sal_Bool SAL_CALL isDesignMode() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
252 : virtual sal_Bool SAL_CALL isTransparent() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
253 :
254 : protected:
255 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
256 : // overwrite this and call the base class if you have additional types
257 :
258 : ::com::sun::star::uno::Sequence< OUString > getAggregateServiceNames();
259 :
260 : private:
261 : void impl_resetStateGuard_nothrow();
262 : };
263 :
264 : // a form control implementing the XBoundControl interface
265 : typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XBoundControl
266 : > OBoundControl_BASE;
267 : class OBoundControl :public OControl
268 : ,public OBoundControl_BASE
269 : {
270 : protected:
271 : bool m_bLocked : 1;
272 :
273 : OUString m_sOriginalHelpText; // as long as the text/value is invalid, we change the help text of our peer
274 : ::com::sun::star::awt::FontDescriptor
275 : m_aOriginalFont; // as long as the text/value is invalid, we also change the font
276 : sal_Int32 m_nOriginalTextLineColor; // (we add red underlining)
277 :
278 : public:
279 : OBoundControl(
280 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
281 : const OUString& _rAggregateService,
282 : const bool _bSetDelegator = true
283 : );
284 :
285 : virtual ~OBoundControl();
286 :
287 562401 : DECLARE_UNO3_AGG_DEFAULTS(OBoundControl, OControl)
288 : 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;
289 :
290 : // XBoundControl
291 : virtual sal_Bool SAL_CALL getLock() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
292 : virtual void SAL_CALL setLock(sal_Bool _bLock) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
293 : // default implementation just disables the controls, overwrite _setLock to change this behaviour
294 :
295 : // XControl
296 : virtual sal_Bool SAL_CALL setModel(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& Model) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
297 :
298 : // XEventListener
299 : virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
300 :
301 : // OComponentHelper
302 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
303 :
304 : protected:
305 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes() SAL_OVERRIDE;
306 : // implement the lock setting
307 : void _setLock(bool _bLock);
308 : };
309 :
310 :
311 : //= OControlModel
312 : //= model of a form layer control
313 :
314 : //added for exporting OCX control
315 : #define INVALID_OBJ_ID_IN_MSO 0xFFFF
316 :
317 : typedef ::cppu::ImplHelper7 < ::com::sun::star::form::XFormComponent
318 : , ::com::sun::star::io::XPersistObject
319 : , ::com::sun::star::container::XNamed
320 : , ::com::sun::star::lang::XServiceInfo
321 : , ::com::sun::star::util::XCloneable
322 : , ::com::sun::star::beans::XPropertyContainer
323 : , ::com::sun::star::beans::XPropertyAccess
324 : > OControlModel_BASE;
325 :
326 : class OControlModel :public ::cppu::OComponentHelper
327 : ,public OPropertySetAggregationHelper
328 : ,public OControlModel_BASE
329 : ,public OCloneableAggregation
330 : ,public IPropertyBagHelperContext
331 : {
332 :
333 : protected:
334 : css::uno::Reference<css::uno::XComponentContext> m_xContext;
335 :
336 : ::osl::Mutex m_aMutex;
337 : oslInterlockedCount m_lockCount;
338 :
339 : InterfaceRef m_xParent; // ParentComponent
340 : PropertyBagHelper m_aPropertyBagHelper;
341 :
342 : const css::uno::Reference<css::uno::XComponentContext>&
343 121 : getContext() const { return m_xContext; }
344 :
345 : // <properties>
346 : OUString m_aName; // name of the control
347 : OUString m_aTag; // tag for additional data
348 : sal_Int16 m_nTabIndex; // index within the taborder
349 : sal_Int16 m_nClassId; // type of the control
350 : bool m_bNativeLook; // should the control use the native platform look?
351 : bool m_bGenerateVbEvents; // should the control generate fake vba events
352 : //added for exporting OCX control
353 : sal_Int16 m_nControlTypeinMSO; //keep the MS office control type for exporting to MS binarary file
354 : sal_uInt16 m_nObjIDinMSO; //keep the OCX control obj id for exporting to MS binarary file
355 : // </properties>
356 :
357 :
358 : protected:
359 : OControlModel(
360 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
361 : const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
362 : const OUString& rDefault = OUString(), // service name of the default control
363 : const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
364 : );
365 : OControlModel(
366 : const OControlModel* _pOriginal, // the original object to clone
367 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rFactory, // factory to create the aggregate with
368 : const bool _bCloneAggregate = true, // should the aggregate of the original be cloned, too?
369 : const bool _bSetDelegator = true // set to sal_False if you want to call setDelegator later (after returning from this ctor)
370 : );
371 : virtual ~OControlModel();
372 :
373 : /** to be called after a OBoundControlModel (a derivee, respectively) has been cloned
374 :
375 : <p>This method contains late initializations which cannot be done in the
376 : constructor of this base class, since the virtual method of derived classes do
377 : not yet work there.</p>
378 : */
379 : virtual void clonedFrom( const OControlModel* _pOriginal );
380 :
381 : using OComponentHelper::rBHelper;
382 :
383 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes();
384 :
385 : void readHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream);
386 : void writeHelpTextCompatibly(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream);
387 :
388 : void doSetDelegator();
389 : void doResetDelegator();
390 :
391 : ::com::sun::star::uno::Sequence< OUString > getAggregateServiceNames();
392 :
393 : public:
394 2001035 : DECLARE_UNO3_AGG_DEFAULTS(OControl, OComponentHelper)
395 : 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;
396 :
397 : // XTypeProvider
398 : virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
399 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> SAL_CALL getTypes() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
400 :
401 : // OComponentHelper
402 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
403 :
404 : // XNamed
405 : virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
406 : virtual void SAL_CALL setName(const OUString& aName) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
407 :
408 : // XServiceInfo
409 : virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
410 : virtual StringSequence SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
411 : virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE = 0;
412 :
413 : // XSericeInfo - static version(s)
414 : static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
415 :
416 : // XPersistObject
417 : virtual OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE = 0;
418 : virtual void SAL_CALL
419 : 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;
420 : virtual void SAL_CALL
421 : 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;
422 :
423 : // XChild (base of XFormComponent)
424 : virtual InterfaceRef SAL_CALL getParent() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
425 : virtual void SAL_CALL setParent(const InterfaceRef& Parent) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
426 :
427 : // XEventListener
428 : virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
429 :
430 : // XPropertySet
431 : virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const SAL_OVERRIDE;
432 : virtual sal_Bool SAL_CALL convertFastPropertyValue(
433 : ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
434 : throw (::com::sun::star::lang::IllegalArgumentException) SAL_OVERRIDE;
435 : virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
436 : throw (::com::sun::star::uno::Exception, std::exception) SAL_OVERRIDE;
437 : using ::cppu::OPropertySetHelper::getFastPropertyValue;
438 :
439 : // ::com::sun::star::beans::XPropertyState
440 : virtual ::com::sun::star::beans::PropertyState getPropertyStateByHandle(sal_Int32 nHandle) SAL_OVERRIDE;
441 : virtual void setPropertyToDefaultByHandle(sal_Int32 nHandle) SAL_OVERRIDE;
442 : virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const SAL_OVERRIDE;
443 :
444 : // XCloneable
445 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE = 0;
446 :
447 : // XPropertyContainer
448 : virtual void SAL_CALL addProperty( const OUString& Name, ::sal_Int16 Attributes, const ::com::sun::star::uno::Any& DefaultValue ) throw (::com::sun::star::beans::PropertyExistException, ::com::sun::star::beans::IllegalTypeException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
449 : virtual void SAL_CALL removeProperty( const OUString& Name ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::NotRemoveableException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
450 :
451 : // XPropertyAccess
452 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL getPropertyValues( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
453 : virtual void SAL_CALL setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
454 :
455 : protected:
456 : using OPropertySetAggregationHelper::setPropertyValues;
457 : using OPropertySetAggregationHelper::getPropertyValues;
458 :
459 : protected:
460 : virtual void writeAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& _rxOutStream ) const;
461 : virtual void readAggregate( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& _rxInStream );
462 :
463 : protected:
464 : // XPropertySet
465 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
466 : // OPropertySetHelper
467 : virtual cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() SAL_OVERRIDE;
468 :
469 : /** describes the properties provided by this class, or its respective
470 : derived class
471 :
472 : Derived classes usually call the base class first, and then append own properties.
473 : */
474 : virtual void describeFixedProperties(
475 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
476 : ) const;
477 :
478 : // IPropertyBagHelperContext
479 : virtual ::osl::Mutex& getMutex() SAL_OVERRIDE;
480 : virtual void describeFixedAndAggregateProperties(
481 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rFixedProperties,
482 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& _out_rAggregateProperties
483 : ) const SAL_OVERRIDE;
484 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet >
485 : getPropertiesInterface() SAL_OVERRIDE;
486 :
487 : /** describes the properties of our aggregate
488 :
489 : The default implementation simply asks m_xAggregateSet for its properties.
490 :
491 : You usually only need to override this method if you want to filter the
492 : aggregate properties.
493 : */
494 : virtual void describeAggregateProperties(
495 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rAggregateProps
496 : ) const;
497 :
498 : public:
499 4281 : struct LockAccess { friend class ControlModelLock; private: LockAccess() { } };
500 :
501 : void lockInstance( LockAccess );
502 : oslInterlockedCount unlockInstance( LockAccess );
503 :
504 : void firePropertyChanges(
505 : const ::com::sun::star::uno::Sequence< sal_Int32 >& _rHandles,
506 : const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rOldValues,
507 : const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& _rNewValues,
508 : LockAccess
509 : );
510 :
511 : inline ::osl::Mutex&
512 50 : getInstanceMutex() { return m_aMutex; }
513 : };
514 :
515 : // constructor for cloning a class
516 : #define DECLARE_DEFAULT_CLONE_CTOR( classname ) \
517 : classname( \
518 : const classname* _pOriginal, \
519 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxFactory \
520 : ); \
521 :
522 : // all xtors for an inner class of the object hierarchy
523 : #define DECLARE_DEFAULT_XTOR( classname ) \
524 : classname( \
525 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxFactory, \
526 : const OUString& _rUnoControlModelTypeName, \
527 : const OUString& _rDefault \
528 : ); \
529 : DECLARE_DEFAULT_CLONE_CTOR( classname ) \
530 : virtual ~classname() \
531 :
532 : // all xtors for an inner class of the object hierarchy which is *bound*
533 : #define DECLARE_DEFAULT_BOUND_XTOR( classname ) \
534 : classname( \
535 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxFactory, \
536 : const OUString& _rUnoControlModelTypeName, \
537 : const OUString& _rDefault, \
538 : const bool _bSupportExternalBinding, \
539 : const bool _bSupportsValidation \
540 : ); \
541 : DECLARE_DEFAULT_CLONE_CTOR( classname ) \
542 : virtual ~classname() \
543 :
544 : // all xtors for a leas class of the object hierarchy
545 : #define DECLARE_DEFAULT_LEAF_XTOR( classname ) \
546 : classname( \
547 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxFactory \
548 : ); \
549 : classname( \
550 : const classname* _pOriginal, \
551 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxFactory \
552 : ); \
553 : virtual ~classname() \
554 :
555 :
556 : #define IMPLEMENT_DEFAULT_CLONING( classname ) \
557 : ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL classname::createClone( ) throw (::com::sun::star::uno::RuntimeException, std::exception) \
558 : { \
559 : classname* pClone = new classname( this, getContext() ); \
560 : pClone->clonedFrom( this ); \
561 : return pClone; \
562 : }
563 :
564 :
565 : //= OBoundControlModel
566 : //= model of a form layer control which is bound to a data source field
567 :
568 : typedef ::cppu::ImplHelper4 < ::com::sun::star::form::XLoadListener
569 : , ::com::sun::star::form::XReset
570 : , ::com::sun::star::beans::XPropertyChangeListener
571 : , ::com::sun::star::sdb::XRowSetChangeListener
572 : > OBoundControlModel_BASE1;
573 :
574 : // separated into an own base class since derivees can disable the support for this
575 : // interface, thus we want to easily exclude it in the queryInterface and getTypes
576 : typedef ::cppu::ImplHelper1 < ::com::sun::star::form::XBoundComponent
577 : > OBoundControlModel_COMMITTING;
578 :
579 : // dito
580 : typedef ::cppu::ImplHelper2 < ::com::sun::star::form::binding::XBindableValue
581 : , ::com::sun::star::util::XModifyListener
582 : > OBoundControlModel_BINDING;
583 :
584 : // dito
585 : typedef ::cppu::ImplHelper2 < ::com::sun::star::form::validation::XValidityConstraintListener
586 : , ::com::sun::star::form::validation::XValidatableFormComponent
587 : > OBoundControlModel_VALIDATION;
588 :
589 : class OBoundControlModel :public OControlModel
590 : ,public OBoundControlModel_BASE1
591 : ,public OBoundControlModel_COMMITTING
592 : ,public OBoundControlModel_BINDING
593 : ,public OBoundControlModel_VALIDATION
594 : ,public ::comphelper::OPropertyChangeListener
595 : {
596 : protected:
597 : enum ValueChangeInstigator
598 : {
599 : eDbColumnBinding,
600 : eExternalBinding,
601 : eOther
602 : };
603 :
604 : private:
605 : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
606 : m_xField;
607 : // the form which controls supplies the field we bind to.
608 : ::com::sun::star::uno::Reference< ::com::sun::star::form::XLoadable >
609 : m_xAmbientForm;
610 :
611 : OUString m_sValuePropertyName;
612 : sal_Int32 m_nValuePropertyAggregateHandle;
613 : sal_Int32 m_nFieldType;
614 : ::com::sun::star::uno::Type m_aValuePropertyType;
615 : bool m_bValuePropertyMayBeVoid;
616 :
617 : ResetHelper m_aResetHelper;
618 : ::cppu::OInterfaceContainerHelper m_aUpdateListeners;
619 : ::cppu::OInterfaceContainerHelper m_aFormComponentListeners;
620 :
621 : ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >
622 : m_xExternalBinding;
623 : ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >
624 : m_xValidator;
625 : ::com::sun::star::uno::Type m_aExternalValueType;
626 :
627 : // <properties>
628 : OUString m_aControlSource; // Datenquelle, Name des Feldes
629 : ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
630 : m_xLabelControl; // reference to a sibling control (model) which is our label
631 : bool m_bInputRequired;
632 : // </properties>
633 :
634 : ::comphelper::OPropertyChangeMultiplexer*
635 : m_pAggPropMultiplexer;
636 :
637 : bool m_bFormListening : 1; // are we currently a XLoadListener at our ambient form?
638 : bool m_bLoaded : 1;
639 : bool m_bRequired : 1;
640 : const bool m_bCommitable : 1; // do we support XBoundComponent?
641 : const bool m_bSupportsExternalBinding : 1; // do we support XBindableValue?
642 : const bool m_bSupportsValidation : 1; // do we support XValidatable?
643 : bool m_bForwardValueChanges : 1; // do we currently handle changes in the bound database field?
644 : bool m_bTransferingValue : 1; // true if we're currently transferring our value to an external binding
645 : bool m_bIsCurrentValueValid : 1; // flag specifying whether our current value is valid, relative to our external validator
646 : bool m_bBindingControlsRO : 1; // is our ReadOnly property currently controlled by our external binding?
647 : bool m_bBindingControlsEnable : 1; // is our Enabled property currently controlled by our external binding?
648 :
649 : ValueChangeInstigator m_eControlValueChangeInstigator;
650 :
651 : protected:
652 : OUString m_aLabelServiceName;
653 : // when setting the label for our control (property FM_PROP_CONTROLLABEL, member m_xLabelControl),
654 : // we accept only objects supporting an XControlModel interface, an XServiceInfo interface and
655 : // support for a service (XServiceInfo::supportsService) determined by this string.
656 : // Any other arguments will throw an IllegalArgumentException.
657 : // The default value is FM_COMPONENT_FIXEDTEXT.
658 :
659 : ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >
660 : m_xCursor;
661 : ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumnUpdate >
662 : m_xColumnUpdate;
663 : ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumn >
664 : m_xColumn;
665 :
666 : protected:
667 : inline const OUString& getValuePropertyName( ) const { return m_sValuePropertyName; }
668 0 : inline sal_Int32 getValuePropertyAggHandle( ) const { return m_nValuePropertyAggregateHandle; }
669 13 : inline const OUString& getControlSource( ) const { return m_aControlSource; }
670 23 : inline bool isRequired() const { return m_bRequired; }
671 0 : inline bool isLoaded() const { return m_bLoaded; }
672 :
673 : protected:
674 :
675 : OBoundControlModel(
676 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxContext,
677 : // factory to create the aggregate with
678 : const OUString& _rUnoControlModelTypeName, // service name of te model to aggregate
679 : const OUString& _rDefault, // service name of the default control
680 : const bool _bCommitable, // is the control (model) commitable ?
681 : const bool _bSupportExternalBinding, // set to sal_True if you want to support XBindableValue
682 : const bool _bSupportsValidation // set to sal_True if you want to support XValidatable
683 : );
684 : OBoundControlModel(
685 : const OBoundControlModel* _pOriginal, // the original object to clone
686 : const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext>& _rxContext
687 : // factory to create the aggregate with
688 : );
689 : virtual ~OBoundControlModel();
690 :
691 : /// late ctor after cloning
692 : virtual void clonedFrom( const OControlModel* _pOriginal ) SAL_OVERRIDE;
693 :
694 : /** initializes the part of the class which is related to the control value.
695 :
696 : <p>Kind of late ctor, to be called for derivees which have a dedicated value property.<br/>
697 : The value property is the property which's value is synced with either the database
698 : column the object is bound to, or with the external value binding, if present.<br/>
699 : E.g. for a text control model, this property will most probably be "Text".</p>
700 :
701 : <p>Derived classes are stronly recommend to call this method - at least the
702 : "DataFieldProperty" (exposed in getFastPropertyValue) relies on the information
703 : given herein, and needs to be supplied otherwise else.</p>
704 :
705 : <p>If this method has been called properly, then <member>setControlValue</member>
706 : does not need to be overridden - it will simply set the property value at the
707 : aggregate then.</p>
708 :
709 : @precond
710 : The method has not be called before during the life time of the object.
711 :
712 : @param _rValuePropertyName
713 : the name of the value property
714 : @param _nValuePropertyExternalHandle
715 : the handle of the property, as exposed to external components.<br/>
716 : Normally, this information can be obtained dynamically (e.g. from describeFixedProperties),
717 : but since this method is to be called from within the constructor of derived classes,
718 : we prefer to be on the *really* safe side here ....
719 :
720 : @see setControlValue
721 : @see suspendValueListening
722 : @see resumeValueListening
723 : @see describeFixedProperties
724 : */
725 : void initValueProperty(
726 : const OUString& _rValuePropertyName,
727 : sal_Int32 _nValuePropertyExternalHandle
728 : );
729 :
730 : /** initializes the part of the class which is related to the control value.
731 :
732 : <p>In opposite to ->initValueProperty, this method is to be used for value properties which are <em>not</em>
733 : implemented by our aggregate, but by ourselves.</p>
734 :
735 : <p>Certain functionality is not available when using own value properties. This includes binding to an external
736 : value and external validation. (This is not a conceptual limit, but simply missing implementation.)</p>
737 : */
738 : void initOwnValueProperty(
739 : const OUString& i_rValuePropertyName
740 : );
741 :
742 : /** suspends listening at the value property
743 :
744 : <p>As long as this listening is suspended, changes in the value property will not be
745 : recognized and not be handled.</p>
746 :
747 : @see initValueProperty
748 : @see resumeValueListening
749 : */
750 : void suspendValueListening( );
751 :
752 : /** resumes listening at the value property
753 :
754 : <p>As long as this listening is suspended, changes in the value property will not be
755 : recognized and not be handled.</p>
756 :
757 : @precond
758 : listening at the value property is currently suspended
759 :
760 : @see initValueProperty
761 : @see resumeValueListening
762 : */
763 : void resumeValueListening( );
764 :
765 : /** (to be) called when the value property changed
766 :
767 : Normally, this is done automatically, since the value property is a property of our aggregate, and we're
768 : a listener at this property.
769 : However, in some cases the value property might not be an aggregate property, but a property of the
770 : delegator instance. In this case, you'll need to call <code>onValuePropertyChange</code> whenever this
771 : property changes.
772 : */
773 : void onValuePropertyChange( ControlModelLock& i_rControLock );
774 :
775 : /** starts listening at the aggregate, for changes in the given property
776 :
777 : <p>The OBoundControlModel automatically registers a multiplexer which listens for
778 : changes in the aggregate property values. By default, only the control value property
779 : is observed. You may add additional properties to be observed with this method.</p>
780 :
781 : @see initValueProperty
782 : @see _propertyChanged
783 : */
784 : void startAggregatePropertyListening( const OUString& _rPropertyName );
785 :
786 : /** returns the default which should be used when resetting the control
787 :
788 : <p>The default implementation returns an empty Any.</p>
789 :
790 : @see resetNoBroadcast
791 : */
792 : virtual ::com::sun::star::uno::Any
793 : getDefaultForReset() const;
794 :
795 : /** translates a db column value into a control value.
796 :
797 : <p>Must transform the very current value of the database column we're bound to
798 : (<member>m_xColumn</member>) into a value which can be used as current value
799 : for the control.</p>
800 :
801 : @see setControlValue
802 : @pure
803 : */
804 : virtual ::com::sun::star::uno::Any
805 : translateDbColumnToControlValue( ) = 0;
806 :
807 : /** returns the data types which the control could use to exchange data with
808 : an external value binding
809 :
810 : The types returned here are completely independent from the concrete value binding,
811 : they're just candidates which depend on the control type, and possible the concrete state
812 : of the control (i.e. some property value).
813 :
814 : If a control implementation supports multiple types, the ordering in the returned
815 : sequence indicates preference: Preferred types are mentioned first.
816 :
817 : The default implementation returns the type of our value property.
818 : */
819 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type >
820 : getSupportedBindingTypes();
821 :
822 : /** translates the given value, which was obtained from the current external value binding,
823 : to a value which can be used in setControlValue
824 :
825 : <p>The default implementation returns the value itself, exception when it is VOID, and
826 : our value property is not allowed to be void - in this case, the returned value is a
827 : default-constructed value of the type required by our value property.
828 :
829 : @see hasExternalValueBinding
830 : @see getExternalValueType
831 : */
832 : virtual ::com::sun::star::uno::Any
833 : translateExternalValueToControlValue( const ::com::sun::star::uno::Any& _rExternalValue ) const;
834 :
835 : /** commits the current control value to our external value binding
836 :
837 : <p>The default implementation simply calls getControlValue.</p>
838 :
839 : @see hasExternalValueBinding
840 : @see initValueProperty
841 : */
842 : virtual ::com::sun::star::uno::Any
843 : translateControlValueToExternalValue( ) const;
844 :
845 : /** commits the current control value to the database column we're bound to
846 : @precond
847 : we're properly bound to a database column, especially <member>m_xColumnUpdate</member>
848 : is not <NULL/>
849 : @param _bPostReset
850 : <TRUE/> if and only if the current control value results from a reset (<member>getDefaultForReset</member>)
851 : @pure
852 : */
853 : virtual bool commitControlValueToDbColumn(
854 : bool _bPostReset
855 : ) = 0;
856 :
857 : /** sets the given value as new current value for the control
858 :
859 : Besides some administrative work (such as caring for <member>m_eControlValueChangeInstigator</member>),
860 : this method simply calls <member>doSetControlValue</member>.
861 :
862 : @precond
863 : Our own mutex is locked.
864 : @param _rValue
865 : The value to set. This value is guaranteed to be created by
866 : <member>translateDbColumnToControlValue</member> or
867 : <member>translateExternalValueToControlValue</member>
868 : @param _eInstigator
869 : the instigator of the value change
870 : */
871 : void setControlValue(
872 : const ::com::sun::star::uno::Any& _rValue,
873 : ValueChangeInstigator _eInstigator
874 : );
875 : /**
876 : <p>The default implementation will forward the given value to the aggregate, using
877 : m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
878 :
879 : @precond
880 : Our own mutex is locked.
881 : @param _rValue
882 : The value to set. This value is guaranteed to be created by
883 : <member>translateDbColumnToControlValue</member> or
884 : <member>translateExternalValueToControlValue</member>
885 : */
886 : virtual void doSetControlValue(
887 : const ::com::sun::star::uno::Any& _rValue
888 : );
889 :
890 : /** retrieves the current value of the control
891 :
892 : <p>The default implementation will ask the aggregate for the property value
893 : determined by either m_nValuePropertyAggregateHandle and/or m_sValuePropertyName.</p>
894 :
895 : @precond
896 : Our own mutex is locked.
897 : */
898 : virtual ::com::sun::star::uno::Any
899 : getControlValue( ) const;
900 :
901 : /** called whenever a connection to a database column has been established
902 : */
903 : virtual void onConnectedDbColumn( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _rxForm );
904 : /** called whenever a connection to a database column has been suspended
905 : */
906 : virtual void onDisconnectedDbColumn();
907 :
908 : /** called whenever a connection to an external supplier of values (XValueBinding) has been established
909 : @see m_xExternalBinding
910 : */
911 : virtual void onConnectedExternalValue( );
912 :
913 : /** called whenever an external validator has been registered
914 : */
915 : void onConnectedValidator( );
916 : /** called whenever an external validator has been revoked
917 : */
918 : void onDisconnectedValidator( );
919 :
920 : /** nFieldType is the type of the field, on which the model will be linked.
921 : The linking happens when sal_True is returned.
922 : The default-implementation allows everything but the three binary types
923 : and FieldType_OTHER.
924 : */
925 : virtual bool approveDbColumnType(sal_Int32 _nColumnType);
926 :
927 : /** retrieves the current value of the control, in a shape which can be used with our
928 : external validator.
929 :
930 : The default implementation simply calls <member>>translateControlValueToExternalValue</member>.
931 :
932 : @precond
933 : Our own mutex is locked.
934 : */
935 : virtual ::com::sun::star::uno::Any
936 : translateControlValueToValidatableValue( ) const;
937 :
938 : /** retrieves the current value of the form component
939 :
940 : This is the implementation method for XValidatableFormComponent::getCurrentValue. The default implementation
941 : calls translateControlValueToValidatableValue if a validator is present, otherwise getControlValue.
942 :
943 : @precond
944 : our mutex is locked when this method is called
945 : */
946 : virtual ::com::sun::star::uno::Any
947 : getCurrentFormComponentValue() const;
948 :
949 : /** We can't write (new) common properties in this base class, as the file format doesn't allow this
950 : (unfortunately). So derived classes may use the following two methods. They secure the written
951 : data with marks, so any new common properties in newer versions will be skipped by older ones.
952 : */
953 : void writeCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream>& _rxOutStream);
954 : void readCommonProperties(const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream>& _rxInStream);
955 : // the next method may be used in derived classes's read when an unknown version is encountered
956 : void defaultCommonProperties();
957 :
958 : /** called to reset the control to some kind of default.
959 :
960 : <p>The semantics of "default" is finally defined by the derived class (in particular,
961 : by <member>getDefaultForReset</member>).</p>
962 :
963 : <p>No listener notification needs to be done in the derived class.</p>
964 :
965 : <p>Normally, you won't override this method, but <member>getDefaultForReset</member> instead.</p>
966 :
967 : @see getDefaultForReset
968 : */
969 : virtual void resetNoBroadcast();
970 :
971 : virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type> _getTypes() SAL_OVERRIDE;
972 :
973 : /// sets m_xField to the given new value, without notifying our listeners
974 : void impl_setField_noNotify(
975 : const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& _rxField
976 : );
977 960 : inline bool hasField() const
978 : {
979 960 : return m_xField.is();
980 : }
981 225 : inline sal_Int32 getFieldType() const
982 : {
983 225 : return m_nFieldType;
984 : }
985 :
986 : // OControlModel's property handling
987 : virtual void describeFixedProperties(
988 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property >& /* [out] */ _rProps
989 : ) const SAL_OVERRIDE;
990 :
991 : public:
992 2202 : inline const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet>& getField() const
993 : {
994 2202 : return m_xField;
995 : }
996 :
997 : public:
998 : // UNO link
999 1511254 : DECLARE_UNO3_AGG_DEFAULTS(OBoundControlModel, OControlModel)
1000 : 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;
1001 :
1002 : // OComponentHelper
1003 : virtual void SAL_CALL disposing() SAL_OVERRIDE;
1004 :
1005 : // XReset
1006 : virtual void SAL_CALL reset( ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1007 : virtual void SAL_CALL addResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1008 : virtual void SAL_CALL removeResetListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XResetListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1009 :
1010 : // XServiceInfo
1011 : virtual StringSequence SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1012 :
1013 : // XServiceInfo - static version
1014 : static StringSequence SAL_CALL getSupportedServiceNames_Static() throw(::com::sun::star::uno::RuntimeException);
1015 :
1016 : // XChild
1017 : virtual void SAL_CALL setParent( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Parent ) throw(::com::sun::star::lang::NoSupportException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1018 :
1019 : // XPersistObject
1020 : virtual void SAL_CALL write( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectOutputStream >& OutStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1021 : virtual void SAL_CALL read( const ::com::sun::star::uno::Reference< ::com::sun::star::io::XObjectInputStream >& InStream ) throw(::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1022 :
1023 : // XBoundComponent
1024 : virtual sal_Bool SAL_CALL commit() throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1025 :
1026 : // XUpdateBroadcaster (base of XBoundComponent)
1027 : virtual void SAL_CALL addUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1028 : virtual void SAL_CALL removeUpdateListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::XUpdateListener >& aListener ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1029 :
1030 : // XPropertySet
1031 : virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const SAL_OVERRIDE;
1032 : virtual sal_Bool SAL_CALL convertFastPropertyValue(
1033 : ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue )
1034 : throw (::com::sun::star::lang::IllegalArgumentException) SAL_OVERRIDE;
1035 : virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue )
1036 : throw (::com::sun::star::uno::Exception, std::exception) SAL_OVERRIDE;
1037 : using ::cppu::OPropertySetHelper::getFastPropertyValue;
1038 :
1039 : // ::com::sun::star::beans::XPropertyState
1040 : virtual ::com::sun::star::uno::Any getPropertyDefaultByHandle( sal_Int32 nHandle ) const SAL_OVERRIDE;
1041 :
1042 : // XEventListener
1043 : virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1044 :
1045 : // XPropertyChangeListener
1046 : virtual void SAL_CALL propertyChange( const ::com::sun::star::beans::PropertyChangeEvent& evt ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1047 :
1048 : // XRowSetChangeListener
1049 : virtual void SAL_CALL onRowSetChanged( const ::com::sun::star::lang::EventObject& i_Event ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1050 :
1051 : // XLoadListener
1052 : virtual void SAL_CALL loaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1053 : virtual void SAL_CALL unloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1054 : virtual void SAL_CALL unloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1055 : virtual void SAL_CALL reloading( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1056 : virtual void SAL_CALL reloaded( const ::com::sun::star::lang::EventObject& aEvent ) throw(::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1057 :
1058 : protected:
1059 : // XBindableValue
1060 : virtual void SAL_CALL setValueBinding( const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding ) throw (::com::sun::star::form::binding::IncompatibleTypesException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1061 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding > SAL_CALL getValueBinding( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1062 :
1063 : // XModifyListener
1064 : virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& _rEvent ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1065 :
1066 : // XValidatable
1067 : virtual void SAL_CALL setValidator( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& Validator ) throw (::com::sun::star::util::VetoException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1068 : virtual ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator > SAL_CALL getValidator( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1069 :
1070 : // XValidityConstraintListener
1071 : virtual void SAL_CALL validityConstraintChanged( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1072 :
1073 : // XValidatableFormComponent
1074 : virtual sal_Bool SAL_CALL isValid( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1075 : virtual ::com::sun::star::uno::Any SAL_CALL getCurrentValue( ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1076 : virtual void SAL_CALL addFormComponentValidityListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XFormComponentValidityListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1077 : virtual void SAL_CALL removeFormComponentValidityListener( const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XFormComponentValidityListener >& Listener ) throw (::com::sun::star::lang::NullPointerException, ::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1078 :
1079 : protected:
1080 : // OPropertyChangeListener
1081 : virtual void
1082 : _propertyChanged( const ::com::sun::star::beans::PropertyChangeEvent& _rEvt ) throw ( ::com::sun::star::uno::RuntimeException ) SAL_OVERRIDE;
1083 :
1084 : /// checks whether we currently have an external value binding in place
1085 1191 : inline bool hasExternalValueBinding() const { return m_xExternalBinding.is(); }
1086 :
1087 : // checks whether we currently have an external validator
1088 745 : inline bool hasValidator() const { return m_xValidator.is(); }
1089 :
1090 : /** transfers the very current value of the db column we're bound to the control
1091 : @precond
1092 : our own mutex is locked
1093 : @precond
1094 : we don't have an external binding in place
1095 : */
1096 : void transferDbValueToControl( );
1097 :
1098 : /** transfers the current value of the active external binding to the control
1099 : @precond
1100 : we do have an active external binding in place
1101 : */
1102 : void transferExternalValueToControl( ControlModelLock& _rInstanceLock );
1103 :
1104 : /** transfers the control value to the external binding
1105 : @precond
1106 : our own mutex is locked, and _rInstanceLock is the guard locking it
1107 : @precond
1108 : we do have an active external binding in place
1109 : */
1110 : void transferControlValueToExternal( ControlModelLock& _rInstanceLock );
1111 :
1112 : /** calculates the type which is to be used to communicate with the current external binding,
1113 : and stores it in m_aExternalValueType
1114 :
1115 : The method checks the possible type candidates as returned by getSupportedBindingTypes,
1116 : and the types supported by the current external binding, if any.
1117 : */
1118 : void calculateExternalValueType();
1119 :
1120 : /** returns the type which should be used to exchange data with our external value binding
1121 :
1122 : @see initValueProperty
1123 : */
1124 : const ::com::sun::star::uno::Type&
1125 19 : getExternalValueType() const { return m_aExternalValueType; }
1126 :
1127 : /** initializes the control from m_xField
1128 :
1129 : Basically, this method calls transferDbValueToControl - but only if our cursor is positioned
1130 : on a valid row. Otherwise, the control is reset.
1131 :
1132 : @precond
1133 : m_xField is not <NULL/>
1134 : */
1135 : void initFromField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm );
1136 :
1137 : private:
1138 : bool connectToField( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& _rxForm );
1139 : void resetField();
1140 :
1141 : /** does a new validation of the control value
1142 :
1143 : If necessary, our <member>m_bIsCurrentValueValid</member> member will be adjusted,
1144 : and changes will be notified.
1145 :
1146 : Note that it's not necessary that we're connected to a validator. If we are not,
1147 : it's assumed that our value is valid, and this is handled appropriately.
1148 :
1149 : Use this method if there is a potential that <b>only</b> the validity flag changed. If
1150 : any of the other aspects (our current value, or our current text) changed, then
1151 : pass <TRUE/> for <member>_bForceNotification</member>.
1152 :
1153 : @param _bForceNotification
1154 : if <TRUE/>, then the validity listeners will be notified, not matter whether the validity
1155 : changed.
1156 : */
1157 : void recheckValidity( bool _bForceNotification );
1158 :
1159 : /// initializes m_pAggPropMultiplexer
1160 : void implInitAggMultiplexer( );
1161 :
1162 : /// initializes listening at the value property
1163 : void implInitValuePropertyListening( ) const;
1164 :
1165 : /** adds or removes the component as load listener to/from our form, and (if necessary) as RowSetChange listener at
1166 : our parent.
1167 :
1168 : @precond there must no external value binding be in place
1169 : */
1170 : void doFormListening( const bool _bStart );
1171 :
1172 1057 : inline bool isFormListening() const { return m_bFormListening; }
1173 :
1174 : /** determines the new value of m_xAmbientForm
1175 : */
1176 : void impl_determineAmbientForm_nothrow();
1177 :
1178 : /** connects to a value supplier which is an database column.
1179 :
1180 : The column is take from our parent, which must be a database form respectively row set.
1181 :
1182 : @precond The control does not have an external value supplier
1183 :
1184 : @param _bFromReload
1185 : Determines whether the connection is made after the row set has been loaded (<FALSE/>)
1186 : or reloaded (<TRUE/>)
1187 :
1188 : @see impl_disconnectDatabaseColumn_noNotify
1189 : */
1190 : void impl_connectDatabaseColumn_noNotify(
1191 : bool _bFromReload
1192 : );
1193 :
1194 : /** disconnects from a value supplier which is an database column
1195 :
1196 : @precond The control does not have an external value supplier
1197 : @see impl_connectDatabaseColumn_noNotify
1198 : */
1199 : void impl_disconnectDatabaseColumn_noNotify();
1200 :
1201 : /** connects to an external value binding
1202 :
1203 : <p>Note that by definition, external data bindings superseede the SQL data binding which
1204 : is defined by our RowSet-column-related properties. This means that in case we're currently
1205 : connected to a database column when this is called, this connection is suspended.</p>
1206 :
1207 : @precond
1208 : the new external binding has already been approved (see <member>impl_approveValueBinding_nolock</member>)
1209 : @precond
1210 : there currently is no external binding in place
1211 : */
1212 : void connectExternalValueBinding(
1213 : const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding,
1214 : ControlModelLock& _rInstanceLock
1215 : );
1216 :
1217 : /** disconnects from an external value binding
1218 :
1219 : @precond
1220 : there currently is an external binding in place
1221 : */
1222 : void disconnectExternalValueBinding( );
1223 :
1224 : /** connects the component to an external validator
1225 :
1226 : @precond
1227 : there currently is no active validator
1228 : @precond
1229 : our mutex is currently locked exactly once
1230 : */
1231 : void connectValidator(
1232 : const ::com::sun::star::uno::Reference< ::com::sun::star::form::validation::XValidator >& _rxValidator
1233 : );
1234 :
1235 : /** disconnects the component from its current an external validator
1236 :
1237 : @precond
1238 : there currently is an active validator
1239 : @precond
1240 : our mutex is currently locked exactly once
1241 : */
1242 : void disconnectValidator( );
1243 :
1244 : /** called from within <member scope="com::sun::star:::form::binding">XBindableValue::setValueBinding</member>
1245 : to approve the new binding
1246 :
1247 : The default implementation approves the binding if and only if it is not <NULL/>, and supports
1248 : the type returned by getExternalValueType.
1249 :
1250 : @param _rxBinding
1251 : the binding which applies for being responsible for our value, Must not be
1252 : <NULL/>
1253 : @return
1254 : <TRUE/> if and only if the given binding can supply values in the proper type
1255 :
1256 : @seealso getExternalValueType
1257 : */
1258 : bool impl_approveValueBinding_nolock(
1259 : const ::com::sun::star::uno::Reference< ::com::sun::star::form::binding::XValueBinding >& _rxBinding
1260 : );
1261 : };
1262 :
1263 :
1264 : //= inlines
1265 :
1266 1436 : inline void ControlModelLock::acquire()
1267 : {
1268 1436 : m_rModel.lockInstance( OControlModel::LockAccess() );
1269 1436 : m_bLocked = true;
1270 1436 : }
1271 1436 : inline void ControlModelLock::release()
1272 : {
1273 : OSL_ENSURE( m_bLocked, "ControlModelLock::release: not locked!" );
1274 1436 : m_bLocked = false;
1275 :
1276 1436 : if ( 0 == m_rModel.unlockInstance( OControlModel::LockAccess() ) )
1277 1409 : impl_notifyAll_nothrow();
1278 1436 : }
1279 :
1280 :
1281 : }
1282 :
1283 :
1284 : #endif // INCLUDED_FORMS_SOURCE_INC_FORMCOMPONENT_HXX
1285 :
1286 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|