android: Update app-specific/MIME type icons
[LibreOffice.git] / include / vbahelper / vbacollectionimpl.hxx
blob2e5184721a83b3e14e837687c8cf587ed4734f3a
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 INCLUDED_VBAHELPER_VBACOLLECTIONIMPL_HXX
21 #define INCLUDED_VBAHELPER_VBACOLLECTIONIMPL_HXX
23 #include <exception>
24 #include <utility>
25 #include <vector>
27 #include <com/sun/star/container/NoSuchElementException.hpp>
28 #include <com/sun/star/container/XEnumeration.hpp>
29 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30 #include <com/sun/star/lang/WrappedTargetException.hpp>
31 #include <com/sun/star/uno/Any.hxx>
32 #include <com/sun/star/uno/Reference.hxx>
33 #include <com/sun/star/uno/RuntimeException.hpp>
34 #include <com/sun/star/uno/Sequence.hxx>
35 #include <com/sun/star/uno/Type.hxx>
36 #include <com/sun/star/uno/TypeClass.hpp>
37 #include <cppu/unotype.hxx>
38 #include <cppuhelper/implbase.hxx>
39 #include <cppuhelper/weakref.hxx>
40 #include <ooo/vba/XCollection.hpp>
41 #include <com/sun/star/container/XIndexAccess.hpp>
42 #include <com/sun/star/container/XNameAccess.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <rtl/ustring.hxx>
45 #include <sal/types.h>
46 #include <vbahelper/vbadllapi.h>
47 #include <vbahelper/vbahelper.hxx>
48 #include <vbahelper/vbahelperinterface.hxx>
50 namespace com::sun::star {
51 namespace container { class XEnumerationAccess; }
52 namespace uno { class XComponentContext; }
55 namespace ooo::vba {
56 class XHelperInterface;
59 typedef ::cppu::WeakImplHelper< css::container::XEnumeration > EnumerationHelper_BASE;
62 /** A wrapper that holds a com.sun.star.container.XIndexAccess and provides a
63 com.sun.star.container.XEnumeration.
65 Can be used to provide an enumeration from an index container that contains
66 completely constructed/initialized VBA implementation objects. CANNOT be
67 used to provide an enumeration from an index container with other objects
68 (e.g. UNO objects) where construction of the VBA objects is needed first.
70 class VBAHELPER_DLLPUBLIC SimpleIndexAccessToEnumeration final : public EnumerationHelper_BASE
72 public:
73 /// @throws css::uno::RuntimeException
74 explicit SimpleIndexAccessToEnumeration(
75 css::uno::Reference< css::container::XIndexAccess > xIndexAccess ) :
76 mxIndexAccess(std::move( xIndexAccess )), mnIndex( 0 ) {}
78 virtual sal_Bool SAL_CALL hasMoreElements() override
80 return mnIndex < mxIndexAccess->getCount();
83 virtual css::uno::Any SAL_CALL nextElement() override
85 if( !hasMoreElements() )
86 throw css::container::NoSuchElementException();
87 return mxIndexAccess->getByIndex( mnIndex++ );
90 private:
91 css::uno::Reference< css::container::XIndexAccess > mxIndexAccess;
92 sal_Int32 mnIndex;
96 /** A wrapper that holds a com.sun.star.container.XEnumeration or a
97 com.sun.star.container.XIndexAccess and provides an enumeration of VBA objects.
99 The method createCollectionObject() needs to be implemented by the derived
100 class. This class can be used to convert an enumeration or an index container
101 containing UNO objects to an enumeration providing the related VBA objects.
103 class VBAHELPER_DLLPUBLIC SimpleEnumerationBase : public EnumerationHelper_BASE
105 public:
106 /// @throws css::uno::RuntimeException
107 explicit SimpleEnumerationBase(
108 const css::uno::Reference< css::container::XIndexAccess >& rxIndexAccess ) :
109 mxEnumeration( new SimpleIndexAccessToEnumeration( rxIndexAccess ) ) {}
111 virtual sal_Bool SAL_CALL hasMoreElements() override
113 return mxEnumeration->hasMoreElements();
116 virtual css::uno::Any SAL_CALL nextElement() override
118 return createCollectionObject( mxEnumeration->nextElement() );
121 /** Derived classes implement creation of a VBA implementation object from
122 the passed container element. */
123 virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ) = 0;
125 private:
126 css::uno::Reference< css::container::XEnumeration > mxEnumeration;
130 // deprecated, use SimpleEnumerationBase instead!
131 class VBAHELPER_DLLPUBLIC EnumerationHelperImpl : public EnumerationHelper_BASE
133 protected:
134 css::uno::WeakReference< ov::XHelperInterface > m_xParent;
135 css::uno::Reference< css::uno::XComponentContext > m_xContext;
136 css::uno::Reference< css::container::XEnumeration > m_xEnumeration;
137 public:
138 /// @throws css::uno::RuntimeException
139 EnumerationHelperImpl( const css::uno::Reference< ov::XHelperInterface >& xParent, css::uno::Reference< css::uno::XComponentContext > xContext, css::uno::Reference< css::container::XEnumeration > xEnumeration ) : m_xParent( xParent ), m_xContext(std::move( xContext )), m_xEnumeration(std::move( xEnumeration )) { }
140 virtual sal_Bool SAL_CALL hasMoreElements( ) override { return m_xEnumeration->hasMoreElements(); }
143 // a wrapper class for a providing a XIndexAccess, XNameAccess, XEnumerationAccess impl based on providing a vector of interfaces
144 // only requirement is the object needs to implement XName
147 template< typename OneIfc >
148 class XNamedObjectCollectionHelper final : public ::cppu::WeakImplHelper< css::container::XNameAccess,
149 css::container::XIndexAccess,
150 css::container::XEnumerationAccess >
152 public:
153 typedef std::vector< css::uno::Reference< OneIfc > > XNamedVec;
154 private:
156 class XNamedEnumerationHelper final : public EnumerationHelper_BASE
158 XNamedVec mXNamedVec;
159 typename XNamedVec::iterator mIt;
160 public:
161 XNamedEnumerationHelper( XNamedVec sMap ) : mXNamedVec(std::move( sMap )), mIt( mXNamedVec.begin() ) {}
163 virtual sal_Bool SAL_CALL hasMoreElements( ) override
165 return ( mIt != mXNamedVec.end() );
168 virtual css::uno::Any SAL_CALL nextElement( ) override
170 if ( hasMoreElements() )
171 return css::uno::Any( *mIt++ );
172 throw css::container::NoSuchElementException();
176 XNamedVec mXNamedVec;
177 typename XNamedVec::iterator cachePos;
178 public:
179 XNamedObjectCollectionHelper( XNamedVec sMap ) : mXNamedVec(std::move( sMap )), cachePos(mXNamedVec.begin()) {}
180 // XElementAccess
181 virtual css::uno::Type SAL_CALL getElementType( ) override { return cppu::UnoType< OneIfc >::get(); }
182 virtual sal_Bool SAL_CALL hasElements( ) override { return ( mXNamedVec.size() > 0 ); }
183 // XNameAccess
184 virtual css::uno::Any SAL_CALL getByName( const OUString& aName ) override
186 if ( !hasByName(aName) )
187 throw css::container::NoSuchElementException();
188 return css::uno::Any( *cachePos );
190 virtual css::uno::Sequence< OUString > SAL_CALL getElementNames( ) override
192 css::uno::Sequence< OUString > sNames( mXNamedVec.size() );
193 OUString* pString = sNames.getArray();
194 typename XNamedVec::iterator it = mXNamedVec.begin();
195 typename XNamedVec::iterator it_end = mXNamedVec.end();
197 for ( ; it != it_end; ++it, ++pString )
199 css::uno::Reference< css::container::XNamed > xName( *it, css::uno::UNO_QUERY_THROW );
200 *pString = xName->getName();
202 return sNames;
204 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override
206 cachePos = mXNamedVec.begin();
207 typename XNamedVec::iterator it_end = mXNamedVec.end();
208 for ( ; cachePos != it_end; ++cachePos )
210 css::uno::Reference< css::container::XNamed > xName( *cachePos, css::uno::UNO_QUERY_THROW );
211 if ( aName == xName->getName() )
212 break;
214 return ( cachePos != it_end );
217 // XElementAccess
218 virtual ::sal_Int32 SAL_CALL getCount( ) override { return mXNamedVec.size(); }
219 virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) override
221 if ( Index < 0 || Index >= getCount() )
222 throw css::lang::IndexOutOfBoundsException();
224 return css::uno::Any( mXNamedVec[ Index ] );
227 // XEnumerationAccess
228 virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration( ) override
230 return new XNamedEnumerationHelper( mXNamedVec );
234 // including a HelperInterface implementation
235 template< typename... Ifc >
236 class SAL_DLLPUBLIC_RTTI ScVbaCollectionBase : public InheritedHelperInterfaceImpl< Ifc... >
238 typedef InheritedHelperInterfaceImpl< Ifc... > BaseColBase;
239 protected:
240 css::uno::Reference< css::container::XIndexAccess > m_xIndexAccess;
241 css::uno::Reference< css::container::XNameAccess > m_xNameAccess;
242 bool mbIgnoreCase;
244 /// @throws css::uno::RuntimeException
245 virtual css::uno::Any getItemByStringIndex( const OUString& sIndex )
247 if ( !m_xNameAccess.is() )
248 throw css::uno::RuntimeException("ScVbaCollectionBase string index access not supported by this object" );
250 if( mbIgnoreCase )
252 const css::uno::Sequence< OUString > sElementNames = m_xNameAccess->getElementNames();
253 for( const OUString& rName : sElementNames )
255 if( rName.equalsIgnoreAsciiCase( sIndex ) )
257 return createCollectionObject( m_xNameAccess->getByName( rName ) );
261 return createCollectionObject( m_xNameAccess->getByName( sIndex ) );
264 /// @throws css::uno::RuntimeException
265 /// @throws css::lang::IndexOutOfBoundsException
266 virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex )
268 if ( !m_xIndexAccess.is() )
269 throw css::uno::RuntimeException("ScVbaCollectionBase numeric index access not supported by this object" );
270 if ( nIndex <= 0 )
272 throw css::lang::IndexOutOfBoundsException(
273 "index is 0 or negative" );
275 // need to adjust for vba index ( for which first element is 1 )
276 return createCollectionObject( m_xIndexAccess->getByIndex( nIndex - 1 ) );
279 void UpdateCollectionIndex( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess )
281 css::uno::Reference< css::container::XNameAccess > xNameAccess( xIndexAccess, css::uno::UNO_QUERY_THROW );
282 m_xIndexAccess = xIndexAccess;
283 m_xNameAccess = xNameAccess;
286 public:
287 ScVbaCollectionBase( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, css::uno::Reference< css::container::XIndexAccess > xIndexAccess, bool bIgnoreCase = false ) : BaseColBase( xParent, xContext ), m_xIndexAccess(std::move( xIndexAccess )), mbIgnoreCase( bIgnoreCase ) { m_xNameAccess.set(m_xIndexAccess, css::uno::UNO_QUERY); }
289 //XCollection
290 virtual ::sal_Int32 SAL_CALL getCount() override
292 return m_xIndexAccess->getCount();
295 virtual css::uno::Any SAL_CALL Item(const css::uno::Any& Index1, const css::uno::Any& /*not processed in this base class*/) override
297 OUString aStringSheet;
298 if (Index1.getValueTypeClass() == css::uno::TypeClass_DOUBLE)
300 // This is needed for ContentControls, where the unique integer ID
301 // can be passed as float to simulate a "by name" lookup.
302 double fIndex = 0;
303 Index1 >>= fIndex;
304 aStringSheet = OUString::number(fIndex);
306 else if (Index1.getValueTypeClass() != css::uno::TypeClass_STRING)
308 sal_Int32 nIndex = 0;
309 if ( !( Index1 >>= nIndex ) )
311 throw css::lang::IndexOutOfBoundsException( "Couldn't convert index to Int32" );
314 return getItemByIntIndex( nIndex );
316 else
317 Index1 >>= aStringSheet;
319 return getItemByStringIndex( aStringSheet );
322 // XDefaultMethod
323 OUString SAL_CALL getDefaultMethodName( ) override
325 return "Item";
327 // XEnumerationAccess
328 virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override = 0;
330 // XElementAccess
331 virtual css::uno::Type SAL_CALL getElementType() override = 0;
332 // XElementAccess
333 virtual sal_Bool SAL_CALL hasElements() override
335 return ( m_xIndexAccess->getCount() > 0 );
337 virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) = 0;
341 typedef ScVbaCollectionBase< ::cppu::WeakImplHelper<ov::XCollection> > CollImplBase;
342 // compatible with the old collections ( pre XHelperInterface base class ) ( some internal objects still use this )
343 class VBAHELPER_DLLPUBLIC ScVbaCollectionBaseImpl : public CollImplBase
345 public:
346 /// @throws css::uno::RuntimeException
347 ScVbaCollectionBaseImpl( const css::uno::Reference< ov::XHelperInterface > & xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ) : CollImplBase( xParent, xContext, xIndexAccess){}
351 template < typename... Ifc > // where Ifc must implement XCollectionTest
352 class SAL_DLLPUBLIC_RTTI CollTestImplHelper : public ScVbaCollectionBase< ::cppu::WeakImplHelper< Ifc... > >
354 typedef ScVbaCollectionBase< ::cppu::WeakImplHelper< Ifc... > > ImplBase;
356 public:
357 /// @throws css::uno::RuntimeException
358 CollTestImplHelper( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess, bool bIgnoreCase = false ) : ImplBase( xParent, xContext, xIndexAccess, bIgnoreCase ) {}
362 #endif //SC_VBA_COLLECTION_IMPL_HXX
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */