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