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