LibreOffice Module reportdesign (master) 1
FunctionHelper.cxx
Go to the documentation of this file.
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#include <FunctionHelper.hxx>
21
22#include <o3tl/safeint.hxx>
23#include <utility>
25#include <formula/funcvarargs.h>
26
27
28namespace rptui
29{
30
31 using namespace ::com::sun::star;
32
33FunctionManager::FunctionManager(uno::Reference< report::meta::XFunctionManager> _xMgr)
34: m_xMgr(std::move(_xMgr))
35{
36}
38{
39}
41{
42 switch(_eToken)
43 {
44 case eOk:
45 return '(';
46 case eClose:
47 return ')';
48 case eSep:
49 return ';';
50 case eArrayOpen:
51 return '{';
52 case eArrayClose:
53 return '}';
54 }
55 return 0;
56}
57
58sal_uInt32 FunctionManager::getCount() const
59{
60 return m_xMgr->getCount();
61}
62
64{
65 if ( _nPos >= m_aCategoryIndex.size() )
66 {
67 uno::Reference< report::meta::XFunctionCategory> xCategory = m_xMgr->getCategory(_nPos);
68 auto pCategory = std::make_shared<FunctionCategory>(this,_nPos + 1,xCategory);
69 m_aCategoryIndex.push_back( m_aCategories.emplace(xCategory->getName(),pCategory).first );
70 }
71 return m_aCategoryIndex[_nPos]->second.get();
72}
73
74void FunctionManager::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& /*_rLastRUFunctions*/) const
75{
76}
77
78std::shared_ptr< FunctionDescription > FunctionManager::get(const uno::Reference< report::meta::XFunctionDescription>& _xFunctionDescription) const
79{
80 std::shared_ptr< FunctionDescription > pDesc;
81 if ( _xFunctionDescription.is() )
82 {
83 const OUString sFunctionName = _xFunctionDescription->getName();
84 TFunctionsMap::const_iterator aFunctionFind = m_aFunctions.find(sFunctionName);
85 if ( aFunctionFind == m_aFunctions.end() )
86 {
87 const uno::Reference< report::meta::XFunctionCategory> xCategory = _xFunctionDescription->getCategory();
88 const OUString sCategoryName = xCategory->getName();
89 TCategoriesMap::iterator aCategoryFind = m_aCategories.find(sCategoryName);
90 if ( aCategoryFind == m_aCategories.end() )
91 {
92 aCategoryFind = m_aCategories.emplace(sCategoryName,std::make_shared< FunctionCategory > (this,xCategory->getNumber() + 1,xCategory)).first;
93 m_aCategoryIndex.push_back( aCategoryFind );
94 }
95 aFunctionFind = m_aFunctions.emplace(sFunctionName,std::make_shared<FunctionDescription>(aCategoryFind->second.get(),_xFunctionDescription)).first;
96 }
97 pDesc = aFunctionFind->second;
98 }
99 return pDesc;
100}
101
102FunctionCategory::FunctionCategory(const FunctionManager* _pFMgr,sal_uInt32 _nPos,const uno::Reference< report::meta::XFunctionCategory>& _xCategory)
103: m_xCategory(_xCategory)
104,m_nFunctionCount(_xCategory->getCount())
105, m_nNumber(_nPos)
106,m_pFunctionManager(_pFMgr)
107{
108}
109
111{
112 return m_nFunctionCount;
113}
114
116{
117 if ( _nPos >= m_aFunctions.size() && _nPos < m_nFunctionCount )
118 {
119 uno::Reference< report::meta::XFunctionDescription> xFunctionDescription = m_xCategory->getFunction(_nPos);
120 std::shared_ptr< FunctionDescription > pFunction = m_pFunctionManager->get(xFunctionDescription);
121 m_aFunctions.push_back( pFunction );
122 }
123 return m_aFunctions[_nPos].get();
124}
125
127{
128 return m_nNumber;
129}
130
132{
133 return m_xCategory->getName();
134}
135
136FunctionDescription::FunctionDescription(const formula::IFunctionCategory* _pFunctionCategory, uno::Reference< report::meta::XFunctionDescription> _xFunctionDescription)
137: m_xFunctionDescription(std::move(_xFunctionDescription))
138, m_pFunctionCategory(_pFunctionCategory)
139{
140 m_aParameter = m_xFunctionDescription->getArguments();
141}
143{
144 return m_xFunctionDescription->getName();
145}
146
148{
149 return m_pFunctionCategory;
150}
151
153{
154 return m_xFunctionDescription->getDescription();
155}
156
158{
159 return m_aParameter.getLength();
160}
161
162OUString FunctionDescription::getFormula(const ::std::vector< OUString >& _aArguments) const
163{
164 OUString sFormula;
165 try
166 {
167 sFormula = m_xFunctionDescription->createFormula(uno::Sequence< OUString >(_aArguments.data(), _aArguments.size()));
168 }
169 catch(const uno::Exception&)
170 {
171 TOOLS_WARN_EXCEPTION( "reportdesign", "");
172 }
173 return sFormula;
174}
175
176void FunctionDescription::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
177{
178 const sal_Int32 nCount = m_aParameter.getLength();
179 for(sal_Int32 i = 0;i < nCount; ++i)
180 {
181 _rArguments.push_back(i);
182 }
183}
184
186{
187}
188
190{
191 return m_xFunctionDescription->getSignature();
192}
193
195{
196 return {};
197}
198
200{
201 return false;
202}
203
205{
206 return m_aParameter.getLength();
207}
208
210{
211 /* XXX there are no variable number of arguments, are there? Nevertheless
212 * consider the varargs handling of the Function Wizard and return a value
213 * within the bounds of parameters. */
214 // Don't use defines/constants that could change in future, parameter count
215 // could be part of an implicit stable API.
216 // offapi/com/sun/star/report/meta/XFunctionDescription.idl doesn't tell.
217 const sal_uInt32 nVarArgs30 = 30; // ugly hard coded old VAR_ARGS of formula::ParaWin
218 const sal_uInt32 nPairedVarArgs60 = 60; // ugly hard coded old PAIRED_VAR_ARGS of formula::ParaWin
219 const sal_uInt32 nVarArgs255 = 255; // ugly hard coded new VAR_ARGS of formula::ParaWin
220 const sal_uInt32 nPairedVarArgs510 = 510; // ugly hard coded new PAIRED_VAR_ARGS of formula::ParaWin
221 sal_uInt32 nLen = m_aParameter.getLength();
222 // If the value of VAR_ARGS changes then adapt *and* maintain implicit API
223 // stability, ie. old code using the old VAR_ARGS and PAIRED_VAR_ARGS
224 // values must still be handled. It is *not* sufficient to simply change
225 // the values here.
226 static_assert(nVarArgs255 == VAR_ARGS && nPairedVarArgs510 == PAIRED_VAR_ARGS,
227 "VAR_ARGS or PAIRED_VAR_ARGS has unexpected value");
228 if (nLen >= nPairedVarArgs510)
229 nLen -= nPairedVarArgs510;
230 else if (nLen >= nVarArgs255)
231 nLen -= nVarArgs255;
232 else if (nLen >= nPairedVarArgs60)
233 nLen -= nPairedVarArgs60;
234 else if (nLen >= nVarArgs30)
235 nLen -= nVarArgs30;
236 return nLen ? nLen - 1 : 0;
237}
238
240{
241 return 0;
242}
243
244OUString FunctionDescription::getParameterName(sal_uInt32 _nPos) const
245{
246 if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) )
247 return m_aParameter[_nPos].Name;
248 return OUString();
249}
250
251OUString FunctionDescription::getParameterDescription(sal_uInt32 _nPos) const
252{
253 if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) )
254 return m_aParameter[_nPos].Description;
255 return OUString();
256}
257
259{
260 if ( _nPos < o3tl::make_unsigned(m_aParameter.getLength()) )
261 return m_aParameter[_nPos].IsOptional;
262 return false;
263}
264
265
266} // rptui
267
268
269/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
std::unique_ptr< weld::ComboBox > m_xCategory
virtual const formula::IFunctionDescription * getFunction(sal_uInt32 _nPos) const override
mutable ::std::vector< std::shared_ptr< FunctionDescription > > m_aFunctions
const FunctionManager * m_pFunctionManager
virtual sal_uInt32 getNumber() const override
virtual sal_uInt32 getCount() const override
virtual OUString getName() const override
css::uno::Reference< css::report::meta::XFunctionCategory > m_xCategory
FunctionCategory(const FunctionManager *_pFMgr, sal_uInt32 _nPos, const css::uno::Reference< css::report::meta::XFunctionCategory > &_xCategory)
virtual OUString getParameterName(sal_uInt32 _nPos) const override
FunctionDescription(const formula::IFunctionCategory *_pFunctionCategory, css::uno::Reference< css::report::meta::XFunctionDescription > _xFunctionDescription)
virtual void fillVisibleArgumentMapping(::std::vector< sal_uInt16 > &_rArguments) const override
virtual bool isHidden() const override
virtual sal_uInt32 getVarArgsStart() const override
virtual OUString getFunctionName() const override
css::uno::Reference< css::report::meta::XFunctionDescription > m_xFunctionDescription
virtual sal_Int32 getSuppressedArgumentCount() const override
virtual OUString getHelpId() const override
virtual OUString getDescription() const override
virtual OUString getParameterDescription(sal_uInt32 _nPos) const override
virtual sal_uInt32 getParameterCount() const override
css::uno::Sequence< css::sheet::FunctionArgument > m_aParameter
virtual OUString getSignature() const override
virtual OUString getFormula(const ::std::vector< OUString > &_aArguments) const override
virtual const formula::IFunctionCategory * getCategory() const override
virtual void initArgumentInfo() const override
const formula::IFunctionCategory * m_pFunctionCategory
virtual bool isParameterOptional(sal_uInt32 _nPos) const override
virtual sal_uInt32 getVarArgsLimit() const override
mutable ::std::vector< TCategoriesMap::iterator > m_aCategoryIndex
TFunctionsMap m_aFunctions
virtual sal_uInt32 getCount() const override
virtual const formula::IFunctionCategory * getCategory(sal_uInt32 nPos) const override
virtual void fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription * > &_rLastRUFunctions) const override
virtual sal_Unicode getSingleToken(const EToken _eToken) const override
FunctionManager(css::uno::Reference< css::report::meta::XFunctionManager > _xMgr)
css::uno::Reference< css::report::meta::XFunctionManager > m_xMgr
std::shared_ptr< FunctionDescription > get(const css::uno::Reference< css::report::meta::XFunctionDescription > &_xFunctionDescription) const
TCategoriesMap m_aCategories
int nCount
#define TOOLS_WARN_EXCEPTION(area, stream)
OString sFormula
#define VAR_ARGS
#define PAIRED_VAR_ARGS
int i
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_uInt16 sal_Unicode
sal_Int32 _nPos