merge the formfield patch from ooo-build
[ooovba.git] / framework / source / uielement / itemcontainer.cxx
blobb0fc5d385f192568dfa14d4f458784d4cd32415c
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: itemcontainer.cxx,v $
10 * $Revision: 1.8 $
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/itemcontainer.hxx>
37 #include <uielement/constitemcontainer.hxx>
38 #include <threadhelp/resetableguard.hxx>
40 //_________________________________________________________________________________________________________________
41 // other includes
42 //_________________________________________________________________________________________________________________
44 using namespace cppu;
45 using namespace com::sun::star::uno;
46 using namespace com::sun::star::lang;
47 using namespace com::sun::star::beans;
48 using namespace com::sun::star::container;
50 const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >";
52 namespace framework
55 //*****************************************************************************************************************
56 // XInterface, XTypeProvider
57 //*****************************************************************************************************************
59 ItemContainer::ItemContainer( const ShareableMutex& rMutex ) :
60 m_aShareMutex( rMutex )
65 ItemContainer::ItemContainer( const ConstItemContainer& rConstItemContainer, const ShareableMutex& rMutex ) : m_aShareMutex( rMutex )
67 copyItemContainer( rConstItemContainer.m_aItemVector, rMutex );
70 ItemContainer::ItemContainer( const Reference< XIndexAccess >& rSourceContainer, const ShareableMutex& rMutex ) :
71 m_aShareMutex( rMutex )
73 if ( rSourceContainer.is() )
75 sal_Int32 nCount = rSourceContainer->getCount();
76 try
78 for ( sal_Int32 i = 0; i < nCount; i++ )
80 Sequence< PropertyValue > aPropSeq;
81 if ( rSourceContainer->getByIndex( i ) >>= aPropSeq )
83 sal_Int32 nContainerIndex = -1;
84 Reference< XIndexAccess > xIndexAccess;
85 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
87 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
89 aPropSeq[j].Value >>= xIndexAccess;
90 nContainerIndex = j;
91 break;
95 if ( xIndexAccess.is() && nContainerIndex >= 0 )
96 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex );
98 m_aItemVector.push_back( aPropSeq );
102 catch ( IndexOutOfBoundsException& )
108 ItemContainer::~ItemContainer()
112 // private
113 void ItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector, const ShareableMutex& rMutex )
115 const sal_uInt32 nCount = rSourceVector.size();
116 for ( sal_uInt32 i = 0; i < nCount; ++i )
118 sal_Int32 nContainerIndex = -1;
119 Sequence< PropertyValue > aPropSeq( rSourceVector[i] );
120 Reference< XIndexAccess > xIndexAccess;
121 for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ )
123 if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" ))
125 aPropSeq[j].Value >>= xIndexAccess;
126 nContainerIndex = j;
127 break;
131 if ( xIndexAccess.is() && nContainerIndex >= 0 )
132 aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex );
134 m_aItemVector.push_back( aPropSeq );
138 Reference< XIndexAccess > ItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer, const ShareableMutex& rMutex )
140 Reference< XIndexAccess > xReturn;
141 if ( rSubContainer.is() )
143 ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer );
144 ItemContainer* pSubContainer( 0 );
145 if ( pSource )
146 pSubContainer = new ItemContainer( *pSource, rMutex );
147 else
148 pSubContainer = new ItemContainer( rSubContainer, rMutex );
149 xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY );
152 return xReturn;
155 // XUnoTunnel
156 sal_Int64 ItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException)
158 if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( ItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
159 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
161 return 0;
164 const Sequence< sal_Int8 >& ItemContainer::GetUnoTunnelId() throw()
166 static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL;
167 if( !pSeq )
169 ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() );
170 if( !pSeq )
172 static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 );
173 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
174 pSeq = &aSeq;
177 return *pSeq;
180 ItemContainer* ItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw()
182 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY );
183 return xUT.is() ? reinterpret_cast< ItemContainer* >(sal::static_int_cast< sal_IntPtr >(
184 xUT->getSomething( ItemContainer::GetUnoTunnelId() ))) : NULL;
187 // XElementAccess
188 sal_Bool SAL_CALL ItemContainer::hasElements()
189 throw ( RuntimeException )
191 ShareGuard aLock( m_aShareMutex );
192 return ( !m_aItemVector.empty() );
195 // XIndexAccess
196 sal_Int32 SAL_CALL ItemContainer::getCount()
197 throw ( RuntimeException )
199 ShareGuard aLock( m_aShareMutex );
200 return m_aItemVector.size();
203 Any SAL_CALL ItemContainer::getByIndex( sal_Int32 Index )
204 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
206 ShareGuard aLock( m_aShareMutex );
207 if ( sal_Int32( m_aItemVector.size()) > Index )
208 return makeAny( m_aItemVector[Index] );
209 else
210 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
213 // XIndexContainer
214 void SAL_CALL ItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem )
215 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
217 Sequence< PropertyValue > aSeq;
218 if ( aItem >>= aSeq )
220 ShareGuard aLock( m_aShareMutex );
221 if ( sal_Int32( m_aItemVector.size()) == Index )
222 m_aItemVector.push_back( aSeq );
223 else if ( sal_Int32( m_aItemVector.size()) >Index )
225 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
226 aIter += Index;
227 m_aItemVector.insert( aIter, aSeq );
229 else
230 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
232 else
233 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
234 (OWeakObject *)this, 2 );
237 void SAL_CALL ItemContainer::removeByIndex( sal_Int32 Index )
238 throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
240 ShareGuard aLock( m_aShareMutex );
241 if ( (sal_Int32)m_aItemVector.size() > Index )
243 std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin();
244 aIter += Index;
245 m_aItemVector.erase( aIter );
247 else
248 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
251 void SAL_CALL ItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem )
252 throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
254 Sequence< PropertyValue > aSeq;
255 if ( aItem >>= aSeq )
257 ShareGuard aLock( m_aShareMutex );
258 if ( sal_Int32( m_aItemVector.size()) > Index )
259 m_aItemVector[Index] = aSeq;
260 else
261 throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this );
263 else
264 throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )),
265 (OWeakObject *)this, 2 );
268 } // namespace framework