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 INCLUDED_FORMS_SOURCE_XFORMS_COLLECTION_HXX
21 : #define INCLUDED_FORMS_SOURCE_XFORMS_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 3 : Collection() {}
65 3 : 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 overridden 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 overridden 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, std::exception ) SAL_OVERRIDE
162 : {
163 0 : return cppu::UnoType<T>::get();
164 : }
165 :
166 0 : virtual sal_Bool SAL_CALL hasElements()
167 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE
168 : {
169 0 : return hasItems();
170 : }
171 :
172 : // XIndexAccess : XElementAccess
173 0 : virtual sal_Int32 SAL_CALL getCount()
174 : throw( RuntimeException_t, std::exception ) SAL_OVERRIDE
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, std::exception) SAL_OVERRIDE
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, std::exception) SAL_OVERRIDE
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, std::exception ) SAL_OVERRIDE
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, std::exception ) SAL_OVERRIDE
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, std::exception ) SAL_OVERRIDE
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, std::exception ) SAL_OVERRIDE
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, std::exception ) SAL_OVERRIDE
259 : {
260 : OSL_ENSURE( xListener.is(), "need listener!" );
261 0 : if( std::find( maListeners.begin(), maListeners.end(), xListener)
262 0 : == 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, std::exception ) SAL_OVERRIDE
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 0 : com::sun::star::uno::makeAny( getItem( nPos ) ),
287 0 : com::sun::star::uno::Any() );
288 0 : for( Listeners_t::iterator aIter = maListeners.begin();
289 0 : aIter != maListeners.end();
290 : ++aIter )
291 : {
292 0 : (*aIter)->elementInserted( aEvent );
293 0 : }
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 0 : aIter != maListeners.end();
305 : ++aIter )
306 : {
307 0 : (*aIter)->elementRemoved( aEvent );
308 0 : }
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 0 : 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 0 : aIter != maListeners.end();
321 : ++aIter )
322 : {
323 0 : (*aIter)->elementReplaced( aEvent );
324 0 : }
325 0 : }
326 :
327 : };
328 :
329 : #endif
330 :
331 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|