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
);
50 class ScResourcePublisher
: public Resource
53 void FreeResource() { Resource::FreeResource(); }
55 ScResourcePublisher( const ScResId
& rId
) : Resource( rId
) {}
56 ~ScResourcePublisher() { FreeResource(); }
57 bool IsAvailableRes( const ResId
& rId
) const
58 { return Resource::IsAvailableRes( rId
); }
62 //========================================================================
64 //========================================================================
66 ScFuncDesc::ScFuncDesc() :
76 bHasSuppressedArgs(false)
79 ScFuncDesc::~ScFuncDesc()
84 void ScFuncDesc::Clear()
86 sal_uInt16 nArgs
= nArgCount
;
87 if (nArgs
>= PAIRED_VAR_ARGS
)
88 nArgs
-= PAIRED_VAR_ARGS
- 2;
89 else if (nArgs
>= VAR_ARGS
)
90 nArgs
-= VAR_ARGS
- 1;
93 for (sal_uInt16 i
=0; i
<nArgs
; i
++ )
95 delete ppDefArgNames
[i
];
96 delete ppDefArgDescs
[i
];
98 delete [] ppDefArgNames
;
99 delete [] ppDefArgDescs
;
100 delete [] pDefArgFlags
;
103 ppDefArgNames
= NULL
;
104 ppDefArgDescs
= NULL
;
117 bHasSuppressedArgs
= false;
120 OUString
ScFuncDesc::GetParamList() const
122 OUString
sep(ScCompiler::GetNativeSymbol(ocSep
));
128 if ( nArgCount
< VAR_ARGS
)
130 sal_uInt16 nLastSuppressed
= nArgCount
;
131 sal_uInt16 nLastAdded
= nArgCount
;
132 for ( sal_uInt16 i
=0; i
<nArgCount
; i
++ )
134 if (pDefArgFlags
[i
].bSuppress
)
139 aSig
.append(*(ppDefArgNames
[i
]));
140 if ( i
!= nArgCount
-1 )
143 aSig
.appendAscii( " " );
147 // If only suppressed parameters follow the last added parameter,
149 if (nLastSuppressed
< nArgCount
&& nLastAdded
< nLastSuppressed
&&
150 aSig
.getLength() >= 2)
151 aSig
.setLength(aSig
.getLength() - 2);
153 else if ( nArgCount
< PAIRED_VAR_ARGS
)
155 sal_uInt16 nFix
= nArgCount
- VAR_ARGS
;
156 for ( sal_uInt16 nArg
= 0; nArg
< nFix
; nArg
++ )
158 if (!pDefArgFlags
[nArg
].bSuppress
)
160 aSig
.append(*(ppDefArgNames
[nArg
]));
162 aSig
.appendAscii( " " );
165 /* NOTE: Currently there are no suppressed var args parameters. If
166 * there were, we'd have to cope with it here and above for the fix
167 * parameters. For now parameters are always added, so no special
168 * treatment of a trailing "; " necessary. */
169 aSig
.append(*(ppDefArgNames
[nFix
]));
173 aSig
.append(*(ppDefArgNames
[nFix
]));
176 aSig
.appendAscii(" ... ");
180 sal_uInt16 nFix
= nArgCount
- PAIRED_VAR_ARGS
;
181 for ( sal_uInt16 nArg
= 0; nArg
< nFix
; nArg
++ )
183 if (!pDefArgFlags
[nArg
].bSuppress
)
185 aSig
.append(*(ppDefArgNames
[nArg
]));
187 aSig
.appendAscii( " " );
191 aSig
.append(*(ppDefArgNames
[nFix
]));
193 aSig
.appendAscii( ", " );
194 aSig
.append(*(ppDefArgNames
[nFix
+1]));
197 aSig
.appendAscii( " " );
198 aSig
.append(*(ppDefArgNames
[nFix
]));
200 aSig
.appendAscii( ", " );
201 aSig
.append(*(ppDefArgNames
[nFix
+1]));
204 aSig
.appendAscii( " ... " );
208 return aSig
.makeStringAndClear();
211 OUString
ScFuncDesc::getSignature() const
217 aSig
.append(*pFuncName
);
219 OUString aParamList
= GetParamList();
220 if( !aParamList
.isEmpty() )
222 aSig
.appendAscii( "( " );
223 aSig
.append(aParamList
);
224 // U+00A0 (NBSP) prevents automatic line break
225 aSig
.append( static_cast< sal_Unicode
>(0xA0) );
226 aSig
.appendAscii( ")" );
229 aSig
.appendAscii( "()" );
231 return aSig
.makeStringAndClear();
234 OUString
ScFuncDesc::getFormula( const ::std::vector
< OUString
>& _aArguments
) const
236 OUString sep
= ScCompiler::GetNativeSymbol(ocSep
);
238 OUStringBuffer aFormula
;
242 aFormula
.append( *pFuncName
);
244 aFormula
.appendAscii( "(" );
245 ::std::vector
< OUString
>::const_iterator aIter
= _aArguments
.begin();
246 ::std::vector
< OUString
>::const_iterator aEnd
= _aArguments
.end();
248 if ( nArgCount
> 0 && aIter
!= aEnd
)
250 bool bLastArg
= aIter
->isEmpty();
252 while( aIter
!= aEnd
&& !bLastArg
)
254 aFormula
.append( *(aIter
) );
255 if ( aIter
!= (aEnd
-1) )
257 bLastArg
= (aIter
+1)->isEmpty();
259 aFormula
.append( sep
);
266 aFormula
.appendAscii( ")" );
268 return aFormula
.makeStringAndClear();
271 sal_uInt16
ScFuncDesc::GetSuppressedArgCount() const
273 if (!bHasSuppressedArgs
|| !pDefArgFlags
)
276 sal_uInt16 nArgs
= nArgCount
;
277 if (nArgs
>= PAIRED_VAR_ARGS
)
278 nArgs
-= PAIRED_VAR_ARGS
- 2;
279 else if (nArgs
>= VAR_ARGS
)
280 nArgs
-= VAR_ARGS
- 1;
281 sal_uInt16 nCount
= nArgs
;
282 for (sal_uInt16 i
=0; i
< nArgs
; ++i
)
284 if (pDefArgFlags
[i
].bSuppress
)
287 if (nArgCount
>= PAIRED_VAR_ARGS
)
288 nCount
+= PAIRED_VAR_ARGS
- 2;
289 else if (nArgCount
>= VAR_ARGS
)
290 nCount
+= VAR_ARGS
- 1;
294 OUString
ScFuncDesc::getFunctionName() const
302 const formula::IFunctionCategory
* ScFuncDesc::getCategory() const
304 return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory
);
307 OUString
ScFuncDesc::getDescription() const
315 xub_StrLen
ScFuncDesc::getSuppressedArgumentCount() const
317 return GetSuppressedArgCount();
320 void ScFuncDesc::fillVisibleArgumentMapping(::std::vector
<sal_uInt16
>& _rArguments
) const
322 if (!bHasSuppressedArgs
|| !pDefArgFlags
)
324 _rArguments
.resize( nArgCount
);
325 ::std::vector
<sal_uInt16
>::iterator iter
= _rArguments
.begin();
326 sal_uInt16 value
= 0;
327 while (iter
!= _rArguments
.end())
331 _rArguments
.reserve( nArgCount
);
332 sal_uInt16 nArgs
= nArgCount
;
333 if (nArgs
>= PAIRED_VAR_ARGS
)
334 nArgs
-= PAIRED_VAR_ARGS
- 2;
335 else if (nArgs
>= VAR_ARGS
)
336 nArgs
-= VAR_ARGS
- 1;
337 for (sal_uInt16 i
=0; i
< nArgs
; ++i
)
339 if (!pDefArgFlags
[i
].bSuppress
)
340 _rArguments
.push_back(i
);
344 void ScFuncDesc::initArgumentInfo() const
346 // get the full argument description
347 // (add-in has to be instantiated to get the type information)
349 if ( bIncomplete
&& pFuncName
)
351 ScUnoAddInCollection
& rAddIns
= *ScGlobal::GetAddInCollection();
352 OUString
aIntName(rAddIns
.FindFunction( *pFuncName
, true )); // pFuncName is upper-case
354 if ( !aIntName
.isEmpty() )
356 // GetFuncData with bComplete=true loads the component and updates
357 // the global function list if needed.
359 rAddIns
.GetFuncData( aIntName
, true );
364 OSL_FAIL( "couldn't initialize add-in function" );
365 const_cast<ScFuncDesc
*>(this)->bIncomplete
= false; // even if there was an error, don't try again
370 OString
ScFuncDesc::getHelpId() const
375 sal_uInt32
ScFuncDesc::getParameterCount() const
380 OUString
ScFuncDesc::getParameterName(sal_uInt32 _nPos
) const
382 return *(ppDefArgNames
[_nPos
]);
385 OUString
ScFuncDesc::getParameterDescription(sal_uInt32 _nPos
) const
387 return *(ppDefArgDescs
[_nPos
]);
390 bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos
) const
392 return pDefArgFlags
[_nPos
].bOptional
;
395 bool ScFuncDesc::compareByName(const ScFuncDesc
* a
, const ScFuncDesc
* b
)
397 return (ScGlobal::GetCaseCollator()->compareString(*a
->pFuncName
, *b
->pFuncName
) < 0);
400 //===================================================================
401 // class ScFunctionList:
402 //===================================================================
404 ScFunctionList::ScFunctionList() :
405 nMaxFuncNameLen ( 0 )
407 ScFuncDesc
* pDesc
= NULL
;
408 xub_StrLen nStrLen
= 0;
409 ::std::list
<ScFuncDesc
*> tmpFuncList
;
410 sal_uInt16 nDescBlock
[] =
412 RID_SC_FUNCTION_DESCRIPTIONS1
,
413 RID_SC_FUNCTION_DESCRIPTIONS2
416 for (sal_uInt16 k
= 0; k
< SAL_N_ELEMENTS(nDescBlock
); ++k
)
418 SAL_WNODEPRECATED_DECLARATIONS_PUSH
419 ::std::auto_ptr
<ScResourcePublisher
> pBlock( new ScResourcePublisher( ScResId( nDescBlock
[k
] ) ) );
420 SAL_WNODEPRECATED_DECLARATIONS_POP
421 // Browse for all possible OpCodes. This is not the fastest method, but
422 // otherwise the sub resources within the resource blocks and the
423 // resource blocks themselfs would had to be ordered according to
424 // OpCodes, which is utopian..
425 for (sal_uInt16 i
= 0; i
<= SC_OPCODE_LAST_OPCODE_ID
; ++i
)
428 aRes
.SetRT(RSC_RESOURCE
);
429 // Sub resource of OpCode available?
430 if (pBlock
->IsAvailableRes(aRes
))
432 pDesc
= new ScFuncDesc
;
433 bool bSuppressed
= false;
434 ScFuncRes
aSubRes( aRes
, pDesc
, bSuppressed
);
435 // Instead of dealing with this exceptional case at 1001 places
436 // we simply don't add an entirely suppressed function to the
437 // list and delete it.
443 tmpFuncList
.push_back(pDesc
);
445 nStrLen
= (*(pDesc
->pFuncName
)).getLength();
446 if (nStrLen
> nMaxFuncNameLen
)
447 nMaxFuncNameLen
= nStrLen
;
453 sal_uInt16 nNextId
= SC_OPCODE_LAST_OPCODE_ID
+ 1; // FuncID for AddIn functions
455 // Interpretation of AddIn list
456 OUString aDefArgNameValue
= "value";
457 OUString aDefArgNameString
= "string";
458 OUString aDefArgNameValues
= "values";
459 OUString aDefArgNameStrings
= "strings";
460 OUString aDefArgNameCells
= "cells";
461 OUString aDefArgNameNone
= "none";
462 OUString aDefArgDescValue
= "a value";
463 OUString aDefArgDescString
= "a string";
464 OUString aDefArgDescValues
= "array of values";
465 OUString aDefArgDescStrings
= "array of strings";
466 OUString aDefArgDescCells
= "range of cells";
467 OUString aDefArgDescNone
= "none";
469 OUString aArgName
, aArgDesc
;
470 const FuncCollection
& rFuncColl
= *ScGlobal::GetFuncCollection();
471 FuncCollection::const_iterator it
= rFuncColl
.begin(), itEnd
= rFuncColl
.end();
472 for (; it
!= itEnd
; ++it
)
474 const FuncData
* pAddInFuncData
= it
->second
;
475 pDesc
= new ScFuncDesc
;
476 sal_uInt16 nArgs
= pAddInFuncData
->GetParamCount() - 1;
477 pAddInFuncData
->getParamDesc( aArgName
, aArgDesc
, 0 );
478 pDesc
->nFIndex
= nNextId
++; // ??? OpCode vergeben
479 pDesc
->nCategory
= ID_FUNCTION_GRP_ADDINS
;
480 pDesc
->pFuncName
= new OUString(pAddInFuncData
->GetInternalName().toAsciiUpperCase());
482 OUStringBuffer
aBuf(aArgDesc
);
484 aBuf
.appendAscii("( AddIn: ");
485 aBuf
.append(pAddInFuncData
->GetModuleName());
486 aBuf
.appendAscii(" )");
487 pDesc
->pFuncDesc
= new OUString(aBuf
.makeStringAndClear());
489 pDesc
->nArgCount
= nArgs
;
492 pDesc
->pDefArgFlags
= new ScFuncDesc::ParameterFlags
[nArgs
];
493 pDesc
->ppDefArgNames
= new OUString
*[nArgs
];
494 pDesc
->ppDefArgDescs
= new OUString
*[nArgs
];
495 for (sal_uInt16 j
= 0; j
< nArgs
; ++j
)
497 pDesc
->pDefArgFlags
[j
].bOptional
= false;
498 pDesc
->pDefArgFlags
[j
].bSuppress
= false;
499 pAddInFuncData
->getParamDesc( aArgName
, aArgDesc
, j
+1 );
500 if ( !aArgName
.isEmpty() )
501 pDesc
->ppDefArgNames
[j
] = new OUString( aArgName
);
504 switch (pAddInFuncData
->GetParamType(j
+1))
507 pDesc
->ppDefArgNames
[j
] = new OUString( aDefArgNameValue
);
510 pDesc
->ppDefArgNames
[j
] = new OUString( aDefArgNameString
);
513 pDesc
->ppDefArgNames
[j
] = new OUString( aDefArgNameValues
);
516 pDesc
->ppDefArgNames
[j
] = new OUString( aDefArgNameStrings
);
519 pDesc
->ppDefArgNames
[j
] = new OUString( aDefArgNameCells
);
522 pDesc
->ppDefArgNames
[j
] = new OUString( aDefArgNameNone
);
526 if ( !aArgDesc
.isEmpty() )
527 pDesc
->ppDefArgDescs
[j
] = new OUString( aArgDesc
);
530 switch (pAddInFuncData
->GetParamType(j
+1))
533 pDesc
->ppDefArgDescs
[j
] = new OUString( aDefArgDescValue
);
536 pDesc
->ppDefArgDescs
[j
] = new OUString( aDefArgDescString
);
539 pDesc
->ppDefArgDescs
[j
] = new OUString( aDefArgDescValues
);
542 pDesc
->ppDefArgDescs
[j
] = new OUString( aDefArgDescStrings
);
545 pDesc
->ppDefArgDescs
[j
] = new OUString( aDefArgDescCells
);
548 pDesc
->ppDefArgDescs
[j
] = new OUString( aDefArgDescNone
);
555 tmpFuncList
.push_back(pDesc
);
556 nStrLen
= (*(pDesc
->pFuncName
)).getLength();
557 if ( nStrLen
> nMaxFuncNameLen
)
558 nMaxFuncNameLen
= nStrLen
;
563 ScUnoAddInCollection
* pUnoAddIns
= ScGlobal::GetAddInCollection();
564 long nUnoCount
= pUnoAddIns
->GetFuncCount();
565 for (long nFunc
=0; nFunc
<nUnoCount
; nFunc
++)
567 pDesc
= new ScFuncDesc
;
568 pDesc
->nFIndex
= nNextId
++;
570 if ( pUnoAddIns
->FillFunctionDesc( nFunc
, *pDesc
) )
572 tmpFuncList
.push_back(pDesc
);
573 nStrLen
= (*(pDesc
->pFuncName
)).getLength();
574 if (nStrLen
> nMaxFuncNameLen
)
575 nMaxFuncNameLen
= nStrLen
;
581 //Move list to vector for better random access performance
582 ::std::vector
<const ScFuncDesc
*> tmp(tmpFuncList
.begin(), tmpFuncList
.end());
584 aFunctionList
.swap(tmp
);
586 //Initialize iterator
587 aFunctionListIter
= aFunctionList
.end();
590 ScFunctionList::~ScFunctionList()
592 const ScFuncDesc
* pDesc
= First();
600 const ScFuncDesc
* ScFunctionList::First()
602 const ScFuncDesc
* pDesc
= NULL
;
603 aFunctionListIter
= aFunctionList
.begin();
604 if(aFunctionListIter
!= aFunctionList
.end())
605 pDesc
= *aFunctionListIter
;
610 const ScFuncDesc
* ScFunctionList::Next()
612 const ScFuncDesc
* pDesc
= NULL
;
613 if(aFunctionListIter
!= aFunctionList
.end())
615 if((++aFunctionListIter
) != aFunctionList
.end())
616 pDesc
= *aFunctionListIter
;
621 const ScFuncDesc
* ScFunctionList::GetFunction( sal_uInt32 nIndex
) const
623 const ScFuncDesc
* pDesc
= NULL
;
624 if(nIndex
< aFunctionList
.size())
625 pDesc
= aFunctionList
.at(nIndex
);
630 //===================================================================
631 // class ScFunctionCategory:
632 //===================================================================
634 sal_uInt32
ScFunctionCategory::getCount() const
636 return m_pCategory
->size();
639 const formula::IFunctionManager
* ScFunctionCategory::getFunctionManager() const
644 OUString
ScFunctionCategory::getName() const
646 if ( m_sName
.isEmpty() )
647 m_sName
= ScFunctionMgr::GetCategoryName(m_nCategory
+1);
651 const formula::IFunctionDescription
* ScFunctionCategory::getFunction(sal_uInt32 _nPos
) const
653 const ScFuncDesc
* pDesc
= NULL
;
654 if(_nPos
< m_pCategory
->size())
655 pDesc
= m_pCategory
->at(_nPos
);
659 sal_uInt32
ScFunctionCategory::getNumber() const
664 //========================================================================
665 // class ScFunctionMgr:
666 //========================================================================
668 ScFunctionMgr::ScFunctionMgr() :
669 pFuncList( ScGlobal::GetStarCalcFunctionList() )
671 OSL_ENSURE( pFuncList
, "Functionlist not found." );
672 sal_uInt32 catCount
[MAX_FUNCCAT
] = {0};
674 aCatLists
[0] = new ::std::vector
<const ScFuncDesc
*>();
675 aCatLists
[0]->reserve(pFuncList
->GetCount());
677 // Retrieve all functions, store in cumulative ("All") category, and count
678 // number of functions in each category
679 for(const ScFuncDesc
* pDesc
= pFuncList
->First(); pDesc
; pDesc
= pFuncList
->Next())
681 OSL_ENSURE((pDesc
->nCategory
) < MAX_FUNCCAT
, "Unknown category");
682 if ((pDesc
->nCategory
) < MAX_FUNCCAT
)
683 ++catCount
[pDesc
->nCategory
];
684 aCatLists
[0]->push_back(pDesc
);
687 // Sort functions in cumulative category by name
688 ::std::sort(aCatLists
[0]->begin(), aCatLists
[0]->end(), ScFuncDesc::compareByName
);
690 // Allocate correct amount of space for categories
691 for (sal_uInt16 i
= 1; i
< MAX_FUNCCAT
; ++i
)
693 aCatLists
[i
] = new ::std::vector
<const ScFuncDesc
*>();
694 aCatLists
[i
]->reserve(catCount
[i
]);
697 // Fill categories with the corresponding functions (still sorted by name)
698 for(::std::vector
<const ScFuncDesc
*>::iterator iter
= aCatLists
[0]->begin(); iter
!=aCatLists
[0]->end(); ++iter
)
700 if (((*iter
)->nCategory
) < MAX_FUNCCAT
)
701 aCatLists
[(*iter
)->nCategory
]->push_back(*iter
);
704 // Initialize iterators
705 pCurCatListIter
= aCatLists
[0]->end();
706 pCurCatListEnd
= aCatLists
[0]->end();
709 ScFunctionMgr::~ScFunctionMgr()
711 for (sal_uInt16 i
= 0; i
< MAX_FUNCCAT
; ++i
)
715 const ScFuncDesc
* ScFunctionMgr::Get( const OUString
& rFName
) const
717 const ScFuncDesc
* pDesc
= NULL
;
718 if (rFName
.getLength() <= pFuncList
->GetMaxFuncNameLen())
720 ::boost::scoped_ptr
<ScFuncDesc
> dummy(new ScFuncDesc
);
721 dummy
->pFuncName
= new OUString(rFName
);
722 ::std::vector
<const ScFuncDesc
*>::iterator lower
=
723 ::std::lower_bound(aCatLists
[0]->begin(), aCatLists
[0]->end(),
724 static_cast<const ScFuncDesc
*>(dummy
.get()), ScFuncDesc::compareByName
);
726 if(rFName
.equalsIgnoreAsciiCase(*(*lower
)->pFuncName
))
732 const ScFuncDesc
* ScFunctionMgr::Get( sal_uInt16 nFIndex
) const
734 const ScFuncDesc
* pDesc
;
735 for (pDesc
= First(0); pDesc
; pDesc
= Next())
736 if (pDesc
->nFIndex
== nFIndex
)
741 const ScFuncDesc
* ScFunctionMgr::First( sal_uInt16 nCategory
) const
743 OSL_ENSURE( nCategory
< MAX_FUNCCAT
, "Unknown category" );
744 const ScFuncDesc
* pDesc
= NULL
;
745 if ( nCategory
< MAX_FUNCCAT
)
747 pCurCatListIter
= aCatLists
[nCategory
]->begin();
748 pCurCatListEnd
= aCatLists
[nCategory
]->end();
749 pDesc
= *pCurCatListIter
;
753 pCurCatListIter
= aCatLists
[0]->end();
754 pCurCatListEnd
= aCatLists
[0]->end();
759 const ScFuncDesc
* ScFunctionMgr::Next() const
761 const ScFuncDesc
* pDesc
= NULL
;
762 if ( pCurCatListIter
!= pCurCatListEnd
)
764 if ( (++pCurCatListIter
) != pCurCatListEnd
)
766 pDesc
= *pCurCatListIter
;
772 sal_uInt32
ScFunctionMgr::getCount() const
774 return MAX_FUNCCAT
- 1;
777 const formula::IFunctionCategory
* ScFunctionMgr::getCategory(sal_uInt32 nCategory
) const
779 formula::IFunctionCategory
* pRet
= NULL
;
780 if ( nCategory
< (MAX_FUNCCAT
-1) )
782 pRet
= new ScFunctionCategory(const_cast<ScFunctionMgr
*>(this),aCatLists
[nCategory
+1],nCategory
); // aCatLists[0] is "all"
787 const formula::IFunctionDescription
* ScFunctionMgr::getFunctionByName(const OUString
& _sFunctionName
) const
789 return Get(_sFunctionName
);
792 void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector
< const formula::IFunctionDescription
*>& _rLastRUFunctions
) const
794 const ScAppOptions
& rAppOpt
= SC_MOD()->GetAppOptions();
795 sal_uInt16 nLRUFuncCount
= std::min( rAppOpt
.GetLRUFuncListCount(), (sal_uInt16
)LRU_MAX
);
796 sal_uInt16
* pLRUListIds
= rAppOpt
.GetLRUFuncList();
800 for (sal_uInt16 i
= 0; i
< nLRUFuncCount
; ++i
)
801 _rLastRUFunctions
.push_back( Get( pLRUListIds
[i
] ) );
805 OUString
ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber
)
807 if ( _nCategoryNumber
> SC_FUNCGROUP_COUNT
)
809 OSL_FAIL("Invalid category number!");
813 SAL_WNODEPRECATED_DECLARATIONS_PUSH
814 ::std::auto_ptr
<ScResourcePublisher
> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES
) ) );
815 SAL_WNODEPRECATED_DECLARATIONS_POP
816 return SC_RESSTR(static_cast<sal_uInt16
>(_nCategoryNumber
));
819 sal_Unicode
ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken
) const
824 return ScCompiler::GetNativeSymbolChar(ocOpen
);
826 return ScCompiler::GetNativeSymbolChar(ocClose
);
828 return ScCompiler::GetNativeSymbolChar(ocSep
);
830 return ScCompiler::GetNativeSymbolChar(ocArrayOpen
);
832 return ScCompiler::GetNativeSymbolChar(ocArrayClose
);
837 //========================================================================
839 //========================================================================
841 ScFuncRes::ScFuncRes( ResId
&aRes
, ScFuncDesc
* pDesc
, bool & rbSuppressed
)
844 rbSuppressed
= (bool)GetNum();
845 pDesc
->nCategory
= GetNum();
846 pDesc
->sHelpId
= ReadByteStringRes();
847 pDesc
->nArgCount
= GetNum();
848 sal_uInt16 nArgs
= pDesc
->nArgCount
;
849 if (nArgs
>= PAIRED_VAR_ARGS
)
850 nArgs
-= PAIRED_VAR_ARGS
- 2;
851 else if (nArgs
>= VAR_ARGS
)
852 nArgs
-= VAR_ARGS
- 1;
855 pDesc
->pDefArgFlags
= new ScFuncDesc::ParameterFlags
[nArgs
];
856 for (sal_uInt16 i
= 0; i
< nArgs
; ++i
)
858 pDesc
->pDefArgFlags
[i
].bOptional
= (bool)GetNum();
861 // Need to read the value from the resource even if nArgs==0 to advance the
862 // resource position pointer, so this can't be in the if(nArgs) block above.
863 sal_uInt16 nSuppressed
= GetNum();
866 if (nSuppressed
> nArgs
)
868 OSL_TRACE( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
869 aRes
.GetId(), (int)nSuppressed
, (int)nArgs
);
870 nSuppressed
= nArgs
; // sanitize
872 for (sal_uInt16 i
= 0; i
< nSuppressed
; ++i
)
874 sal_uInt16 nParam
= GetNum();
877 if (pDesc
->nArgCount
>= PAIRED_VAR_ARGS
&& nParam
>= nArgs
-2)
879 OSL_TRACE( "ScFuncRes: PAIRED_VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d >= arg %d-2",
880 aRes
.GetId(), (int)nParam
, (int)nArgs
);
882 else if (pDesc
->nArgCount
>= VAR_ARGS
&& nParam
== nArgs
-1)
884 OSL_TRACE( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
885 aRes
.GetId(), (int)nParam
, (int)nArgs
);
889 pDesc
->pDefArgFlags
[nParam
].bSuppress
= true;
890 pDesc
->bHasSuppressedArgs
= true;
895 OSL_TRACE( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
896 aRes
.GetId(), (int)nParam
, (int)nArgs
);
901 pDesc
->pFuncName
= new OUString( ScCompiler::GetNativeSymbol( static_cast<OpCode
>( aRes
.GetId())));
902 pDesc
->pFuncDesc
= new OUString( SC_RESSTR(1) );
906 pDesc
->ppDefArgNames
= new OUString
*[nArgs
];
907 pDesc
->ppDefArgDescs
= new OUString
*[nArgs
];
908 for (sal_uInt16 i
= 0; i
< nArgs
; ++i
)
910 pDesc
->ppDefArgNames
[i
] = new OUString(SC_RESSTR(2*(i
+1) ));
911 pDesc
->ppDefArgDescs
[i
] = new OUString(SC_RESSTR(2*(i
+1)+1));
918 sal_uInt16
ScFuncRes::GetNum()
920 return ReadShortRes();
923 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */