1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 #include <comphelper/servicehelper.hxx>
23 #include <comphelper/sequence.hxx>
24 #include <uielement/rootitemcontainer.hxx>
25 #include <uielement/itemcontainer.hxx>
26 #include <uielement/constitemcontainer.hxx>
28 #include <properties.h>
30 #include <com/sun/star/beans/PropertyAttribute.hpp>
33 using namespace com::sun::star::uno
;
34 using namespace com::sun::star::lang
;
35 using namespace com::sun::star::beans
;
36 using namespace com::sun::star::container
;
38 const char WRONG_TYPE_EXCEPTION
[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
40 const int PROPHANDLE_UINAME
= 1;
41 const int PROPCOUNT
= 1;
42 const char PROPNAME_UINAME
[] = "UIName";
47 RootItemContainer::RootItemContainer()
48 : ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
>( m_aMutex
)
49 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
53 RootItemContainer::RootItemContainer( const Reference
< XIndexAccess
>& rSourceContainer
)
54 : ::cppu::OBroadcastHelperVar
< ::cppu::OMultiTypeInterfaceContainerHelper
, ::cppu::OMultiTypeInterfaceContainerHelper::keyType
>( m_aMutex
)
55 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper
* >(this)) )
57 // We also have to copy the UIName property
60 Reference
< XPropertySet
> xPropSet( rSourceContainer
, UNO_QUERY
);
63 xPropSet
->getPropertyValue("UIName") >>= m_aUIName
;
66 catch ( const Exception
& )
70 if ( rSourceContainer
.is() )
72 sal_Int32 nCount
= rSourceContainer
->getCount();
75 for ( sal_Int32 i
= 0; i
< nCount
; i
++ )
77 Sequence
< PropertyValue
> aPropSeq
;
78 if ( rSourceContainer
->getByIndex( i
) >>= aPropSeq
)
80 sal_Int32 nContainerIndex
= -1;
81 Reference
< XIndexAccess
> xIndexAccess
;
82 for ( sal_Int32 j
= 0; j
< aPropSeq
.getLength(); j
++ )
84 if ( aPropSeq
[j
].Name
== "ItemDescriptorContainer" )
86 aPropSeq
[j
].Value
>>= xIndexAccess
;
92 if ( xIndexAccess
.is() && nContainerIndex
>= 0 )
93 aPropSeq
[nContainerIndex
].Value
<<= deepCopyContainer( xIndexAccess
);
95 m_aItemVector
.push_back( aPropSeq
);
99 catch ( const IndexOutOfBoundsException
& )
105 RootItemContainer::~RootItemContainer()
109 Any SAL_CALL
RootItemContainer::queryInterface( const Type
& _rType
) throw(RuntimeException
, std::exception
)
111 Any aRet
= RootItemContainer_BASE::queryInterface( _rType
);
112 if ( !aRet
.hasValue() )
113 aRet
= OPropertySetHelper::queryInterface( _rType
);
117 Sequence
< Type
> SAL_CALL
RootItemContainer::getTypes( ) throw(RuntimeException
, std::exception
)
119 return comphelper::concatSequences(
120 RootItemContainer_BASE::getTypes(),
121 ::cppu::OPropertySetHelper::getTypes()
125 Reference
< XIndexAccess
> RootItemContainer::deepCopyContainer( const Reference
< XIndexAccess
>& rSubContainer
)
127 Reference
< XIndexAccess
> xReturn
;
128 if ( rSubContainer
.is() )
130 ConstItemContainer
* pSource
= ConstItemContainer::GetImplementation( rSubContainer
);
131 ItemContainer
* pSubContainer( 0 );
133 pSubContainer
= new ItemContainer( *pSource
, m_aShareMutex
);
135 pSubContainer
= new ItemContainer( rSubContainer
, m_aShareMutex
);
136 xReturn
= Reference
< XIndexAccess
>( static_cast< OWeakObject
* >( pSubContainer
), UNO_QUERY
);
143 sal_Int64
RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence
< sal_Int8
>& rIdentifier
) throw(::com::sun::star::uno::RuntimeException
, std::exception
)
145 if( ( rIdentifier
.getLength() == 16 ) && ( 0 == memcmp( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier
.getConstArray(), 16 ) ) )
146 return sal::static_int_cast
< sal_Int64
>( reinterpret_cast< sal_IntPtr
>( this ));
152 class theRootItemContainerUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theRootItemContainerUnoTunnelId
> {};
155 const Sequence
< sal_Int8
>& RootItemContainer::GetUnoTunnelId() throw()
157 return theRootItemContainerUnoTunnelId::get().getSeq();
160 RootItemContainer
* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
>& rxIFace
) throw()
162 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XUnoTunnel
> xUT( rxIFace
, ::com::sun::star::uno::UNO_QUERY
);
163 return xUT
.is() ? reinterpret_cast< RootItemContainer
* >(sal::static_int_cast
< sal_IntPtr
>(
164 xUT
->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL
;
168 sal_Bool SAL_CALL
RootItemContainer::hasElements()
169 throw ( RuntimeException
, std::exception
)
171 ShareGuard
aLock( m_aShareMutex
);
172 return ( !m_aItemVector
.empty() );
176 sal_Int32 SAL_CALL
RootItemContainer::getCount()
177 throw ( RuntimeException
, std::exception
)
179 ShareGuard
aLock( m_aShareMutex
);
180 return m_aItemVector
.size();
183 Any SAL_CALL
RootItemContainer::getByIndex( sal_Int32 Index
)
184 throw ( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
186 ShareGuard
aLock( m_aShareMutex
);
187 if ( sal_Int32( m_aItemVector
.size()) > Index
)
188 return makeAny( m_aItemVector
[Index
] );
190 throw IndexOutOfBoundsException( OUString(), (OWeakObject
*)this );
194 void SAL_CALL
RootItemContainer::insertByIndex( sal_Int32 Index
, const Any
& aItem
)
195 throw ( IllegalArgumentException
, IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
197 Sequence
< PropertyValue
> aSeq
;
198 if ( aItem
>>= aSeq
)
200 ShareGuard
aLock( m_aShareMutex
);
201 if ( sal_Int32( m_aItemVector
.size()) == Index
)
202 m_aItemVector
.push_back( aSeq
);
203 else if ( sal_Int32( m_aItemVector
.size()) >Index
)
205 std::vector
< Sequence
< PropertyValue
> >::iterator aIter
= m_aItemVector
.begin();
207 m_aItemVector
.insert( aIter
, aSeq
);
210 throw IndexOutOfBoundsException( OUString(), (OWeakObject
*)this );
213 throw IllegalArgumentException( WRONG_TYPE_EXCEPTION
, (OWeakObject
*)this, 2 );
216 void SAL_CALL
RootItemContainer::removeByIndex( sal_Int32 nIndex
)
217 throw ( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
219 ShareGuard
aLock( m_aShareMutex
);
220 if ( (sal_Int32
)m_aItemVector
.size() > nIndex
)
222 m_aItemVector
.erase(m_aItemVector
.begin() + nIndex
);
225 throw IndexOutOfBoundsException( OUString(), (OWeakObject
*)this );
228 void SAL_CALL
RootItemContainer::replaceByIndex( sal_Int32 Index
, const Any
& aItem
)
229 throw ( IllegalArgumentException
, IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
231 Sequence
< PropertyValue
> aSeq
;
232 if ( aItem
>>= aSeq
)
234 ShareGuard
aLock( m_aShareMutex
);
235 if ( sal_Int32( m_aItemVector
.size()) > Index
)
236 m_aItemVector
[Index
] = aSeq
;
238 throw IndexOutOfBoundsException( OUString(), (OWeakObject
*)this );
241 throw IllegalArgumentException( WRONG_TYPE_EXCEPTION
, (OWeakObject
*)this, 2 );
244 Reference
< XInterface
> SAL_CALL
RootItemContainer::createInstanceWithContext( const Reference
< XComponentContext
>& )
245 throw ( Exception
, RuntimeException
, std::exception
)
247 return (OWeakObject
*)(new ItemContainer( m_aShareMutex
));
250 Reference
< XInterface
> SAL_CALL
RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence
< Any
>&, const Reference
< XComponentContext
>& )
251 throw (Exception
, RuntimeException
, std::exception
)
253 return (OWeakObject
*)(new ItemContainer( m_aShareMutex
));
256 // XPropertySet helper
257 sal_Bool SAL_CALL
RootItemContainer::convertFastPropertyValue( Any
& aConvertedValue
,
261 throw( com::sun::star::lang::IllegalArgumentException
)
263 // Initialize state with sal_False !!!
264 // (Handle can be invalid)
265 bool bReturn
= false;
269 case PROPHANDLE_UINAME
:
270 bReturn
= PropHelper::willPropertyBeChanged(
271 com::sun::star::uno::makeAny(m_aUIName
),
278 // Return state of operation.
282 void SAL_CALL
RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
283 const com::sun::star::uno::Any
& aValue
)
284 throw( com::sun::star::uno::Exception
, std::exception
)
288 case PROPHANDLE_UINAME
:
289 aValue
>>= m_aUIName
;
294 void SAL_CALL
RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any
& aValue
,
295 sal_Int32 nHandle
) const
299 case PROPHANDLE_UINAME
:
300 aValue
<<= m_aUIName
;
305 ::cppu::IPropertyArrayHelper
& SAL_CALL
RootItemContainer::getInfoHelper()
307 // Optimize this method !
308 // We initialize a static variable only one time. And we don't must use a mutex at every call!
309 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
310 static ::cppu::OPropertyArrayHelper
* pInfoHelper
= NULL
;
312 if( pInfoHelper
== NULL
)
314 // Ready for multithreading
315 osl::MutexGuard
aGuard( osl::Mutex::getGlobalMutex() );
317 // Control this pointer again, another instance can be faster then these!
318 if( pInfoHelper
== NULL
)
320 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
321 // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
322 // "sal_True" say: Table is sorted by name.
323 static ::cppu::OPropertyArrayHelper
aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True
);
324 pInfoHelper
= &aInfoHelper
;
328 return(*pInfoHelper
);
331 com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> SAL_CALL
RootItemContainer::getPropertySetInfo()
332 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
334 // Optimize this method !
335 // We initialize a static variable only one time. And we don't must use a mutex at every call!
336 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
337 static com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
>* pInfo
= NULL
;
341 // Ready for multithreading
342 osl::MutexGuard
aGuard( osl::Mutex::getGlobalMutex() );
343 // Control this pointer again, another instance can be faster then these!
346 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
347 // (Use method "getInfoHelper()".)
348 static com::sun::star::uno::Reference
< com::sun::star::beans::XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
356 const com::sun::star::uno::Sequence
< com::sun::star::beans::Property
> RootItemContainer::impl_getStaticPropertyDescriptor()
358 // Create a property array to initialize sequence!
359 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
360 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
361 // It's necessary for methods of OPropertySetHelper.
363 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
365 const com::sun::star::beans::Property pProperties
[] =
367 com::sun::star::beans::Property( OUString(PROPNAME_UINAME
), PROPHANDLE_UINAME
,
368 cppu::UnoType
<OUString
>::get(),
369 com::sun::star::beans::PropertyAttribute::TRANSIENT
)
371 // Use it to initialize sequence!
372 const com::sun::star::uno::Sequence
< com::sun::star::beans::Property
> lPropertyDescriptor( pProperties
, PROPCOUNT
);
373 // Return "PropertyDescriptor"
374 return lPropertyDescriptor
;
377 } // namespace framework
379 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */