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