Branch data 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 _COLLECTION_HXX
21 : : #define _COLLECTION_HXX
22 : :
23 : : #include "enumeration.hxx"
24 : :
25 : : #include <cppuhelper/implbase3.hxx>
26 : : #include <com/sun/star/container/ElementExistException.hpp>
27 : : #include <com/sun/star/container/NoSuchElementException.hpp>
28 : : #include <com/sun/star/container/XEnumeration.hpp>
29 : : #include <com/sun/star/container/XIndexReplace.hpp>
30 : : #include <com/sun/star/container/XSet.hpp>
31 : : #include <com/sun/star/container/XContainer.hpp>
32 : : #include <com/sun/star/container/XContainerListener.hpp>
33 : : #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 : : #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
35 : : #include <com/sun/star/lang/WrappedTargetException.hpp>
36 : : #include <com/sun/star/uno/Any.hxx>
37 : : #include <com/sun/star/uno/Reference.hxx>
38 : : #include <com/sun/star/uno/RuntimeException.hpp>
39 : : #include <com/sun/star/uno/Type.hxx>
40 : : #include <vector>
41 : : #include <algorithm>
42 : :
43 : :
44 : : typedef cppu::WeakImplHelper3<
45 : : com::sun::star::container::XIndexReplace,
46 : : com::sun::star::container::XSet,
47 : : com::sun::star::container::XContainer>
48 : : Collection_t;
49 : :
50 : : template<class ELEMENT_TYPE>
51 : : class Collection : public Collection_t
52 : : {
53 : : public:
54 : : typedef ELEMENT_TYPE T;
55 : : typedef com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> XContainerListener_t;
56 : : typedef std::vector<XContainerListener_t> Listeners_t;
57 : :
58 : : protected:
59 : : std::vector<T> maItems;
60 : : Listeners_t maListeners;
61 : :
62 : : public:
63 : :
64 [ # # ][ # # ]: 0 : Collection() {}
[ # # ][ # # ]
65 [ # # ][ # # ]: 0 : virtual ~Collection() {}
66 : :
67 : 0 : const T& getItem( sal_Int32 n ) const
68 : : {
69 : : OSL_ENSURE( isValidIndex(n), "invalid index" );
70 : : OSL_ENSURE( isValid( maItems[n] ), "invalid item found" );
71 : 0 : return maItems[n];
72 : : }
73 : :
74 : 0 : void setItem( sal_Int32 n, const T& t)
75 : : {
76 : : OSL_ENSURE( isValidIndex(n), "invalid index" );
77 : : OSL_ENSURE( isValid ( t ), "invalid item" );
78 : :
79 : 0 : T& aRef = maItems[ n ];
80 : 0 : _elementReplaced( n, t );
81 : 0 : _remove( aRef );
82 : 0 : aRef = t;
83 : 0 : _insert( t );
84 : 0 : }
85 : :
86 : 0 : bool hasItem( const T& t ) const
87 : : {
88 [ # # ][ # # ]: 0 : return maItems.end() != std::find( maItems.begin(), maItems.end(), t );
89 : : }
90 : :
91 : 0 : sal_Int32 addItem( const T& t )
92 : : {
93 : : OSL_ENSURE( !hasItem( t ), "item to be added already present" );
94 : : OSL_ENSURE( isValid( t ), "invalid item" );
95 : :
96 : 0 : maItems.push_back( t );
97 : 0 : _insert( t );
98 : 0 : _elementInserted( maItems.size() - 1 );
99 : 0 : return ( maItems.size() - 1 );
100 : : }
101 : :
102 : 0 : void removeItem( const T& t )
103 : : {
104 : : OSL_ENSURE( hasItem( t ), "item to be removed not present" );
105 : : OSL_ENSURE( isValid( t ), "an invalid item, funny that!" );
106 : :
107 : 0 : _elementRemoved( t );
108 : 0 : _remove( t );
109 : 0 : maItems.erase( std::find( maItems.begin(), maItems.end(), t ) );
110 : 0 : }
111 : :
112 : 0 : bool hasItems() const
113 : : {
114 : 0 : return maItems.size() != 0;
115 : : }
116 : :
117 : 0 : sal_Int32 countItems() const
118 : : {
119 : 0 : return static_cast<sal_Int32>( maItems.size() );
120 : : }
121 : :
122 : 0 : bool isValidIndex( sal_Int32 n ) const
123 : : {
124 [ # # ][ # # ]: 0 : return n >= 0 && n < static_cast<sal_Int32>( maItems.size() );
[ # # ][ # # ]
125 : : }
126 : :
127 : :
128 : : // the following method may be overriden by sub-classes for
129 : : // customized behaviour
130 : :
131 : : /// called before insertion to determine whether item is valid
132 : 0 : virtual bool isValid( const T& ) const { return true; }
133 : :
134 : :
135 : : protected:
136 : :
137 : : // the following methods may be overriden by sub-classes for
138 : : // customized behaviour
139 : :
140 : : /// called after item has been inserted into the collection
141 : 0 : virtual void _insert( const T& ) { }
142 : :
143 : : /// called before item is removed from the collection
144 : 0 : virtual void _remove( const T& ) { }
145 : :
146 : : public:
147 : :
148 : : typedef com::sun::star::uno::Type Type_t;
149 : : typedef com::sun::star::uno::Any Any_t;
150 : : typedef com::sun::star::uno::RuntimeException RuntimeException_t;
151 : : typedef com::sun::star::lang::IllegalArgumentException IllegalArgumentException_t;
152 : : typedef com::sun::star::container::NoSuchElementException NoSuchElementException_t;
153 : : typedef com::sun::star::lang::IndexOutOfBoundsException IndexOutOfBoundsException_t;
154 : : typedef com::sun::star::uno::Reference<com::sun::star::container::XEnumeration> XEnumeration_t;
155 : : typedef com::sun::star::lang::WrappedTargetException WrappedTargetException_t;
156 : : typedef com::sun::star::container::ElementExistException ElementExistException_t;
157 : :
158 : :
159 : : // XElementAccess
160 : 0 : virtual Type_t SAL_CALL getElementType()
161 : : throw( RuntimeException_t )
162 : : {
163 : 0 : return getCppuType( static_cast<T*>( NULL ) );
164 : : }
165 : :
166 : 0 : virtual sal_Bool SAL_CALL hasElements()
167 : : throw( RuntimeException_t )
168 : : {
169 : 0 : return hasItems();
170 : : }
171 : :
172 : : // XIndexAccess : XElementAccess
173 : 0 : virtual sal_Int32 SAL_CALL getCount()
174 : : throw( RuntimeException_t )
175 : : {
176 : 0 : return countItems();
177 : : }
178 : :
179 : 0 : virtual Any_t SAL_CALL getByIndex( sal_Int32 nIndex )
180 : : throw( IndexOutOfBoundsException_t,
181 : : WrappedTargetException_t,
182 : : RuntimeException_t)
183 : : {
184 [ # # ][ # # ]: 0 : if( isValidIndex( nIndex ) )
185 : 0 : return com::sun::star::uno::makeAny( getItem( nIndex ) );
186 : : else
187 [ # # ][ # # ]: 0 : throw IndexOutOfBoundsException_t();
188 : : }
189 : :
190 : : // XIndexReplace : XIndexAccess
191 : 0 : virtual void SAL_CALL replaceByIndex( sal_Int32 nIndex,
192 : : const Any_t& aElement )
193 : : throw( IllegalArgumentException_t,
194 : : IndexOutOfBoundsException_t,
195 : : WrappedTargetException_t,
196 : : RuntimeException_t)
197 : : {
198 [ # # ]: 0 : T t;
199 [ # # ][ # # ]: 0 : if( isValidIndex( nIndex) )
200 [ # # ][ # # ]: 0 : if( ( aElement >>= t ) && isValid( t ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
201 [ # # ][ # # ]: 0 : setItem( nIndex, t );
202 : : else
203 [ # # ][ # # ]: 0 : throw IllegalArgumentException_t();
204 : : else
205 [ # # ][ # # ]: 0 : throw IndexOutOfBoundsException_t();
[ # # ]
206 : 0 : }
207 : :
208 : : // XEnumerationAccess : XElementAccess
209 : 0 : virtual XEnumeration_t SAL_CALL createEnumeration()
210 : : throw( RuntimeException_t )
211 : : {
212 [ # # ][ # # ]: 0 : return new Enumeration( this );
[ # # ][ # # ]
213 : : }
214 : :
215 : :
216 : : // XSet : XEnumerationAccess
217 : 0 : virtual sal_Bool SAL_CALL has( const Any_t& aElement )
218 : : throw( RuntimeException_t )
219 : : {
220 [ # # ]: 0 : T t;
221 [ # # ][ # # ]: 0 : return ( aElement >>= t ) ? hasItem( t ) : sal_False;
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
222 : : }
223 : :
224 : 0 : virtual void SAL_CALL insert( const Any_t& aElement )
225 : : throw( IllegalArgumentException_t,
226 : : ElementExistException_t,
227 : : RuntimeException_t )
228 : : {
229 [ # # ]: 0 : T t;
230 [ # # ][ # # ]: 0 : if( ( aElement >>= t ) && isValid( t ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
231 [ # # ][ # # ]: 0 : if( ! hasItem( t ) )
[ # # ][ # # ]
232 [ # # ][ # # ]: 0 : addItem( t );
233 : : else
234 [ # # ][ # # ]: 0 : throw ElementExistException_t();
235 : : else
236 [ # # ][ # # ]: 0 : throw IllegalArgumentException_t();
[ # # ]
237 : 0 : }
238 : :
239 : 0 : virtual void SAL_CALL remove( const Any_t& aElement )
240 : : throw( IllegalArgumentException_t,
241 : : NoSuchElementException_t,
242 : : RuntimeException_t )
243 : : {
244 [ # # ]: 0 : T t;
245 [ # # ][ # # ]: 0 : if( aElement >>= t )
[ # # ][ # # ]
246 [ # # ][ # # ]: 0 : if( hasItem( t ) )
[ # # ][ # # ]
247 [ # # ][ # # ]: 0 : removeItem( t );
248 : : else
249 [ # # ][ # # ]: 0 : throw NoSuchElementException_t();
250 : : else
251 [ # # ][ # # ]: 0 : throw IllegalArgumentException_t();
[ # # ]
252 : 0 : }
253 : :
254 : :
255 : : // XContainer
256 : 0 : virtual void SAL_CALL addContainerListener(
257 : : const XContainerListener_t& xListener )
258 : : throw( RuntimeException_t )
259 : : {
260 : : OSL_ENSURE( xListener.is(), "need listener!" );
261 [ # # ][ # # ]: 0 : if( std::find( maListeners.begin(), maListeners.end(), xListener)
[ # # ][ # # ]
262 : : == maListeners.end() )
263 : 0 : maListeners.push_back( xListener );
264 : 0 : }
265 : :
266 : 0 : virtual void SAL_CALL removeContainerListener(
267 : : const XContainerListener_t& xListener )
268 : : throw( RuntimeException_t )
269 : : {
270 : : OSL_ENSURE( xListener.is(), "need listener!" );
271 : : Listeners_t::iterator aIter =
272 [ # # ][ # # ]: 0 : std::find( maListeners.begin(), maListeners.end(), xListener );
273 [ # # ][ # # ]: 0 : if( aIter != maListeners.end() )
[ # # ][ # # ]
274 [ # # ][ # # ]: 0 : maListeners.erase( aIter );
275 : 0 : }
276 : :
277 : : protected:
278 : :
279 : : // call listeners:
280 : 0 : void _elementInserted( sal_Int32 nPos )
281 : : {
282 : : OSL_ENSURE( isValidIndex(nPos), "invalid index" );
283 : : com::sun::star::container::ContainerEvent aEvent(
284 : : static_cast<com::sun::star::container::XIndexReplace*>( this ),
285 : : com::sun::star::uno::makeAny( nPos ),
286 : : com::sun::star::uno::makeAny( getItem( nPos ) ),
287 [ # # ][ # # ]: 0 : com::sun::star::uno::Any() );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
288 [ # # ][ # # ]: 0 : for( Listeners_t::iterator aIter = maListeners.begin();
[ # # ][ # # ]
[ # # ][ # # ]
289 : : aIter != maListeners.end();
290 : : aIter++ )
291 : : {
292 [ # # ][ # # ]: 0 : (*aIter)->elementInserted( aEvent );
[ # # ][ # # ]
[ # # ][ # # ]
293 : : }
294 : 0 : }
295 : :
296 : 0 : void _elementRemoved( const T& aOld )
297 : : {
298 : : com::sun::star::container::ContainerEvent aEvent(
299 : : static_cast<com::sun::star::container::XIndexReplace*>( this ),
300 : : com::sun::star::uno::Any(),
301 : : com::sun::star::uno::makeAny( aOld ),
302 [ # # ][ # # ]: 0 : com::sun::star::uno::Any() );
[ # # ][ # # ]
[ # # ][ # # ]
303 [ # # ][ # # ]: 0 : for( Listeners_t::iterator aIter = maListeners.begin();
[ # # ][ # # ]
[ # # ][ # # ]
304 : : aIter != maListeners.end();
305 : : aIter++ )
306 : : {
307 [ # # ][ # # ]: 0 : (*aIter)->elementRemoved( aEvent );
[ # # ][ # # ]
[ # # ][ # # ]
308 : : }
309 : 0 : }
310 : :
311 : 0 : void _elementReplaced( const sal_Int32 nPos, const T& aNew )
312 : : {
313 : : OSL_ENSURE( isValidIndex(nPos), "invalid index" );
314 : : com::sun::star::container::ContainerEvent aEvent(
315 : : static_cast<com::sun::star::container::XIndexReplace*>( this ),
316 : : com::sun::star::uno::makeAny( nPos ),
317 : : com::sun::star::uno::makeAny( getItem( nPos ) ),
318 [ # # ][ # # ]: 0 : com::sun::star::uno::makeAny( aNew ) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
319 [ # # ][ # # ]: 0 : for( Listeners_t::iterator aIter = maListeners.begin();
[ # # ][ # # ]
[ # # ][ # # ]
320 : : aIter != maListeners.end();
321 : : aIter++ )
322 : : {
323 [ # # ][ # # ]: 0 : (*aIter)->elementReplaced( aEvent );
[ # # ][ # # ]
[ # # ][ # # ]
324 : : }
325 : 0 : }
326 : :
327 : : };
328 : :
329 : : #endif
330 : :
331 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|