fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / core / data / funcdesc.cxx
blobd9d026685c20af8f77162686d85f4cbd398cbbe6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "funcdesc.hxx"
22 #include "addincol.hxx"
23 #include "appoptio.hxx"
24 #include "callform.hxx"
25 #include "compiler.hxx"
26 #include "global.hxx"
27 #include "sc.hrc"
28 #include "scmod.hxx"
29 #include "scresid.hxx"
31 #include <rtl/ustring.hxx>
32 #include <rtl/ustrbuf.hxx>
33 #include <tools/rcid.h>
34 #include <tools/resid.hxx>
35 #include <unotools/collatorwrapper.hxx>
37 #include <numeric>
38 #include <boost/scoped_ptr.hpp>
40 class ScFuncRes : public Resource
42 public:
43 ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
45 private:
46 sal_uInt16 GetNum();
49 class ScResourcePublisher : public Resource
51 private:
52 void FreeResource() { Resource::FreeResource(); }
53 public:
54 ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
55 ~ScResourcePublisher() { FreeResource(); }
56 bool IsAvailableRes( const ResId& rId ) const
57 { return Resource::IsAvailableRes( rId ); }
61 // class ScFuncDesc:
63 ScFuncDesc::ScFuncDesc() :
64 pFuncName (NULL),
65 pFuncDesc (NULL),
66 pDefArgFlags (NULL),
67 nFIndex (0),
68 nCategory (0),
69 nArgCount (0),
70 bIncomplete (false),
71 bHasSuppressedArgs(false)
74 ScFuncDesc::~ScFuncDesc()
76 Clear();
79 void ScFuncDesc::Clear()
81 sal_uInt16 nArgs = nArgCount;
82 if (nArgs >= PAIRED_VAR_ARGS)
83 nArgs -= PAIRED_VAR_ARGS - 2;
84 else if (nArgs >= VAR_ARGS)
85 nArgs -= VAR_ARGS - 1;
86 if (nArgs)
88 delete [] pDefArgFlags;
90 nArgCount = 0;
91 maDefArgNames.clear();
92 maDefArgDescs.clear();
93 pDefArgFlags = NULL;
95 delete pFuncName;
96 pFuncName = NULL;
98 delete pFuncDesc;
99 pFuncDesc = NULL;
101 nFIndex = 0;
102 nCategory = 0;
103 sHelpId.clear();
104 bIncomplete = false;
105 bHasSuppressedArgs = false;
108 OUString ScFuncDesc::GetParamList() const
110 OUString sep(ScCompiler::GetNativeSymbol(ocSep));
112 OUStringBuffer aSig;
114 if ( nArgCount > 0 )
116 if ( nArgCount < VAR_ARGS )
118 sal_uInt16 nLastSuppressed = nArgCount;
119 sal_uInt16 nLastAdded = nArgCount;
120 for ( sal_uInt16 i=0; i<nArgCount; i++ )
122 if (pDefArgFlags[i].bSuppress)
123 nLastSuppressed = i;
124 else
126 nLastAdded = i;
127 aSig.append(maDefArgNames[i]);
128 if ( i != nArgCount-1 )
130 aSig.append(sep);
131 aSig.appendAscii( " " );
135 // If only suppressed parameters follow the last added parameter,
136 // remove one "; "
137 if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed &&
138 aSig.getLength() >= 2)
139 aSig.setLength(aSig.getLength() - 2);
141 else if ( nArgCount < PAIRED_VAR_ARGS)
143 sal_uInt16 nFix = nArgCount - VAR_ARGS;
144 for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
146 if (!pDefArgFlags[nArg].bSuppress)
148 aSig.append(maDefArgNames[nArg]);
149 aSig.append(sep);
150 aSig.appendAscii( " " );
153 /* NOTE: Currently there are no suppressed var args parameters. If
154 * there were, we'd have to cope with it here and above for the fix
155 * parameters. For now parameters are always added, so no special
156 * treatment of a trailing "; " necessary. */
157 aSig.append(maDefArgNames[nFix]);
158 aSig.append('1');
159 aSig.append(sep);
160 aSig.append(' ');
161 aSig.append(maDefArgNames[nFix]);
162 aSig.append('2');
163 aSig.append(sep);
164 aSig.appendAscii(" ... ");
166 else
168 sal_uInt16 nFix = nArgCount - PAIRED_VAR_ARGS;
169 for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
171 if (!pDefArgFlags[nArg].bSuppress)
173 aSig.append(maDefArgNames[nArg]);
174 aSig.append(sep);
175 aSig.appendAscii( " " );
179 aSig.append(maDefArgNames[nFix]);
180 aSig.append('1');
181 aSig.append(sep);
182 aSig.append(maDefArgNames[nFix+1]);
183 aSig.append('1');
184 aSig.append(sep);
185 aSig.appendAscii( " " );
186 aSig.append(maDefArgNames[nFix]);
187 aSig.append('2');
188 aSig.append(sep);
189 aSig.append(maDefArgNames[nFix+1]);
190 aSig.append('2');
191 aSig.append(sep);
192 aSig.appendAscii( " ... " );
196 return aSig.makeStringAndClear();
199 OUString ScFuncDesc::getSignature() const
201 OUStringBuffer aSig;
203 if(pFuncName)
205 aSig.append(*pFuncName);
207 OUString aParamList = GetParamList();
208 if( !aParamList.isEmpty() )
210 aSig.appendAscii( "( " );
211 aSig.append(aParamList);
212 // U+00A0 (NBSP) prevents automatic line break
213 aSig.append( static_cast< sal_Unicode >(0xA0) );
214 aSig.appendAscii( ")" );
216 else
217 aSig.appendAscii( "()" );
219 return aSig.makeStringAndClear();
222 OUString ScFuncDesc::getFormula( const ::std::vector< OUString >& _aArguments ) const
224 OUString sep = ScCompiler::GetNativeSymbol(ocSep);
226 OUStringBuffer aFormula;
228 if(pFuncName)
230 aFormula.append( *pFuncName );
232 aFormula.appendAscii( "(" );
233 if ( nArgCount > 0 && !_aArguments.empty() && !_aArguments[0].isEmpty())
235 ::std::vector< OUString >::const_iterator aIter = _aArguments.begin();
236 ::std::vector< OUString >::const_iterator aEnd = _aArguments.end();
238 aFormula.append( *aIter );
239 ++aIter;
240 while( aIter != aEnd && !aIter->isEmpty() )
242 aFormula.append( sep );
243 aFormula.append( *aIter );
244 ++aIter;
248 aFormula.appendAscii( ")" );
250 return aFormula.makeStringAndClear();
253 sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
255 if (!bHasSuppressedArgs || !pDefArgFlags)
256 return nArgCount;
258 sal_uInt16 nArgs = nArgCount;
259 if (nArgs >= PAIRED_VAR_ARGS)
260 nArgs -= PAIRED_VAR_ARGS - 2;
261 else if (nArgs >= VAR_ARGS)
262 nArgs -= VAR_ARGS - 1;
263 sal_uInt16 nCount = nArgs;
264 for (sal_uInt16 i=0; i < nArgs; ++i)
266 if (pDefArgFlags[i].bSuppress)
267 --nCount;
269 if (nArgCount >= PAIRED_VAR_ARGS)
270 nCount += PAIRED_VAR_ARGS - 2;
271 else if (nArgCount >= VAR_ARGS)
272 nCount += VAR_ARGS - 1;
273 return nCount;
276 OUString ScFuncDesc::getFunctionName() const
278 OUString sRet;
279 if ( pFuncName )
280 sRet = *pFuncName;
281 return sRet;
284 const formula::IFunctionCategory* ScFuncDesc::getCategory() const
286 return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
289 OUString ScFuncDesc::getDescription() const
291 OUString sRet;
292 if ( pFuncDesc )
293 sRet = *pFuncDesc;
294 return sRet;
297 sal_Int32 ScFuncDesc::getSuppressedArgumentCount() const
299 return GetSuppressedArgCount();
302 void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
304 if (!bHasSuppressedArgs || !pDefArgFlags)
306 _rArguments.resize( nArgCount);
307 ::std::vector<sal_uInt16>::iterator iter = _rArguments.begin();
308 sal_uInt16 value = 0;
309 while (iter != _rArguments.end())
310 *iter++ = value++;
313 _rArguments.reserve( nArgCount);
314 sal_uInt16 nArgs = nArgCount;
315 if (nArgs >= PAIRED_VAR_ARGS)
316 nArgs -= PAIRED_VAR_ARGS - 2;
317 else if (nArgs >= VAR_ARGS)
318 nArgs -= VAR_ARGS - 1;
319 for (sal_uInt16 i=0; i < nArgs; ++i)
321 if (!pDefArgFlags || !pDefArgFlags[i].bSuppress)
322 _rArguments.push_back(i);
326 void ScFuncDesc::initArgumentInfo() const
328 // get the full argument description
329 // (add-in has to be instantiated to get the type information)
331 if ( bIncomplete && pFuncName )
333 ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection();
334 OUString aIntName(rAddIns.FindFunction( *pFuncName, true )); // pFuncName is upper-case
336 if ( !aIntName.isEmpty() )
338 // GetFuncData with bComplete=true loads the component and updates
339 // the global function list if needed.
341 rAddIns.GetFuncData( aIntName, true );
344 if ( bIncomplete )
346 OSL_FAIL( "couldn't initialize add-in function" );
347 const_cast<ScFuncDesc*>(this)->bIncomplete = false; // even if there was an error, don't try again
352 OString ScFuncDesc::getHelpId() const
354 return sHelpId;
357 sal_uInt32 ScFuncDesc::getParameterCount() const
359 return nArgCount;
362 OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
364 return maDefArgNames[_nPos];
367 OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
369 return maDefArgDescs[_nPos];
372 bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
374 return pDefArgFlags[_nPos].bOptional;
377 bool ScFuncDesc::compareByName(const ScFuncDesc* a, const ScFuncDesc* b)
379 return (ScGlobal::GetCaseCollator()->compareString(*a->pFuncName, *b->pFuncName ) < 0);
382 // class ScFunctionList:
384 ScFunctionList::ScFunctionList() :
385 nMaxFuncNameLen ( 0 )
387 ScFuncDesc* pDesc = NULL;
388 sal_Int32 nStrLen = 0;
389 ::std::list<ScFuncDesc*> tmpFuncList;
390 sal_uInt16 nDescBlock[] =
392 RID_SC_FUNCTION_DESCRIPTIONS1,
393 RID_SC_FUNCTION_DESCRIPTIONS2
396 for (sal_uInt16 k = 0; k < SAL_N_ELEMENTS(nDescBlock); ++k)
398 boost::scoped_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) );
399 // Browse for all possible OpCodes. This is not the fastest method, but
400 // otherwise the sub resources within the resource blocks and the
401 // resource blocks themselves would had to be ordered according to
402 // OpCodes, which is utopian...
403 for (sal_uInt16 i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; ++i)
405 ScResId aRes(i);
406 aRes.SetRT(RSC_RESOURCE);
407 // Sub resource of OpCode available?
408 if (pBlock->IsAvailableRes(aRes))
410 pDesc = new ScFuncDesc;
411 bool bSuppressed = false;
412 ScFuncRes aSubRes( aRes, pDesc, bSuppressed);
413 // Instead of dealing with this exceptional case at 1001 places
414 // we simply don't add an entirely suppressed function to the
415 // list and delete it.
416 if (bSuppressed)
417 delete pDesc;
418 else
420 pDesc->nFIndex = i;
421 tmpFuncList.push_back(pDesc);
423 nStrLen = (*(pDesc->pFuncName)).getLength();
424 if (nStrLen > nMaxFuncNameLen)
425 nMaxFuncNameLen = nStrLen;
431 sal_uInt16 nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions
433 // Interpretation of AddIn list
434 OUString aDefArgNameValue = "value";
435 OUString aDefArgNameString = "string";
436 OUString aDefArgNameValues = "values";
437 OUString aDefArgNameStrings = "strings";
438 OUString aDefArgNameCells = "cells";
439 OUString aDefArgNameNone = "none";
440 OUString aDefArgDescValue = "a value";
441 OUString aDefArgDescString = "a string";
442 OUString aDefArgDescValues = "array of values";
443 OUString aDefArgDescStrings = "array of strings";
444 OUString aDefArgDescCells = "range of cells";
445 OUString aDefArgDescNone = "none";
447 OUString aArgName, aArgDesc;
448 const FuncCollection& rFuncColl = *ScGlobal::GetFuncCollection();
449 FuncCollection::const_iterator it = rFuncColl.begin(), itEnd = rFuncColl.end();
450 for (; it != itEnd; ++it)
452 const FuncData* pAddInFuncData = it->second;
453 pDesc = new ScFuncDesc;
454 sal_uInt16 nArgs = pAddInFuncData->GetParamCount() - 1;
455 pAddInFuncData->getParamDesc( aArgName, aArgDesc, 0 );
456 pDesc->nFIndex = nNextId++; // ??? OpCode vergeben
457 pDesc->nCategory = ID_FUNCTION_GRP_ADDINS;
458 pDesc->pFuncName = new OUString(pAddInFuncData->GetInternalName().toAsciiUpperCase());
460 OUStringBuffer aBuf(aArgDesc);
461 aBuf.append('\n');
462 aBuf.appendAscii("( AddIn: ");
463 aBuf.append(pAddInFuncData->GetModuleName());
464 aBuf.appendAscii(" )");
465 pDesc->pFuncDesc = new OUString(aBuf.makeStringAndClear());
467 pDesc->nArgCount = nArgs;
468 if (nArgs)
470 pDesc->maDefArgNames.clear();
471 pDesc->maDefArgNames.resize(nArgs);
472 pDesc->maDefArgDescs.clear();
473 pDesc->maDefArgDescs.resize(nArgs);
474 pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
475 for (sal_uInt16 j = 0; j < nArgs; ++j)
477 pDesc->pDefArgFlags[j].bOptional = false;
478 pDesc->pDefArgFlags[j].bSuppress = false;
479 pAddInFuncData->getParamDesc( aArgName, aArgDesc, j+1 );
480 if ( !aArgName.isEmpty() )
481 pDesc->maDefArgNames[j] = aArgName;
482 else
484 switch (pAddInFuncData->GetParamType(j+1))
486 case ParamType::PTR_DOUBLE:
487 pDesc->maDefArgNames[j] = aDefArgNameValue;
488 break;
489 case ParamType::PTR_STRING:
490 pDesc->maDefArgNames[j] = aDefArgNameString;
491 break;
492 case ParamType::PTR_DOUBLE_ARR:
493 pDesc->maDefArgNames[j] = aDefArgNameValues;
494 break;
495 case ParamType::PTR_STRING_ARR:
496 pDesc->maDefArgNames[j] = aDefArgNameStrings;
497 break;
498 case ParamType::PTR_CELL_ARR:
499 pDesc->maDefArgNames[j] = aDefArgNameCells;
500 break;
501 default:
502 pDesc->maDefArgNames[j] = aDefArgNameNone;
503 break;
506 if ( !aArgDesc.isEmpty() )
507 pDesc->maDefArgDescs[j] = aArgDesc;
508 else
510 switch (pAddInFuncData->GetParamType(j+1))
512 case ParamType::PTR_DOUBLE:
513 pDesc->maDefArgDescs[j] = aDefArgDescValue;
514 break;
515 case ParamType::PTR_STRING:
516 pDesc->maDefArgDescs[j] = aDefArgDescString;
517 break;
518 case ParamType::PTR_DOUBLE_ARR:
519 pDesc->maDefArgDescs[j] = aDefArgDescValues;
520 break;
521 case ParamType::PTR_STRING_ARR:
522 pDesc->maDefArgDescs[j] = aDefArgDescStrings;
523 break;
524 case ParamType::PTR_CELL_ARR:
525 pDesc->maDefArgDescs[j] = aDefArgDescCells;
526 break;
527 default:
528 pDesc->maDefArgDescs[j] = aDefArgDescNone;
529 break;
535 tmpFuncList.push_back(pDesc);
536 nStrLen = (*(pDesc->pFuncName)).getLength();
537 if ( nStrLen > nMaxFuncNameLen)
538 nMaxFuncNameLen = nStrLen;
541 // StarOne AddIns
543 ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection();
544 long nUnoCount = pUnoAddIns->GetFuncCount();
545 for (long nFunc=0; nFunc<nUnoCount; nFunc++)
547 pDesc = new ScFuncDesc;
548 pDesc->nFIndex = nNextId++;
550 if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) )
552 tmpFuncList.push_back(pDesc);
553 nStrLen = (*(pDesc->pFuncName)).getLength();
554 if (nStrLen > nMaxFuncNameLen)
555 nMaxFuncNameLen = nStrLen;
557 else
558 delete pDesc;
561 //Move list to vector for better random access performance
562 ::std::vector<const ScFuncDesc*> tmp(tmpFuncList.begin(), tmpFuncList.end());
563 tmpFuncList.clear();
564 aFunctionList.swap(tmp);
566 //Initialize iterator
567 aFunctionListIter = aFunctionList.end();
570 ScFunctionList::~ScFunctionList()
572 const ScFuncDesc* pDesc = First();
573 while (pDesc)
575 delete pDesc;
576 pDesc = Next();
580 const ScFuncDesc* ScFunctionList::First()
582 const ScFuncDesc* pDesc = NULL;
583 aFunctionListIter = aFunctionList.begin();
584 if(aFunctionListIter != aFunctionList.end())
585 pDesc = *aFunctionListIter;
587 return pDesc;
590 const ScFuncDesc* ScFunctionList::Next()
592 const ScFuncDesc* pDesc = NULL;
593 if(aFunctionListIter != aFunctionList.end())
595 if((++aFunctionListIter) != aFunctionList.end())
596 pDesc = *aFunctionListIter;
598 return pDesc;
601 const ScFuncDesc* ScFunctionList::GetFunction( sal_uInt32 nIndex ) const
603 const ScFuncDesc* pDesc = NULL;
604 if(nIndex < aFunctionList.size())
605 pDesc = aFunctionList.at(nIndex);
607 return pDesc;
610 // class ScFunctionCategory:
612 sal_uInt32 ScFunctionCategory::getCount() const
614 return m_pCategory->size();
617 const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
619 return m_pMgr;
622 OUString ScFunctionCategory::getName() const
624 if ( m_sName.isEmpty() )
625 m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1);
626 return m_sName;
629 const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const
631 const ScFuncDesc* pDesc = NULL;
632 if(_nPos < m_pCategory->size())
633 pDesc = m_pCategory->at(_nPos);
634 return pDesc;
637 sal_uInt32 ScFunctionCategory::getNumber() const
639 return m_nCategory;
642 // class ScFunctionMgr:
644 ScFunctionMgr::ScFunctionMgr() :
645 pFuncList( ScGlobal::GetStarCalcFunctionList() )
647 OSL_ENSURE( pFuncList, "Functionlist not found." );
648 sal_uInt32 catCount[MAX_FUNCCAT] = {0};
650 aCatLists[0] = new ::std::vector<const ScFuncDesc*>();
651 aCatLists[0]->reserve(pFuncList->GetCount());
653 // Retrieve all functions, store in cumulative ("All") category, and count
654 // number of functions in each category
655 for(const ScFuncDesc* pDesc = pFuncList->First(); pDesc; pDesc = pFuncList->Next())
657 OSL_ENSURE((pDesc->nCategory) < MAX_FUNCCAT, "Unknown category");
658 if ((pDesc->nCategory) < MAX_FUNCCAT)
659 ++catCount[pDesc->nCategory];
660 aCatLists[0]->push_back(pDesc);
663 // Sort functions in cumulative category by name
664 ::std::sort(aCatLists[0]->begin(), aCatLists[0]->end(), ScFuncDesc::compareByName);
666 // Allocate correct amount of space for categories
667 for (sal_uInt16 i = 1; i < MAX_FUNCCAT; ++i)
669 aCatLists[i] = new ::std::vector<const ScFuncDesc*>();
670 aCatLists[i]->reserve(catCount[i]);
673 // Fill categories with the corresponding functions (still sorted by name)
674 for(::std::vector<const ScFuncDesc*>::iterator iter = aCatLists[0]->begin(); iter!=aCatLists[0]->end(); ++iter)
676 if (((*iter)->nCategory) < MAX_FUNCCAT)
677 aCatLists[(*iter)->nCategory]->push_back(*iter);
680 // Initialize iterators
681 pCurCatListIter = aCatLists[0]->end();
682 pCurCatListEnd = aCatLists[0]->end();
685 ScFunctionMgr::~ScFunctionMgr()
687 for (sal_uInt16 i = 0; i < MAX_FUNCCAT; ++i)
688 delete aCatLists[i];
691 const ScFuncDesc* ScFunctionMgr::Get( const OUString& rFName ) const
693 const ScFuncDesc* pDesc = NULL;
694 if (rFName.getLength() <= pFuncList->GetMaxFuncNameLen())
696 ::boost::scoped_ptr<ScFuncDesc> dummy(new ScFuncDesc);
697 dummy->pFuncName = new OUString(rFName);
698 ::std::vector<const ScFuncDesc*>::iterator lower =
699 ::std::lower_bound(aCatLists[0]->begin(), aCatLists[0]->end(),
700 static_cast<const ScFuncDesc*>(dummy.get()), ScFuncDesc::compareByName);
702 if(rFName.equalsIgnoreAsciiCase(*(*lower)->pFuncName))
703 pDesc = *lower;
705 return pDesc;
708 const ScFuncDesc* ScFunctionMgr::Get( sal_uInt16 nFIndex ) const
710 const ScFuncDesc* pDesc;
711 for (pDesc = First(0); pDesc; pDesc = Next())
712 if (pDesc->nFIndex == nFIndex)
713 break;
714 return pDesc;
717 const ScFuncDesc* ScFunctionMgr::First( sal_uInt16 nCategory ) const
719 OSL_ENSURE( nCategory < MAX_FUNCCAT, "Unknown category" );
720 const ScFuncDesc* pDesc = NULL;
721 if ( nCategory < MAX_FUNCCAT )
723 pCurCatListIter = aCatLists[nCategory]->begin();
724 pCurCatListEnd = aCatLists[nCategory]->end();
725 pDesc = *pCurCatListIter;
727 else
729 pCurCatListIter = aCatLists[0]->end();
730 pCurCatListEnd = aCatLists[0]->end();
732 return pDesc;
735 const ScFuncDesc* ScFunctionMgr::Next() const
737 const ScFuncDesc* pDesc = NULL;
738 if ( pCurCatListIter != pCurCatListEnd )
740 if ( (++pCurCatListIter) != pCurCatListEnd )
742 pDesc = *pCurCatListIter;
745 return pDesc;
748 sal_uInt32 ScFunctionMgr::getCount() const
750 return MAX_FUNCCAT - 1;
753 const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
755 if ( nCategory < (MAX_FUNCCAT-1) )
757 if (m_aCategories.find(nCategory) == m_aCategories.end())
758 m_aCategories[nCategory].reset(new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory)); // aCatLists[0] is "all"
759 return m_aCategories[nCategory].get();
761 return NULL;
764 const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const OUString& _sFunctionName) const
766 return Get(_sFunctionName);
769 void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const
771 const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
772 sal_uInt16 nLRUFuncCount = std::min( rAppOpt.GetLRUFuncListCount(), (sal_uInt16)LRU_MAX );
773 sal_uInt16* pLRUListIds = rAppOpt.GetLRUFuncList();
774 _rLastRUFunctions.clear();
776 if ( pLRUListIds )
778 for (sal_uInt16 i = 0; i < nLRUFuncCount; ++i)
780 _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) );
785 OUString ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
787 if ( _nCategoryNumber > SC_FUNCGROUP_COUNT )
789 OSL_FAIL("Invalid category number!");
790 return OUString();
793 boost::scoped_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) );
794 return SC_RESSTR(static_cast<sal_uInt16>(_nCategoryNumber));
797 sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
799 switch(_eToken)
801 case eOk:
802 return ScCompiler::GetNativeSymbolChar(ocOpen);
803 case eClose:
804 return ScCompiler::GetNativeSymbolChar(ocClose);
805 case eSep:
806 return ScCompiler::GetNativeSymbolChar(ocSep);
807 case eArrayOpen:
808 return ScCompiler::GetNativeSymbolChar(ocArrayOpen);
809 case eArrayClose:
810 return ScCompiler::GetNativeSymbolChar(ocArrayClose);
812 return 0;
815 // class ScFuncRes:
817 ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
818 : Resource(aRes)
820 rbSuppressed = (bool)GetNum();
821 pDesc->nCategory = GetNum();
822 pDesc->sHelpId = ReadByteStringRes();
823 pDesc->nArgCount = GetNum();
824 sal_uInt16 nArgs = pDesc->nArgCount;
825 if (nArgs >= PAIRED_VAR_ARGS)
826 nArgs -= PAIRED_VAR_ARGS - 2;
827 else if (nArgs >= VAR_ARGS)
828 nArgs -= VAR_ARGS - 1;
829 if (nArgs)
831 pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
832 for (sal_uInt16 i = 0; i < nArgs; ++i)
834 pDesc->pDefArgFlags[i].bOptional = (bool)GetNum();
837 // Need to read the value from the resource even if nArgs==0 to advance the
838 // resource position pointer, so this can't be in the if(nArgs) block above.
839 sal_uInt16 nSuppressed = GetNum();
840 if (nSuppressed)
842 if (nSuppressed > nArgs)
844 SAL_WARN("sc.core", "ScFuncRes: suppressed parameters count mismatch on OpCode " <<
845 aRes.GetId() << ": suppressed " << nSuppressed << " > params " << nArgs);
846 nSuppressed = nArgs; // sanitize
848 for (sal_uInt16 i = 0; i < nSuppressed; ++i)
850 sal_uInt16 nParam = GetNum();
851 if (nParam < nArgs)
853 if (pDesc->nArgCount >= PAIRED_VAR_ARGS && nParam >= nArgs-2)
855 SAL_WARN("sc.core", "ScFuncRes: PAIRED_VAR_ARGS parameters can't be suppressed, on OpCode " <<
856 aRes.GetId() << ": param " << nParam << " >= arg " << nArgs << "-2");
858 else if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
860 SAL_WARN("sc.core", "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode " <<
861 aRes.GetId() << ": param " << nParam << " == arg " << nArgs << "-1");
863 else
865 pDesc->pDefArgFlags[nParam].bSuppress = true;
866 pDesc->bHasSuppressedArgs = true;
869 else
871 SAL_WARN("sc.core", "ScFuncRes: suppressed parameter exceeds count on OpCode " <<
872 aRes.GetId() << ": param " << nParam << " >= args " << nArgs);
877 pDesc->pFuncName = new OUString( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId())));
878 pDesc->pFuncDesc = new OUString( SC_RESSTR(1) );
880 if (nArgs)
882 pDesc->maDefArgNames.clear();
883 pDesc->maDefArgNames.resize(nArgs);
884 pDesc->maDefArgDescs.clear();
885 pDesc->maDefArgDescs.resize(nArgs);
886 for (sal_uInt16 i = 0; i < nArgs; ++i)
888 pDesc->maDefArgNames[i] = SC_RESSTR(2*(i+1) );
889 pDesc->maDefArgDescs[i] = SC_RESSTR(2*(i+1)+1);
893 FreeResource();
896 sal_uInt16 ScFuncRes::GetNum()
898 return ReadShortRes();
901 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */