1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef INCLUDED_COMPHELPER_PROPAGG_HXX
21 #define INCLUDED_COMPHELPER_PROPAGG_HXX
23 #include <config_options.h>
24 #include <com/sun/star/beans/Property.hpp>
25 #include <com/sun/star/beans/PropertyState.hpp>
26 #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
27 #include <com/sun/star/beans/XVetoableChangeListener.hpp>
28 #include <com/sun/star/lang/EventObject.hpp>
29 #include <comphelper/propstate.hxx>
30 #include <comphelper/comphelperdllapi.h>
37 //= property helper classes
45 //= internal helper class for OPropertyArrayAggregationHelper
49 struct OPropertyAccessor
51 sal_Int32 nOriginalHandle
;
55 OPropertyAccessor(sal_Int32 _nOriginalHandle
, sal_Int32 _nPos
, bool _bAggregate
)
56 :nOriginalHandle(_nOriginalHandle
) ,nPos(_nPos
) ,bAggregate(_bAggregate
) { }
58 :nOriginalHandle(-1) ,nPos(-1) ,bAggregate(false) { }
60 bool operator==(const OPropertyAccessor
& rOb
) const { return nPos
== rOb
.nPos
; }
61 bool operator <(const OPropertyAccessor
& rOb
) const { return nPos
< rOb
.nPos
; }
64 typedef std::map
< sal_Int32
, OPropertyAccessor
> PropertyAccessorMap
;
65 typedef PropertyAccessorMap::const_iterator ConstPropertyAccessorMapIterator
;
70 * used as callback for an OPropertyArrayAggregationHelper
72 class IPropertyInfoService
75 /** get the preferred handle for the given property
76 @param _rName the property name
77 @return the handle the property should be referred by, or -1 if there are no
78 preferences for the given property
80 virtual sal_Int32
getPreferredPropertyId(const OUString
& _rName
) = 0;
83 ~IPropertyInfoService() {}
87 * used for implementing a cppu::IPropertyArrayHelper for classes
88 * aggregating property sets
91 #define DEFAULT_AGGREGATE_PROPERTY_ID 10000
93 class COMPHELPER_DLLPUBLIC OPropertyArrayAggregationHelper final
: public ::cppu::IPropertyArrayHelper
95 friend class OPropertySetAggregationHelper
;
97 std::vector
<css::beans::Property
> m_aProperties
;
98 internal::PropertyAccessorMap m_aPropertyAccessors
;
101 /** construct the object.
102 @param _rProperties the properties of the object doing the aggregation. These properties
103 are used without any checks, so the caller has to ensure that the names and
105 @param _rAggProperties the properties of the aggregate, usually got via a call to getProperties on the
106 XPropertySetInfo of the aggregate.
107 The names of the properties are used without any checks, so the caller has to ensure
108 that there are no doubles.
109 The handles are stored for later quick access, but the outside-handles the
110 aggregate properties get depend from the following two parameters.
112 If not NULL, the object pointed to is used to calc handles which should be used
113 for referring the aggregate's properties from outside.
114 If one of the properties returned from the info service conflict with other handles
115 already present (e.g. through _rProperties), the property is handled as if -1 was returned.
116 If NULL (or, for a special property, a call to getPreferredPropertyId returns -1),
117 the aggregate property(ies) get a new handle which they can be referred by from outside.
118 @param _nFirstAggregateId
119 if the object is about to create new handles for the aggregate properties, it uses
120 id's ascending from this given id.
121 No checks are made if the handle range determined by _nFirstAggregateId conflicts with other
122 handles within _rProperties.
124 OPropertyArrayAggregationHelper(const css::uno::Sequence
< css::beans::Property
>& _rProperties
,
125 const css::uno::Sequence
< css::beans::Property
>& _rAggProperties
,
126 IPropertyInfoService
* _pInfoService
= nullptr,
127 sal_Int32 _nFirstAggregateId
= DEFAULT_AGGREGATE_PROPERTY_ID
);
130 /// inherited from IPropertyArrayHelper
131 virtual sal_Bool SAL_CALL
fillPropertyMembersByHandle( OUString
* _pPropName
, sal_Int16
* _pAttributes
,
132 sal_Int32 _nHandle
) override
;
134 /// inherited from IPropertyArrayHelper
135 virtual css::uno::Sequence
< css::beans::Property
> SAL_CALL
getProperties() override
;
136 /// inherited from IPropertyArrayHelper
137 virtual css::beans::Property SAL_CALL
getPropertyByName(const OUString
& _rPropertyName
) override
;
139 /// inherited from IPropertyArrayHelper
140 virtual sal_Bool SAL_CALL
hasPropertyByName(const OUString
& _rPropertyName
) override
;
141 /// inherited from IPropertyArrayHelper
142 virtual sal_Int32 SAL_CALL
getHandleByName(const OUString
& _rPropertyName
) override
;
143 /// inherited from IPropertyArrayHelper
144 virtual sal_Int32 SAL_CALL
fillHandles( /*out*/sal_Int32
* _pHandles
, const css::uno::Sequence
< OUString
>& _rPropNames
) override
;
146 /** returns information about a property of the aggregate.
147 @param _pPropName points to a string to receive the property name. No name is returned if this is NULL.
148 @param _pOriginalHandle points to a sal_Int32 to receive the original property handle. No original handle is returned
150 @param _nHandle the handle of the property as got by, for instance, fillHandles
152 @return sal_True, if _nHandle marks an aggregate property, otherwise sal_False
154 bool fillAggregatePropertyInfoByHandle(OUString
* _pPropName
, sal_Int32
* _pOriginalHandle
,
155 sal_Int32 _nHandle
) const;
157 /** returns information about a property given by handle
159 bool getPropertyByHandle( sal_Int32 _nHandle
, css::beans::Property
& _rProperty
) const;
162 enum class PropertyOrigin
168 /** prefer this one over the XPropertySetInfo of the aggregate!
170 <p>The reason is that OPropertyArrayAggregationHelper is the only instance which really knows
171 which properties of the aggregate are to be exposed. <br/>
173 For instance, some derivee of OPropertySetAggregationHelper may decide to create an
174 OPropertyArrayAggregationHelper which contains only a subset of the aggregate properties. This way,
175 some of the aggregate properties may be hidden to the public.<br/>
177 When using the XPropertySetInfo of the aggregate set to determine the existence of a property, then this
178 would return false positives.</p>
180 PropertyOrigin
classifyProperty( const OUString
& _rName
);
183 const css::beans::Property
* findPropertyByName(const OUString
& _rName
) const;
189 class PropertyForwarder
;
193 * helper class for implementing the property-set-related interfaces
194 * for an object doin' aggregation
195 * supports at least XPropertySet and XMultiPropertySet
198 class UNLESS_MERGELIBS(COMPHELPER_DLLPUBLIC
) OPropertySetAggregationHelper
:public OPropertyStateHelper
199 ,public css::beans::XPropertiesChangeListener
200 ,public css::beans::XVetoableChangeListener
202 friend class internal::PropertyForwarder
;
205 css::uno::Reference
< css::beans::XPropertyState
> m_xAggregateState
;
206 css::uno::Reference
< css::beans::XPropertySet
> m_xAggregateSet
;
207 css::uno::Reference
< css::beans::XMultiPropertySet
> m_xAggregateMultiSet
;
208 css::uno::Reference
< css::beans::XFastPropertySet
> m_xAggregateFastSet
;
210 std::unique_ptr
<internal::PropertyForwarder
> m_pForwarder
;
211 bool m_bListening
: 1;
214 OPropertySetAggregationHelper( ::cppu::OBroadcastHelper
& rBHelper
);
216 virtual css::uno::Any SAL_CALL
queryInterface(const css::uno::Type
& aType
) override
;
219 virtual void SAL_CALL
disposing(const css::lang::EventObject
& Source
) override
;
222 virtual void SAL_CALL
setFastPropertyValue(sal_Int32 nHandle
, const css::uno::Any
& aValue
) override
;
223 virtual css::uno::Any SAL_CALL
getFastPropertyValue(sal_Int32 nHandle
) override
;
226 virtual void SAL_CALL
addPropertyChangeListener(const OUString
& aPropertyName
, const css::uno::Reference
< css::beans::XPropertyChangeListener
>& xListener
) override
;
227 virtual void SAL_CALL
addVetoableChangeListener(const OUString
& PropertyName
, const css::uno::Reference
< css::beans::XVetoableChangeListener
>& aListener
) override
;
229 // XPropertiesChangeListener
230 virtual void SAL_CALL
propertiesChange(const css::uno::Sequence
< css::beans::PropertyChangeEvent
>& evt
) override
;
232 // XVetoableChangeListener
233 virtual void SAL_CALL
vetoableChange(const css::beans::PropertyChangeEvent
& aEvent
) override
;
236 virtual void SAL_CALL
setPropertyValues(const css::uno::Sequence
< OUString
>& PropertyNames
, const css::uno::Sequence
< css::uno::Any
>& Values
) override
;
237 virtual void SAL_CALL
addPropertiesChangeListener(const css::uno::Sequence
< OUString
>& aPropertyNames
, const css::uno::Reference
< css::beans::XPropertiesChangeListener
>& xListener
) override
;
240 virtual css::beans::PropertyState SAL_CALL
getPropertyState(const OUString
& PropertyName
) override
;
241 virtual void SAL_CALL
setPropertyToDefault(const OUString
& PropertyName
) override
;
242 virtual css::uno::Any SAL_CALL
getPropertyDefault(const OUString
& aPropertyName
) override
;
244 // OPropertySetHelper
245 /** still waiting to be overwritten ...
246 you <B>must<B/> use an OPropertyArrayAggregationHelper here, as the implementation strongly relies on this.
248 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper() override
= 0;
250 /** only implemented for "forwarded" properties, every other property must be handled
251 in the derivee, and will assert if passed herein
253 virtual sal_Bool SAL_CALL
convertFastPropertyValue( css::uno::Any
& _rConvertedValue
, css::uno::Any
& _rOldValue
, sal_Int32 _nHandle
, const css::uno::Any
& _rValue
) override
;
255 /** only implemented for "forwarded" properties, every other property must be handled
256 in the derivee, and will assert if passed herein
258 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle
, const css::uno::Any
& _rValue
) override
;
261 virtual ~OPropertySetAggregationHelper() override
;
263 virtual void SAL_CALL
getFastPropertyValue(css::uno::Any
& rValue
, sal_Int32 nHandle
) const override
;
266 sal_Int32
getOriginalHandle( sal_Int32 _nHandle
) const;
267 OUString
getPropertyName( sal_Int32 _nHandle
) const;
269 /** declares the property with the given (public) handle as one to be forwarded to the aggregate
271 Sometimes, you might want to <em>overwrite</em> properties at the aggregate. That is,
272 though the aggregate implements this property, and still is to hold the property value,
273 you want to do additional handling upon setting the property, but then forward the value
276 Use this method to declare such properties.
278 When a "forwarded property" is set from outside, the class first calls
279 <member>forwardingPropertyValue</member> for any preprocessing, then forwards the property
280 value to the aggregate, and then calls <member>forwardedPropertyValue</member>.
282 When you declare a property as "forwarded", the class takes care for some multi-threading
283 issues, for instance, it won't fire any property change notifications which result from
284 forwarding a property value, unless it's safe to do so (i.e. unless our mutex is
287 @see forwardingPropertyValue
288 @see forwardedPropertyValue
290 void declareForwardedProperty( sal_Int32 _nHandle
);
292 /** checks whether we're actually forwarding a property value to our aggregate
294 @see declareForwardedProperty
295 @see forwardingPropertyValue
296 @see forwardedPropertyValue
298 bool isCurrentlyForwardingProperty( sal_Int32 _nHandle
) const;
300 /** called immediately before a property value which is overwritten in this instance
301 is forwarded to the aggregate
303 @see declareForwardedProperty
304 @see forwardedPropertyValue
306 virtual void forwardingPropertyValue( sal_Int32 _nHandle
);
308 /** called immediately after a property value which is overwritten in this instance
309 has been forwarded to the aggregate
311 @see declareForwardedProperty
312 @see forwardingPropertyValue
314 virtual void forwardedPropertyValue( sal_Int32 _nHandle
);
316 /// must be called before aggregation, if aggregation is used
318 /// @throws css::lang::IllegalArgumentException
319 void setAggregation(const css::uno::Reference
< css::uno::XInterface
>&);
320 void startListening();
324 } // namespace comphelper
327 #endif // INCLUDED_COMPHELPER_PROPAGG_HXX
329 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */