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 "funcdesc.hxx"
22 #include "addincol.hxx"
23 #include "appoptio.hxx"
24 #include "callform.hxx"
25 #include "compiler.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>
38 #include <boost/scoped_ptr.hpp>
40 class ScFuncRes
: public Resource
43 ScFuncRes( ResId
&, ScFuncDesc
*, bool & rbSuppressed
);
49 class ScResourcePublisher
: public Resource
52 void FreeResource() { Resource::FreeResource(); }
54 ScResourcePublisher( const ScResId
& rId
) : Resource( rId
) {}
55 ~ScResourcePublisher() { FreeResource(); }
56 bool IsAvailableRes( const ResId
& rId
) const
57 { return Resource::IsAvailableRes( rId
); }
63 ScFuncDesc::ScFuncDesc() :
71 bHasSuppressedArgs(false)
74 ScFuncDesc::~ScFuncDesc()
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;
88 delete [] pDefArgFlags
;
91 maDefArgNames
.clear();
92 maDefArgDescs
.clear();
105 bHasSuppressedArgs
= false;
108 OUString
ScFuncDesc::GetParamList() const
110 OUString
sep(ScCompiler::GetNativeSymbol(ocSep
));
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
)
127 aSig
.append(maDefArgNames
[i
]);
128 if ( i
!= nArgCount
-1 )
131 aSig
.appendAscii( " " );
135 // If only suppressed parameters follow the last added parameter,
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
]);
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
]);
161 aSig
.append(maDefArgNames
[nFix
]);
164 aSig
.appendAscii(" ... ");
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
]);
175 aSig
.appendAscii( " " );
179 aSig
.append(maDefArgNames
[nFix
]);
182 aSig
.append(maDefArgNames
[nFix
+1]);
185 aSig
.appendAscii( " " );
186 aSig
.append(maDefArgNames
[nFix
]);
189 aSig
.append(maDefArgNames
[nFix
+1]);
192 aSig
.appendAscii( " ... " );
196 return aSig
.makeStringAndClear();
199 OUString
ScFuncDesc::getSignature() const
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( ")" );
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
;
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
);
240 while( aIter
!= aEnd
&& !aIter
->isEmpty() )
242 aFormula
.append( sep
);
243 aFormula
.append( *aIter
);
248 aFormula
.appendAscii( ")" );
250 return aFormula
.makeStringAndClear();
253 sal_uInt16
ScFuncDesc::GetSuppressedArgCount() const
255 if (!bHasSuppressedArgs
|| !pDefArgFlags
)
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
)
269 if (nArgCount
>= PAIRED_VAR_ARGS
)
270 nCount
+= PAIRED_VAR_ARGS
- 2;
271 else if (nArgCount
>= VAR_ARGS
)
272 nCount
+= VAR_ARGS
- 1;
276 OUString
ScFuncDesc::getFunctionName() const
284 const formula::IFunctionCategory
* ScFuncDesc::getCategory() const
286 return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory
);
289 OUString
ScFuncDesc::getDescription() const
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())
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 );
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
357 sal_uInt32
ScFuncDesc::getParameterCount() const
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
)
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.
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
);
462 aBuf
.appendAscii("( AddIn: ");
463 aBuf
.append(pAddInFuncData
->GetModuleName());
464 aBuf
.appendAscii(" )");
465 pDesc
->pFuncDesc
= new OUString(aBuf
.makeStringAndClear());
467 pDesc
->nArgCount
= 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
;
484 switch (pAddInFuncData
->GetParamType(j
+1))
486 case ParamType::PTR_DOUBLE
:
487 pDesc
->maDefArgNames
[j
] = aDefArgNameValue
;
489 case ParamType::PTR_STRING
:
490 pDesc
->maDefArgNames
[j
] = aDefArgNameString
;
492 case ParamType::PTR_DOUBLE_ARR
:
493 pDesc
->maDefArgNames
[j
] = aDefArgNameValues
;
495 case ParamType::PTR_STRING_ARR
:
496 pDesc
->maDefArgNames
[j
] = aDefArgNameStrings
;
498 case ParamType::PTR_CELL_ARR
:
499 pDesc
->maDefArgNames
[j
] = aDefArgNameCells
;
502 pDesc
->maDefArgNames
[j
] = aDefArgNameNone
;
506 if ( !aArgDesc
.isEmpty() )
507 pDesc
->maDefArgDescs
[j
] = aArgDesc
;
510 switch (pAddInFuncData
->GetParamType(j
+1))
512 case ParamType::PTR_DOUBLE
:
513 pDesc
->maDefArgDescs
[j
] = aDefArgDescValue
;
515 case ParamType::PTR_STRING
:
516 pDesc
->maDefArgDescs
[j
] = aDefArgDescString
;
518 case ParamType::PTR_DOUBLE_ARR
:
519 pDesc
->maDefArgDescs
[j
] = aDefArgDescValues
;
521 case ParamType::PTR_STRING_ARR
:
522 pDesc
->maDefArgDescs
[j
] = aDefArgDescStrings
;
524 case ParamType::PTR_CELL_ARR
:
525 pDesc
->maDefArgDescs
[j
] = aDefArgDescCells
;
528 pDesc
->maDefArgDescs
[j
] = aDefArgDescNone
;
535 tmpFuncList
.push_back(pDesc
);
536 nStrLen
= (*(pDesc
->pFuncName
)).getLength();
537 if ( nStrLen
> nMaxFuncNameLen
)
538 nMaxFuncNameLen
= nStrLen
;
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
;
561 //Move list to vector for better random access performance
562 ::std::vector
<const ScFuncDesc
*> tmp(tmpFuncList
.begin(), tmpFuncList
.end());
564 aFunctionList
.swap(tmp
);
566 //Initialize iterator
567 aFunctionListIter
= aFunctionList
.end();
570 ScFunctionList::~ScFunctionList()
572 const ScFuncDesc
* pDesc
= First();
580 const ScFuncDesc
* ScFunctionList::First()
582 const ScFuncDesc
* pDesc
= NULL
;
583 aFunctionListIter
= aFunctionList
.begin();
584 if(aFunctionListIter
!= aFunctionList
.end())
585 pDesc
= *aFunctionListIter
;
590 const ScFuncDesc
* ScFunctionList::Next()
592 const ScFuncDesc
* pDesc
= NULL
;
593 if(aFunctionListIter
!= aFunctionList
.end())
595 if((++aFunctionListIter
) != aFunctionList
.end())
596 pDesc
= *aFunctionListIter
;
601 const ScFuncDesc
* ScFunctionList::GetFunction( sal_uInt32 nIndex
) const
603 const ScFuncDesc
* pDesc
= NULL
;
604 if(nIndex
< aFunctionList
.size())
605 pDesc
= aFunctionList
.at(nIndex
);
610 // class ScFunctionCategory:
612 sal_uInt32
ScFunctionCategory::getCount() const
614 return m_pCategory
->size();
617 const formula::IFunctionManager
* ScFunctionCategory::getFunctionManager() const
622 OUString
ScFunctionCategory::getName() const
624 if ( m_sName
.isEmpty() )
625 m_sName
= ScFunctionMgr::GetCategoryName(m_nCategory
+1);
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
);
637 sal_uInt32
ScFunctionCategory::getNumber() const
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
)
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
))
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
)
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
;
729 pCurCatListIter
= aCatLists
[0]->end();
730 pCurCatListEnd
= aCatLists
[0]->end();
735 const ScFuncDesc
* ScFunctionMgr::Next() const
737 const ScFuncDesc
* pDesc
= NULL
;
738 if ( pCurCatListIter
!= pCurCatListEnd
)
740 if ( (++pCurCatListIter
) != pCurCatListEnd
)
742 pDesc
= *pCurCatListIter
;
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();
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();
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!");
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
802 return ScCompiler::GetNativeSymbolChar(ocOpen
);
804 return ScCompiler::GetNativeSymbolChar(ocClose
);
806 return ScCompiler::GetNativeSymbolChar(ocSep
);
808 return ScCompiler::GetNativeSymbolChar(ocArrayOpen
);
810 return ScCompiler::GetNativeSymbolChar(ocArrayClose
);
817 ScFuncRes::ScFuncRes( ResId
&aRes
, ScFuncDesc
* pDesc
, bool & rbSuppressed
)
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;
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();
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();
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");
865 pDesc
->pDefArgFlags
[nParam
].bSuppress
= true;
866 pDesc
->bHasSuppressedArgs
= true;
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) );
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);
896 sal_uInt16
ScFuncRes::GetNum()
898 return ReadShortRes();
901 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */