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
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>
42 typedef ::cppu::WeakImplHelper1
< css::container::XEnumeration
> EnumerationHelper_BASE
;
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
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
, std::exception
) SAL_OVERRIDE
63 return mnIndex
< mxIndexAccess
->getCount();
66 virtual css::uno::Any SAL_CALL
nextElement() throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
68 if( !hasMoreElements() )
69 throw css::container::NoSuchElementException();
70 return mxIndexAccess
->getByIndex( mnIndex
++ );
74 css::uno::Reference
< css::container::XIndexAccess
> mxIndexAccess
;
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
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
, std::exception
) SAL_OVERRIDE
104 return mxEnumeration
->hasMoreElements();
107 virtual css::uno::Any SAL_CALL
nextElement() throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
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;
117 css::uno::Reference
< ov::XHelperInterface
> mxParent
;
118 css::uno::Reference
< css::uno::XComponentContext
> mxContext
;
119 css::uno::Reference
< css::container::XEnumeration
> mxEnumeration
;
124 // deprecated, use SimpleEnumerationBase instead!
125 class VBAHELPER_DLLPUBLIC EnumerationHelperImpl
: public EnumerationHelper_BASE
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
;
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
, std::exception
) SAL_OVERRIDE
{ 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
148 typedef std::vector
< css::uno::Reference
< Ifc1
> > XNamedVec
;
151 class XNamedEnumerationHelper
: public EnumerationHelper_BASE
153 XNamedVec mXNamedVec
;
154 typename
XNamedVec::iterator mIt
;
156 XNamedEnumerationHelper( const XNamedVec
& sMap
) : mXNamedVec( sMap
), mIt( mXNamedVec
.begin() ) {}
158 virtual sal_Bool SAL_CALL
hasMoreElements( ) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
160 return ( mIt
!= mXNamedVec
.end() );
163 virtual css::uno::Any SAL_CALL
nextElement( ) throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
165 if ( hasMoreElements() )
166 return css::uno::makeAny( *mIt
++ );
167 throw css::container::NoSuchElementException();
172 XNamedVec mXNamedVec
;
173 typename
XNamedVec::iterator cachePos
;
175 XNamedObjectCollectionHelper( const XNamedVec
& sMap
) : mXNamedVec( sMap
), cachePos(mXNamedVec
.begin()) {}
177 virtual css::uno::Type SAL_CALL
getElementType( ) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
{ return cppu::UnoType
<Ifc1
>::get(); }
178 virtual sal_Bool SAL_CALL
hasElements( ) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
{ return ( mXNamedVec
.size() > 0 ); }
180 virtual css::uno::Any SAL_CALL
getByName( const OUString
& aName
) throw (css::container::NoSuchElementException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
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
, std::exception
) SAL_OVERRIDE
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();
200 virtual sal_Bool SAL_CALL
hasByName( const OUString
& aName
) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
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() ) )
210 return ( cachePos
!= it_end
);
214 virtual ::sal_Int32 SAL_CALL
getCount( ) throw (css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
{ return mXNamedVec
.size(); }
215 virtual css::uno::Any SAL_CALL
getByIndex( ::sal_Int32 Index
) throw (css::lang::IndexOutOfBoundsException
, css::lang::WrappedTargetException
, css::uno::RuntimeException
, std::exception
) SAL_OVERRIDE
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
, std::exception
) SAL_OVERRIDE
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
;
236 css::uno::Reference
< css::container::XIndexAccess
> m_xIndexAccess
;
237 css::uno::Reference
< css::container::XNameAccess
> m_xNameAccess
;
240 virtual css::uno::Any
getItemByStringIndex( const OUString
& sIndex
) throw (css::uno::RuntimeException
)
242 if ( !m_xNameAccess
.is() )
243 throw css::uno::RuntimeException("ScVbaCollectionBase string index access not supported by this object" );
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
, css::lang::IndexOutOfBoundsException
)
262 if ( !m_xIndexAccess
.is() )
263 throw css::uno::RuntimeException("ScVbaCollectionBase numeric index access not supported by this object" );
266 throw css::lang::IndexOutOfBoundsException(
267 "index is 0 or negative" );
269 // need to adjust for vba index ( for which first element is 1 )
270 return createCollectionObject( m_xIndexAccess
->getByIndex( nIndex
- 1 ) );
273 virtual void UpdateCollectionIndex( const css::uno::Reference
< css::container::XIndexAccess
>& xIndexAccess
)
275 css::uno::Reference
< css::container::XNameAccess
> xNameAccess( xIndexAccess
, css::uno::UNO_QUERY_THROW
);
276 m_xIndexAccess
= xIndexAccess
;
277 m_xNameAccess
= xNameAccess
;
281 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
); }
284 virtual ::sal_Int32 SAL_CALL
getCount() throw (css::uno::RuntimeException
) SAL_OVERRIDE
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*/)
290 throw (css::lang::IndexOutOfBoundsException
, css::script::BasicErrorException
, css::uno::RuntimeException
) SAL_OVERRIDE
292 if ( Index1
.getValueTypeClass() != css::uno::TypeClass_STRING
)
294 sal_Int32 nIndex
= 0;
296 if ( !( Index1
>>= nIndex
) )
298 throw css::lang::IndexOutOfBoundsException( "Couldn't convert index to Int32" );
300 return getItemByIntIndex( nIndex
);
302 OUString aStringSheet
;
304 Index1
>>= aStringSheet
;
305 return getItemByStringIndex( aStringSheet
);
309 OUString SAL_CALL
getDefaultMethodName( ) throw (css::uno::RuntimeException
) SAL_OVERRIDE
311 return OUString("Item");
313 // XEnumerationAccess
314 virtual css::uno::Reference
< css::container::XEnumeration
> SAL_CALL
createEnumeration() throw (css::uno::RuntimeException
) SAL_OVERRIDE
= 0;
317 virtual css::uno::Type SAL_CALL
getElementType() throw (css::uno::RuntimeException
) SAL_OVERRIDE
= 0;
319 virtual sal_Bool SAL_CALL
hasElements() throw (css::uno::RuntimeException
) SAL_OVERRIDE
321 return ( m_xIndexAccess
->getCount() > 0 );
323 virtual css::uno::Any
createCollectionObject( const css::uno::Any
& aSource
) = 0;
327 typedef ::cppu::WeakImplHelper1
<ov::XCollection
> XCollection_InterfacesBASE
;
329 typedef ScVbaCollectionBase
< XCollection_InterfacesBASE
> CollImplBase1
;
330 // compatible with the old collections ( pre XHelperInterface base class ) ( some internal objects still use this )
331 class VBAHELPER_DLLPUBLIC ScVbaCollectionBaseImpl
: public CollImplBase1
334 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
){}
338 template <typename Ifc
> // where Ifc must implement XCollectionTest
339 class CollTestImplHelper
: public ScVbaCollectionBase
< ::cppu::WeakImplHelper1
< Ifc
> >
341 typedef ScVbaCollectionBase
< ::cppu::WeakImplHelper1
< Ifc
> > ImplBase1
;
344 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
) : ImplBase1( xParent
, xContext
, xIndexAccess
, bIgnoreCase
) {}
348 #endif //SC_VBA_COLLECTION_IMPL_HXX
350 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */