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/script/BasicErrorException.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
{ namespace sun
{ namespace star
{
51 namespace container
{ class XEnumerationAccess
; }
52 namespace uno
{ class XComponentContext
; }
55 namespace ooo
{ namespace 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
: public EnumerationHelper_BASE
73 explicit SimpleIndexAccessToEnumeration(
74 const css::uno::Reference
< css::container::XIndexAccess
>& rxIndexAccess
) throw (css::uno::RuntimeException
) :
75 mxIndexAccess( rxIndexAccess
), mnIndex( 0 ) {}
77 virtual sal_Bool SAL_CALL
hasMoreElements() throw (css::uno::RuntimeException
, std::exception
) override
79 return mnIndex
< mxIndexAccess
->getCount();
82 virtual css::uno::Any SAL_CALL
nextElement() throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) 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 explicit SimpleEnumerationBase(
106 const css::uno::Reference
< css::container::XIndexAccess
>& rxIndexAccess
) throw (css::uno::RuntimeException
) :
107 mxEnumeration( new SimpleIndexAccessToEnumeration( rxIndexAccess
) ) {}
109 virtual sal_Bool SAL_CALL
hasMoreElements() throw (css::uno::RuntimeException
, std::exception
) override
111 return mxEnumeration
->hasMoreElements();
114 virtual css::uno::Any SAL_CALL
nextElement() throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) override
116 return createCollectionObject( mxEnumeration
->nextElement() );
119 /** Derived classes implement creation of a VBA implementation object from
120 the passed container element. */
121 virtual css::uno::Any
createCollectionObject( const css::uno::Any
& rSource
) = 0;
124 css::uno::Reference
< css::container::XEnumeration
> mxEnumeration
;
128 // deprecated, use SimpleEnumerationBase instead!
129 class VBAHELPER_DLLPUBLIC EnumerationHelperImpl
: public EnumerationHelper_BASE
132 css::uno::WeakReference
< ov::XHelperInterface
> m_xParent
;
133 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
134 css::uno::Reference
< css::container::XEnumeration
> m_xEnumeration
;
137 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
) { }
138 virtual sal_Bool SAL_CALL
hasMoreElements( ) throw (css::uno::RuntimeException
, std::exception
) override
{ return m_xEnumeration
->hasMoreElements(); }
141 // a wrapper class for a providing a XIndexAccess, XNameAccess, XEnumerationAccess impl based on providing a vector of interfaces
142 // only requirement is the object needs to implement XName
145 typedef ::cppu::WeakImplHelper
< css::container::XNameAccess
, css::container::XIndexAccess
, css::container::XEnumerationAccess
> XNamedCollectionHelper_BASE
;
147 template< typename OneIfc
>
148 class XNamedObjectCollectionHelper
: public XNamedCollectionHelper_BASE
151 typedef std::vector
< css::uno::Reference
< OneIfc
> > XNamedVec
;
154 class XNamedEnumerationHelper
: public EnumerationHelper_BASE
156 XNamedVec mXNamedVec
;
157 typename
XNamedVec::iterator mIt
;
159 XNamedEnumerationHelper( const XNamedVec
& sMap
) : mXNamedVec( sMap
), mIt( mXNamedVec
.begin() ) {}
161 virtual sal_Bool SAL_CALL
hasMoreElements( ) throw (css::uno::RuntimeException
, std::exception
) override
163 return ( mIt
!= mXNamedVec
.end() );
166 virtual css::uno::Any SAL_CALL
nextElement( ) throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) override
168 if ( hasMoreElements() )
169 return css::uno::makeAny( *mIt
++ );
170 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( ) throw (css::uno::RuntimeException
, std::exception
) override
{ return cppu::UnoType
< OneIfc
>::get(); }
181 virtual sal_Bool SAL_CALL
hasElements( ) throw (css::uno::RuntimeException
, std::exception
) override
{ return ( mXNamedVec
.size() > 0 ); }
183 virtual css::uno::Any SAL_CALL
getByName( const OUString
& aName
) throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) 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( ) throw (css::uno::RuntimeException
, std::exception
) 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
) throw (css::uno::RuntimeException
, std::exception
) 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
.equals( xName
->getName() ) )
213 return ( cachePos
!= it_end
);
217 virtual ::sal_Int32 SAL_CALL
getCount( ) throw (css::uno::RuntimeException
, std::exception
) override
{ return mXNamedVec
.size(); }
218 virtual css::uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) throw (css::lang::IndexOutOfBoundsException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) 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( ) throw (css::uno::RuntimeException
, std::exception
) override
229 return new XNamedEnumerationHelper( mXNamedVec
);
233 // including a HelperInterface implementation
234 template< typename
... Ifc
>
235 class 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 virtual css::uno::Any
getItemByStringIndex( const OUString
& sIndex
) throw (css::uno::RuntimeException
)
245 if ( !m_xNameAccess
.is() )
246 throw css::uno::RuntimeException("ScVbaCollectionBase string index access not supported by this object" );
250 css::uno::Sequence
< OUString
> sElementNames
= m_xNameAccess
->getElementNames();
251 for( sal_Int32 i
= 0; i
< sElementNames
.getLength(); i
++ )
253 OUString aName
= sElementNames
[i
];
254 if( aName
.equalsIgnoreAsciiCase( sIndex
) )
256 return createCollectionObject( m_xNameAccess
->getByName( aName
) );
260 return createCollectionObject( m_xNameAccess
->getByName( sIndex
) );
263 virtual css::uno::Any
getItemByIntIndex( const sal_Int32 nIndex
) throw (css::uno::RuntimeException
, css::lang::IndexOutOfBoundsException
)
265 if ( !m_xIndexAccess
.is() )
266 throw css::uno::RuntimeException("ScVbaCollectionBase numeric index access not supported by this object" );
269 throw css::lang::IndexOutOfBoundsException(
270 "index is 0 or negative" );
272 // need to adjust for vba index ( for which first element is 1 )
273 return createCollectionObject( m_xIndexAccess
->getByIndex( nIndex
- 1 ) );
276 void UpdateCollectionIndex( const css::uno::Reference
< css::container::XIndexAccess
>& xIndexAccess
)
278 css::uno::Reference
< css::container::XNameAccess
> xNameAccess( xIndexAccess
, css::uno::UNO_QUERY_THROW
);
279 m_xIndexAccess
= xIndexAccess
;
280 m_xNameAccess
= xNameAccess
;
284 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
); }
287 virtual ::sal_Int32 SAL_CALL
getCount() throw (css::uno::RuntimeException
) override
289 return m_xIndexAccess
->getCount();
292 virtual css::uno::Any SAL_CALL
Item(const css::uno::Any
& Index1
, const css::uno::Any
& /*not processed in this base class*/)
293 throw (css::lang::IndexOutOfBoundsException
, css::script::BasicErrorException
, css::uno::RuntimeException
) override
295 if ( Index1
.getValueTypeClass() != css::uno::TypeClass_STRING
)
297 sal_Int32 nIndex
= 0;
299 if ( !( Index1
>>= nIndex
) )
301 throw css::lang::IndexOutOfBoundsException( "Couldn't convert index to Int32" );
303 return getItemByIntIndex( nIndex
);
305 OUString aStringSheet
;
307 Index1
>>= aStringSheet
;
308 return getItemByStringIndex( aStringSheet
);
312 OUString SAL_CALL
getDefaultMethodName( ) throw (css::uno::RuntimeException
) override
314 return OUString("Item");
316 // XEnumerationAccess
317 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
createEnumeration() throw (css::uno::RuntimeException
) override
= 0;
320 virtual css::uno::Type SAL_CALL
getElementType() throw (css::uno::RuntimeException
) override
= 0;
322 virtual sal_Bool SAL_CALL
hasElements() throw (css::uno::RuntimeException
) override
324 return ( m_xIndexAccess
->getCount() > 0 );
326 virtual css::uno::Any
createCollectionObject( const css::uno::Any
& aSource
) = 0;
330 typedef ::cppu::WeakImplHelper
<ov::XCollection
> XCollection_InterfacesBASE
;
332 typedef ScVbaCollectionBase
< XCollection_InterfacesBASE
> CollImplBase
;
333 // compatible with the old collections ( pre XHelperInterface base class ) ( some internal objects still use this )
334 class VBAHELPER_DLLPUBLIC ScVbaCollectionBaseImpl
: public CollImplBase
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
) throw( css::uno::RuntimeException
) : CollImplBase( xParent
, xContext
, xIndexAccess
){}
341 template < typename
... Ifc
> // where Ifc must implement XCollectionTest
342 class CollTestImplHelper
: public ScVbaCollectionBase
< ::cppu::WeakImplHelper
< Ifc
... > >
344 typedef ScVbaCollectionBase
< ::cppu::WeakImplHelper
< Ifc
... > > ImplBase
;
347 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 ) throw( css::uno::RuntimeException
) : ImplBase( xParent
, xContext
, xIndexAccess
, bIgnoreCase
) {}
351 #endif //SC_VBA_COLLECTION_IMPL_HXX
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */