update credits
[LibreOffice.git] / include / vbahelper / vbacollectionimpl.hxx
blob780741e06a629b1c51bc499af12cea7ac20b413e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
20 #ifndef OOVBAAPI_VBA_COLLECTION_IMPL_HXX
21 #define OOVBAAPI_VBA_COLLECTION_IMPL_HXX
23 #include <ooo/vba/XCollection.hpp>
24 #include <com/sun/star/container/XEnumerationAccess.hpp>
25 #include <com/sun/star/uno/XComponentContext.hpp>
26 #include <com/sun/star/script/XDefaultMethod.hpp>
27 #include <com/sun/star/container/XIndexAccess.hpp>
28 #include <com/sun/star/container/XNameAccess.hpp>
29 #include <com/sun/star/container/XNamed.hpp>
31 #include <cppuhelper/implbase3.hxx>
32 #include <cppuhelper/implbase2.hxx>
33 #include <cppuhelper/implbase1.hxx>
35 #include "vbahelper/vbahelper.hxx"
36 #include "vbahelper/vbahelperinterface.hxx"
38 #include <vector>
40 // ============================================================================
42 typedef ::cppu::WeakImplHelper1< css::container::XEnumeration > EnumerationHelper_BASE;
44 // ============================================================================
46 /** A wrapper that holds a com.sun.star.container.XIndexAccess and provides a
47 com.sun.star.container.XEnumeration.
49 Can be used to provide an enumeration from an index container that contains
50 completely constructed/initialized VBA implementation objects. CANNOT be
51 used to provide an enumeration from an index container with other objects
52 (e.g. UNO objects) where construction of the VBA objects is needed first.
54 class VBAHELPER_DLLPUBLIC SimpleIndexAccessToEnumeration : public EnumerationHelper_BASE
56 public:
57 explicit SimpleIndexAccessToEnumeration(
58 const css::uno::Reference< css::container::XIndexAccess >& rxIndexAccess ) throw (css::uno::RuntimeException) :
59 mxIndexAccess( rxIndexAccess ), mnIndex( 0 ) {}
61 virtual sal_Bool SAL_CALL hasMoreElements() throw (css::uno::RuntimeException)
63 return mnIndex < mxIndexAccess->getCount();
66 virtual css::uno::Any SAL_CALL nextElement() throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
68 if( !hasMoreElements() )
69 throw css::container::NoSuchElementException();
70 return mxIndexAccess->getByIndex( mnIndex++ );
73 private:
74 css::uno::Reference< css::container::XIndexAccess > mxIndexAccess;
75 sal_Int32 mnIndex;
78 // ============================================================================
80 /** A wrapper that holds a com.sun.star.container.XEnumeration or a
81 com.sun.star.container.XIndexAccess and provides an enumeration of VBA objects.
83 The method createCollectionObject() needs to be implemented by the derived
84 class. This class can be used to convert an enumeration or an index container
85 containing UNO objects to an enumeration providing the related VBA objects.
87 class VBAHELPER_DLLPUBLIC SimpleEnumerationBase : public EnumerationHelper_BASE
89 public:
90 explicit SimpleEnumerationBase(
91 const css::uno::Reference< ov::XHelperInterface >& rxParent,
92 const css::uno::Reference< css::uno::XComponentContext >& rxContext,
93 const css::uno::Reference< css::container::XEnumeration >& rxEnumeration ) throw (css::uno::RuntimeException) :
94 mxParent( rxParent ), mxContext( rxContext ), mxEnumeration( rxEnumeration ) {}
96 explicit SimpleEnumerationBase(
97 const css::uno::Reference< ov::XHelperInterface >& rxParent,
98 const css::uno::Reference< css::uno::XComponentContext >& rxContext,
99 const css::uno::Reference< css::container::XIndexAccess >& rxIndexAccess ) throw (css::uno::RuntimeException) :
100 mxParent( rxParent ), mxContext( rxContext ), mxEnumeration( new SimpleIndexAccessToEnumeration( rxIndexAccess ) ) {}
102 virtual sal_Bool SAL_CALL hasMoreElements() throw (css::uno::RuntimeException)
104 return mxEnumeration->hasMoreElements();
107 virtual css::uno::Any SAL_CALL nextElement() throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
109 return createCollectionObject( mxEnumeration->nextElement() );
112 /** Derived classes implement creation of a VBA implementation object from
113 the passed container element. */
114 virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ) = 0;
116 protected:
117 css::uno::Reference< ov::XHelperInterface > mxParent;
118 css::uno::Reference< css::uno::XComponentContext > mxContext;
119 css::uno::Reference< css::container::XEnumeration > mxEnumeration;
122 // ============================================================================
124 // deprecated, use SimpleEnumerationBase instead!
125 class VBAHELPER_DLLPUBLIC EnumerationHelperImpl : public EnumerationHelper_BASE
127 protected:
128 css::uno::WeakReference< ov::XHelperInterface > m_xParent;
129 css::uno::Reference< css::uno::XComponentContext > m_xContext;
130 css::uno::Reference< css::container::XEnumeration > m_xEnumeration;
131 public:
133 EnumerationHelperImpl( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XEnumeration >& xEnumeration ) throw ( css::uno::RuntimeException ) : m_xParent( xParent ), m_xContext( xContext ), m_xEnumeration( xEnumeration ) { }
134 virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (css::uno::RuntimeException) { return m_xEnumeration->hasMoreElements(); }
137 // a wrapper class for a providing a XIndexAccess, XNameAccess, XEnumerationAccess impl based on providing a vector of interfaces
138 // only requirement is the object needs to implement XName
142 typedef ::cppu::WeakImplHelper3< css::container::XNameAccess, css::container::XIndexAccess, css::container::XEnumerationAccess > XNamedCollectionHelper_BASE;
144 template< typename Ifc1 >
145 class XNamedObjectCollectionHelper : public XNamedCollectionHelper_BASE
147 public:
148 typedef std::vector< css::uno::Reference< Ifc1 > > XNamedVec;
149 private:
151 class XNamedEnumerationHelper : public EnumerationHelper_BASE
153 XNamedVec mXNamedVec;
154 typename XNamedVec::iterator mIt;
155 public:
156 XNamedEnumerationHelper( const XNamedVec& sMap ) : mXNamedVec( sMap ), mIt( mXNamedVec.begin() ) {}
158 virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (css::uno::RuntimeException)
160 return ( mIt != mXNamedVec.end() );
163 virtual css::uno::Any SAL_CALL nextElement( ) throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
165 if ( hasMoreElements() )
166 return css::uno::makeAny( *mIt++ );
167 throw css::container::NoSuchElementException();
171 protected:
172 XNamedVec mXNamedVec;
173 typename XNamedVec::iterator cachePos;
174 public:
175 XNamedObjectCollectionHelper( const XNamedVec& sMap ) : mXNamedVec( sMap ), cachePos(mXNamedVec.begin()) {}
176 // XElementAccess
177 virtual css::uno::Type SAL_CALL getElementType( ) throw (css::uno::RuntimeException) { return Ifc1::static_type(0); }
178 virtual ::sal_Bool SAL_CALL hasElements( ) throw (css::uno::RuntimeException) { return ( mXNamedVec.size() > 0 ); }
179 // XNameAcess
180 virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
182 if ( !hasByName(aName) )
183 throw css::container::NoSuchElementException();
184 return css::uno::makeAny( *cachePos );
186 virtual css::uno::Sequence< OUString > SAL_CALL getElementNames( ) throw (css::uno::RuntimeException)
188 css::uno::Sequence< OUString > sNames( mXNamedVec.size() );
189 OUString* pString = sNames.getArray();
190 typename XNamedVec::iterator it = mXNamedVec.begin();
191 typename XNamedVec::iterator it_end = mXNamedVec.end();
193 for ( ; it != it_end; ++it, ++pString )
195 css::uno::Reference< css::container::XNamed > xName( *it, css::uno::UNO_QUERY_THROW );
196 *pString = xName->getName();
198 return sNames;
200 virtual ::sal_Bool SAL_CALL hasByName( const OUString& aName ) throw (css::uno::RuntimeException)
202 cachePos = mXNamedVec.begin();
203 typename XNamedVec::iterator it_end = mXNamedVec.end();
204 for ( ; cachePos != it_end; ++cachePos )
206 css::uno::Reference< css::container::XNamed > xName( *cachePos, css::uno::UNO_QUERY_THROW );
207 if ( aName.equals( xName->getName() ) )
208 break;
210 return ( cachePos != it_end );
213 // XElementAccess
214 virtual ::sal_Int32 SAL_CALL getCount( ) throw (css::uno::RuntimeException) { return mXNamedVec.size(); }
215 virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (css::lang::IndexOutOfBoundsException, css::lang::WrappedTargetException, css::uno::RuntimeException )
217 if ( Index < 0 || Index >= getCount() )
218 throw css::lang::IndexOutOfBoundsException();
220 return css::uno::makeAny( mXNamedVec[ Index ] );
223 // XEnumerationAccess
224 virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration( ) throw (css::uno::RuntimeException)
226 return new XNamedEnumerationHelper( mXNamedVec );
230 // including a HelperInterface implementation
231 template< typename Ifc1 >
232 class ScVbaCollectionBase : public InheritedHelperInterfaceImpl< Ifc1 >
234 typedef InheritedHelperInterfaceImpl< Ifc1 > BaseColBase;
235 protected:
236 css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess;
237 css::uno::Reference< css::container::XNameAccess > m_xNameAccess;
238 sal_Bool mbIgnoreCase;
240 virtual css::uno::Any getItemByStringIndex( const OUString& sIndex ) throw (css::uno::RuntimeException)
242 if ( !m_xNameAccess.is() )
243 throw css::uno::RuntimeException( OUString( "ScVbaCollectionBase string index access not supported by this object" ), css::uno::Reference< css::uno::XInterface >() );
245 if( mbIgnoreCase )
247 css::uno::Sequence< OUString > sElementNames = m_xNameAccess->getElementNames();
248 for( sal_Int32 i = 0; i < sElementNames.getLength(); i++ )
250 OUString aName = sElementNames[i];
251 if( aName.equalsIgnoreAsciiCase( sIndex ) )
253 return createCollectionObject( m_xNameAccess->getByName( aName ) );
257 return createCollectionObject( m_xNameAccess->getByName( sIndex ) );
260 virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex ) throw (css::uno::RuntimeException)
262 if ( !m_xIndexAccess.is() )
263 throw css::uno::RuntimeException( OUString( "ScVbaCollectionBase numeric index access not supported by this object" ), css::uno::Reference< css::uno::XInterface >() );
264 if ( nIndex <= 0 )
266 throw css::lang::IndexOutOfBoundsException(
267 OUString( "index is 0 or negative" ),
268 css::uno::Reference< css::uno::XInterface >() );
270 // need to adjust for vba index ( for which first element is 1 )
271 return createCollectionObject( m_xIndexAccess->getByIndex( nIndex - 1 ) );
274 virtual void UpdateCollectionIndex( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess )
276 css::uno::Reference< css::container::XNameAccess > xNameAccess( xIndexAccess, css::uno::UNO_QUERY_THROW );
277 m_xIndexAccess = xIndexAccess;
278 m_xNameAccess = xNameAccess;
281 public:
282 ScVbaCollectionBase( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, sal_Bool bIgnoreCase = sal_False ) : BaseColBase( xParent, xContext ), m_xIndexAccess( xIndexAccess ), mbIgnoreCase( bIgnoreCase ) { m_xNameAccess.set(m_xIndexAccess, css::uno::UNO_QUERY); }
283 //XCollection
284 virtual ::sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException)
286 return m_xIndexAccess->getCount();
289 virtual css::uno::Any SAL_CALL Item( const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/ ) throw (css::uno::RuntimeException)
291 if ( Index1.getValueTypeClass() != css::uno::TypeClass_STRING )
293 sal_Int32 nIndex = 0;
295 if ( ( Index1 >>= nIndex ) != sal_True )
297 OUString message;
298 message = OUString( "Couldn't convert index to Int32");
299 throw css::lang::IndexOutOfBoundsException( message,
300 css::uno::Reference< css::uno::XInterface >() );
302 return getItemByIntIndex( nIndex );
304 OUString aStringSheet;
306 Index1 >>= aStringSheet;
307 return getItemByStringIndex( aStringSheet );
309 // XDefaultMethod
310 OUString SAL_CALL getDefaultMethodName( ) throw (css::uno::RuntimeException)
312 const static OUString sName( "Item" );
313 return sName;
315 // XEnumerationAccess
316 virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException) = 0;
318 // XElementAccess
319 virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException) = 0;
320 // XElementAccess
321 virtual ::sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException)
323 return ( m_xIndexAccess->getCount() > 0 );
325 virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) = 0;
329 typedef ::cppu::WeakImplHelper1<ov::XCollection> XCollection_InterfacesBASE;
331 typedef ScVbaCollectionBase< XCollection_InterfacesBASE > CollImplBase1;
332 // compatible with the old collections ( pre XHelperInterface base class ) ( some internal objects still use this )
333 class VBAHELPER_DLLPUBLIC ScVbaCollectionBaseImpl : public CollImplBase1
335 public:
336 ScVbaCollectionBaseImpl( const css::uno::Reference< ov::XHelperInterface > xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ) throw( css::uno::RuntimeException ) : CollImplBase1( xParent, xContext, xIndexAccess){}
340 template <typename Ifc> // where Ifc must implement XCollectionTest
341 class CollTestImplHelper : public ScVbaCollectionBase< ::cppu::WeakImplHelper1< Ifc > >
343 typedef ScVbaCollectionBase< ::cppu::WeakImplHelper1< Ifc > > ImplBase1;
345 public:
346 CollTestImplHelper( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, sal_Bool bIgnoreCase = sal_False ) throw( css::uno::RuntimeException ) : ImplBase1( xParent, xContext, xIndexAccess, bIgnoreCase ) {}
350 #endif //SC_VBA_COLLECTION_IMPL_HXX
352 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */