xref: /trunk/main/framework/source/fwi/uielement/rootitemcontainer.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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