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 #include <FunctionHelper.hxx>
22 #include <o3tl/safeint.hxx>
24 #include <comphelper/diagnose_ex.hxx>
25 #include <formula/funcvarargs.h>
31 using namespace ::com::sun::star
;
33 FunctionManager::FunctionManager(uno::Reference
< report::meta::XFunctionManager
> _xMgr
)
34 : m_xMgr(std::move(_xMgr
))
37 FunctionManager::~FunctionManager()
40 sal_Unicode
FunctionManager::getSingleToken(const formula::IFunctionManager::EToken _eToken
) const
62 const formula::IFunctionDescription
* FunctionManager::Get(sal_uInt16
/*nFIndex*/) const
67 sal_uInt32
FunctionManager::getCount() const
69 return m_xMgr
->getCount();
72 const formula::IFunctionCategory
* FunctionManager::getCategory(sal_uInt32 _nPos
) const
74 if ( _nPos
>= m_aCategoryIndex
.size() )
76 uno::Reference
< report::meta::XFunctionCategory
> xCategory
= m_xMgr
->getCategory(_nPos
);
77 auto pCategory
= std::make_shared
<FunctionCategory
>(this,_nPos
+ 1,xCategory
);
78 m_aCategoryIndex
.push_back( m_aCategories
.emplace(xCategory
->getName(),pCategory
).first
);
80 return m_aCategoryIndex
[_nPos
]->second
.get();
83 sal_uInt16
FunctionManager::getFunctionIndex(const formula::IFunctionDescription
* /*_pDesc*/) const
88 void FunctionManager::fillLastRecentlyUsedFunctions(::std::vector
< const formula::IFunctionDescription
*>& /*_rLastRUFunctions*/) const
92 void FunctionManager::fillFavouriteFunctions(::std::unordered_set
<sal_uInt16
>& /*rFavouriteFunctions*/) const
96 std::shared_ptr
< FunctionDescription
> FunctionManager::get(const uno::Reference
< report::meta::XFunctionDescription
>& _xFunctionDescription
) const
98 std::shared_ptr
< FunctionDescription
> pDesc
;
99 if ( _xFunctionDescription
.is() )
101 const OUString sFunctionName
= _xFunctionDescription
->getName();
102 TFunctionsMap::const_iterator aFunctionFind
= m_aFunctions
.find(sFunctionName
);
103 if ( aFunctionFind
== m_aFunctions
.end() )
105 const uno::Reference
< report::meta::XFunctionCategory
> xCategory
= _xFunctionDescription
->getCategory();
106 const OUString sCategoryName
= xCategory
->getName();
107 TCategoriesMap::iterator aCategoryFind
= m_aCategories
.find(sCategoryName
);
108 if ( aCategoryFind
== m_aCategories
.end() )
110 aCategoryFind
= m_aCategories
.emplace(sCategoryName
,std::make_shared
< FunctionCategory
> (this,xCategory
->getNumber() + 1,xCategory
)).first
;
111 m_aCategoryIndex
.push_back( aCategoryFind
);
113 aFunctionFind
= m_aFunctions
.emplace(sFunctionName
,std::make_shared
<FunctionDescription
>(aCategoryFind
->second
.get(),_xFunctionDescription
)).first
;
115 pDesc
= aFunctionFind
->second
;
120 FunctionCategory::FunctionCategory(const FunctionManager
* _pFMgr
,sal_uInt32 _nPos
,const uno::Reference
< report::meta::XFunctionCategory
>& _xCategory
)
121 : m_xCategory(_xCategory
)
122 ,m_nFunctionCount(_xCategory
->getCount())
124 ,m_pFunctionManager(_pFMgr
)
128 sal_uInt32
FunctionCategory::getCount() const
130 return m_nFunctionCount
;
133 const formula::IFunctionDescription
* FunctionCategory::getFunction(sal_uInt32 _nPos
) const
135 if ( _nPos
>= m_aFunctions
.size() && _nPos
< m_nFunctionCount
)
137 uno::Reference
< report::meta::XFunctionDescription
> xFunctionDescription
= m_xCategory
->getFunction(_nPos
);
138 std::shared_ptr
< FunctionDescription
> pFunction
= m_pFunctionManager
->get(xFunctionDescription
);
139 m_aFunctions
.push_back( pFunction
);
141 return m_aFunctions
[_nPos
].get();
144 sal_uInt32
FunctionCategory::getNumber() const
149 OUString
FunctionCategory::getName() const
151 return m_xCategory
->getName();
154 FunctionDescription::FunctionDescription(const formula::IFunctionCategory
* _pFunctionCategory
, uno::Reference
< report::meta::XFunctionDescription
> _xFunctionDescription
)
155 : m_xFunctionDescription(std::move(_xFunctionDescription
))
156 , m_pFunctionCategory(_pFunctionCategory
)
158 m_aParameter
= m_xFunctionDescription
->getArguments();
160 OUString
FunctionDescription::getFunctionName() const
162 return m_xFunctionDescription
->getName();
165 const formula::IFunctionCategory
* FunctionDescription::getCategory() const
167 return m_pFunctionCategory
;
170 OUString
FunctionDescription::getDescription() const
172 return m_xFunctionDescription
->getDescription();
175 sal_Int32
FunctionDescription::getSuppressedArgumentCount() const
177 return m_aParameter
.getLength();
180 OUString
FunctionDescription::getFormula(const ::std::vector
< OUString
>& _aArguments
) const
185 sFormula
= m_xFunctionDescription
->createFormula(uno::Sequence
< OUString
>(_aArguments
.data(), _aArguments
.size()));
187 catch(const uno::Exception
&)
189 TOOLS_WARN_EXCEPTION( "reportdesign", "");
194 void FunctionDescription::fillVisibleArgumentMapping(::std::vector
<sal_uInt16
>& _rArguments
) const
196 const sal_Int32 nCount
= m_aParameter
.getLength();
197 for(sal_Int32 i
= 0;i
< nCount
; ++i
)
199 _rArguments
.push_back(i
);
203 void FunctionDescription::initArgumentInfo() const
207 OUString
FunctionDescription::getSignature() const
209 return m_xFunctionDescription
->getSignature();
212 OUString
FunctionDescription::getHelpId() const
217 bool FunctionDescription::isHidden() const
222 sal_uInt32
FunctionDescription::getParameterCount() const
224 return m_aParameter
.getLength();
227 sal_uInt32
FunctionDescription::getVarArgsStart() const
229 /* XXX there are no variable number of arguments, are there? Nevertheless
230 * consider the varargs handling of the Function Wizard and return a value
231 * within the bounds of parameters. */
232 // Don't use defines/constants that could change in future, parameter count
233 // could be part of an implicit stable API.
234 // offapi/com/sun/star/report/meta/XFunctionDescription.idl doesn't tell.
235 const sal_uInt32 nVarArgs30
= 30; // ugly hard coded old VAR_ARGS of formula::ParaWin
236 const sal_uInt32 nPairedVarArgs60
= 60; // ugly hard coded old PAIRED_VAR_ARGS of formula::ParaWin
237 const sal_uInt32 nVarArgs255
= 255; // ugly hard coded new VAR_ARGS of formula::ParaWin
238 const sal_uInt32 nPairedVarArgs510
= 510; // ugly hard coded new PAIRED_VAR_ARGS of formula::ParaWin
239 sal_uInt32 nLen
= m_aParameter
.getLength();
240 // If the value of VAR_ARGS changes then adapt *and* maintain implicit API
241 // stability, ie. old code using the old VAR_ARGS and PAIRED_VAR_ARGS
242 // values must still be handled. It is *not* sufficient to simply change
244 static_assert(nVarArgs255
== VAR_ARGS
&& nPairedVarArgs510
== PAIRED_VAR_ARGS
,
245 "VAR_ARGS or PAIRED_VAR_ARGS has unexpected value");
246 if (nLen
>= nPairedVarArgs510
)
247 nLen
-= nPairedVarArgs510
;
248 else if (nLen
>= nVarArgs255
)
250 else if (nLen
>= nPairedVarArgs60
)
251 nLen
-= nPairedVarArgs60
;
252 else if (nLen
>= nVarArgs30
)
254 return nLen
? nLen
- 1 : 0;
257 sal_uInt32
FunctionDescription::getVarArgsLimit() const
262 OUString
FunctionDescription::getParameterName(sal_uInt32 _nPos
) const
264 if ( _nPos
< o3tl::make_unsigned(m_aParameter
.getLength()) )
265 return m_aParameter
[_nPos
].Name
;
269 OUString
FunctionDescription::getParameterDescription(sal_uInt32 _nPos
) const
271 if ( _nPos
< o3tl::make_unsigned(m_aParameter
.getLength()) )
272 return m_aParameter
[_nPos
].Description
;
276 bool FunctionDescription::isParameterOptional(sal_uInt32 _nPos
) const
278 if ( _nPos
< o3tl::make_unsigned(m_aParameter
.getLength()) )
279 return m_aParameter
[_nPos
].IsOptional
;
287 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */