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 #include <Functions.hxx>
20 #include <Function.hxx>
21 #include <core_resource.hxx>
22 #include <strings.hrc>
23 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
24 #include <com/sun/star/lang/NoSupportException.hpp>
25 
26 namespace reportdesign
27 {
28 
29     using namespace com::sun::star;
30 
OFunctions(const uno::Reference<report::XFunctionsSupplier> & _xParent,const uno::Reference<uno::XComponentContext> & context)31 OFunctions::OFunctions(const uno::Reference< report::XFunctionsSupplier >& _xParent,const uno::Reference< uno::XComponentContext >& context)
32 :FunctionsBase(m_aMutex)
33 ,m_aContainerListeners(m_aMutex)
34 ,m_xContext(context)
35 ,m_xParent(_xParent)
36 {
37 }
38 
39 // TODO: VirtualFunctionFinder: This is virtual function!
40 
~OFunctions()41 OFunctions::~OFunctions()
42 {
43 }
44 
dispose()45 void SAL_CALL OFunctions::dispose()
46 {
47     cppu::WeakComponentImplHelperBase::dispose();
48 }
49 
50 // TODO: VirtualFunctionFinder: This is virtual function!
51 
disposing()52 void SAL_CALL OFunctions::disposing()
53 {
54     for (auto& rFunction : m_aFunctions)
55         rFunction->dispose();
56     m_aFunctions.clear();
57     lang::EventObject aDisposeEvent( static_cast< ::cppu::OWeakObject* >( this ) );
58     m_aContainerListeners.disposeAndClear( aDisposeEvent );
59     m_xContext.clear();
60 }
61 
62 // XFunctionsSupplier
63 
createFunction()64 uno::Reference< report::XFunction > SAL_CALL OFunctions::createFunction(  )
65 {
66     return new OFunction(m_xContext);
67 }
68 
69 // XIndexContainer
insertByIndex(::sal_Int32 Index,const uno::Any & aElement)70 void SAL_CALL OFunctions::insertByIndex( ::sal_Int32 Index, const uno::Any& aElement )
71 {
72     {
73         ::osl::MutexGuard aGuard(m_aMutex);
74         bool bAdd = (Index == static_cast<sal_Int32>(m_aFunctions.size()));
75         if ( !bAdd )
76             checkIndex(Index);
77         uno::Reference< report::XFunction > xFunction(aElement,uno::UNO_QUERY);
78         if ( !xFunction.is() )
79             throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,2);
80 
81         if ( bAdd )
82             m_aFunctions.push_back(xFunction);
83         else
84         {
85             TFunctions::iterator aPos = m_aFunctions.begin();
86             ::std::advance(aPos,Index);
87             m_aFunctions.insert(aPos, xFunction);
88         }
89         xFunction->setParent(*this);
90     }
91     // notify our container listeners
92     container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::makeAny(Index), aElement, uno::Any());
93     m_aContainerListeners.notifyEach(&container::XContainerListener::elementInserted,aEvent);
94 }
95 
96 
removeByIndex(::sal_Int32 Index)97 void SAL_CALL OFunctions::removeByIndex( ::sal_Int32 Index )
98 {
99     uno::Reference< report::XFunction > xFunction;
100     {
101         ::osl::MutexGuard aGuard(m_aMutex);
102         checkIndex(Index);
103         TFunctions::iterator aPos = m_aFunctions.begin();
104         ::std::advance(aPos,Index);
105         xFunction = *aPos;
106         m_aFunctions.erase(aPos);
107         xFunction->setParent(nullptr);
108     }
109     container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::makeAny(Index), uno::makeAny(xFunction), uno::Any());
110     m_aContainerListeners.notifyEach(&container::XContainerListener::elementRemoved,aEvent);
111 }
112 
113 // XIndexReplace
replaceByIndex(::sal_Int32 Index,const uno::Any & Element)114 void SAL_CALL OFunctions::replaceByIndex( ::sal_Int32 Index, const uno::Any& Element )
115 {
116     uno::Any aOldElement;
117     {
118         ::osl::MutexGuard aGuard(m_aMutex);
119         checkIndex(Index);
120         uno::Reference< report::XFunction > xFunction(Element,uno::UNO_QUERY);
121         if ( !xFunction.is() )
122             throw lang::IllegalArgumentException(RptResId(RID_STR_ARGUMENT_IS_NULL),*this,2);
123         TFunctions::iterator aPos = m_aFunctions.begin();
124         ::std::advance(aPos,Index);
125         aOldElement <<= *aPos;
126         *aPos = xFunction;
127     }
128 
129     container::ContainerEvent aEvent(static_cast<container::XContainer*>(this), uno::makeAny(Index), Element, aOldElement);
130     m_aContainerListeners.notifyEach(&container::XContainerListener::elementReplaced,aEvent);
131 }
132 
133 // XIndexAccess
getCount()134 ::sal_Int32 SAL_CALL OFunctions::getCount(  )
135 {
136     ::osl::MutexGuard aGuard(m_aMutex);
137     return m_aFunctions.size();
138 }
139 
getByIndex(::sal_Int32 Index)140 uno::Any SAL_CALL OFunctions::getByIndex( ::sal_Int32 Index )
141 {
142     ::osl::MutexGuard aGuard(m_aMutex);
143     checkIndex(Index);
144     TFunctions::const_iterator aPos = m_aFunctions.begin();
145     ::std::advance(aPos,Index);
146     return uno::makeAny(*aPos);
147 }
148 
149 // XElementAccess
getElementType()150 uno::Type SAL_CALL OFunctions::getElementType(  )
151 {
152     return cppu::UnoType<report::XFunction>::get();
153 }
154 
hasElements()155 sal_Bool SAL_CALL OFunctions::hasElements(  )
156 {
157     ::osl::MutexGuard aGuard(m_aMutex);
158     return !m_aFunctions.empty();
159 }
160 
161 // XChild
getParent()162 uno::Reference< uno::XInterface > SAL_CALL OFunctions::getParent(  )
163 {
164     return m_xParent;
165 }
166 
setParent(const uno::Reference<uno::XInterface> &)167 void SAL_CALL OFunctions::setParent( const uno::Reference< uno::XInterface >& /*Parent*/ )
168 {
169     throw lang::NoSupportException();
170 }
171 
172 // XContainer
addContainerListener(const uno::Reference<container::XContainerListener> & xListener)173 void SAL_CALL OFunctions::addContainerListener( const uno::Reference< container::XContainerListener >& xListener )
174 {
175     m_aContainerListeners.addInterface(xListener);
176 }
177 
removeContainerListener(const uno::Reference<container::XContainerListener> & xListener)178 void SAL_CALL OFunctions::removeContainerListener( const uno::Reference< container::XContainerListener >& xListener )
179 {
180     m_aContainerListeners.removeInterface(xListener);
181 }
182 
checkIndex(sal_Int32 _nIndex)183 void OFunctions::checkIndex(sal_Int32 _nIndex)
184 {
185     if ( _nIndex < 0 || static_cast<sal_Int32>(m_aFunctions.size()) <= _nIndex )
186         throw lang::IndexOutOfBoundsException();
187 }
188 
189 }
190 
191 
192 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
193