1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
26 #include <com/sun/star/container/NoSuchElementException.hpp>
27 #include <com/sun/star/container/XEnumeration.hpp>
28 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29 #include <com/sun/star/lang/WrappedTargetException.hpp>
30 #include <com/sun/star/uno/Any.hxx>
31 #include <com/sun/star/uno/Reference.hxx>
32 #include <com/sun/star/uno/RuntimeException.hpp>
33 #include <com/sun/star/uno/Sequence.hxx>
34 #include <com/sun/star/uno/Type.hxx>
35 #include <com/sun/star/uno/TypeClass.hpp>
36 #include <cppu/unotype.hxx>
37 #include <cppuhelper/implbase.hxx>
38 #include <cppuhelper/weakref.hxx>
39 #include <ooo/vba/XCollection.hpp>
40 #include <com/sun/star/container/XIndexAccess.hpp>
41 #include <com/sun/star/container/XNameAccess.hpp>
42 #include <com/sun/star/container/XNamed.hpp>
43 #include <rtl/ustring.hxx>
44 #include <sal/types.h>
45 #include <vbahelper/vbadllapi.h>
46 #include <vbahelper/vbahelper.hxx>
47 #include <vbahelper/vbahelperinterface.hxx>
49 namespace com::sun::star
{
50 namespace container
{ class XEnumerationAccess
; }
51 namespace uno
{ class XComponentContext
; }
55 class XHelperInterface
;
58 typedef ::cppu::WeakImplHelper
< css::container::XEnumeration
> EnumerationHelper_BASE
;
61 /** A wrapper that holds a com.sun.star.container.XIndexAccess and provides a
62 com.sun.star.container.XEnumeration.
64 Can be used to provide an enumeration from an index container that contains
65 completely constructed/initialized VBA implementation objects. CANNOT be
66 used to provide an enumeration from an index container with other objects
67 (e.g. UNO objects) where construction of the VBA objects is needed first.
69 class VBAHELPER_DLLPUBLIC SimpleIndexAccessToEnumeration final
: public EnumerationHelper_BASE
72 /// @throws css::uno::RuntimeException
73 explicit SimpleIndexAccessToEnumeration(
74 const css::uno::Reference
< css::container::XIndexAccess
>& rxIndexAccess
) :
75 mxIndexAccess( rxIndexAccess
), mnIndex( 0 ) {}
77 virtual sal_Bool SAL_CALL
hasMoreElements() override
79 return mnIndex
< mxIndexAccess
->getCount();
82 virtual css::uno::Any SAL_CALL
nextElement() override
84 if( !hasMoreElements() )
85 throw css::container::NoSuchElementException();
86 return mxIndexAccess
->getByIndex( mnIndex
++ );
90 css::uno::Reference
< css::container::XIndexAccess
> mxIndexAccess
;
95 /** A wrapper that holds a com.sun.star.container.XEnumeration or a
96 com.sun.star.container.XIndexAccess and provides an enumeration of VBA objects.
98 The method createCollectionObject() needs to be implemented by the derived
99 class. This class can be used to convert an enumeration or an index container
100 containing UNO objects to an enumeration providing the related VBA objects.
102 class VBAHELPER_DLLPUBLIC SimpleEnumerationBase
: public EnumerationHelper_BASE
105 /// @throws css::uno::RuntimeException
106 explicit SimpleEnumerationBase(
107 const css::uno::Reference
< css::container::XIndexAccess
>& rxIndexAccess
) :
108 mxEnumeration( new SimpleIndexAccessToEnumeration( rxIndexAccess
) ) {}
110 virtual sal_Bool SAL_CALL
hasMoreElements() override
112 return mxEnumeration
->hasMoreElements();
115 virtual css::uno::Any SAL_CALL
nextElement() override
117 return createCollectionObject( mxEnumeration
->nextElement() );
120 /** Derived classes implement creation of a VBA implementation object from
121 the passed container element. */
122 virtual css::uno::Any
createCollectionObject( const css::uno::Any
& rSource
) = 0;
125 css::uno::Reference
< css::container::XEnumeration
> mxEnumeration
;
129 // deprecated, use SimpleEnumerationBase instead!
130 class VBAHELPER_DLLPUBLIC EnumerationHelperImpl
: public EnumerationHelper_BASE
133 css::uno::WeakReference
< ov::XHelperInterface
> m_xParent
;
134 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
135 css::uno::Reference
< css::container::XEnumeration
> m_xEnumeration
;
137 /// @throws css::uno::RuntimeException
138 EnumerationHelperImpl( const css::uno::Reference
< ov::XHelperInterface
>& xParent
, const css::uno::Reference
< css::uno::XComponentContext
>& xContext
, const css::uno::Reference
< css::container::XEnumeration
>& xEnumeration
) : m_xParent( xParent
), m_xContext( xContext
), m_xEnumeration( xEnumeration
) { }
139 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
{ return m_xEnumeration
->hasMoreElements(); }
142 // a wrapper class for a providing a XIndexAccess, XNameAccess, XEnumerationAccess impl based on providing a vector of interfaces
143 // only requirement is the object needs to implement XName
146 template< typename OneIfc
>
147 class XNamedObjectCollectionHelper final
: public ::cppu::WeakImplHelper
< css::container::XNameAccess
,
148 css::container::XIndexAccess
,
149 css::container::XEnumerationAccess
>
152 typedef std::vector
< css::uno::Reference
< OneIfc
> > XNamedVec
;
155 class XNamedEnumerationHelper
: public EnumerationHelper_BASE
157 XNamedVec mXNamedVec
;
158 typename
XNamedVec::iterator mIt
;
160 XNamedEnumerationHelper( const XNamedVec
& sMap
) : mXNamedVec( sMap
), mIt( mXNamedVec
.begin() ) {}
162 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
164 return ( mIt
!= mXNamedVec
.end() );
167 virtual css::uno::Any SAL_CALL
nextElement( ) override
169 if ( hasMoreElements() )
170 return css::uno::makeAny( *mIt
++ );
171 throw css::container::NoSuchElementException();
175 XNamedVec mXNamedVec
;
176 typename
XNamedVec::iterator cachePos
;
178 XNamedObjectCollectionHelper( const XNamedVec
& sMap
) : mXNamedVec( sMap
), cachePos(mXNamedVec
.begin()) {}
180 virtual css::uno::Type SAL_CALL
getElementType( ) override
{ return cppu::UnoType
< OneIfc
>::get(); }
181 virtual sal_Bool SAL_CALL
hasElements( ) override
{ return ( mXNamedVec
.size() > 0 ); }
183 virtual css::uno::Any SAL_CALL
getByName( const OUString
& aName
) override
185 if ( !hasByName(aName
) )
186 throw css::container::NoSuchElementException();
187 return css::uno::makeAny( *cachePos
);
189 virtual css::uno::Sequence
< OUString
> SAL_CALL
getElementNames( ) override
191 css::uno::Sequence
< OUString
> sNames( mXNamedVec
.size() );
192 OUString
* pString
= sNames
.getArray();
193 typename
XNamedVec::iterator it
= mXNamedVec
.begin();
194 typename
XNamedVec::iterator it_end
= mXNamedVec
.end();
196 for ( ; it
!= it_end
; ++it
, ++pString
)
198 css::uno::Reference
< css::container::XNamed
> xName( *it
, css::uno::UNO_QUERY_THROW
);
199 *pString
= xName
->getName();
203 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) override
205 cachePos
= mXNamedVec
.begin();
206 typename
XNamedVec::iterator it_end
= mXNamedVec
.end();
207 for ( ; cachePos
!= it_end
; ++cachePos
)
209 css::uno::Reference
< css::container::XNamed
> xName( *cachePos
, css::uno::UNO_QUERY_THROW
);
210 if ( aName
== xName
->getName() )
213 return ( cachePos
!= it_end
);
217 virtual ::sal_Int32 SAL_CALL
getCount( ) override
{ return mXNamedVec
.size(); }
218 virtual css::uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) override
220 if ( Index
< 0 || Index
>= getCount() )
221 throw css::lang::IndexOutOfBoundsException();
223 return css::uno::makeAny( mXNamedVec
[ Index
] );
226 // XEnumerationAccess
227 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
createEnumeration( ) override
229 return new XNamedEnumerationHelper( mXNamedVec
);
233 // including a HelperInterface implementation
234 template< typename
... Ifc
>
235 class SAL_DLLPUBLIC_RTTI ScVbaCollectionBase
: public InheritedHelperInterfaceImpl
< Ifc
... >
237 typedef InheritedHelperInterfaceImpl
< Ifc
... > BaseColBase
;
239 css::uno::Reference
< css::container::XIndexAccess
> m_xIndexAccess
;
240 css::uno::Reference
< css::container::XNameAccess
> m_xNameAccess
;
243 /// @throws css::uno::RuntimeException
244 virtual css::uno::Any
getItemByStringIndex( const OUString
& sIndex
)
246 if ( !m_xNameAccess
.is() )
247 throw css::uno::RuntimeException("ScVbaCollectionBase string index access not supported by this object" );
251 const css::uno::Sequence
< OUString
> sElementNames
= m_xNameAccess
->getElementNames();
252 for( const OUString
& rName
: sElementNames
)
254 if( rName
.equalsIgnoreAsciiCase( sIndex
) )
256 return createCollectionObject( m_xNameAccess
->getByName( rName
) );
260 return createCollectionObject( m_xNameAccess
->getByName( sIndex
) );
263 /// @throws css::uno::RuntimeException
264 /// @throws css::lang::IndexOutOfBoundsException
265 virtual css::uno::Any
getItemByIntIndex( const sal_Int32 nIndex
)
267 if ( !m_xIndexAccess
.is() )
268 throw css::uno::RuntimeException("ScVbaCollectionBase numeric index access not supported by this object" );
271 throw css::lang::IndexOutOfBoundsException(
272 "index is 0 or negative" );
274 // need to adjust for vba index ( for which first element is 1 )
275 return createCollectionObject( m_xIndexAccess
->getByIndex( nIndex
- 1 ) );
278 void UpdateCollectionIndex( const css::uno::Reference
< css::container::XIndexAccess
>& xIndexAccess
)
280 css::uno::Reference
< css::container::XNameAccess
> xNameAccess( xIndexAccess
, css::uno::UNO_QUERY_THROW
);
281 m_xIndexAccess
= xIndexAccess
;
282 m_xNameAccess
= xNameAccess
;
286 ScVbaCollectionBase( 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 ) : BaseColBase( xParent
, xContext
), m_xIndexAccess( xIndexAccess
), mbIgnoreCase( bIgnoreCase
) { m_xNameAccess
.set(m_xIndexAccess
, css::uno::UNO_QUERY
); }
289 virtual ::sal_Int32 SAL_CALL
getCount() override
291 return m_xIndexAccess
->getCount();
294 virtual css::uno::Any SAL_CALL
Item(const css::uno::Any
& Index1
, const css::uno::Any
& /*not processed in this base class*/) override
296 if ( Index1
.getValueTypeClass() != css::uno::TypeClass_STRING
)
298 sal_Int32 nIndex
= 0;
300 if ( !( Index1
>>= nIndex
) )
302 throw css::lang::IndexOutOfBoundsException( "Couldn't convert index to Int32" );
304 return getItemByIntIndex( nIndex
);
306 OUString aStringSheet
;
308 Index1
>>= aStringSheet
;
309 return getItemByStringIndex( aStringSheet
);
313 OUString SAL_CALL
getDefaultMethodName( ) override
317 // XEnumerationAccess
318 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
createEnumeration() override
= 0;
321 virtual css::uno::Type SAL_CALL
getElementType() override
= 0;
323 virtual sal_Bool SAL_CALL
hasElements() override
325 return ( m_xIndexAccess
->getCount() > 0 );
327 virtual css::uno::Any
createCollectionObject( const css::uno::Any
& aSource
) = 0;
331 typedef ScVbaCollectionBase
< ::cppu::WeakImplHelper
<ov::XCollection
> > CollImplBase
;
332 // compatible with the old collections ( pre XHelperInterface base class ) ( some internal objects still use this )
333 class VBAHELPER_DLLPUBLIC ScVbaCollectionBaseImpl
: public CollImplBase
336 /// @throws css::uno::RuntimeException
337 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
){}
341 template < typename
... Ifc
> // where Ifc must implement XCollectionTest
342 class SAL_DLLPUBLIC_RTTI CollTestImplHelper
: public ScVbaCollectionBase
< ::cppu::WeakImplHelper
< Ifc
... > >
344 typedef ScVbaCollectionBase
< ::cppu::WeakImplHelper
< Ifc
... > > ImplBase
;
347 /// @throws css::uno::RuntimeException
348 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
) {}
352 #endif //SC_VBA_COLLECTION_IMPL_HXX
354 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */