1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #ifndef _COMPHELPER_PROPERTY_AGGREGATION_HXX_ 29 #define _COMPHELPER_PROPERTY_AGGREGATION_HXX_ 30 31 #include <com/sun/star/uno/XAggregation.hpp> 32 #include <comphelper/propstate.hxx> 33 #include "comphelper/comphelperdllapi.h" 34 35 #include <map> 36 37 //========================================================================= 38 //= property helper classes 39 //========================================================================= 40 41 //......................................................................... 42 namespace comphelper 43 { 44 //......................................................................... 45 46 //================================================================== 47 //= OPropertyAccessor 48 //= internal helper class for OPropertyArrayAggregationHelper 49 //================================================================== 50 namespace internal 51 { 52 struct OPropertyAccessor 53 { 54 sal_Int32 nOriginalHandle; 55 sal_Int32 nPos; 56 sal_Bool bAggregate; 57 58 OPropertyAccessor(sal_Int32 _nOriginalHandle, sal_Int32 _nPos, sal_Bool _bAggregate) 59 :nOriginalHandle(_nOriginalHandle) ,nPos(_nPos) ,bAggregate(_bAggregate) { } 60 OPropertyAccessor() 61 :nOriginalHandle(-1) ,nPos(-1) ,bAggregate(sal_False) { } 62 63 sal_Bool operator==(const OPropertyAccessor& rOb) const { return nPos == rOb.nPos; } 64 sal_Bool operator <(const OPropertyAccessor& rOb) const { return nPos < rOb.nPos; } 65 }; 66 67 typedef std::map< sal_Int32, OPropertyAccessor, ::std::less< sal_Int32 > > PropertyAccessorMap; 68 typedef PropertyAccessorMap::iterator PropertyAccessorMapIterator; 69 typedef PropertyAccessorMap::const_iterator ConstPropertyAccessorMapIterator; 70 } 71 72 //================================================================== 73 /** 74 * used as callback for a OPropertyArrayAggregationHelper 75 */ 76 class IPropertyInfoService 77 { 78 public: 79 /** get the prefered handle for the given property 80 @param _rName the property name 81 @return the handle the property should be refered by, or -1 if there are no 82 preferences for the given property 83 */ 84 virtual sal_Int32 getPreferedPropertyId(const ::rtl::OUString& _rName) = 0; 85 }; 86 87 /** 88 * used for implementing an cppu::IPropertyArrayHelper for classes 89 * aggregating property sets 90 */ 91 92 #define DEFAULT_AGGREGATE_PROPERTY_ID 10000 93 //------------------------------------------------------------------ 94 class COMPHELPER_DLLPUBLIC OPropertyArrayAggregationHelper: public ::cppu::IPropertyArrayHelper 95 { 96 friend class OPropertySetAggregationHelper; 97 protected: 98 99 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> m_aProperties; 100 internal::PropertyAccessorMap m_aPropertyAccessors; 101 102 public: 103 /** construct the object. 104 @param _rProperties the properties of the object doing the aggregation. These properties 105 are used without any checks, so the caller has to ensure that the names and 106 handles are valid. 107 @param _rAggProperties the properties of the aggregate, usually got via an call to getProperties on the 108 XPropertySetInfo of the aggregate. 109 The names of the properties are used without any checks, so the caller has to ensure 110 that there are no doubles. 111 The handles are stored for later quick access, but the outside-handles the 112 aggregate properties get depend from the following two parameters. 113 @param _pInfoService 114 If not NULL, the object pointed to is used to calc handles which should be used 115 for refering the aggregate's properties from outside. 116 If one of the properties returned from the info service conflict with other handles 117 alread present (e.g. through _rProperties), the property is handled as if -1 was returned. 118 If NULL (or, for a special property, a call to getPreferedPropertyId returns -1), 119 the aggregate property(ies) get a new handle which they can be refered by from outside. 120 @param _nFirstAggregateId 121 if the object is about to create new handles for the aggregate properties, it uses 122 id's ascending from this given id. 123 No checks are made if the handle range determined by _nFirstAggregateId conflicts with other 124 handles within _rProperties. 125 */ 126 OPropertyArrayAggregationHelper(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& _rProperties, 127 const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property>& _rAggProperties, 128 IPropertyInfoService* _pInfoService = NULL, 129 sal_Int32 _nFirstAggregateId = DEFAULT_AGGREGATE_PROPERTY_ID); 130 131 132 /// inherited from IPropertyArrayHelper 133 virtual sal_Bool SAL_CALL fillPropertyMembersByHandle( ::rtl::OUString* _pPropName, sal_Int16* _pAttributes, 134 sal_Int32 _nHandle) ; 135 136 /// inherited from IPropertyArrayHelper 137 virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> SAL_CALL getProperties(); 138 /// inherited from IPropertyArrayHelper 139 virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName(const ::rtl::OUString& _rPropertyName) 140 throw(::com::sun::star::beans::UnknownPropertyException); 141 142 /// inherited from IPropertyArrayHelper 143 virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& _rPropertyName) ; 144 /// inherited from IPropertyArrayHelper 145 virtual sal_Int32 SAL_CALL getHandleByName(const ::rtl::OUString & _rPropertyName); 146 /// inherited from IPropertyArrayHelper 147 virtual sal_Int32 SAL_CALL fillHandles( /*out*/sal_Int32* _pHandles, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropNames ); 148 149 /** returns information about a property of the aggregate. 150 @param _pPropName points to a string to recieve the property name. No name is returned if this is NULL. 151 @param _pOriginalHandle points to a sal_Int32 to recieve the original property hande. No original handle is returned 152 if this is NULL. 153 @param _nHandle the handle of the property as got by, for instance, fillHandles 154 155 @return sal_True, if _nHandle marks an aggregate property, otherwise sal_False 156 */ 157 virtual sal_Bool SAL_CALL fillAggregatePropertyInfoByHandle(::rtl::OUString* _pPropName, sal_Int32* _pOriginalHandle, 158 sal_Int32 _nHandle) const; 159 160 /** returns information about a property given by handle 161 */ 162 sal_Bool getPropertyByHandle( sal_Int32 _nHandle, ::com::sun::star::beans::Property& _rProperty ) const; 163 164 165 enum PropertyOrigin 166 { 167 AGGREGATE_PROPERTY, 168 DELEGATOR_PROPERTY, 169 UNKNOWN_PROPERTY 170 }; 171 /** prefer this one over the XPropertySetInfo of the aggregate! 172 173 <p>The reason is that OPropertyArrayAggregationHelper is the only instance which really knows 174 which properties of the aggregate are to be exposed. <br/> 175 176 For instance, some derivee of OPropertySetAggregationHelper may decide to create an 177 OPropertyArrayAggregationHelper which contains only a subset of the aggregate properties. This way, 178 some of the aggregate properties may be hidded to the public.<br/> 179 180 When using the XPropertySetInfo of the aggregate set to determine the existence of a property, then this 181 would return false positives.</p> 182 */ 183 PropertyOrigin classifyProperty( const ::rtl::OUString& _rName ); 184 185 protected: 186 const ::com::sun::star::beans::Property* findPropertyByName(const ::rtl::OUString& _rName) const; 187 }; 188 189 //================================================================== 190 namespace internal 191 { 192 class PropertyForwarder; 193 } 194 195 /** 196 * helper class for implementing the property-set-related interfaces 197 * for an object doin' aggregation 198 * supports at least XPropertySet and XMultiPropertySet 199 * 200 */ 201 class COMPHELPER_DLLPUBLIC OPropertySetAggregationHelper :public OPropertyStateHelper 202 ,public ::com::sun::star::beans::XPropertiesChangeListener 203 ,public ::com::sun::star::beans::XVetoableChangeListener 204 { 205 friend class internal::PropertyForwarder; 206 207 protected: 208 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyState> m_xAggregateState; 209 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> m_xAggregateSet; 210 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XMultiPropertySet> m_xAggregateMultiSet; 211 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet> m_xAggregateFastSet; 212 213 internal::PropertyForwarder* m_pForwarder; 214 sal_Bool m_bListening : 1; 215 216 public: 217 OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHelper ); 218 219 virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(const ::com::sun::star::uno::Type& aType) throw(::com::sun::star::uno::RuntimeException); 220 221 // XEventListener 222 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw (::com::sun::star::uno::RuntimeException); 223 224 // XFastPropertySet 225 virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) 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); 226 virtual ::com::sun::star::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 227 228 // XPropertySet 229 virtual void SAL_CALL addPropertyChangeListener(const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 230 virtual void SAL_CALL addVetoableChangeListener(const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 231 232 // XPropertiesChangeListener 233 virtual void SAL_CALL propertiesChange(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent >& evt) throw(::com::sun::star::uno::RuntimeException); 234 235 // XVetoableChangeListener 236 virtual void SAL_CALL vetoableChange(const ::com::sun::star::beans::PropertyChangeEvent& aEvent) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException); 237 238 // XMultiPropertySet 239 virtual void SAL_CALL setPropertyValues(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& PropertyNames, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values) throw(::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 240 virtual void SAL_CALL addPropertiesChangeListener(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener >& xListener) throw(::com::sun::star::uno::RuntimeException); 241 242 // XPropertyState 243 virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); 244 virtual void SAL_CALL setPropertyToDefault(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); 245 virtual ::com::sun::star::uno::Any SAL_CALL getPropertyDefault(const ::rtl::OUString& aPropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); 246 247 // OPropertySetHelper 248 /** still waiting to be overwritten ... 249 you <B>must<B/> use an OPropertyArrayAggregationHelper here, as the implementation strongly relies on this. 250 */ 251 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() = 0; 252 253 /** only implemented for "forwarded" properties, every other property must be handled 254 in the derivee, and will assert if passed herein 255 */ 256 virtual sal_Bool SAL_CALL convertFastPropertyValue( ::com::sun::star::uno::Any& _rConvertedValue, ::com::sun::star::uno::Any& _rOldValue, sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw(::com::sun::star::lang::IllegalArgumentException); 257 258 /** only implemented for "forwarded" properties, every other property must be handled 259 in the derivee, and will assert if passed herein 260 */ 261 virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const ::com::sun::star::uno::Any& _rValue ) throw ( ::com::sun::star::uno::Exception ); 262 263 protected: 264 ~OPropertySetAggregationHelper(); 265 266 virtual void SAL_CALL getFastPropertyValue(::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const; 267 virtual void SAL_CALL disposing(); 268 269 sal_Int32 getOriginalHandle( sal_Int32 _nHandle ) const; 270 ::rtl::OUString getPropertyName( sal_Int32 _nHandle ) const; 271 272 /** declares the property with the given (public) handle as one to be forwarded to the aggregate 273 274 Sometimes, you might want to <em>overwrite</em> properties at the aggregate. That is, 275 though the aggregate implements this property, and still is to hold the property value, 276 you want to do additional handling upon setting the property, but then forward the value 277 to the aggregate. 278 279 Use this method to declare such properties. 280 281 When a "forwarded property" is set from outside, the class first calls 282 <member>forwardingPropertyValue</member> for any preprocessing, then forwards the property 283 value to the aggregate, and then calls <member>forwardedPropertyValue</member>. 284 285 When you declare a property as "forwarded", the class takes care for some multi-threading 286 issues, for instance, it won't fire any property change notifications which result from 287 forwarding a property value, unless it's safe to do so (i.e. unless our mutex is 288 released). 289 290 @see forwardingPropertyValue 291 @see forwardedPropertyValue 292 */ 293 void declareForwardedProperty( sal_Int32 _nHandle ); 294 295 /** checks whether we're actually forwarding a property value to our aggregate 296 297 @see declareForwardedProperty 298 @see forwardingPropertyValue 299 @see forwardedPropertyValue 300 */ 301 bool isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const; 302 303 /** called immediately before a property value which is overwritten in this instance 304 is forwarded to the aggregate 305 306 @see declareForwardedProperty 307 @see forwardedPropertyValue 308 */ 309 virtual void SAL_CALL forwardingPropertyValue( sal_Int32 _nHandle ); 310 311 /** called immediately after a property value which is overwritten in this instance 312 has been forwarded to the aggregate 313 314 @see declareForwardedProperty 315 @see forwardingPropertyValue 316 */ 317 virtual void SAL_CALL forwardedPropertyValue( sal_Int32 _nHandle, bool _bSuccess ); 318 319 /// must be called before aggregation, if aggregation is used 320 void setAggregation(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >&) throw( ::com::sun::star::lang::IllegalArgumentException ); 321 void startListening(); 322 }; 323 324 //......................................................................... 325 } // namespace comphelper 326 //......................................................................... 327 328 #endif // _COMPHELPER_PROPERTY_AGGREGATION_HXX_ 329 330