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