1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 #include "precompiled_reportdesign.hxx"
30 #include "FunctionHelper.hxx"
31 #include <tools/debug.hxx>
32 
33 // =============================================================================
34 namespace rptui
35 {
36 // =============================================================================
37     using namespace ::com::sun::star;
38 
39 FunctionManager::FunctionManager(const uno::Reference< report::meta::XFunctionManager>& _xMgr)
40 : m_xMgr(_xMgr)
41 {
42 }
43 FunctionManager::~FunctionManager()
44 {
45 }
46 sal_Unicode FunctionManager::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
47 {
48     switch(_eToken)
49     {
50         case eOk:
51             return sal_Unicode('(');
52         case eClose:
53             return sal_Unicode(')');
54         case eSep:
55             return sal_Unicode(';');
56         case eArrayOpen:
57             return sal_Unicode('{');
58         case eArrayClose:
59             return sal_Unicode('}');
60     } // switch(_eToken)
61     return 0;
62 }
63 // -----------------------------------------------------------------------------
64 sal_uInt32 FunctionManager::getCount() const
65 {
66     return m_xMgr->getCount();
67 }
68 // -----------------------------------------------------------------------------
69 const formula::IFunctionCategory* FunctionManager::getCategory(sal_uInt32 _nPos) const
70 {
71     if ( _nPos >= m_aCategoryIndex.size() )
72     {
73         uno::Reference< report::meta::XFunctionCategory> xCategory = m_xMgr->getCategory(_nPos);
74         ::boost::shared_ptr< FunctionCategory > pCategory(new FunctionCategory(this,_nPos + 1,xCategory));
75         m_aCategoryIndex.push_back( m_aCategories.insert(TCategoriesMap::value_type(xCategory->getName(),pCategory)).first );
76     }
77     return m_aCategoryIndex[_nPos]->second.get();
78 }
79 // -----------------------------------------------------------------------------
80 const formula::IFunctionDescription* FunctionManager::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
81 {
82     const formula::IFunctionDescription* pDesc = NULL;
83     try
84     {
85         pDesc = get(m_xMgr->getFunctionByName(_sFunctionName)).get();
86     }
87     catch(uno::Exception&)
88     {
89     }
90     return pDesc;
91 }
92 // -----------------------------------------------------------------------------
93 void FunctionManager::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& /*_rLastRUFunctions*/) const
94 {
95     //const sal_uInt32 nCount = getCount();
96     //for(sal_uInt32 i = 0 ; i < nCount ; ++i)
97     //{
98     //    const formula::IFunctionCategory* pCategory = getCategory(
99     //}
100 }
101 // -----------------------------------------------------------------------------
102 ::boost::shared_ptr< FunctionDescription > FunctionManager::get(const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription) const
103 {
104     ::boost::shared_ptr< FunctionDescription > pDesc;
105     if ( _xFunctionDescription.is() )
106     {
107         const ::rtl::OUString sFunctionName = _xFunctionDescription->getName();
108         TFunctionsMap::const_iterator aFunctionFind = m_aFunctions.find(sFunctionName);
109         if ( aFunctionFind == m_aFunctions.end() )
110         {
111             const uno::Reference< report::meta::XFunctionCategory> xCategory = _xFunctionDescription->getCategory();
112             const ::rtl::OUString sCategoryName = xCategory->getName();
113             TCategoriesMap::iterator aCategoryFind = m_aCategories.find(sCategoryName);
114             if ( aCategoryFind == m_aCategories.end() )
115             {
116                 aCategoryFind = m_aCategories.insert(TCategoriesMap::value_type(sCategoryName,::boost::shared_ptr< FunctionCategory > (new FunctionCategory(this,xCategory->getNumber() + 1,xCategory)))).first;
117                 m_aCategoryIndex.push_back( aCategoryFind );
118             }
119             aFunctionFind = m_aFunctions.insert(TFunctionsMap::value_type(sFunctionName,::boost::shared_ptr<FunctionDescription>(new FunctionDescription(aCategoryFind->second.get(),_xFunctionDescription)))).first;
120         } // if ( aFind == m_aFunctions.end() )
121         pDesc = aFunctionFind->second;
122     } // if ( _xFunctionDescription.is() )
123     return pDesc;
124 }
125 // -----------------------------------------------------------------------------
126 FunctionCategory::FunctionCategory(const FunctionManager* _pFMgr,sal_uInt32 _nPos,const uno::Reference< report::meta::XFunctionCategory>& _xCategory)
127 : m_xCategory(_xCategory)
128 ,m_nFunctionCount(_xCategory->getCount())
129 , m_nNumber(_nPos)
130 ,m_pFunctionManager(_pFMgr)
131 {
132 }
133 // -----------------------------------------------------------------------------
134 sal_uInt32 FunctionCategory::getCount() const
135 {
136     return m_nFunctionCount;
137 }
138 // -----------------------------------------------------------------------------
139 const formula::IFunctionDescription* FunctionCategory::getFunction(sal_uInt32 _nPos) const
140 {
141     if ( _nPos >= m_aFunctions.size() && _nPos < m_nFunctionCount )
142     {
143         uno::Reference< report::meta::XFunctionDescription> xFunctionDescription = m_xCategory->getFunction(_nPos);
144         ::boost::shared_ptr< FunctionDescription > pFunction = m_pFunctionManager->get(xFunctionDescription);
145         m_aFunctions.push_back( pFunction );
146     }
147     return m_aFunctions[_nPos].get();
148 }
149 // -----------------------------------------------------------------------------
150 sal_uInt32 FunctionCategory::getNumber() const
151 {
152     return m_nNumber;
153 }
154 // -----------------------------------------------------------------------------
155 const formula::IFunctionManager* FunctionCategory::getFunctionManager() const
156 {
157     return m_pFunctionManager;
158 }
159 // -----------------------------------------------------------------------------
160 ::rtl::OUString FunctionCategory::getName() const
161 {
162     return m_xCategory->getName();
163 }
164 // -----------------------------------------------------------------------------
165 FunctionDescription::FunctionDescription(const formula::IFunctionCategory* _pFunctionCategory,const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription)
166 : m_xFunctionDescription(_xFunctionDescription)
167 , m_pFunctionCategory(_pFunctionCategory)
168 {
169     m_aParameter = m_xFunctionDescription->getArguments();
170 }
171 ::rtl::OUString FunctionDescription::getFunctionName() const
172 {
173     return m_xFunctionDescription->getName();
174 }
175 // -----------------------------------------------------------------------------
176 const formula::IFunctionCategory* FunctionDescription::getCategory() const
177 {
178     return m_pFunctionCategory;
179 }
180 // -----------------------------------------------------------------------------
181 ::rtl::OUString FunctionDescription::getDescription() const
182 {
183     return m_xFunctionDescription->getDescription();
184 }
185 // -----------------------------------------------------------------------------
186 xub_StrLen FunctionDescription::getSuppressedArgumentCount() const
187 {
188     return static_cast<xub_StrLen>(m_aParameter.getLength());
189 }
190 // -----------------------------------------------------------------------------
191 ::rtl::OUString FunctionDescription::getFormula(const ::std::vector< ::rtl::OUString >& _aArguments) const
192 {
193     ::rtl::OUString sFormula;
194     try
195     {
196         const ::rtl::OUString *pArguments = _aArguments.empty() ? 0 : &_aArguments[0];
197         sFormula = m_xFunctionDescription->createFormula(uno::Sequence< ::rtl::OUString >(pArguments, _aArguments.size()));
198     }
199     catch(const uno::Exception&)
200     {
201         DBG_ERROR("Exception caught!");
202     }
203     return sFormula;
204 }
205 // -----------------------------------------------------------------------------
206 void FunctionDescription::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
207 {
208     const sal_Int32 nCount = m_aParameter.getLength();
209     for(sal_uInt16 i = 0;i < nCount; ++i)
210     {
211         _rArguments.push_back(i);
212     }
213 }
214 // -----------------------------------------------------------------------------
215 void FunctionDescription::initArgumentInfo()  const
216 {
217 }
218 // -----------------------------------------------------------------------------
219 ::rtl::OUString FunctionDescription::getSignature() const
220 {
221     return m_xFunctionDescription->getSignature();
222 }
223 // -----------------------------------------------------------------------------
224 rtl::OString FunctionDescription::getHelpId() const
225 {
226     return rtl::OString();
227 }
228 // -----------------------------------------------------------------------------
229 sal_uInt32 FunctionDescription::getParameterCount() const
230 {
231     return m_aParameter.getLength();
232 }
233 // -----------------------------------------------------------------------------
234 ::rtl::OUString FunctionDescription::getParameterName(sal_uInt32 _nPos) const
235 {
236     if ( _nPos < static_cast<sal_uInt32>(m_aParameter.getLength()) )
237         return m_aParameter[_nPos].Name;
238     return ::rtl::OUString();
239 }
240 // -----------------------------------------------------------------------------
241 ::rtl::OUString FunctionDescription::getParameterDescription(sal_uInt32 _nPos) const
242 {
243     if ( _nPos < static_cast<sal_uInt32>(m_aParameter.getLength()) )
244         return m_aParameter[_nPos].Description;
245     return ::rtl::OUString();
246 }
247 // -----------------------------------------------------------------------------
248 bool FunctionDescription::isParameterOptional(sal_uInt32 _nPos) const
249 {
250     if ( _nPos < static_cast<sal_uInt32>(m_aParameter.getLength()) )
251         return m_aParameter[_nPos].IsOptional;
252     return false;
253 }
254 // -----------------------------------------------------------------------------
255 // =============================================================================
256 } // rptui
257 // =============================================================================
258