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_framework.hxx"
26 //_________________________________________________________________________________________________________________
27 // my own includes
28 //_________________________________________________________________________________________________________________
29 #include <uielement/rootitemcontainer.hxx>
30
31 #ifndef __FRAMEWORK_UIELEMENT_ITEMCONTAINER_HHX_
32 #include <uielement/itemcontainer.hxx>
33 #endif
34
35 #ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HHX_
36 #include <uielement/constitemcontainer.hxx>
37 #endif
38 #include <threadhelp/resetableguard.hxx>
39 #include <general.h>
40 #include <properties.h>
41
42 //_________________________________________________________________________________________________________________
43 // interface includes
44 //_________________________________________________________________________________________________________________
45 #include <com/sun/star/beans/PropertyAttribute.hpp>
46
47 //_________________________________________________________________________________________________________________
48 // other includes
49 //_________________________________________________________________________________________________________________
50
51 using namespace cppu;
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;
56
57 const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
58
59 const int PROPHANDLE_UINAME = 1;
60 const int PROPCOUNT = 1;
61 const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" ));
62
63 namespace framework
64 {
65
66 //*****************************************************************************************************************
67 // XInterface, XTypeProvider
68 //*****************************************************************************************************************
DEFINE_XINTERFACE_10(RootItemContainer,OWeakObject,DIRECT_INTERFACE (::com::sun::star::lang::XTypeProvider),DIRECT_INTERFACE (::com::sun::star::container::XIndexContainer),DIRECT_INTERFACE (::com::sun::star::lang::XUnoTunnel),DIRECT_INTERFACE (::com::sun::star::lang::XSingleComponentFactory),DIRECT_INTERFACE (::com::sun::star::beans::XMultiPropertySet),DIRECT_INTERFACE (::com::sun::star::beans::XFastPropertySet),DIRECT_INTERFACE (::com::sun::star::beans::XPropertySet),DERIVED_INTERFACE (::com::sun::star::container::XIndexReplace,com::sun::star::container::XIndexContainer),DERIVED_INTERFACE (::com::sun::star::container::XIndexAccess,com::sun::star::container::XIndexReplace),DERIVED_INTERFACE (::com::sun::star::container::XElementAccess,::com::sun::star::container::XIndexAccess))69 DEFINE_XINTERFACE_10 ( RootItemContainer ,
70 OWeakObject ,
71 DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ),
72 DIRECT_INTERFACE( ::com::sun::star::container::XIndexContainer ),
73 DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel ),
74 DIRECT_INTERFACE( ::com::sun::star::lang::XSingleComponentFactory ),
75 DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ),
76 DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ),
77 DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ),
78 DERIVED_INTERFACE( ::com::sun::star::container::XIndexReplace, com::sun::star::container::XIndexContainer ),
79 DERIVED_INTERFACE( ::com::sun::star::container::XIndexAccess, com::sun::star::container::XIndexReplace ),
80 DERIVED_INTERFACE( ::com::sun::star::container::XElementAccess, ::com::sun::star::container::XIndexAccess )
81 )
82
83 DEFINE_XTYPEPROVIDER_10 ( RootItemContainer ,
84 ::com::sun::star::lang::XTypeProvider ,
85 ::com::sun::star::container::XIndexContainer ,
86 ::com::sun::star::container::XIndexReplace ,
87 ::com::sun::star::container::XIndexAccess ,
88 ::com::sun::star::container::XElementAccess ,
89 ::com::sun::star::beans::XMultiPropertySet ,
90 ::com::sun::star::beans::XFastPropertySet ,
91 ::com::sun::star::beans::XPropertySet ,
92 ::com::sun::star::lang::XUnoTunnel ,
93 ::com::sun::star::lang::XSingleComponentFactory
94 )
95
96 RootItemContainer::RootItemContainer()
97 : ThreadHelpBase ( )
98 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
99 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
100 , ::cppu::OWeakObject()
101 {
102 }
103
RootItemContainer(const ConstItemContainer & rConstItemContainer)104 RootItemContainer::RootItemContainer( const ConstItemContainer& rConstItemContainer )
105 : ThreadHelpBase ( )
106 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
107 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
108 , ::cppu::OWeakObject()
109 {
110 m_aUIName = rConstItemContainer.m_aUIName;
111 copyItemContainer( rConstItemContainer.m_aItemVector );
112 }
113
RootItemContainer(const Reference<XIndexAccess> & rSourceContainer)114 RootItemContainer::RootItemContainer( const Reference< XIndexAccess >& rSourceContainer )
115 : ThreadHelpBase ( )
116 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() )
117 , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) )
118 , ::cppu::OWeakObject()
119 {
120 // We also have to copy the UIName property
121 try
122 {
123 Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY );
124 if ( xPropSet.is() )
125 {
126 xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName;
127 }
128 }
129 catch ( Exception& )
130 {
131 }
132
133 if ( rSourceContainer.is() )
134 {
135 sal_Int32 nCount = rSourceContainer->getCount();
136 try
137 {
138 for ( sal_Int32 i = 0; i < nCount; i++ )
139 {
140 Sequence< PropertyValue > aPropSeq;
141 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
142 {
143 sal_Int32 nContainerIndex = -1;
144 Reference< XIndexAccess > xIndexAccess;
145 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
146 {
147 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
148 {
149 aPropSeq[j].Value >>= xIndexAccess;
150 nContainerIndex = j;
151 break;
152 }
153 }
154
155 if ( xIndexAccess.is() && nContainerIndex >= 0 )
156 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
157
158 m_aItemVector.push_back( aPropSeq );
159 }
160 }
161 }
162 catch ( IndexOutOfBoundsException& )
163 {
164 }
165 }
166 }
167
~RootItemContainer()168 RootItemContainer::~RootItemContainer()
169 {
170 }
171
172 // private
copyItemContainer(const std::vector<Sequence<PropertyValue>> & rSourceVector)173 void RootItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector )
174 {
175 const sal_uInt32 nCount = rSourceVector.size();
176 m_aItemVector.reserve(nCount);
177 for ( sal_uInt32 i = 0; i < nCount; i++ )
178 {
179 sal_Int32 nContainerIndex = -1;
180 Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
181 Reference< XIndexAccess > xIndexAccess;
182 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
183 {
184 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
185 {
186 aPropSeq[j].Value >>= xIndexAccess;
187 nContainerIndex = j;
188 break;
189 }
190 }
191
192 if ( xIndexAccess.is() && nContainerIndex >= 0 )
193 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess );
194
195 m_aItemVector.push_back( aPropSeq );
196 }
197 }
198
deepCopyContainer(const Reference<XIndexAccess> & rSubContainer)199 Reference< XIndexAccess > RootItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer )
200 {
201 Reference< XIndexAccess > xReturn;
202 if ( rSubContainer.is() )
203 {
204 ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer );
205 ItemContainer* pSubContainer( 0 );
206 if ( pSource )
207 pSubContainer = new ItemContainer( *pSource, m_aShareMutex );
208 else
209 pSubContainer = new ItemContainer( rSubContainer, m_aShareMutex );
210 xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
211 }
212
213 return xReturn;
214 }
215
216 // XUnoTunnel
getSomething(const::com::sun::star::uno::Sequence<sal_Int8> & rIdentifier)217 sal_Int64 RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier )
218 {
219 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
220 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
221 return 0;
222 }
223
GetUnoTunnelId()224 const Sequence< sal_Int8 >& RootItemContainer::GetUnoTunnelId() throw()
225 {
226 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
227 if( !pSeq )
228 {
229 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
230 if( !pSeq )
231 {
232 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
233 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
234 pSeq = &aSeq;
235 }
236 }
237 return *pSeq;
238 }
239
GetImplementation(const::com::sun::star::uno::Reference<::com::sun::star::uno::XInterface> & rxIFace)240 RootItemContainer* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
241 {
242 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
243 return xUT.is() ? reinterpret_cast< RootItemContainer* >(sal::static_int_cast< sal_IntPtr >(
244 xUT->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL;
245 }
246
247 // XElementAccess
hasElements()248 sal_Bool SAL_CALL RootItemContainer::hasElements()
249 {
250 ShareGuard aLock( m_aShareMutex );
251 return ( !m_aItemVector.empty() );
252 }
253
254 // XIndexAccess
getCount()255 sal_Int32 SAL_CALL RootItemContainer::getCount()
256 {
257 ShareGuard aLock( m_aShareMutex );
258 return m_aItemVector.size();
259 }
260
getByIndex(sal_Int32 Index)261 Any SAL_CALL RootItemContainer::getByIndex( sal_Int32 Index )
262 {
263 ShareGuard aLock( m_aShareMutex );
264 if ( sal_Int32( m_aItemVector.size()) > Index )
265 return makeAny( m_aItemVector[Index] );
266 else
267 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
268 }
269
270 // XIndexContainer
insertByIndex(sal_Int32 Index,const Any & aItem)271 void SAL_CALL RootItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem )
272 {
273 Sequence< PropertyValue > aSeq;
274 if ( aItem >>= aSeq )
275 {
276 ShareGuard aLock( m_aShareMutex );
277 if ( sal_Int32( m_aItemVector.size()) == Index )
278 m_aItemVector.push_back( aSeq );
279 else if ( sal_Int32( m_aItemVector.size()) >Index )
280 {
281 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
282 aIter += Index;
283 m_aItemVector.insert( aIter, aSeq );
284 }
285 else
286 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
287 }
288 else
289 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
290 (OWeakObject *)this, 2 );
291 }
292
removeByIndex(sal_Int32 Index)293 void SAL_CALL RootItemContainer::removeByIndex( sal_Int32 Index )
294 {
295 ShareGuard aLock( m_aShareMutex );
296 if ( (sal_Int32)m_aItemVector.size() > Index )
297 {
298 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
299 aIter += Index;
300 m_aItemVector.erase( aIter );
301 }
302 else
303 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
304 }
305
replaceByIndex(sal_Int32 Index,const Any & aItem)306 void SAL_CALL RootItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem )
307 {
308 Sequence< PropertyValue > aSeq;
309 if ( aItem >>= aSeq )
310 {
311 ShareGuard aLock( m_aShareMutex );
312 if ( sal_Int32( m_aItemVector.size()) > Index )
313 m_aItemVector[Index] = aSeq;
314 else
315 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
316 }
317 else
318 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
319 (OWeakObject *)this, 2 );
320 }
321
createInstanceWithContext(const Reference<XComponentContext> &)322 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& )
323 {
324 return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
325 }
326
createInstanceWithArgumentsAndContext(const Sequence<Any> &,const Reference<XComponentContext> &)327 Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence< Any >&, const Reference< XComponentContext >& )
328 {
329 return (OWeakObject *)(new ItemContainer( m_aShareMutex ));
330 }
331
332 // XPropertySet helper
convertFastPropertyValue(Any & aConvertedValue,Any & aOldValue,sal_Int32 nHandle,const Any & aValue)333 sal_Bool SAL_CALL RootItemContainer::convertFastPropertyValue( Any& aConvertedValue ,
334 Any& aOldValue ,
335 sal_Int32 nHandle ,
336 const Any& aValue )
337 {
338 // Initialize state with sal_False !!!
339 // (Handle can be invalid)
340 sal_Bool bReturn = sal_False;
341
342 switch( nHandle )
343 {
344 case PROPHANDLE_UINAME:
345 bReturn = PropHelper::willPropertyBeChanged(
346 com::sun::star::uno::makeAny(m_aUIName),
347 aValue,
348 aOldValue,
349 aConvertedValue);
350 break;
351 }
352
353 // Return state of operation.
354 return bReturn ;
355 }
356
setFastPropertyValue_NoBroadcast(sal_Int32 nHandle,const com::sun::star::uno::Any & aValue)357 void SAL_CALL RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle ,
358 const com::sun::star::uno::Any& aValue )
359 {
360 switch( nHandle )
361 {
362 case PROPHANDLE_UINAME:
363 aValue >>= m_aUIName;
364 break;
365 }
366 }
367
getFastPropertyValue(com::sun::star::uno::Any & aValue,sal_Int32 nHandle) const368 void SAL_CALL RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any& aValue ,
369 sal_Int32 nHandle ) const
370 {
371 switch( nHandle )
372 {
373 case PROPHANDLE_UINAME:
374 aValue <<= m_aUIName;
375 break;
376 }
377 }
378
getInfoHelper()379 ::cppu::IPropertyArrayHelper& SAL_CALL RootItemContainer::getInfoHelper()
380 {
381 // Optimize this method !
382 // We initialize a static variable only one time. And we don't must use a mutex at every call!
383 // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL!
384 static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL;
385
386 if( pInfoHelper == NULL )
387 {
388 // Ready for multithreading
389 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
390
391 // Control this pointer again, another instance can be faster then these!
392 if( pInfoHelper == NULL )
393 {
394 // Define static member to give structure of properties to baseclass "OPropertySetHelper".
395 // "impl_getStaticPropertyDescriptor" is a non exported and static function, who will define a static propertytable.
396 // "sal_True" say: Table is sorted by name.
397 static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True );
398 pInfoHelper = &aInfoHelper;
399 }
400 }
401
402 return(*pInfoHelper);
403 }
404
getPropertySetInfo()405 com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL RootItemContainer::getPropertySetInfo()
406 {
407 // Optimize this method !
408 // We initialize a static variable only one time. And we don't must use a mutex at every call!
409 // For the first call; pInfo is NULL - for the second call pInfo is different from NULL!
410 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL;
411
412 if( pInfo == NULL )
413 {
414 // Ready for multithreading
415 osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ;
416 // Control this pointer again, another instance can be faster then these!
417 if( pInfo == NULL )
418 {
419 // Create structure of propertysetinfo for baseclass "OPropertySetHelper".
420 // (Use method "getInfoHelper()".)
421 static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
422 pInfo = &xInfo;
423 }
424 }
425
426 return (*pInfo);
427 }
428
impl_getStaticPropertyDescriptor()429 const com::sun::star::uno::Sequence< com::sun::star::beans::Property > RootItemContainer::impl_getStaticPropertyDescriptor()
430 {
431 // Create a new static property array to initialize sequence!
432 // Table of all predefined properties of this class. Its used from OPropertySetHelper-class!
433 // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!!
434 // It's necessary for methods of OPropertySetHelper.
435 // ATTENTION:
436 // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!!
437
438 static const com::sun::star::beans::Property pProperties[] =
439 {
440 com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME ,
441 ::getCppuType((const rtl::OUString*)NULL),
442 com::sun::star::beans::PropertyAttribute::TRANSIENT )
443 };
444 // Use it to initialize sequence!
445 static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT );
446 // Return static "PropertyDescriptor"
447 return lPropertyDescriptor;
448 }
449
450 } // namespace framework
451