merge the formfield patch from ooo-build
[ooovba.git] / comphelper / source / property / propertystatecontainer.cxx
blobe7e2277796bed671ec8b4873ad5f80ac7bdc55fc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: propertystatecontainer.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
33 #include "comphelper/propertystatecontainer.hxx"
34 #include <rtl/ustrbuf.hxx>
36 //.........................................................................
37 namespace comphelper
39 //.........................................................................
41 using namespace ::com::sun::star::uno;
42 using namespace ::com::sun::star::beans;
43 using namespace ::com::sun::star::lang;
45 namespace
47 static ::rtl::OUString lcl_getUnknownPropertyErrorMessage( const ::rtl::OUString& _rPropertyName )
49 // TODO: perhaps it's time to think about resources in the comphelper module?
50 // Would be nice to have localized exception strings (a simply resource file containing
51 // strings only would suffice, and could be realized with an UNO service, so we do not
52 // need the dependency to the Tools project)
53 ::rtl::OUStringBuffer sMessage;
54 sMessage.appendAscii( "The property \"" );
55 sMessage.append( _rPropertyName );
56 sMessage.appendAscii( "\" is unknown." );
57 return sMessage.makeStringAndClear();
61 //=====================================================================
62 //= OPropertyStateContainer
63 //=====================================================================
64 //---------------------------------------------------------------------
65 OPropertyStateContainer::OPropertyStateContainer( ::cppu::OBroadcastHelper& _rBHelper )
66 :OPropertyContainer( _rBHelper )
70 //--------------------------------------------------------------------
71 Any SAL_CALL OPropertyStateContainer::queryInterface( const Type& _rType ) throw (RuntimeException)
73 Any aReturn = OPropertyContainer::queryInterface( _rType );
74 if ( !aReturn.hasValue() )
75 aReturn = OPropertyStateContainer_TBase::queryInterface( _rType );
76 return aReturn;
79 //--------------------------------------------------------------------
80 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyStateContainer, OPropertyContainer, OPropertyStateContainer_TBase )
82 //--------------------------------------------------------------------
83 sal_Int32 OPropertyStateContainer::getHandleForName( const ::rtl::OUString& _rPropertyName ) SAL_THROW( ( UnknownPropertyException ) )
85 // look up the handle for the name
86 ::cppu::IPropertyArrayHelper& rPH = getInfoHelper();
87 sal_Int32 nHandle = rPH.getHandleByName( _rPropertyName );
89 if ( -1 == nHandle )
90 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( _rPropertyName ), static_cast< XPropertyState* >( this ) );
92 return nHandle;
95 //--------------------------------------------------------------------
96 PropertyState SAL_CALL OPropertyStateContainer::getPropertyState( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
98 return getPropertyStateByHandle( getHandleForName( _rPropertyName ) );
101 //--------------------------------------------------------------------
102 Sequence< PropertyState > SAL_CALL OPropertyStateContainer::getPropertyStates( const Sequence< ::rtl::OUString >& _rPropertyNames ) throw (UnknownPropertyException, RuntimeException)
104 sal_Int32 nProperties = _rPropertyNames.getLength();
105 Sequence< PropertyState> aStates( nProperties );
106 if ( !nProperties )
107 return aStates;
109 #ifdef _DEBUG
110 // precondition: property sequence is sorted (the algorythm below relies on this)
112 const ::rtl::OUString* pNames = _rPropertyNames.getConstArray();
113 const ::rtl::OUString* pNamesCompare = pNames + 1;
114 const ::rtl::OUString* pNamesEnd = _rPropertyNames.getConstArray() + _rPropertyNames.getLength();
115 for ( ; pNamesCompare != pNamesEnd; ++pNames, ++pNamesCompare )
116 OSL_PRECOND( pNames->compareTo( *pNamesCompare ) < 0,
117 "OPropertyStateContainer::getPropertyStates: property sequence not sorted!" );
119 #endif
121 const ::rtl::OUString* pLookup = _rPropertyNames.getConstArray();
122 const ::rtl::OUString* pLookupEnd = pLookup + nProperties;
123 PropertyState* pStates = aStates.getArray();
125 cppu::IPropertyArrayHelper& rHelper = getInfoHelper();
126 Sequence< Property> aAllProperties = rHelper.getProperties();
127 sal_Int32 nAllProperties = aAllProperties.getLength();
128 const Property* pAllProperties = aAllProperties.getConstArray();
129 const Property* pAllPropertiesEnd = pAllProperties + nAllProperties;
131 osl::MutexGuard aGuard( rBHelper.rMutex );
132 for ( ; ( pAllProperties != pAllPropertiesEnd ) && ( pLookup != pLookupEnd ); ++pAllProperties )
134 #ifdef _DEBUG
135 if ( pAllProperties < pAllPropertiesEnd - 1 )
136 OSL_ENSURE( pAllProperties->Name.compareTo( (pAllProperties + 1)->Name ) < 0,
137 "OPropertyStateContainer::getPropertyStates: all-properties not sorted!" );
138 #endif
139 if ( pAllProperties->Name.equals( *pLookup ) )
141 *pStates++ = getPropertyState( *pLookup );
142 ++pLookup;
146 if ( pLookup != pLookupEnd )
147 // we run out of properties from the IPropertyArrayHelper, but still have properties to lookup
148 // -> we were asked for a nonexistent property
149 throw UnknownPropertyException( lcl_getUnknownPropertyErrorMessage( *pLookup ), static_cast< XPropertyState* >( this ) );
151 return aStates;
154 //--------------------------------------------------------------------
155 void SAL_CALL OPropertyStateContainer::setPropertyToDefault( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, RuntimeException)
157 setPropertyToDefaultByHandle( getHandleForName( _rPropertyName ) );
160 //--------------------------------------------------------------------
161 Any SAL_CALL OPropertyStateContainer::getPropertyDefault( const ::rtl::OUString& _rPropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
163 Any aDefault;
164 getPropertyDefaultByHandle( getHandleForName( _rPropertyName ), aDefault );
165 return aDefault;
168 //--------------------------------------------------------------------
169 PropertyState OPropertyStateContainer::getPropertyStateByHandle( sal_Int32 _nHandle )
171 // simply compare the current and the default value
172 Any aCurrentValue; getFastPropertyValue( aCurrentValue, _nHandle );
173 Any aDefaultValue; getPropertyDefaultByHandle( _nHandle, aDefaultValue );
175 sal_Bool bEqual = uno_type_equalData(
176 const_cast< void* >( aCurrentValue.getValue() ), aCurrentValue.getValueType().getTypeLibType(),
177 const_cast< void* >( aDefaultValue.getValue() ), aDefaultValue.getValueType().getTypeLibType(),
178 reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
179 reinterpret_cast< uno_ReleaseFunc >(cpp_release)
181 if ( bEqual )
182 return PropertyState_DEFAULT_VALUE;
183 else
184 return PropertyState_DIRECT_VALUE;
187 //--------------------------------------------------------------------
188 void OPropertyStateContainer::setPropertyToDefaultByHandle( sal_Int32 _nHandle )
190 Any aDefault;
191 getPropertyDefaultByHandle( _nHandle, aDefault );
192 setFastPropertyValue( _nHandle, aDefault );
195 //.........................................................................
196 } // namespace comphelper
197 //.........................................................................
199 #ifdef FS_PRIV_DEBUG
200 #define STATECONTAINER_TEST
201 #endif
203 #ifdef STATECONTAINER_TEST
204 #include <com/sun/star/beans/PropertyAttribute.hpp>
205 #include <comphelper/proparrhlp.hxx>
206 #include <comphelper/broadcasthelper.hxx>
208 //.........................................................................
209 namespace comphelper
211 //.........................................................................
213 using namespace ::com::sun::star::uno;
214 using namespace ::com::sun::star::beans;
216 //=====================================================================
217 //= Test - compiler test
218 //=====================================================================
219 typedef ::cppu::OWeakAggObject Test_RefCountBase;
220 class Test :public OMutexAndBroadcastHelper
221 ,public OPropertyStateContainer
222 ,public OPropertyArrayUsageHelper< Test >
223 ,public Test_RefCountBase
225 private:
226 ::rtl::OUString m_sStringProperty;
227 Reference< XInterface > m_xInterfaceProperty;
228 Any m_aMayBeVoidProperty;
230 protected:
231 Test( );
233 DECLARE_XINTERFACE( )
235 public:
236 static Test* Create( );
238 protected:
239 virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(RuntimeException);
240 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
241 virtual ::cppu::IPropertyArrayHelper* createArrayHelper( ) const;
243 protected:
244 // OPropertyStateContainer overridables
245 virtual void getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const;
248 //---------------------------------------------------------------------
249 Test::Test( )
250 :OPropertyStateContainer( GetBroadcastHelper() )
252 registerProperty(
253 ::rtl::OUString::createFromAscii( "StringProperty" ),
255 PropertyAttribute::BOUND,
256 &m_sStringProperty,
257 ::getCppuType( &m_sStringProperty )
260 registerProperty(
261 ::rtl::OUString::createFromAscii( "InterfaceProperty" ),
263 PropertyAttribute::BOUND,
264 &m_xInterfaceProperty,
265 ::getCppuType( &m_xInterfaceProperty )
268 registerMayBeVoidProperty(
269 ::rtl::OUString::createFromAscii( "IntProperty" ),
271 PropertyAttribute::BOUND,
272 &m_aMayBeVoidProperty,
273 ::getCppuType( static_cast< sal_Int32* >( NULL ) )
276 registerPropertyNoMember(
277 ::rtl::OUString::createFromAscii( "OtherInterfaceProperty" ),
279 PropertyAttribute::BOUND | PropertyAttribute::MAYBEVOID,
280 ::getCppuType( static_cast< Reference< XInterface >* >( NULL ) ),
281 NULL
285 //---------------------------------------------------------------------
286 IMPLEMENT_FORWARD_XINTERFACE2( Test, Test_RefCountBase, OPropertyStateContainer )
288 //---------------------------------------------------------------------
289 void Test::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const
291 switch ( _nHandle )
293 case 1:
294 _rDefault = makeAny( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringPropertyDefault" ) ) );
295 break;
296 case 2:
297 _rDefault = makeAny( Reference< XInterface >( ) );
298 break;
299 case 3:
300 // void
301 break;
302 case 4:
303 _rDefault = makeAny( Reference< XInterface >( ) );
304 break;
305 default:
306 OSL_ENSURE( sal_False, "Test::getPropertyDefaultByHandle: invalid handle!" );
310 //---------------------------------------------------------------------
311 Reference< XPropertySetInfo > SAL_CALL Test::getPropertySetInfo( ) throw(RuntimeException)
313 return createPropertySetInfo( getInfoHelper() );
316 //---------------------------------------------------------------------
317 ::cppu::IPropertyArrayHelper& SAL_CALL Test::getInfoHelper()
319 return *getArrayHelper();
322 //---------------------------------------------------------------------
323 ::cppu::IPropertyArrayHelper* Test::createArrayHelper( ) const
325 Sequence< Property > aProps;
326 describeProperties( aProps );
327 return new ::cppu::OPropertyArrayHelper( aProps );
330 //---------------------------------------------------------------------
331 Test* Test::Create( )
333 Test* pInstance = new Test;
334 return pInstance;
337 //.........................................................................
338 } // namespace comphelper
339 //.........................................................................
341 #endif