Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #ifndef OOVBAAPI_VBA_COLLECTION_IMPL_HXX
21 : #define OOVBAAPI_VBA_COLLECTION_IMPL_HXX
22 :
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>
30 :
31 : #include <cppuhelper/implbase3.hxx>
32 : #include <cppuhelper/implbase2.hxx>
33 : #include <cppuhelper/implbase1.hxx>
34 :
35 : #include "vbahelper/vbahelper.hxx"
36 : #include "vbahelper/vbahelperinterface.hxx"
37 :
38 : #include <vector>
39 :
40 : // ============================================================================
41 :
42 : typedef ::cppu::WeakImplHelper1< css::container::XEnumeration > EnumerationHelper_BASE;
43 :
44 : // ============================================================================
45 :
46 : /** A wrapper that holds a com.sun.star.container.XIndexAccess and provides a
47 : com.sun.star.container.XEnumeration.
48 :
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.
53 : */
54 0 : class VBAHELPER_DLLPUBLIC SimpleIndexAccessToEnumeration : public EnumerationHelper_BASE
55 : {
56 : public:
57 0 : explicit SimpleIndexAccessToEnumeration(
58 : const css::uno::Reference< css::container::XIndexAccess >& rxIndexAccess ) throw (css::uno::RuntimeException) :
59 0 : mxIndexAccess( rxIndexAccess ), mnIndex( 0 ) {}
60 :
61 0 : virtual sal_Bool SAL_CALL hasMoreElements() throw (css::uno::RuntimeException)
62 : {
63 0 : return mnIndex < mxIndexAccess->getCount();
64 : }
65 :
66 0 : virtual css::uno::Any SAL_CALL nextElement() throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
67 : {
68 0 : if( !hasMoreElements() )
69 0 : throw css::container::NoSuchElementException();
70 0 : return mxIndexAccess->getByIndex( mnIndex++ );
71 : }
72 :
73 : private:
74 : css::uno::Reference< css::container::XIndexAccess > mxIndexAccess;
75 : sal_Int32 mnIndex;
76 : };
77 :
78 : // ============================================================================
79 :
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.
82 :
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.
86 : */
87 0 : class VBAHELPER_DLLPUBLIC SimpleEnumerationBase : public EnumerationHelper_BASE
88 : {
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 ) {}
95 :
96 0 : 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 0 : mxParent( rxParent ), mxContext( rxContext ), mxEnumeration( new SimpleIndexAccessToEnumeration( rxIndexAccess ) ) {}
101 :
102 0 : virtual sal_Bool SAL_CALL hasMoreElements() throw (css::uno::RuntimeException)
103 : {
104 0 : return mxEnumeration->hasMoreElements();
105 : }
106 :
107 0 : virtual css::uno::Any SAL_CALL nextElement() throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
108 : {
109 0 : return createCollectionObject( mxEnumeration->nextElement() );
110 : }
111 :
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;
115 :
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;
120 : };
121 :
122 : // ============================================================================
123 :
124 : // deprecated, use SimpleEnumerationBase instead!
125 0 : class VBAHELPER_DLLPUBLIC EnumerationHelperImpl : public EnumerationHelper_BASE
126 : {
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:
132 :
133 0 : 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 0 : virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (css::uno::RuntimeException) { return m_xEnumeration->hasMoreElements(); }
135 : };
136 :
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
139 :
140 :
141 :
142 : typedef ::cppu::WeakImplHelper3< css::container::XNameAccess, css::container::XIndexAccess, css::container::XEnumerationAccess > XNamedCollectionHelper_BASE;
143 :
144 : template< typename Ifc1 >
145 0 : class XNamedObjectCollectionHelper : public XNamedCollectionHelper_BASE
146 : {
147 : public:
148 : typedef std::vector< css::uno::Reference< Ifc1 > > XNamedVec;
149 : private:
150 :
151 0 : class XNamedEnumerationHelper : public EnumerationHelper_BASE
152 : {
153 : XNamedVec mXNamedVec;
154 : typename XNamedVec::iterator mIt;
155 : public:
156 0 : XNamedEnumerationHelper( const XNamedVec& sMap ) : mXNamedVec( sMap ), mIt( mXNamedVec.begin() ) {}
157 :
158 0 : virtual ::sal_Bool SAL_CALL hasMoreElements( ) throw (css::uno::RuntimeException)
159 : {
160 0 : return ( mIt != mXNamedVec.end() );
161 : }
162 :
163 0 : virtual css::uno::Any SAL_CALL nextElement( ) throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
164 : {
165 0 : if ( hasMoreElements() )
166 0 : return css::uno::makeAny( *mIt++ );
167 0 : throw css::container::NoSuchElementException();
168 : }
169 : };
170 :
171 : protected:
172 : XNamedVec mXNamedVec;
173 : typename XNamedVec::iterator cachePos;
174 : public:
175 0 : XNamedObjectCollectionHelper( const XNamedVec& sMap ) : mXNamedVec( sMap ), cachePos(mXNamedVec.begin()) {}
176 : // XElementAccess
177 0 : virtual css::uno::Type SAL_CALL getElementType( ) throw (css::uno::RuntimeException) { return Ifc1::static_type(0); }
178 0 : virtual ::sal_Bool SAL_CALL hasElements( ) throw (css::uno::RuntimeException) { return ( mXNamedVec.size() > 0 ); }
179 : // XNameAcess
180 0 : virtual css::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException)
181 : {
182 0 : if ( !hasByName(aName) )
183 0 : throw css::container::NoSuchElementException();
184 0 : return css::uno::makeAny( *cachePos );
185 : }
186 0 : virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (css::uno::RuntimeException)
187 : {
188 0 : css::uno::Sequence< rtl::OUString > sNames( mXNamedVec.size() );
189 0 : rtl::OUString* pString = sNames.getArray();
190 0 : typename XNamedVec::iterator it = mXNamedVec.begin();
191 0 : typename XNamedVec::iterator it_end = mXNamedVec.end();
192 :
193 0 : for ( ; it != it_end; ++it, ++pString )
194 : {
195 0 : css::uno::Reference< css::container::XNamed > xName( *it, css::uno::UNO_QUERY_THROW );
196 0 : *pString = xName->getName();
197 : }
198 0 : return sNames;
199 : }
200 0 : virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException)
201 : {
202 0 : cachePos = mXNamedVec.begin();
203 0 : typename XNamedVec::iterator it_end = mXNamedVec.end();
204 0 : for ( ; cachePos != it_end; ++cachePos )
205 : {
206 0 : css::uno::Reference< css::container::XNamed > xName( *cachePos, css::uno::UNO_QUERY_THROW );
207 0 : if ( aName.equals( xName->getName() ) )
208 0 : break;
209 : }
210 0 : return ( cachePos != it_end );
211 : }
212 :
213 : // XElementAccess
214 0 : virtual ::sal_Int32 SAL_CALL getCount( ) throw (css::uno::RuntimeException) { return mXNamedVec.size(); }
215 0 : virtual css::uno::Any SAL_CALL getByIndex( ::sal_Int32 Index ) throw (css::lang::IndexOutOfBoundsException, css::lang::WrappedTargetException, css::uno::RuntimeException )
216 : {
217 0 : if ( Index < 0 || Index >= getCount() )
218 0 : throw css::lang::IndexOutOfBoundsException();
219 :
220 0 : return css::uno::makeAny( mXNamedVec[ Index ] );
221 :
222 : }
223 : // XEnumerationAccess
224 0 : virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration( ) throw (css::uno::RuntimeException)
225 : {
226 0 : return new XNamedEnumerationHelper( mXNamedVec );
227 : }
228 : };
229 :
230 : // including a HelperInterface implementation
231 : template< typename Ifc1 >
232 0 : class ScVbaCollectionBase : public InheritedHelperInterfaceImpl< Ifc1 >
233 : {
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;
239 :
240 0 : virtual css::uno::Any getItemByStringIndex( const rtl::OUString& sIndex ) throw (css::uno::RuntimeException)
241 : {
242 0 : if ( !m_xNameAccess.is() )
243 0 : throw css::uno::RuntimeException( rtl::OUString( "ScVbaCollectionBase string index access not supported by this object" ), css::uno::Reference< css::uno::XInterface >() );
244 :
245 0 : if( mbIgnoreCase )
246 : {
247 0 : css::uno::Sequence< rtl::OUString > sElementNames = m_xNameAccess->getElementNames();
248 0 : for( sal_Int32 i = 0; i < sElementNames.getLength(); i++ )
249 : {
250 0 : rtl::OUString aName = sElementNames[i];
251 0 : if( aName.equalsIgnoreAsciiCase( sIndex ) )
252 : {
253 0 : return createCollectionObject( m_xNameAccess->getByName( aName ) );
254 : }
255 : }
256 : }
257 0 : return createCollectionObject( m_xNameAccess->getByName( sIndex ) );
258 : }
259 :
260 0 : virtual css::uno::Any getItemByIntIndex( const sal_Int32 nIndex ) throw (css::uno::RuntimeException)
261 : {
262 0 : if ( !m_xIndexAccess.is() )
263 0 : throw css::uno::RuntimeException( rtl::OUString( "ScVbaCollectionBase numeric index access not supported by this object" ), css::uno::Reference< css::uno::XInterface >() );
264 0 : if ( nIndex <= 0 )
265 : {
266 : throw css::lang::IndexOutOfBoundsException(
267 : ::rtl::OUString( "index is 0 or negative" ),
268 0 : css::uno::Reference< css::uno::XInterface >() );
269 : }
270 : // need to adjust for vba index ( for which first element is 1 )
271 0 : return createCollectionObject( m_xIndexAccess->getByIndex( nIndex - 1 ) );
272 : }
273 :
274 0 : virtual void UpdateCollectionIndex( const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess )
275 : {
276 0 : css::uno::Reference< css::container::XNameAccess > xNameAccess( xIndexAccess, css::uno::UNO_QUERY_THROW );
277 0 : m_xIndexAccess = xIndexAccess;
278 0 : m_xNameAccess = xNameAccess;
279 0 : }
280 :
281 : public:
282 0 : 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 0 : virtual ::sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException)
285 : {
286 0 : return m_xIndexAccess->getCount();
287 : }
288 :
289 0 : 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)
290 : {
291 0 : if ( Index1.getValueTypeClass() != css::uno::TypeClass_STRING )
292 : {
293 0 : sal_Int32 nIndex = 0;
294 :
295 0 : if ( ( Index1 >>= nIndex ) != sal_True )
296 : {
297 0 : rtl::OUString message;
298 0 : message = rtl::OUString( "Couldn't convert index to Int32");
299 : throw css::lang::IndexOutOfBoundsException( message,
300 0 : css::uno::Reference< css::uno::XInterface >() );
301 : }
302 0 : return getItemByIntIndex( nIndex );
303 : }
304 0 : rtl::OUString aStringSheet;
305 :
306 0 : Index1 >>= aStringSheet;
307 0 : return getItemByStringIndex( aStringSheet );
308 : }
309 : // XDefaultMethod
310 0 : ::rtl::OUString SAL_CALL getDefaultMethodName( ) throw (css::uno::RuntimeException)
311 : {
312 0 : const static rtl::OUString sName( "Item" );
313 0 : return sName;
314 : }
315 : // XEnumerationAccess
316 : virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException) = 0;
317 :
318 : // XElementAccess
319 : virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException) = 0;
320 : // XElementAccess
321 0 : virtual ::sal_Bool SAL_CALL hasElements() throw (css::uno::RuntimeException)
322 : {
323 0 : return ( m_xIndexAccess->getCount() > 0 );
324 : }
325 : virtual css::uno::Any createCollectionObject( const css::uno::Any& aSource ) = 0;
326 :
327 : };
328 :
329 : typedef ::cppu::WeakImplHelper1<ov::XCollection> XCollection_InterfacesBASE;
330 :
331 : typedef ScVbaCollectionBase< XCollection_InterfacesBASE > CollImplBase1;
332 : // compatible with the old collections ( pre XHelperInterface base class ) ( some internal objects still use this )
333 0 : class VBAHELPER_DLLPUBLIC ScVbaCollectionBaseImpl : public CollImplBase1
334 : {
335 : public:
336 0 : 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){}
337 :
338 : };
339 :
340 : template <typename Ifc> // where Ifc must implement XCollectionTest
341 0 : class CollTestImplHelper : public ScVbaCollectionBase< ::cppu::WeakImplHelper1< Ifc > >
342 : {
343 : typedef ScVbaCollectionBase< ::cppu::WeakImplHelper1< Ifc > > ImplBase1;
344 :
345 : public:
346 0 : 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 ) {}
347 : };
348 :
349 :
350 : #endif //SC_VBA_COLLECTION_IMPL_HXX
351 :
352 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|