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