merge the formfield patch from ooo-build
[ooovba.git] / framework / source / uielement / rootitemcontainer.cxx
blob6275f2a7a8ee71986e37972cc12a56a5ed59dee3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rootitemcontainer.cxx,v $
10 * $Revision: 1.9 $
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_framework.hxx"
33 //_________________________________________________________________________________________________________________
34 // my own includes
35 //_________________________________________________________________________________________________________________
36 #include <uielement/rootitemcontainer.hxx>
38 #ifndef __FRAMEWORK_UIELEMENT_ITEMCONTAINER_HHX_
39 #include <uielement/itemcontainer.hxx>
40 #endif
42 #ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HHX_
43 #include <uielement/constitemcontainer.hxx>
44 #endif
45 #include <threadhelp/resetableguard.hxx>
46 #include <general.h>
47 #include <properties.h>
49 //_________________________________________________________________________________________________________________
50 // interface includes
51 //_________________________________________________________________________________________________________________
52 #include <com/sun/star/beans/PropertyAttribute.hpp>
54 //_________________________________________________________________________________________________________________
55 // other includes
56 //_________________________________________________________________________________________________________________
58 using namespace cppu;
59 using namespace com::sun::star::uno;
60 using namespace com::sun::star::lang;
61 using namespace com::sun::star::beans;
62 using namespace com::sun::star::container;
64 const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
66 const int PROPHANDLE_UINAME = 1;
67 const int PROPCOUNT = 1;
68 const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
70 namespace framework
73 //*****************************************************************************************************************
74 // XInterface, XTypeProvider
75 //*****************************************************************************************************************
76 DEFINE_XINTERFACE_10 ( RootItemContainer ,
77 OWeakObject ,
78 DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
79 DIRECT_INTERFACE( ::com::sun::star::container::XIndexContainer ),
80 DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel ),
81 DIRECT_INTERFACE( ::com::sun::star::lang::XSingleComponentFactory ),
82 DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
83 DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
84 DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
85 DERIVED_INTERFACE( ::com::sun::star::container::XIndexReplace, com::sun::star::container::XIndexContainer ),
86 DERIVED_INTERFACE( ::com::sun::star::container::XIndexAccess, com::sun::star::container::XIndexReplace ),
87 DERIVED_INTERFACE( ::com::sun::star::container::XElementAccess, ::com::sun::star::container::XIndexAccess )
90 DEFINE_XTYPEPROVIDER_10 ( RootItemContainer ,
91 ::com::sun::star::lang::XTypeProvider ,
92 ::com::sun::star::container::XIndexContainer ,
93 ::com::sun::star::container::XIndexReplace ,
94 ::com::sun::star::container::XIndexAccess ,
95 ::com::sun::star::container::XElementAccess ,
96 ::com::sun::star::beans::XMultiPropertySet ,
97 ::com::sun::star::beans::XFastPropertySet ,
98 ::com::sun::star::beans::XPropertySet ,
99 ::com::sun::star::lang::XUnoTunnel ,
100 ::com::sun::star::lang::XSingleComponentFactory
103 RootItemContainer::RootItemContainer()
104 : ThreadHelpBase ( )
105 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
106 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
107 , ::cppu::OWeakObject()
111 RootItemContainer::RootItemContainer( const ConstItemContainer& rConstItemContainer )
112 : ThreadHelpBase ( )
113 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
114 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
115 , ::cppu::OWeakObject()
117 m_aUIName = rConstItemContainer.m_aUIName;
118 copyItemContainer( rConstItemContainer.m_aItemVector );
121 RootItemContainer::RootItemContainer( const Reference< XIndexAccess >& rSourceContainer )
122 : ThreadHelpBase ( )
123 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
124 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
125 , ::cppu::OWeakObject()
127 // We also have to copy the UIName property
130 Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY );
131 if ( xPropSet.is() )
133 rtl::OUString aUIName;
134 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName;
137 catch ( Exception& )
141 if ( rSourceContainer.is() )
143 sal_Int32 nCount = rSourceContainer->getCount();
146 for ( sal_Int32 i = 0; i < nCount; i++ )
148 Sequence< PropertyValue > aPropSeq;
149 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
151 sal_Int32 nContainerIndex = -1;
152 Reference< XIndexAccess > xIndexAccess;
153 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
155 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
157 aPropSeq[j].Value >>= xIndexAccess;
158 nContainerIndex = j;
159 break;
163 if ( xIndexAccess.is() && nContainerIndex >= 0 )
164 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
166 m_aItemVector.push_back( aPropSeq );
170 catch ( IndexOutOfBoundsException& )
176 RootItemContainer::~RootItemContainer()
180 // private
181 void RootItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector )
183 const sal_uInt32 nCount = rSourceVector.size();
184 m_aItemVector.reserve(nCount);
185 for ( sal_uInt32 i = 0; i < nCount; i++ )
187 sal_Int32 nContainerIndex = -1;
188 Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
189 Reference< XIndexAccess > xIndexAccess;
190 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
192 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
194 aPropSeq[j].Value >>= xIndexAccess;
195 nContainerIndex = j;
196 break;
200 if ( xIndexAccess.is() && nContainerIndex >= 0 )
201 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
203 m_aItemVector.push_back( aPropSeq );
207 Reference< XIndexAccess > RootItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer )
209 Reference< XIndexAccess > xReturn;
210 if ( rSubContainer.is() )
212 ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer );
213 ItemContainer* pSubContainer( 0 );
214 if ( pSource )
215 pSubContainer = new ItemContainer( *pSource, m_aShareMutex );
216 else
217 pSubContainer = new ItemContainer( rSubContainer, m_aShareMutex );
218 xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
221 return xReturn;
224 // XUnoTunnel
225 sal_Int64 RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException)
227 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
228 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
229 return 0;
232 const Sequence< sal_Int8 >& RootItemContainer::GetUnoTunnelId() throw()
234 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
235 if( !pSeq )
237 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
238 if( !pSeq )
240 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
241 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
242 pSeq = &aSeq;
245 return *pSeq;
248 RootItemContainer* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
250 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
251 return xUT.is() ? reinterpret_cast< RootItemContainer* >(sal::static_int_cast< sal_IntPtr >(
252 xUT->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL;
255 // XElementAccess
256 sal_Bool SAL_CALL RootItemContainer::hasElements()
257 throw ( RuntimeException )
259 ShareGuard aLock( m_aShareMutex );
260 return ( !m_aItemVector.empty() );
263 // XIndexAccess
264 sal_Int32 SAL_CALL RootItemContainer::getCount()
265 throw ( RuntimeException )
267 ShareGuard aLock( m_aShareMutex );
268 return m_aItemVector.size();
271 Any SAL_CALL RootItemContainer::getByIndex( sal_Int32 Index )
272 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
274 ShareGuard aLock( m_aShareMutex );
275 if ( sal_Int32( m_aItemVector.size()) > Index )
276 return makeAny( m_aItemVector[Index] );
277 else
278 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
281 // XIndexContainer
282 void SAL_CALL RootItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem )
283 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
285 Sequence< PropertyValue > aSeq;
286 if ( aItem >>= aSeq )
288 ShareGuard aLock( m_aShareMutex );
289 if ( sal_Int32( m_aItemVector.size()) == Index )
290 m_aItemVector.push_back( aSeq );
291 else if ( sal_Int32( m_aItemVector.size()) >Index )
293 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
294 aIter += Index;
295 m_aItemVector.insert( aIter, aSeq );
297 else
298 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
300 else
301 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
302 (OWeakObject *)this, 2 );
305 void SAL_CALL RootItemContainer::removeByIndex( sal_Int32 Index )
306 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
308 ShareGuard aLock( m_aShareMutex );
309 if ( (sal_Int32)m_aItemVector.size() > Index )
311 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
312 aIter += Index;
313 m_aItemVector.erase( aIter );
315 else
316 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
319 void SAL_CALL RootItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem )
320 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
322 Sequence< PropertyValue > aSeq;
323 if ( aItem >>= aSeq )
325 ShareGuard aLock( m_aShareMutex );
326 if ( sal_Int32( m_aItemVector.size()) > Index )
327 m_aItemVector[Index] = aSeq;
328 else
329 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
331 else
332 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
333 (OWeakObject *)this, 2 );
336 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& )
337 throw ( Exception, RuntimeException)
339 return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
342 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence< Any >&, const Reference< XComponentContext >& )
343 throw (Exception, RuntimeException)
345 return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
348 // XPropertySet helper
349 sal_Bool SAL_CALL RootItemContainer::convertFastPropertyValue( Any& aConvertedValue ,
350 Any& aOldValue ,
351 sal_Int32 nHandle ,
352 const Any& aValue )
353 throw( com::sun::star::lang::IllegalArgumentException )
355 // Initialize state with FALSE !!!
356 // (Handle can be invalid)
357 sal_Bool bReturn = sal_False;
359 switch( nHandle )
361 case PROPHANDLE_UINAME:
362 bReturn = PropHelper::willPropertyBeChanged(
363 com::sun::star::uno::makeAny(m_aUIName),
364 aValue,
365 aOldValue,
366 aConvertedValue);
367 break;
370 // Return state of operation.
371 return bReturn ;
374 void SAL_CALL RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
375 const com::sun::star::uno::Any& aValue )
376 throw( com::sun::star::uno::Exception )
378 switch( nHandle )
380 case PROPHANDLE_UINAME:
381 aValue >>= m_aUIName;
382 break;
386 void SAL_CALL RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any& aValue ,
387 sal_Int32 nHandle ) const
389 switch( nHandle )
391 case PROPHANDLE_UINAME:
392 aValue <<= m_aUIName;
393 break;
397 ::cppu::IPropertyArrayHelper& SAL_CALL RootItemContainer::getInfoHelper()
399 // Optimize this method !
400 // We initialize a static variable only one time. And we don't must use a mutex at every call!
401 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
402 static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
404 if( pInfoHelper == NULL )
406 // Ready for multithreading
407 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
409 // Control this pointer again, another instance can be faster then these!
410 if( pInfoHelper == NULL )
412 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
413 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
414 // "sal_True" say: Table is sorted by name.
415 static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
416 pInfoHelper = &aInfoHelper;
420 return(*pInfoHelper);
423 com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL RootItemContainer::getPropertySetInfo()
424 throw (::com::sun::star::uno::RuntimeException)
426 // Optimize this method !
427 // We initialize a static variable only one time. And we don't must use a mutex at every call!
428 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
429 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL;
431 if( pInfo == NULL )
433 // Ready for multithreading
434 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
435 // Control this pointer again, another instance can be faster then these!
436 if( pInfo == NULL )
438 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
439 // (Use method "getInfoHelper()".)
440 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
441 pInfo = &xInfo;
445 return (*pInfo);
448 const com::sun::star::uno::Sequence< com::sun::star::beans::Property > RootItemContainer::impl_getStaticPropertyDescriptor()
450 // Create a new static property array to initialize sequence!
451 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
452 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
453 // It's necessary for methods of OPropertySetHelper.
454 // ATTENTION:
455 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
457 static const com::sun::star::beans::Property pProperties[] =
459 com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME ,
460 ::getCppuType((const rtl::OUString*)NULL),
461 com::sun::star::beans::PropertyAttribute::TRANSIENT )
463 // Use it to initialize sequence!
464 static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT );
465 // Return static "PropertyDescriptor"
466 return lPropertyDescriptor;
469 } // namespace framework