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: constitemcontainer.cxx,v $
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 //_________________________________________________________________________________________________________________
35 //_________________________________________________________________________________________________________________
36 #include <uielement/constitemcontainer.hxx>
37 #include <uielement/rootitemcontainer.hxx>
38 #include <uielement/itemcontainer.hxx>
39 #include <threadhelp/resetableguard.hxx>
41 //_________________________________________________________________________________________________________________
43 //_________________________________________________________________________________________________________________
44 #include <com/sun/star/beans/PropertyAttribute.hpp>
46 //_________________________________________________________________________________________________________________
48 //_________________________________________________________________________________________________________________
49 #include <cppuhelper/implbase1.hxx>
52 using namespace com::sun::star::uno
;
53 using namespace com::sun::star::lang
;
54 using namespace com::sun::star::beans
;
55 using namespace com::sun::star::container
;
57 const char WRONG_TYPE_EXCEPTION
[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
59 const int PROPHANDLE_UINAME
= 1;
60 const int PROPCOUNT
= 1;
61 const rtl::OUString
PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
67 * The class which implements the PropertySetInfo interface.
71 static int SAL_CALL
compare_OUString_Property_Impl( const void *arg1
, const void *arg2
) SAL_THROW( () )
73 return ((::rtl::OUString
*)arg1
)->compareTo( ((Property
*)arg2
)->Name
);
77 class OPropertySetHelperInfo_Impl
78 : public WeakImplHelper1
< ::com::sun::star::beans::XPropertySetInfo
>
80 Sequence
< Property
> aInfos
;
83 OPropertySetHelperInfo_Impl( IPropertyArrayHelper
& rHelper_
) SAL_THROW( () );
85 // XPropertySetInfo-Methoden
86 virtual Sequence
< Property
> SAL_CALL
getProperties(void) throw(::com::sun::star::uno::RuntimeException
);
87 virtual Property SAL_CALL
getPropertyByName(const ::rtl::OUString
& PropertyName
) throw(::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
);
88 virtual sal_Bool SAL_CALL
hasPropertyByName(const ::rtl::OUString
& PropertyName
) throw(::com::sun::star::uno::RuntimeException
);
93 * Create an object that implements XPropertySetInfo IPropertyArrayHelper.
95 OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl(
96 IPropertyArrayHelper
& rHelper_
)
98 :aInfos( rHelper_
.getProperties() )
103 * Return the sequence of properties, which are provided throug the constructor.
105 Sequence
< Property
> OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException
)
111 * Return the sequence of properties, which are provided throug the constructor.
113 Property
OPropertySetHelperInfo_Impl::getPropertyByName( const ::rtl::OUString
& PropertyName
) throw(::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::uno::RuntimeException
)
116 pR
= (Property
*)bsearch( &PropertyName
, aInfos
.getConstArray(), aInfos
.getLength(),
118 compare_OUString_Property_Impl
);
120 throw UnknownPropertyException();
127 * Return the sequence of properties, which are provided throug the constructor.
129 sal_Bool
OPropertySetHelperInfo_Impl::hasPropertyByName( const ::rtl::OUString
& PropertyName
) throw(::com::sun::star::uno::RuntimeException
)
132 pR
= (Property
*)bsearch( &PropertyName
, aInfos
.getConstArray(), aInfos
.getLength(),
134 compare_OUString_Property_Impl
);
138 //*****************************************************************************************************************
139 // XInterface, XTypeProvider
140 //*****************************************************************************************************************
141 DEFINE_XINTERFACE_6 ( ConstItemContainer
,
143 DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider
),
144 DIRECT_INTERFACE( ::com::sun::star::container::XElementAccess
),
145 DIRECT_INTERFACE( ::com::sun::star::container::XIndexAccess
),
146 DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet
),
147 DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet
),
148 DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel
)
151 DEFINE_XTYPEPROVIDER_6 ( ConstItemContainer
,
152 ::com::sun::star::lang::XTypeProvider
,
153 ::com::sun::star::container::XIndexAccess
,
154 ::com::sun::star::container::XElementAccess
,
155 ::com::sun::star::beans::XFastPropertySet
,
156 ::com::sun::star::beans::XPropertySet
,
157 ::com::sun::star::lang::XUnoTunnel
160 ConstItemContainer::ConstItemContainer() : ::cppu::OWeakObject()
164 ConstItemContainer::ConstItemContainer( const RootItemContainer
& rRootItemContainer
, sal_Bool bFastCopy
)
166 ShareGuard( rRootItemContainer
.m_aShareMutex
);
168 // If bFastCopy is set the onwer of the root item container will transfer ownership to us. So
169 // it is possible to copy only the root part.
170 m_aUIName
= rRootItemContainer
.m_aUIName
;
172 m_aItemVector
= rRootItemContainer
.m_aItemVector
;
174 copyItemContainer( rRootItemContainer
.m_aItemVector
);
177 ConstItemContainer::ConstItemContainer( const ItemContainer
& rItemContainer
)
179 ShareGuard( rItemContainer
.m_aShareMutex
);
180 copyItemContainer( rItemContainer
.m_aItemVector
);
183 ConstItemContainer::ConstItemContainer( const Reference
< XIndexAccess
>& rSourceContainer
, sal_Bool bFastCopy
)
185 // We also have to copy the UIName property
188 Reference
< XPropertySet
> xPropSet( rSourceContainer
, UNO_QUERY
);
191 rtl::OUString aUIName
;
192 xPropSet
->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName
;
199 if ( rSourceContainer
.is() )
203 sal_Int32 nCount
= rSourceContainer
->getCount();
204 m_aItemVector
.reserve(nCount
);
207 for ( sal_Int32 i
= 0; i
< nCount
; i
++ )
209 Sequence
< PropertyValue
> aPropSeq
;
210 if ( rSourceContainer
->getByIndex( i
) >>= aPropSeq
)
211 m_aItemVector
.push_back( aPropSeq
);
216 for ( sal_Int32 i
= 0; i
< nCount
; i
++ )
218 Sequence
< PropertyValue
> aPropSeq
;
219 if ( rSourceContainer
->getByIndex( i
) >>= aPropSeq
)
221 sal_Int32 nContainerIndex
= -1;
222 Reference
< XIndexAccess
> xIndexAccess
;
223 for ( sal_Int32 j
= 0; j
< aPropSeq
.getLength(); j
++ )
225 if ( aPropSeq
[j
].Name
.equalsAscii( "ItemDescriptorContainer" ))
227 aPropSeq
[j
].Value
>>= xIndexAccess
;
233 if ( xIndexAccess
.is() && nContainerIndex
>= 0 )
234 aPropSeq
[nContainerIndex
].Value
<<= deepCopyContainer( xIndexAccess
);
236 m_aItemVector
.push_back( aPropSeq
);
241 catch ( IndexOutOfBoundsException
& )
247 ConstItemContainer::~ConstItemContainer()
252 void ConstItemContainer::copyItemContainer( const std::vector
< Sequence
< PropertyValue
> >& rSourceVector
)
254 const sal_uInt32 nCount
= rSourceVector
.size();
255 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
257 sal_Int32 nContainerIndex
= -1;
258 Sequence
< PropertyValue
> aPropSeq( rSourceVector
[i
] );
259 Reference
< XIndexAccess
> xIndexAccess
;
260 for ( sal_Int32 j
= 0; j
< aPropSeq
.getLength(); j
++ )
262 if ( aPropSeq
[j
].Name
.equalsAscii( "ItemDescriptorContainer" ))
264 aPropSeq
[j
].Value
>>= xIndexAccess
;
270 if ( xIndexAccess
.is() && nContainerIndex
>= 0 )
271 aPropSeq
[nContainerIndex
].Value
<<= deepCopyContainer( xIndexAccess
);
273 m_aItemVector
.push_back( aPropSeq
);
277 Reference
< XIndexAccess
> ConstItemContainer::deepCopyContainer( const Reference
< XIndexAccess
>& rSubContainer
)
279 Reference
< XIndexAccess
> xReturn
;
280 if ( rSubContainer
.is() )
282 ItemContainer
* pSource
= ItemContainer::GetImplementation( rSubContainer
);
283 ConstItemContainer
* pSubContainer( 0 );
285 pSubContainer
= new ConstItemContainer( *pSource
);
287 pSubContainer
= new ConstItemContainer( rSubContainer
);
288 xReturn
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( pSubContainer
), UNO_QUERY
);
295 sal_Int64
ConstItemContainer::getSomething( const ::com::sun::star::uno::Sequence
< sal_Int8
>& rIdentifier
) throw(::com::sun::star::uno::RuntimeException
)
297 if( ( rIdentifier
.getLength() == 16 ) && ( 0 == rtl_compareMemory( ConstItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier
.getConstArray(), 16 ) ) )
299 return reinterpret_cast< sal_Int64
>( this );
304 const Sequence
< sal_Int8
>& ConstItemContainer::GetUnoTunnelId() throw()
306 static ::com::sun::star::uno::Sequence
< sal_Int8
> * pSeq
= NULL
;
309 ::osl::Guard
< ::osl::Mutex
> aGuard( ::osl::Mutex::getGlobalMutex() );
312 static ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq( 16 );
313 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
320 ConstItemContainer
* ConstItemContainer::GetImplementation( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& rxIFace
) throw()
322 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XUnoTunnel
> xUT( rxIFace
, ::com::sun::star::uno::UNO_QUERY
);
323 return xUT
.is() ? reinterpret_cast< ConstItemContainer
* >(sal::static_int_cast
< sal_IntPtr
>(
324 xUT
->getSomething( ConstItemContainer::GetUnoTunnelId() ))) : NULL
;
328 sal_Bool SAL_CALL
ConstItemContainer::hasElements()
329 throw ( RuntimeException
)
331 return ( !m_aItemVector
.empty() );
335 sal_Int32 SAL_CALL
ConstItemContainer::getCount()
336 throw ( RuntimeException
)
338 return m_aItemVector
.size();
341 Any SAL_CALL
ConstItemContainer::getByIndex( sal_Int32 Index
)
342 throw ( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
344 if ( sal_Int32( m_aItemVector
.size()) > Index
)
345 return makeAny( m_aItemVector
[Index
] );
347 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject
*)this );
351 Reference
< XPropertySetInfo
> SAL_CALL
ConstItemContainer::getPropertySetInfo()
352 throw (::com::sun::star::uno::RuntimeException
)
354 // Optimize this method !
355 // We initialize a static variable only one time. And we don't must use a mutex at every call!
356 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
357 static Reference
< XPropertySetInfo
>* pInfo
= NULL
;
361 // Ready for multithreading
362 osl::MutexGuard
aGuard( osl::Mutex::getGlobalMutex() ) ;
363 // Control this pointer again, another instance can be faster then these!
366 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
367 // (Use method "getInfoHelper()".)
368 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
376 void SAL_CALL
ConstItemContainer::setPropertyValue( const ::rtl::OUString
&, const Any
& )
377 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::beans::PropertyVetoException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
381 Any SAL_CALL
ConstItemContainer::getPropertyValue( const ::rtl::OUString
& PropertyName
)
382 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
384 if ( PropertyName
.equals( PROPNAME_UINAME
))
385 return makeAny( m_aUIName
);
387 throw UnknownPropertyException();
390 void SAL_CALL
ConstItemContainer::addPropertyChangeListener( const ::rtl::OUString
&, const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& )
391 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
395 void SAL_CALL
ConstItemContainer::removePropertyChangeListener( const ::rtl::OUString
&, const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertyChangeListener
>& )
396 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
398 // Only read-only properties - do nothing
401 void SAL_CALL
ConstItemContainer::addVetoableChangeListener( const ::rtl::OUString
&, const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XVetoableChangeListener
>& )
402 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
404 // Only read-only properties - do nothing
407 void SAL_CALL
ConstItemContainer::removeVetoableChangeListener( const ::rtl::OUString
&, const ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XVetoableChangeListener
>& )
408 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
410 // Only read-only properties - do nothing
414 void SAL_CALL
ConstItemContainer::setFastPropertyValue( sal_Int32
, const ::com::sun::star::uno::Any
& )
415 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::beans::PropertyVetoException
, ::com::sun::star::lang::IllegalArgumentException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
419 Any SAL_CALL
ConstItemContainer::getFastPropertyValue( sal_Int32 nHandle
)
420 throw (::com::sun::star::beans::UnknownPropertyException
, ::com::sun::star::lang::WrappedTargetException
, ::com::sun::star::uno::RuntimeException
)
422 if ( nHandle
== PROPHANDLE_UINAME
)
423 return makeAny( m_aUIName
);
425 throw UnknownPropertyException();
428 ::cppu::IPropertyArrayHelper
& SAL_CALL
ConstItemContainer::getInfoHelper()
430 // Optimize this method !
431 // We initialize a static variable only one time. And we don't must use a mutex at every call!
432 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
433 static ::cppu::OPropertyArrayHelper
* pInfoHelper
= NULL
;
435 if( pInfoHelper
== NULL
)
437 // Ready for multithreading
438 osl::MutexGuard
aGuard( osl::Mutex::getGlobalMutex() ) ;
440 // Control this pointer again, another instance can be faster then these!
441 if( pInfoHelper
== NULL
)
443 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
444 // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable.
445 // "sal_True" say: Table is sorted by name.
446 static ::cppu::OPropertyArrayHelper
aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True
);
447 pInfoHelper
= &aInfoHelper
;
451 return(*pInfoHelper
);
454 const com::sun::star::uno::Sequence
< com::sun::star::beans::Property
> ConstItemContainer::impl_getStaticPropertyDescriptor()
456 // Create a new static property array to initialize sequence!
457 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
458 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
459 // It's necessary for methods of OPropertySetHelper.
461 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
463 static const com::sun::star::beans::Property pProperties
[] =
465 com::sun::star::beans::Property( PROPNAME_UINAME
, PROPHANDLE_UINAME
,
466 ::getCppuType((const rtl::OUString
*)NULL
),
467 com::sun::star::beans::PropertyAttribute::TRANSIENT
| com::sun::star::beans::PropertyAttribute::READONLY
)
469 // Use it to initialize sequence!
470 static const com::sun::star::uno::Sequence
< com::sun::star::beans::Property
> lPropertyDescriptor( pProperties
, PROPCOUNT
);
471 // Return static "PropertyDescriptor"
472 return lPropertyDescriptor
;
475 Reference
< XPropertySetInfo
> ConstItemContainer::createPropertySetInfo(
476 IPropertyArrayHelper
& rProperties
) SAL_THROW( () )
478 return static_cast< XPropertySetInfo
* >( new OPropertySetHelperInfo_Impl( rProperties
) );
481 } // namespace framework