1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "OPropertySet.hxx"
27 #include "ImplOPropertySet.hxx"
28 #include "ContainerHelper.hxx"
29 #include <rtl/uuid.h>
30 #include <cppuhelper/queryinterface.hxx>
31 
32 #include <vector>
33 #include <algorithm>
34 
35 using namespace ::com::sun::star;
36 
37 using ::com::sun::star::style::XStyleSupplier;
38 // using ::com::sun::star::beans::XFastPropertyState;
39 
40 using ::com::sun::star::uno::Reference;
41 using ::com::sun::star::uno::Sequence;
42 using ::com::sun::star::uno::Any;
43 using ::rtl::OUString;
44 using ::osl::MutexGuard;
45 
46 // needed for MS compiler
47 using ::cppu::OBroadcastHelper;
48 using ::cppu::OPropertySetHelper;
49 using ::cppu::OWeakObject;
50 
51 namespace property
52 {
53 
OPropertySet(::osl::Mutex & par_rMutex)54 OPropertySet::OPropertySet( ::osl::Mutex & par_rMutex ) :
55         OBroadcastHelper( par_rMutex ),
56         // the following causes a warning; there seems to be no way to avoid it
57         OPropertySetHelper( static_cast< OBroadcastHelper & >( *this )),
58         m_rMutex( par_rMutex ),
59         m_pImplProperties( new impl::ImplOPropertySet() ),
60         m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
61 {
62 }
63 
OPropertySet(const OPropertySet & rOther,::osl::Mutex & par_rMutex)64 OPropertySet::OPropertySet( const OPropertySet & rOther, ::osl::Mutex & par_rMutex ) :
65         OBroadcastHelper( par_rMutex ),
66         // the following causes a warning; there seems to be no way to avoid it
67         OPropertySetHelper( static_cast< OBroadcastHelper & >( *this )),
68         m_rMutex( par_rMutex ),
69         m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault(false)
70 {
71     // /--
72     MutexGuard aGuard( m_rMutex );
73     if( rOther.m_pImplProperties.get())
74         m_pImplProperties.reset( new impl::ImplOPropertySet( * rOther.m_pImplProperties.get()));
75     // \--
76 }
77 
SetNewValuesExplicitlyEvenIfTheyEqualDefault()78 void OPropertySet::SetNewValuesExplicitlyEvenIfTheyEqualDefault()
79 {
80     m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault = true;
81 }
82 
~OPropertySet()83 OPropertySet::~OPropertySet()
84 {}
85 
disposePropertySet()86 void OPropertySet::disposePropertySet()
87 {
88     m_pImplProperties.reset( 0 );
89 }
90 
queryInterface(const uno::Type & aType)91 Any SAL_CALL OPropertySet::queryInterface( const uno::Type& aType )
92     throw (uno::RuntimeException)
93 {
94     return ::cppu::queryInterface(
95         aType,
96 //         static_cast< uno::XInterface * >(
97 //             static_cast< uno::XWeak * >( this )),
98 //         static_cast< uno::XWeak * >( this ),
99 //         static_cast< lang::XServiceInfo * >( this ),
100         static_cast< lang::XTypeProvider * >( this ),
101         static_cast< beans::XPropertySet * >( this ),
102         static_cast< beans::XMultiPropertySet * >( this ),
103         static_cast< beans::XFastPropertySet * >( this ),
104         static_cast< beans::XPropertyState * >( this ),
105         static_cast< beans::XMultiPropertyStates * >( this ),
106         static_cast< XStyleSupplier * >( this ) );
107 //         static_cast< XFastPropertyState * >( this ) );
108 }
109 
110 // void SAL_CALL OPropertySet::acquire() throw ()
111 // {
112 //     OWeakObject::acquire();
113 // }
114 
115 // void SAL_CALL OPropertySet::release() throw ()
116 // {
117 //     OWeakObject::release();
118 // }
119 
120 
121 // ____ XServiceInfo ____
122 // OUString SAL_CALL
123 //     OPropertySet::getImplementationName()
124 //     throw (uno::RuntimeException)
125 // {
126 //     return OUString( RTL_CONSTASCII_USTRINGPARAM( "property::OPropertySet" ));
127 // }
128 
129 // sal_Bool SAL_CALL
130 //     OPropertySet::supportsService( const OUString& ServiceName )
131 //     throw (uno::RuntimeException)
132 // {
133 //     return ( 0 == ServiceName.reverseCompareToAsciiL(
134 //                  RTL_CONSTASCII_STRINGPARAM( "com.sun.star.beans.PropertySet" )));
135 // }
136 
137 // Sequence< OUString > SAL_CALL
138 //     OPropertySet::getSupportedServiceNames()
139 //     throw (uno::RuntimeException)
140 // {
141 //     Sequence< OUString > aServiceNames( 1 );
142 //     aServiceNames[ 0 ] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.beans.PropertySet" ));
143 //     return aServiceNames;
144 // }
145 
146 #define LCL_PROP_CPPUTYPE(t) (::getCppuType( reinterpret_cast< const Reference<t> *>(0)))
147 
148 // // ____ XTypeProvider ____
149 Sequence< uno::Type > SAL_CALL
getTypes()150     OPropertySet::getTypes()
151     throw (uno::RuntimeException)
152 {
153     static Sequence< uno::Type > aTypeList;
154 
155     // /--
156     MutexGuard aGuard( m_rMutex );
157 
158     if( aTypeList.getLength() == 0 )
159     {
160         ::std::vector< uno::Type > aTypes;
161 
162 //         aTypes.push_back( LCL_PROP_CPPUTYPE( uno::XWeak ));
163 //         aTypes.push_back( LCL_PROP_CPPUTYPE( lang::XServiceInfo ));
164         aTypes.push_back( LCL_PROP_CPPUTYPE( lang::XTypeProvider ));
165         aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XPropertySet ));
166         aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XMultiPropertySet ));
167         aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XFastPropertySet ));
168         aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XPropertyState ));
169         aTypes.push_back( LCL_PROP_CPPUTYPE( beans::XMultiPropertyStates ));
170         aTypes.push_back( LCL_PROP_CPPUTYPE( XStyleSupplier ));
171 //         aTypes.push_back( LCL_PROP_CPPUTYPE( XFastPropertyState ));
172 
173         aTypeList = ::chart::ContainerHelper::ContainerToSequence( aTypes );
174     }
175 
176     return aTypeList;
177     // \--
178 }
179 
180 Sequence< sal_Int8 > SAL_CALL
getImplementationId()181     OPropertySet::getImplementationId()
182     throw (uno::RuntimeException)
183 {
184 	static uno::Sequence< sal_Int8 > aId;
185 	if( aId.getLength() == 0 )
186 	{
187 		aId.realloc( 16 );
188 		rtl_createUuid( (sal_uInt8 *)aId.getArray(), 0, sal_True );
189 	}
190 	return aId;
191 }
192 
193 
194 // ____ XPropertyState ____
195 beans::PropertyState SAL_CALL
getPropertyState(const OUString & PropertyName)196     OPropertySet::getPropertyState( const OUString& PropertyName )
197     throw (beans::UnknownPropertyException,
198            uno::RuntimeException)
199 {
200 	cppu::IPropertyArrayHelper & rPH = getInfoHelper();
201 
202     return m_pImplProperties->GetPropertyStateByHandle(
203         rPH.getHandleByName( PropertyName ));
204 }
205 
206 Sequence< beans::PropertyState > SAL_CALL
getPropertyStates(const Sequence<OUString> & aPropertyName)207     OPropertySet::getPropertyStates( const Sequence< OUString >& aPropertyName )
208     throw (beans::UnknownPropertyException,
209            uno::RuntimeException)
210 {
211 	cppu::IPropertyArrayHelper & rPH = getInfoHelper();
212 
213     sal_Int32 * pHandles = new sal_Int32[ aPropertyName.getLength() ];
214     rPH.fillHandles( pHandles, aPropertyName );
215 
216     ::std::vector< sal_Int32 > aHandles( pHandles, pHandles + aPropertyName.getLength());
217     delete[] pHandles;
218 
219     return m_pImplProperties->GetPropertyStatesByHandle( aHandles );
220 }
221 
222 void SAL_CALL
setPropertyToDefault(const OUString & PropertyName)223     OPropertySet::setPropertyToDefault( const OUString& PropertyName )
224     throw (beans::UnknownPropertyException,
225            uno::RuntimeException)
226 {
227 	cppu::IPropertyArrayHelper & rPH = getInfoHelper();
228 
229     m_pImplProperties->SetPropertyToDefault( rPH.getHandleByName( PropertyName ));
230     firePropertyChangeEvent();
231 }
232 
233 Any SAL_CALL
getPropertyDefault(const OUString & aPropertyName)234     OPropertySet::getPropertyDefault( const OUString& aPropertyName )
235     throw (beans::UnknownPropertyException,
236            lang::WrappedTargetException,
237            uno::RuntimeException)
238 {
239 	cppu::IPropertyArrayHelper & rPH = getInfoHelper();
240 
241     return GetDefaultValue( rPH.getHandleByName( aPropertyName ) );
242 }
243 
244 
245 // ____ XMultiPropertyStates ____
246 
247 // Note: getPropertyStates() is already implemented in XPropertyState with the
248 // same signature
249 
250 void SAL_CALL
setAllPropertiesToDefault()251     OPropertySet::setAllPropertiesToDefault()
252     throw (uno::RuntimeException)
253 {
254     m_pImplProperties->SetAllPropertiesToDefault();
255     firePropertyChangeEvent();
256 }
257 
258 void SAL_CALL
setPropertiesToDefault(const Sequence<OUString> & aPropertyNames)259     OPropertySet::setPropertiesToDefault( const Sequence< OUString >& aPropertyNames )
260     throw (beans::UnknownPropertyException,
261            uno::RuntimeException)
262 {
263 	cppu::IPropertyArrayHelper & rPH = getInfoHelper();
264 
265     sal_Int32 * pHandles = new sal_Int32[ aPropertyNames.getLength() ];
266     rPH.fillHandles( pHandles, aPropertyNames );
267 
268     ::std::vector< sal_Int32 > aHandles( pHandles, pHandles + aPropertyNames.getLength());
269     delete[] pHandles;
270 
271     m_pImplProperties->SetPropertiesToDefault( aHandles );
272 }
273 
274 Sequence< Any > SAL_CALL
getPropertyDefaults(const Sequence<OUString> & aPropertyNames)275     OPropertySet::getPropertyDefaults( const Sequence< OUString >& aPropertyNames )
276     throw (beans::UnknownPropertyException,
277            lang::WrappedTargetException,
278            uno::RuntimeException)
279 {
280 	::cppu::IPropertyArrayHelper & rPH = getInfoHelper();
281     const sal_Int32 nElements = aPropertyNames.getLength();
282 
283     Sequence< Any > aResult( nElements );
284     Any * pResultArray = aResult.getArray();
285     sal_Int32 nI = 0;
286 
287     for( ; nI < nElements; ++nI )
288     {
289         pResultArray[ nI ] = GetDefaultValue(
290             rPH.getHandleByName( aPropertyNames[ nI ] ));
291     }
292 
293     return aResult;
294 }
295 
convertFastPropertyValue(Any & rConvertedValue,Any & rOldValue,sal_Int32 nHandle,const Any & rValue)296 sal_Bool SAL_CALL OPropertySet::convertFastPropertyValue
297     ( Any & rConvertedValue,
298       Any & rOldValue,
299       sal_Int32 nHandle,
300       const Any& rValue )
301     throw (lang::IllegalArgumentException)
302 {
303     getFastPropertyValue( rOldValue, nHandle );
304     //accept longs also for short values
305     {
306         sal_Int16 nValue;
307         if( (rOldValue>>=nValue) && !(rValue>>=nValue) )
308         {
309             sal_Int32 n32Value = 0;
310             if( rValue>>=n32Value )
311             {
312                 rConvertedValue = uno::makeAny( static_cast<sal_Int16>(n32Value) );
313                 return sal_True;
314             }
315 
316             sal_Int64 n64Value = 0;
317             if( rValue>>=n64Value )
318             {
319                 rConvertedValue = uno::makeAny( static_cast<sal_Int16>(n64Value) );
320                 return sal_True;
321             }
322         }
323     }
324     rConvertedValue = rValue;
325     if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault && rOldValue == rConvertedValue )
326         return sal_False;//no change necessary
327     return sal_True;
328 }
329 
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const Any & rValue)330 void SAL_CALL OPropertySet::setFastPropertyValue_NoBroadcast
331     ( sal_Int32 nHandle,
332       const Any& rValue )
333     throw (uno::Exception)
334 {
335 #if OSL_DEBUG_LEVEL > 0
336     if( rValue.hasValue())
337     {
338         cppu::IPropertyArrayHelper & rPH = getInfoHelper();
339         OUString aName;
340         rPH.fillPropertyMembersByHandle( &aName, 0, nHandle );
341         OSL_ENSURE( rValue.isExtractableTo( rPH.getPropertyByName( aName ).Type ),
342                     "Property type is wrong" );
343     }
344 #endif
345 
346     Any aDefault;
347     try
348     {
349         aDefault = GetDefaultValue( nHandle );
350     }
351     catch( beans::UnknownPropertyException ex )
352     {
353         aDefault.clear();
354     }
355     m_pImplProperties->SetPropertyValueByHandle( nHandle, rValue );
356     if( !m_bSetNewValuesExplicitlyEvenIfTheyEqualDefault && aDefault.hasValue() && aDefault == rValue ) //#i98893# don't export defaults to file
357         m_pImplProperties->SetPropertyToDefault( nHandle );
358     else
359         m_pImplProperties->SetPropertyValueByHandle( nHandle, rValue );
360 }
361 
getFastPropertyValue(Any & rValue,sal_Int32 nHandle) const362 void SAL_CALL OPropertySet::getFastPropertyValue
363     ( Any& rValue,
364       sal_Int32 nHandle ) const
365 {
366     if( ! m_pImplProperties->GetPropertyValueByHandle( rValue, nHandle ))
367     {
368 //         OSL_TRACE( "OPropertySet: asking style for property" );
369         // property was not set -> try style
370         uno::Reference< beans::XFastPropertySet > xStylePropSet( m_pImplProperties->GetStyle(), uno::UNO_QUERY );
371         if( xStylePropSet.is() )
372         {
373 #ifdef DBG_UTIL
374             {
375                 // check if the handle of the style points to the same property
376                 // name as the handle in this property set
377                 uno::Reference< beans::XPropertySet > xPropSet( xStylePropSet, uno::UNO_QUERY );
378                 if( xPropSet.is())
379                 {
380                     uno::Reference< beans::XPropertySetInfo > xInfo( xPropSet->getPropertySetInfo(),
381                                                                      uno::UNO_QUERY );
382                     if( xInfo.is() )
383                     {
384                         // for some reason the virtual method getInfoHelper() is
385                         // not const
386                         ::cppu::IPropertyArrayHelper & rPH =
387                               const_cast< OPropertySet * >( this )->getInfoHelper();
388 
389                         // find the Property with Handle nHandle in Style
390                         Sequence< beans::Property > aProps( xInfo->getProperties() );
391                         sal_Int32 nI = aProps.getLength() - 1;
392                         while( ( nI >= 0 ) && nHandle != aProps[ nI ].Handle )
393                             --nI;
394 
395                         if( nI >= 0 ) // => nHandle == aProps[nI].Handle
396                         {
397                             // check whether the handle in this property set is
398                             // the same as the one in the style
399                             beans::Property aProp( rPH.getPropertyByName( aProps[ nI ].Name ) );
400                             OSL_ENSURE( nHandle == aProp.Handle,
401                                         "HandleCheck: Handles for same property differ!" );
402 
403                             if( nHandle == aProp.Handle )
404                             {
405                                 OSL_ENSURE( aProp.Type == aProps[nI].Type,
406                                             "HandleCheck: Types differ!" );
407                                 OSL_ENSURE( aProp.Attributes == aProps[nI].Attributes,
408                                             "HandleCheck: Attributes differ!" );
409                             }
410                         }
411                         else
412                         {
413                             OSL_ENSURE( false,  "HandleCheck: Handle not found in Style" );
414                         }
415                     }
416                     else
417                         OSL_ENSURE( false, "HandleCheck: Invalid XPropertySetInfo returned" );
418                 }
419                 else
420                     OSL_ENSURE( false, "HandleCheck: XPropertySet not supported" );
421             }
422 #endif
423             rValue = xStylePropSet->getFastPropertyValue( nHandle );
424         }
425         else
426         {
427 //             OSL_TRACE( "OPropertySet: no style => getting default for property" );
428             // there is no style (or the style does not support XFastPropertySet)
429             // => take the default value
430             try
431             {
432                 rValue = GetDefaultValue( nHandle );
433             }
434             catch( beans::UnknownPropertyException ex )
435             {
436                 rValue.clear();
437             }
438         }
439     }
440 }
441 
firePropertyChangeEvent()442 void OPropertySet::firePropertyChangeEvent()
443 {
444     // nothing in base class
445 }
446 
447 // ____ XStyleSupplier ____
getStyle()448 Reference< style::XStyle > SAL_CALL OPropertySet::getStyle()
449     throw (uno::RuntimeException)
450 {
451     return m_pImplProperties->GetStyle();
452 }
453 
setStyle(const Reference<style::XStyle> & xStyle)454 void SAL_CALL OPropertySet::setStyle( const Reference< style::XStyle >& xStyle )
455     throw (lang::IllegalArgumentException,
456            uno::RuntimeException)
457 {
458     if( ! m_pImplProperties->SetStyle( xStyle ))
459         throw lang::IllegalArgumentException(
460             OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty Style" )),
461             static_cast< beans::XPropertySet * >( this ),
462             0 );
463 }
464 
465 // ____ XFastPropertyState ____
466 // beans::PropertyState OPropertySet::SAL_CALL getFastPropertyState( sal_Int32 nHandle )
467 //     throw (beans::UnknownPropertyException,
468 //            uno::RuntimeException)
469 // {
470 //     return m_pImplProperties->GetPropertyStateByHandle( nHandle );
471 // }
472 
473 // uno::Sequence< beans::PropertyState > OPropertySet::SAL_CALL getFastPropertyStates(
474 //     const uno::Sequence< sal_Int32 >& aHandles )
475 //     throw (beans::UnknownPropertyException,
476 //            uno::RuntimeException)
477 // {
478 //     ::std::vector< sal_Int32 > aHandleVec(
479 //         aHandles.getConstArray(),
480 //         aHandles.getConstArray() + aHandles.getLength() );
481 
482 //     return m_pImplProperties->GetPropertyStatesByHandle( aHandleVec );
483 // }
484 
485 // void OPropertySet::SAL_CALL setFastPropertyToDefault( sal_Int32 nHandle )
486 //     throw (beans::UnknownPropertyException,
487 //            uno::RuntimeException)
488 // {
489 //     m_pImplProperties->SetPropertyToDefault( nHandle );
490 // }
491 
492 // uno::Any OPropertySet::SAL_CALL getFastPropertyDefault( sal_Int32 nHandle )
493 //     throw (beans::UnknownPropertyException,
494 //            lang::WrappedTargetException,
495 //            uno::RuntimeException)
496 // {
497 //     return GetDefaultValue( nHandle );
498 // }
499 
500 // ____ XMultiPropertySet ____
setPropertyValues(const Sequence<OUString> & PropertyNames,const Sequence<Any> & Values)501 void SAL_CALL OPropertySet::setPropertyValues(
502     const Sequence< OUString >& PropertyNames, const Sequence< Any >& Values )
503     throw(beans::PropertyVetoException,
504           lang::IllegalArgumentException,
505           lang::WrappedTargetException,
506           uno::RuntimeException)
507 {
508     ::cppu::OPropertySetHelper::setPropertyValues( PropertyNames, Values );
509 
510     firePropertyChangeEvent();
511 }
512 
513 // ____ XFastPropertySet ____
setFastPropertyValue(sal_Int32 nHandle,const Any & rValue)514 void SAL_CALL OPropertySet::setFastPropertyValue( sal_Int32 nHandle, const Any& rValue )
515     throw(beans::UnknownPropertyException,
516           beans::PropertyVetoException,
517           lang::IllegalArgumentException,
518           lang::WrappedTargetException, uno::RuntimeException)
519 {
520     ::cppu::OPropertySetHelper::setFastPropertyValue( nHandle, rValue );
521 
522     firePropertyChangeEvent();
523 }
524 
525 
526 } //  namespace property
527