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_FORMS_SOURCE_XFORMS_COLLECTION_HXX
21 #define INCLUDED_FORMS_SOURCE_XFORMS_COLLECTION_HXX
23 #include "enumeration.hxx"
25 #include <cppuhelper/implbase.hxx>
26 #include <osl/diagnose.h>
27 #include <com/sun/star/container/ElementExistException.hpp>
28 #include <com/sun/star/container/NoSuchElementException.hpp>
29 #include <com/sun/star/container/XEnumeration.hpp>
30 #include <com/sun/star/container/XIndexReplace.hpp>
31 #include <com/sun/star/container/XSet.hpp>
32 #include <com/sun/star/container/XContainer.hpp>
33 #include <com/sun/star/container/XContainerListener.hpp>
34 #include <com/sun/star/lang/IllegalArgumentException.hpp>
35 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
36 #include <com/sun/star/uno/Any.hxx>
37 #include <com/sun/star/uno/Reference.hxx>
38 #include <com/sun/star/uno/Type.hxx>
42 typedef cppu::WeakImplHelper
<
43 css::container::XIndexReplace
,
45 css::container::XContainer
>
48 template<class ELEMENT_TYPE
>
49 class Collection
: public Collection_t
52 typedef ELEMENT_TYPE T
;
53 typedef std::vector
<css::uno::Reference
<css::container::XContainerListener
> > Listeners_t
;
56 std::vector
<T
> maItems
;
57 Listeners_t maListeners
;
63 const T
& getItem( sal_Int32 n
) const
65 OSL_ENSURE( isValidIndex(n
), "invalid index" );
66 OSL_ENSURE( isValid( maItems
[n
] ), "invalid item found" );
70 void setItem( sal_Int32 n
, const T
& t
)
72 OSL_ENSURE( isValidIndex(n
), "invalid index" );
73 OSL_ENSURE( isValid ( t
), "invalid item" );
75 T
& aRef
= maItems
[ n
];
76 _elementReplaced( n
, t
);
82 bool hasItem( const T
& t
) const
84 return maItems
.end() != std::find( maItems
.begin(), maItems
.end(), t
);
87 sal_Int32
addItem( const T
& t
)
89 OSL_ENSURE( !hasItem( t
), "item to be added already present" );
90 OSL_ENSURE( isValid( t
), "invalid item" );
92 maItems
.push_back( t
);
94 _elementInserted( maItems
.size() - 1 );
95 return ( maItems
.size() - 1 );
98 void removeItem( const T
& t
)
100 OSL_ENSURE( hasItem( t
), "item to be removed not present" );
101 OSL_ENSURE( isValid( t
), "an invalid item, funny that!" );
103 _elementRemoved( t
);
105 maItems
.erase( std::find( maItems
.begin(), maItems
.end(), t
) );
108 bool hasItems() const
110 return maItems
.size() != 0;
113 sal_Int32
countItems() const
115 return static_cast<sal_Int32
>( maItems
.size() );
118 bool isValidIndex( sal_Int32 n
) const
120 return n
>= 0 && n
< static_cast<sal_Int32
>( maItems
.size() );
124 // the following method may be overridden by sub-classes for
125 // customized behaviour
127 /// called before insertion to determine whether item is valid
128 virtual bool isValid( const T
& ) const { return true; }
133 // the following methods may be overridden by sub-classes for
134 // customized behaviour
136 /// called after item has been inserted into the collection
137 virtual void _insert( const T
& ) { }
139 /// called before item is removed from the collection
140 virtual void _remove( const T
& ) { }
145 virtual css::uno::Type SAL_CALL
getElementType() override
147 return cppu::UnoType
<T
>::get();
150 virtual sal_Bool SAL_CALL
hasElements() override
155 // XIndexAccess : XElementAccess
156 virtual sal_Int32 SAL_CALL
getCount() override
161 virtual css::uno::Any SAL_CALL
getByIndex( sal_Int32 nIndex
) override
163 if( !isValidIndex( nIndex
) )
164 throw css::lang::IndexOutOfBoundsException();
165 return css::uno::makeAny( getItem( nIndex
) );
168 // XIndexReplace : XIndexAccess
169 virtual void SAL_CALL
replaceByIndex( sal_Int32 nIndex
,
170 const css::uno::Any
& aElement
) override
173 if( !isValidIndex( nIndex
) )
174 throw css::lang::IndexOutOfBoundsException();
175 if( !( aElement
>>= t
) || !isValid( t
) )
176 throw css::lang::IllegalArgumentException();
177 setItem( nIndex
, t
);
180 // XEnumerationAccess : XElementAccess
181 virtual css::uno::Reference
<css::container::XEnumeration
> SAL_CALL
createEnumeration() override
183 return new Enumeration( this );
187 // XSet : XEnumerationAccess
188 virtual sal_Bool SAL_CALL
has( const css::uno::Any
& aElement
) override
191 return ( aElement
>>= t
) && hasItem( t
);
194 virtual void SAL_CALL
insert( const css::uno::Any
& aElement
) override
197 if( !( aElement
>>= t
) || !isValid( t
) )
198 throw css::lang::IllegalArgumentException();
200 throw css::container::ElementExistException();
204 virtual void SAL_CALL
remove( const css::uno::Any
& aElement
) override
207 if( !(aElement
>>= t
) )
208 throw css::lang::IllegalArgumentException();
210 throw css::container::NoSuchElementException();
216 virtual void SAL_CALL
addContainerListener(
217 const css::uno::Reference
<css::container::XContainerListener
>& xListener
) override
219 OSL_ENSURE( xListener
.is(), "need listener!" );
220 if( std::find( maListeners
.begin(), maListeners
.end(), xListener
)
221 == maListeners
.end() )
222 maListeners
.push_back( xListener
);
225 virtual void SAL_CALL
removeContainerListener(
226 const css::uno::Reference
<css::container::XContainerListener
>& xListener
) override
228 OSL_ENSURE( xListener
.is(), "need listener!" );
229 Listeners_t::iterator aIter
=
230 std::find( maListeners
.begin(), maListeners
.end(), xListener
);
231 if( aIter
!= maListeners
.end() )
232 maListeners
.erase( aIter
);
238 void _elementInserted( sal_Int32 nPos
)
240 OSL_ENSURE( isValidIndex(nPos
), "invalid index" );
241 css::container::ContainerEvent
aEvent(
242 static_cast<css::container::XIndexReplace
*>( this ),
243 css::uno::makeAny( nPos
),
244 css::uno::makeAny( getItem( nPos
) ),
246 for (auto const& listener
: maListeners
)
248 listener
->elementInserted( aEvent
);
252 void _elementRemoved( const T
& aOld
)
254 css::container::ContainerEvent
aEvent(
255 static_cast<css::container::XIndexReplace
*>( this ),
257 css::uno::makeAny( aOld
),
259 for (auto const& listener
: maListeners
)
261 listener
->elementRemoved( aEvent
);
265 void _elementReplaced( const sal_Int32 nPos
, const T
& aNew
)
267 OSL_ENSURE( isValidIndex(nPos
), "invalid index" );
268 css::container::ContainerEvent
aEvent(
269 static_cast<css::container::XIndexReplace
*>( this ),
270 css::uno::makeAny( nPos
),
271 css::uno::makeAny( getItem( nPos
) ),
272 css::uno::makeAny( aNew
) );
273 for (auto const& listener
: maListeners
)
275 listener
->elementReplaced( aEvent
);
283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */