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 : #include "OPropertySet.hxx"
21 : #include "ImplOPropertySet.hxx"
22 : #include "ContainerHelper.hxx"
23 : #include <cppuhelper/queryinterface.hxx>
24 : #include <comphelper/servicehelper.hxx>
25 :
26 : #include <vector>
27 : #include <algorithm>
28 : #include <boost/scoped_array.hpp>
29 :
30 : using namespace ::com::sun::star;
31 :
32 : using ::com::sun::star::style::XStyleSupplier;
33 :
34 : using ::com::sun::star::uno::Reference;
35 : using ::com::sun::star::uno::Sequence;
36 : using ::com::sun::star::uno::Any;
37 : using ::osl::MutexGuard;
38 :
39 : // needed for MS compiler
40 : using ::cppu::OBroadcastHelper;
41 : using ::cppu::OPropertySetHelper;
42 : using ::cppu::OWeakObject;
43 :
44 : namespace property
45 : {
46 :
47 0 : OPropertySet::OPropertySet( ::osl::Mutex & par_rMutex ) :
48 : OBroadcastHelper( par_rMutex ),
49 : // the following causes a warning; there seems to be no way to avoid it
50 : OPropertySetHelper( static_cast< OBroadcastHelper & >( *this )),
51 : m_rMutex( par_rMutex ),
52 0 : m_pImplProperties( new impl::ImplOPropertySet() ),
53 0 : m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
54 : {
55 0 : }
56 :
57 0 : OPropertySet::OPropertySet( const OPropertySet & rOther, ::osl::Mutex & par_rMutex ) :
58 : OBroadcastHelper( par_rMutex ),
59 : // the following causes a warning; there seems to be no way to avoid it
60 : OPropertySetHelper( static_cast< OBroadcastHelper & >( *this )),
61 : m_rMutex( par_rMutex ),
62 0 : m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
63 : {
64 0 : MutexGuard aGuard( m_rMutex );
65 0 : if( rOther.m_pImplProperties.get())
66 0 : m_pImplProperties.reset( new impl::ImplOPropertySet( * rOther.m_pImplProperties.get()));
67 0 : }
68 :
69 0 : void OPropertySet::SetNewValuesExplicitlyEvenIfTheyEqualDefault()
70 : {
71 0 : m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault = true;
72 0 : }
73 :
74 0 : OPropertySet::~OPropertySet()
75 0 : {}
76 :
77 0 : void OPropertySet::disposePropertySet()
78 : {
79 0 : m_pImplProperties.reset( 0 );
80 0 : }
81 :
82 0 : Any SAL_CALL OPropertySet::queryInterface( const uno::Type& aType )
83 : throw (uno::RuntimeException, std::exception)
84 : {
85 : return ::cppu::queryInterface(
86 : aType,
87 : static_cast< lang::XTypeProvider * >( this ),
88 : static_cast< beans::XPropertySet * >( this ),
89 : static_cast< beans::XMultiPropertySet * >( this ),
90 : static_cast< beans::XFastPropertySet * >( this ),
91 : static_cast< beans::XPropertyState * >( this ),
92 : static_cast< beans::XMultiPropertyStates * >( this ),
93 0 : static_cast< XStyleSupplier * >( this ) );
94 : }
95 :
96 : #define LCL_PROP_CPPUTYPE(t) (::getCppuType( reinterpret_cast< const Reference<t> *>(0)))
97 :
98 : // // ____ XTypeProvider ____
99 : Sequence< uno::Type > SAL_CALL
100 0 : OPropertySet::getTypes()
101 : throw (uno::RuntimeException, std::exception)
102 : {
103 0 : static Sequence< uno::Type > aTypeList;
104 :
105 0 : MutexGuard aGuard( m_rMutex );
106 :
107 0 : if( aTypeList.getLength() == 0 )
108 : {
109 0 : ::std::vector< uno::Type > aTypes;
110 :
111 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( lang::XTypeProvider ));
112 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XPropertySet ));
113 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XMultiPropertySet ));
114 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XFastPropertySet ));
115 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XPropertyState ));
116 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XMultiPropertyStates ));
117 0 : aTypes.push_back( LCL_PROP_CPPUTYPE( XStyleSupplier ));
118 :
119 0 : aTypeList = ::chart::ContainerHelper::ContainerToSequence( aTypes );
120 : }
121 :
122 0 : return aTypeList;
123 : }
124 :
125 : Sequence< sal_Int8 > SAL_CALL
126 0 : OPropertySet::getImplementationId()
127 : throw (uno::RuntimeException, std::exception)
128 : {
129 0 : return css::uno::Sequence<sal_Int8>();
130 : }
131 :
132 : // ____ XPropertyState ____
133 : beans::PropertyState SAL_CALL
134 0 : OPropertySet::getPropertyState( const OUString& PropertyName )
135 : throw (beans::UnknownPropertyException,
136 : uno::RuntimeException, std::exception)
137 : {
138 0 : cppu::IPropertyArrayHelper & rPH = getInfoHelper();
139 :
140 : return m_pImplProperties->GetPropertyStateByHandle(
141 0 : rPH.getHandleByName( PropertyName ));
142 : }
143 :
144 : Sequence< beans::PropertyState > SAL_CALL
145 0 : OPropertySet::getPropertyStates( const Sequence< OUString >& aPropertyName )
146 : throw (beans::UnknownPropertyException,
147 : uno::RuntimeException, std::exception)
148 : {
149 0 : cppu::IPropertyArrayHelper & rPH = getInfoHelper();
150 :
151 0 : boost::scoped_array<sal_Int32> pHandles(new sal_Int32[ aPropertyName.getLength() ]);
152 0 : rPH.fillHandles( pHandles.get(), aPropertyName );
153 :
154 0 : ::std::vector< sal_Int32 > aHandles( pHandles.get(), pHandles.get() + aPropertyName.getLength());
155 0 : pHandles.reset();
156 :
157 0 : return m_pImplProperties->GetPropertyStatesByHandle( aHandles );
158 : }
159 :
160 : void SAL_CALL
161 0 : OPropertySet::setPropertyToDefault( const OUString& PropertyName )
162 : throw (beans::UnknownPropertyException,
163 : uno::RuntimeException, std::exception)
164 : {
165 0 : cppu::IPropertyArrayHelper & rPH = getInfoHelper();
166 :
167 0 : m_pImplProperties->SetPropertyToDefault( rPH.getHandleByName( PropertyName ));
168 0 : firePropertyChangeEvent();
169 0 : }
170 :
171 : Any SAL_CALL
172 0 : OPropertySet::getPropertyDefault( const OUString& aPropertyName )
173 : throw (beans::UnknownPropertyException,
174 : lang::WrappedTargetException,
175 : uno::RuntimeException, std::exception)
176 : {
177 0 : cppu::IPropertyArrayHelper & rPH = getInfoHelper();
178 :
179 0 : return GetDefaultValue( rPH.getHandleByName( aPropertyName ) );
180 : }
181 :
182 : // ____ XMultiPropertyStates ____
183 :
184 : // Note: getPropertyStates() is already implemented in XPropertyState with the
185 : // same signature
186 :
187 : void SAL_CALL
188 0 : OPropertySet::setAllPropertiesToDefault()
189 : throw (uno::RuntimeException, std::exception)
190 : {
191 0 : m_pImplProperties->SetAllPropertiesToDefault();
192 0 : firePropertyChangeEvent();
193 0 : }
194 :
195 : void SAL_CALL
196 0 : OPropertySet::setPropertiesToDefault( const Sequence< OUString >& aPropertyNames )
197 : throw (beans::UnknownPropertyException,
198 : uno::RuntimeException, std::exception)
199 : {
200 0 : cppu::IPropertyArrayHelper & rPH = getInfoHelper();
201 :
202 0 : boost::scoped_array<sal_Int32> pHandles(new sal_Int32[ aPropertyNames.getLength() ]);
203 0 : rPH.fillHandles( pHandles.get(), aPropertyNames );
204 :
205 0 : ::std::vector< sal_Int32 > aHandles( pHandles.get(), pHandles.get() + aPropertyNames.getLength());
206 0 : pHandles.reset();
207 :
208 0 : m_pImplProperties->SetPropertiesToDefault( aHandles );
209 0 : }
210 :
211 : Sequence< Any > SAL_CALL
212 0 : OPropertySet::getPropertyDefaults( const Sequence< OUString >& aPropertyNames )
213 : throw (beans::UnknownPropertyException,
214 : lang::WrappedTargetException,
215 : uno::RuntimeException, std::exception)
216 : {
217 0 : ::cppu::IPropertyArrayHelper & rPH = getInfoHelper();
218 0 : const sal_Int32 nElements = aPropertyNames.getLength();
219 :
220 0 : Sequence< Any > aResult( nElements );
221 0 : Any * pResultArray = aResult.getArray();
222 0 : sal_Int32 nI = 0;
223 :
224 0 : for( ; nI < nElements; ++nI )
225 : {
226 0 : pResultArray[ nI ] = GetDefaultValue(
227 0 : rPH.getHandleByName( aPropertyNames[ nI ] ));
228 : }
229 :
230 0 : return aResult;
231 : }
232 :
233 0 : sal_Bool SAL_CALL OPropertySet::convertFastPropertyValue
234 : ( Any & rConvertedValue,
235 : Any & rOldValue,
236 : sal_Int32 nHandle,
237 : const Any& rValue )
238 : throw (lang::IllegalArgumentException)
239 : {
240 0 : getFastPropertyValue( rOldValue, nHandle );
241 : //accept longs also for short values
242 : {
243 : sal_Int16 nValue;
244 0 : if( (rOldValue>>=nValue) && !(rValue>>=nValue) )
245 : {
246 0 : sal_Int32 n32Value = 0;
247 0 : if( rValue>>=n32Value )
248 : {
249 0 : rConvertedValue = uno::makeAny( static_cast<sal_Int16>(n32Value) );
250 0 : return sal_True;
251 : }
252 :
253 0 : sal_Int64 n64Value = 0;
254 0 : if( rValue>>=n64Value )
255 : {
256 0 : rConvertedValue = uno::makeAny( static_cast<sal_Int16>(n64Value) );
257 0 : return sal_True;
258 : }
259 : }
260 : }
261 0 : rConvertedValue = rValue;
262 0 : if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault && rOldValue == rConvertedValue )
263 0 : return sal_False;//no change necessary
264 0 : return sal_True;
265 : }
266 :
267 0 : void SAL_CALL OPropertySet::setFastPropertyValue_NoBroadcast
268 : ( sal_Int32 nHandle,
269 : const Any& rValue )
270 : throw (uno::Exception, std::exception)
271 : {
272 : #if OSL_DEBUG_LEVEL > 0
273 : if( rValue.hasValue())
274 : {
275 : cppu::IPropertyArrayHelper & rPH = getInfoHelper();
276 : OUString aName;
277 : rPH.fillPropertyMembersByHandle( &aName, 0, nHandle );
278 : OSL_ENSURE( rValue.isExtractableTo( rPH.getPropertyByName( aName ).Type ),
279 : "Property type is wrong" );
280 : }
281 : #endif
282 :
283 0 : Any aDefault;
284 : try
285 : {
286 0 : aDefault = GetDefaultValue( nHandle );
287 : }
288 0 : catch( const beans::UnknownPropertyException& )
289 : {
290 0 : aDefault.clear();
291 : }
292 0 : m_pImplProperties->SetPropertyValueByHandle( nHandle, rValue );
293 0 : if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault && aDefault.hasValue() && aDefault == rValue ) //#i98893# don't export defaults to file
294 0 : m_pImplProperties->SetPropertyToDefault( nHandle );
295 : else
296 0 : m_pImplProperties->SetPropertyValueByHandle( nHandle, rValue );
297 0 : }
298 :
299 0 : void SAL_CALL OPropertySet::getFastPropertyValue
300 : ( Any& rValue,
301 : sal_Int32 nHandle ) const
302 : {
303 0 : if( ! m_pImplProperties->GetPropertyValueByHandle( rValue, nHandle ))
304 : {
305 : // property was not set -> try style
306 0 : uno::Reference< beans::XFastPropertySet > xStylePropSet( m_pImplProperties->GetStyle(), uno::UNO_QUERY );
307 0 : if( xStylePropSet.is() )
308 : {
309 : #ifdef DBG_UTIL
310 : {
311 : // check if the handle of the style points to the same property
312 : // name as the handle in this property set
313 : uno::Reference< beans::XPropertySet > xPropSet( xStylePropSet, uno::UNO_QUERY );
314 : if( xPropSet.is())
315 : {
316 : uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo(),
317 : uno::UNO_QUERY );
318 : if( xInfo.is() )
319 : {
320 : // for some reason the virtual method getInfoHelper() is
321 : // not const
322 : ::cppu::IPropertyArrayHelper & rPH =
323 : const_cast< OPropertySet * >( this )->getInfoHelper();
324 :
325 : // find the Property with Handle nHandle in Style
326 : Sequence< beans::Property > aProps( xInfo->getProperties() );
327 : sal_Int32 nI = aProps.getLength() - 1;
328 : while( ( nI >= 0 ) && nHandle != aProps[ nI ].Handle )
329 : --nI;
330 :
331 : if( nI >= 0 ) // => nHandle == aProps[nI].Handle
332 : {
333 : // check whether the handle in this property set is
334 : // the same as the one in the style
335 : beans::Property aProp( rPH.getPropertyByName( aProps[ nI ].Name ) );
336 : OSL_ENSURE( nHandle == aProp.Handle,
337 : "HandleCheck: Handles for same property differ!" );
338 :
339 : if( nHandle == aProp.Handle )
340 : {
341 : OSL_ENSURE( aProp.Type == aProps[nI].Type,
342 : "HandleCheck: Types differ!" );
343 : OSL_ENSURE( aProp.Attributes == aProps[nI].Attributes,
344 : "HandleCheck: Attributes differ!" );
345 : }
346 : }
347 : else
348 : {
349 : OSL_FAIL( "HandleCheck: Handle not found in Style" );
350 : }
351 : }
352 : else
353 : OSL_FAIL( "HandleCheck: Invalid XPropertySetInfo returned" );
354 : }
355 : else
356 : OSL_FAIL( "HandleCheck: XPropertySet not supported" );
357 : }
358 : #endif
359 0 : rValue = xStylePropSet->getFastPropertyValue( nHandle );
360 : }
361 : else
362 : {
363 : // there is no style (or the style does not support XFastPropertySet)
364 : // => take the default value
365 : try
366 : {
367 0 : rValue = GetDefaultValue( nHandle );
368 : }
369 0 : catch( const beans::UnknownPropertyException& )
370 : {
371 0 : rValue.clear();
372 : }
373 0 : }
374 : }
375 0 : }
376 :
377 0 : void OPropertySet::firePropertyChangeEvent()
378 : {
379 : // nothing in base class
380 0 : }
381 :
382 : // ____ XStyleSupplier ____
383 0 : Reference< style::XStyle > SAL_CALL OPropertySet::getStyle()
384 : throw (uno::RuntimeException, std::exception)
385 : {
386 0 : return m_pImplProperties->GetStyle();
387 : }
388 :
389 0 : void SAL_CALL OPropertySet::setStyle( const Reference< style::XStyle >& xStyle )
390 : throw (lang::IllegalArgumentException,
391 : uno::RuntimeException, std::exception)
392 : {
393 0 : if( ! m_pImplProperties->SetStyle( xStyle ))
394 : throw lang::IllegalArgumentException(
395 : "Empty Style",
396 : static_cast< beans::XPropertySet * >( this ),
397 0 : 0 );
398 0 : }
399 :
400 : // ____ XMultiPropertySet ____
401 0 : void SAL_CALL OPropertySet::setPropertyValues(
402 : const Sequence< OUString >& PropertyNames, const Sequence< Any >& Values )
403 : throw(beans::PropertyVetoException,
404 : lang::IllegalArgumentException,
405 : lang::WrappedTargetException,
406 : uno::RuntimeException, std::exception)
407 : {
408 0 : ::cppu::OPropertySetHelper::setPropertyValues( PropertyNames, Values );
409 :
410 0 : firePropertyChangeEvent();
411 0 : }
412 :
413 : // ____ XFastPropertySet ____
414 0 : void SAL_CALL OPropertySet::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
415 : throw(beans::UnknownPropertyException,
416 : beans::PropertyVetoException,
417 : lang::IllegalArgumentException,
418 : lang::WrappedTargetException, uno::RuntimeException, std::exception)
419 : {
420 0 : ::cppu::OPropertySetHelper::setFastPropertyValue( nHandle, rValue );
421 :
422 0 : firePropertyChangeEvent();
423 0 : }
424 :
425 : } // namespace property
426 :
427 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|