summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/inc/funcdesc.hxx176
-rw-r--r--sc/source/core/data/funcdesc.cxx858
-rw-r--r--sc/source/core/data/global.cxx809
-rw-r--r--sc/source/core/data/makefile.mk1
4 files changed, 1001 insertions, 843 deletions
diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index 6187121e7640..ecebacba2006 100644
--- a/sc/inc/funcdesc.hxx
+++ b/sc/inc/funcdesc.hxx
@@ -34,39 +34,160 @@
* global.cxx
*/
+#include "scfuncs.hrc"
+
#include <tools/list.hxx>
-#include <tools/string.hxx>
#include <formula/IFunctionDescription.hxx>
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
#define MAX_FUNCCAT 12 /* maximum number of categories for functions */
+class ScFuncDesc;
+class ScFunctionList;
+class ScFunctionCategory;
+class ScFunctionMgr;
+
+/**
+ Stores and generates human readable descriptions for spreadsheet-functions,
+ e.g. functions used in formulas in calc
+*/
class ScFuncDesc : public formula::IFunctionDescription
{
public:
+ ScFuncDesc();
+ virtual ~ScFuncDesc();
- virtual ::rtl::OUString getFunctionName() const ;
+ /**
+ Clears the object
+
+ Deletes all objets referenced by the pointers in the class,
+ sets pointers to NULL, and all numerical variables to 0
+ */
+ void Clear();
+
+ /**
+ Fills a mapping with indexes for non-suppressed arguments
+
+ Fills mapping from visible arguments to real arguments, e.g. if of 4
+ parameters the second one is suppressed {0,2,3}. For VAR_ARGS
+ parameters only one element is added to the end of the sequence.
+
+ @param _rArgumens
+ Vector, which the indices are written to
+ */
+ virtual void fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const ;
+
+ /**
+ Returns the category of the function
+
+ @return the category of the function
+ */
virtual const formula::IFunctionCategory* getCategory() const ;
+
+ /**
+ Returns the description of the function
+
+ @return the description of the function, or an empty OUString if there is no description
+ */
virtual ::rtl::OUString getDescription() const ;
- // GetSuppressedArgCount
- virtual xub_StrLen getSuppressedArgumentCount() const ;
- /** Returns the function signature with parameters from the passed string array. */
+
+ /**
+ Returns the function signature with parameters from the passed string array.
+
+ @return function signature with parameters
+ */
virtual ::rtl::OUString getFormula(const ::std::vector< ::rtl::OUString >& _aArguments) const ;
- // GetVisibleArgMapping
- /** Returns mapping from visible arguments to real arguments, e.g. if of 4
- parameters the second one is suppressed {0,2,3}. For VAR_ARGS
- parameters only one element is added to the end of the sequence. */
- virtual void fillVisibleArgumentMapping(::std::vector<USHORT>& _rArguments) const ;
- virtual void initArgumentInfo() const;
- /** Returns the full function signature: "FUNCTIONNAME( parameter list )". */
- virtual ::rtl::OUString getSignature() const ;
+
+ /**
+ Returns the name of the function
+
+ @return the name of the function, or an empty OUString if there is no name
+ */
+ virtual ::rtl::OUString getFunctionName() const ;
+
+ /**
+ Returns the help id of the function
+
+ @return help id of the function
+ */
virtual long getHelpId() const ;
- // parameter
+ /**
+ Returns number of arguments
+
+ @return help id of the function
+ */
virtual sal_uInt32 getParameterCount() const ;
- virtual ::rtl::OUString getParameterName(sal_uInt32 _nPos) const ;
+
+ /**
+ Returns description of parameter at given position
+
+ @param _nPos
+ Position of the parameter
+
+ @return OUString description of the parameter
+ */
virtual ::rtl::OUString getParameterDescription(sal_uInt32 _nPos) const ;
+
+ /**
+ Returns name of parameter at given position
+
+ @param _nPos
+ Position of the parameter
+
+ @return OUString name of the parameter
+ */
+ virtual ::rtl::OUString getParameterName(sal_uInt32 _nPos) const ;
+
+ /**
+ Returns list of all parameter names
+
+ @return OUString containing separated list of all parameter names
+ */
+ ::rtl::OUString GetParamList() const;
+
+ /**
+ Returns the full function signature
+
+ @return OUString of the form "FUNCTIONNAME( parameter list )"
+ */
+ virtual ::rtl::OUString getSignature() const ;
+
+ /**
+ Returns the number of non-suppressed arguments
+
+ In case there are variable arguments the number of fixed non-suppressed
+ arguments plus VAR_ARGS, same as for nArgCount (variable arguments can't
+ be suppressed). The two functions are equal apart from return type and
+ name.
+
+ @return number of non-suppressed arguments
+ */
+ sal_uInt16 GetSuppressedArgCount() const;
+ virtual xub_StrLen getSuppressedArgumentCount() const ;
+
+ /**
+ Requests function data from AddInCollection
+
+ Logs error message on failure for debugging purposes
+ */
+ virtual void initArgumentInfo() const;
+
+ /**
+ Returns true if parameter at given position is optional
+
+ @param _nPos
+ Position of the parameter
+
+ @return true if optional, false if not optional
+ */
virtual bool isParameterOptional(sal_uInt32 _nPos) const ;
+
+ /**
+ Stores whether a parameter is optional or suppressed
+ */
struct ParameterFlags
{
bool bOptional :1; // Parameter is optional
@@ -76,35 +197,22 @@ public:
};
- ScFuncDesc();
- virtual ~ScFuncDesc();
-
- void Clear();
-
- /** Returns a semicolon separated list of all parameter names. */
- ::rtl::OUString GetParamList () const;
-
-
-
- /** Returns the number of non-suppressed arguments. In case there are
- variable arguments the number of fixed non-suppressed arguments plus
- VAR_ARGS, same as for nArgCount (variable arguments can't be
- suppressed). */
- USHORT GetSuppressedArgCount() const;
::rtl::OUString *pFuncName; // Function name
::rtl::OUString *pFuncDesc; // Description of function
::rtl::OUString **ppDefArgNames; // Parameter name(s)
::rtl::OUString **ppDefArgDescs; // Description(s) of parameter(s)
ParameterFlags *pDefArgFlags; // Flags for each parameter
- USHORT nFIndex; // Unique function index
- USHORT nCategory; // Function category
- USHORT nArgCount; // All parameter count, suppressed and unsuppressed
- USHORT nHelpId; // HelpID of function
+ sal_uInt16 nFIndex; // Unique function index
+ sal_uInt16 nCategory; // Function category
+ sal_uInt16 nArgCount; // All parameter count, suppressed and unsuppressed
+ sal_uInt16 nHelpId; // HelpId of function
bool bIncomplete :1; // Incomplete argument info (set for add-in info from configuration)
bool bHasSuppressedArgs :1; // Whether there is any suppressed parameter.
};
+
+
//============================================================================
class ScFunctionList
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
new file mode 100644
index 000000000000..d0e29c4dc5aa
--- /dev/null
+++ b/sc/source/core/data/funcdesc.cxx
@@ -0,0 +1,858 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "funcdesc.hxx"
+
+#include "addincol.hxx"
+#include "appoptio.hxx"
+#include "callform.hxx"
+#include "compiler.hxx"
+#include "global.hxx"
+#include "sc.hrc"
+#include "scmod.hxx"
+#include "scresid.hxx"
+
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/list.hxx>
+#include <tools/rcid.h>
+#include <tools/resid.hxx>
+#include <tools/string.hxx>
+#include <unotools/collatorwrapper.hxx>
+
+#include <numeric>
+
+class ScFuncRes : public Resource
+{
+public:
+ ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
+
+private:
+ USHORT GetNum();
+};
+
+
+class ScResourcePublisher : public Resource
+{
+private:
+ void FreeResource() { Resource::FreeResource(); }
+public:
+ ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
+ ~ScResourcePublisher() { FreeResource(); }
+ BOOL IsAvailableRes( const ResId& rId ) const
+ { return Resource::IsAvailableRes( rId ); }
+
+};
+
+//========================================================================
+// class ScFuncDesc:
+
+ScFuncDesc::ScFuncDesc() :
+ pFuncName (NULL),
+ pFuncDesc (NULL),
+ ppDefArgNames (NULL),
+ ppDefArgDescs (NULL),
+ pDefArgFlags (NULL),
+ nFIndex (0),
+ nCategory (0),
+ nArgCount (0),
+ nHelpId (0),
+ bIncomplete (false),
+ bHasSuppressedArgs(false)
+{}
+
+//------------------------------------------------------------------------
+
+ScFuncDesc::~ScFuncDesc()
+{
+ Clear();
+}
+
+//------------------------------------------------------------------------
+
+void ScFuncDesc::Clear()
+{
+ sal_uInt16 nArgs = nArgCount;
+ if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1;
+ if (nArgs)
+ {
+ for (sal_uInt16 i=0; i<nArgs; i++ )
+ {
+ delete ppDefArgNames[i];
+ delete ppDefArgDescs[i];
+ }
+ delete [] ppDefArgNames;
+ delete [] ppDefArgDescs;
+ delete [] pDefArgFlags;
+ }
+ nArgCount = 0;
+ ppDefArgNames = NULL;
+ ppDefArgDescs = NULL;
+ pDefArgFlags = NULL;
+
+ delete pFuncName;
+ pFuncName = NULL;
+
+ delete pFuncDesc;
+ pFuncDesc = NULL;
+
+ nFIndex = 0;
+ nCategory = 0;
+ nHelpId = 0;
+ bIncomplete = false;
+ bHasSuppressedArgs = false;
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString ScFuncDesc::GetParamList() const
+{
+ ::rtl::OUString sep(ScCompiler::GetNativeSymbol(ocSep));
+
+ ::rtl::OUStringBuffer aSig;
+
+ if ( nArgCount > 0 )
+ {
+ if ( nArgCount < VAR_ARGS )
+ {
+ sal_uInt16 nLastSuppressed = nArgCount;
+ sal_uInt16 nLastAdded = nArgCount;
+ for ( sal_uInt16 i=0; i<nArgCount; i++ )
+ {
+ if (pDefArgFlags[i].bSuppress)
+ nLastSuppressed = i;
+ else
+ {
+ nLastAdded = i;
+ aSig.append(*(ppDefArgNames[i]));
+ if ( i != nArgCount-1 )
+ {
+ aSig.append(sep);
+ aSig.appendAscii( " " );
+ }
+ }
+ }
+ // If only suppressed parameters follow the last added parameter,
+ // remove one "; "
+ if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed &&
+ aSig.getLength() >= 2)
+ aSig.setLength(aSig.getLength() - 2);
+ }
+ else
+ {
+ sal_uInt16 nFix = nArgCount - VAR_ARGS;
+ for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
+ {
+ if (!pDefArgFlags[nArg].bSuppress)
+ {
+ aSig.append(*(ppDefArgNames[nArg]));
+ aSig.append(sep);
+ aSig.appendAscii( " " );
+ }
+ }
+ /* NOTE: Currently there are no suppressed var args parameters. If
+ * there were, we'd have to cope with it here and above for the fix
+ * parameters. For now parameters are always added, so no special
+ * treatment of a trailing "; " necessary. */
+ aSig.append(*(ppDefArgNames[nFix]));
+ aSig.append(sal_Unicode('1'));
+ aSig.append(sep);
+ aSig.append(sal_Unicode(' '));
+ aSig.append(*(ppDefArgNames[nFix]));
+ aSig.append(sal_Unicode('2'));
+ aSig.append(sep);
+ aSig.appendAscii(" ... ");
+ }
+ }
+
+ return aSig.makeStringAndClear();
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString ScFuncDesc::getSignature() const
+{
+ ::rtl::OUStringBuffer aSig;
+
+ if(pFuncName)
+ {
+ aSig.append(*pFuncName);
+
+ ::rtl::OUString aParamList = GetParamList();
+ if( aParamList.getLength() )
+ {
+ aSig.appendAscii( "( " );
+ aSig.append(aParamList);
+ // U+00A0 (NBSP) prevents automatic line break
+ aSig.append( static_cast< sal_Unicode >(0xA0) );
+ aSig.appendAscii( ")" );
+ }
+ else
+ aSig.appendAscii( "()" );
+ }
+ return aSig.makeStringAndClear();
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const
+{
+ const String& sep = ScCompiler::GetNativeSymbol(ocSep);
+
+ ::rtl::OUStringBuffer aFormula;
+
+ if(pFuncName)
+ {
+ aFormula.append( *pFuncName );
+
+ aFormula.appendAscii( "(" );
+ ::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin();
+ ::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end();
+
+ if ( nArgCount > 0 && aIter != aEnd )
+ {
+ BOOL bLastArg = ( aIter->getLength() == 0 );
+
+ while( aIter != aEnd && !bLastArg )
+ {
+ aFormula.append( *(aIter) );
+ if ( aIter != (aEnd-1) )
+ {
+ bLastArg = !( (aIter+1)->getLength() > 0 );
+ if ( !bLastArg )
+ aFormula.append( sep );
+ }
+
+ ++aIter;
+ }
+ }
+
+ aFormula.appendAscii( ")" );
+ }
+ return aFormula.makeStringAndClear();
+}
+
+//------------------------------------------------------------------------
+
+sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
+{
+ if (!bHasSuppressedArgs || !pDefArgFlags)
+ return nArgCount;
+
+ sal_uInt16 nArgs = nArgCount;
+ if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
+ sal_uInt16 nCount = nArgs;
+ for (sal_uInt16 i=0; i < nArgs; ++i)
+ {
+ if (pDefArgFlags[i].bSuppress)
+ --nCount;
+ }
+ if (nArgCount >= VAR_ARGS)
+ nCount += VAR_ARGS - 1;
+ return nCount;
+}
+
+//------------------------------------------------------------------------
+
+::rtl::OUString ScFuncDesc::getFunctionName() const
+{
+ ::rtl::OUString sRet;
+ if ( pFuncName )
+ sRet = *pFuncName;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionCategory* ScFuncDesc::getCategory() const
+{
+ return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getDescription() const
+{
+ ::rtl::OUString sRet;
+ if ( pFuncDesc )
+ sRet = *pFuncDesc;
+ return sRet;
+}
+// -----------------------------------------------------------------------------
+// GetSuppressedArgCount
+xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
+{
+ return GetSuppressedArgCount();
+}
+// -----------------------------------------------------------------------------
+//
+void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
+{
+ if (!bHasSuppressedArgs || !pDefArgFlags)
+ {
+ _rArguments.resize( nArgCount);
+ ::std::iota( _rArguments.begin(), _rArguments.end(), 0);
+ }
+
+ _rArguments.reserve( nArgCount);
+ sal_uInt16 nArgs = nArgCount;
+ if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
+ for (sal_uInt16 i=0; i < nArgs; ++i)
+ {
+ if (!pDefArgFlags[i].bSuppress)
+ _rArguments.push_back(i);
+ }
+}
+// -----------------------------------------------------------------------------
+void ScFuncDesc::initArgumentInfo() const
+{
+ // get the full argument description
+ // (add-in has to be instantiated to get the type information)
+
+ if ( bIncomplete && pFuncName )
+ {
+ ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection();
+ String aIntName = rAddIns.FindFunction( *pFuncName, TRUE ); // pFuncName is upper-case
+
+ if ( aIntName.Len() )
+ {
+ // GetFuncData with bComplete=true loads the component and updates
+ // the global function list if needed.
+
+ rAddIns.GetFuncData( aIntName, true );
+ }
+
+ if ( bIncomplete )
+ {
+ DBG_ERRORFILE( "couldn't initialize add-in function" );
+ const_cast<ScFuncDesc*>(this)->bIncomplete = FALSE; // even if there was an error, don't try again
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+long ScFuncDesc::getHelpId() const
+{
+ return (long)nHelpId;
+}
+// -----------------------------------------------------------------------------
+
+// parameter
+sal_uInt32 ScFuncDesc::getParameterCount() const
+{
+ return nArgCount;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
+{
+ return *(ppDefArgNames[_nPos]);
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
+{
+ return *(ppDefArgDescs[_nPos]);
+}
+// -----------------------------------------------------------------------------
+bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
+{
+ return pDefArgFlags[_nPos].bOptional;
+}
+// -----------------------------------------------------------------------------
+
+
+
+//===================================================================
+// class ScFunctionList:
+//===================================================================
+
+ScFunctionList::ScFunctionList() :
+ nMaxFuncNameLen ( 0 )
+{
+ ScFuncDesc* pDesc = NULL;
+ xub_StrLen nStrLen = 0;
+ FuncCollection* pFuncColl;
+ USHORT i,j;
+ USHORT nDescBlock[] =
+ {
+ RID_SC_FUNCTION_DESCRIPTIONS1,
+ RID_SC_FUNCTION_DESCRIPTIONS2
+ };
+
+ aFunctionList.Clear();
+
+ for ( USHORT k = 0; k < SAL_N_ELEMENTS(nDescBlock); k++ )
+ {
+ ::std::auto_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) );
+ // Browse for all possible OpCodes. This is not the fastest method, but
+ // otherwise the sub resources within the resource blocks and the
+ // resource blocks themselfs would had to be ordered according to
+ // OpCodes, which is utopian..
+ for (i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++)
+ {
+ ScResId aRes(i);
+ aRes.SetRT(RSC_RESOURCE);
+ // Sub resource of OpCode available?
+ if (pBlock->IsAvailableRes(aRes))
+ {
+ pDesc = new ScFuncDesc;
+ bool bSuppressed = false;
+ ScFuncRes aSubRes( aRes, pDesc, bSuppressed);
+ // Instead of dealing with this exceptional case at 1001 places
+ // we simply don't add an entirely suppressed function to the
+ // list and delete it.
+ if (bSuppressed)
+ delete pDesc;
+ else
+ {
+ pDesc->nFIndex = i;
+ aFunctionList.Insert( pDesc, LIST_APPEND );
+
+ nStrLen = (*(pDesc->pFuncName)).getLength();
+ if (nStrLen > nMaxFuncNameLen)
+ nMaxFuncNameLen = nStrLen;
+ }
+ }
+ }
+ }
+
+ USHORT nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions
+
+ // Auswertung AddIn-Liste
+ String aDefArgNameValue(RTL_CONSTASCII_USTRINGPARAM("value"));
+ String aDefArgNameString(RTL_CONSTASCII_USTRINGPARAM("string"));
+ String aDefArgNameValues(RTL_CONSTASCII_USTRINGPARAM("values"));
+ String aDefArgNameStrings(RTL_CONSTASCII_USTRINGPARAM("strings"));
+ String aDefArgNameCells(RTL_CONSTASCII_USTRINGPARAM("cells"));
+ String aDefArgNameNone(RTL_CONSTASCII_USTRINGPARAM("none"));
+ String aDefArgDescValue(RTL_CONSTASCII_USTRINGPARAM("a value"));
+ String aDefArgDescString(RTL_CONSTASCII_USTRINGPARAM("a string"));
+ String aDefArgDescValues(RTL_CONSTASCII_USTRINGPARAM("array of values"));
+ String aDefArgDescStrings(RTL_CONSTASCII_USTRINGPARAM("array of strings"));
+ String aDefArgDescCells(RTL_CONSTASCII_USTRINGPARAM("range of cells"));
+ String aDefArgDescNone(RTL_CONSTASCII_USTRINGPARAM("none"));
+ String aArgName, aArgDesc;
+ pFuncColl = ScGlobal::GetFuncCollection();
+ for (i = 0; i < pFuncColl->GetCount(); i++)
+ {
+ pDesc = new ScFuncDesc;
+ FuncData *pAddInFuncData = (FuncData*)pFuncColl->At(i);
+ USHORT nArgs = pAddInFuncData->GetParamCount() - 1;
+ pAddInFuncData->GetParamDesc( aArgName, aArgDesc, 0 );
+ pDesc->nFIndex = nNextId++; // ??? OpCode vergeben
+ pDesc->nCategory = ID_FUNCTION_GRP_ADDINS;
+ pDesc->pFuncName = new ::rtl::OUString(pAddInFuncData->GetInternalName());
+ pDesc->pFuncName->toAsciiUpperCase();
+
+ ::rtl::OUStringBuffer aBuf(aArgDesc);
+ aBuf.append(sal_Unicode('\n'));
+ aBuf.appendAscii("( AddIn: ");
+ aBuf.append(pAddInFuncData->GetModuleName());
+ aBuf.appendAscii(" )");
+ pDesc->pFuncDesc = new ::rtl::OUString(aBuf.makeStringAndClear());
+
+ pDesc->nArgCount = nArgs;
+ if (nArgs)
+ {
+ pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
+ pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
+ pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
+ for (j = 0; j < nArgs; j++)
+ {
+ pDesc->pDefArgFlags[j].bOptional = false;
+ pDesc->pDefArgFlags[j].bSuppress = false;
+ pAddInFuncData->GetParamDesc( aArgName, aArgDesc, j+1 );
+ if ( aArgName.Len() )
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aArgName );
+ else
+ {
+ switch (pAddInFuncData->GetParamType(j+1))
+ {
+ case PTR_DOUBLE:
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValue );
+ break;
+ case PTR_STRING:
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameString );
+ break;
+ case PTR_DOUBLE_ARR:
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValues );
+ break;
+ case PTR_STRING_ARR:
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameStrings );
+ break;
+ case PTR_CELL_ARR:
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameCells );
+ break;
+ default:
+ pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameNone );
+ break;
+ }
+ }
+ if ( aArgDesc.Len() )
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aArgDesc );
+ else
+ {
+ switch (pAddInFuncData->GetParamType(j+1))
+ {
+ case PTR_DOUBLE:
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValue );
+ break;
+ case PTR_STRING:
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescString );
+ break;
+ case PTR_DOUBLE_ARR:
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValues );
+ break;
+ case PTR_STRING_ARR:
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescStrings );
+ break;
+ case PTR_CELL_ARR:
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescCells );
+ break;
+ default:
+ pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescNone );
+ break;
+ }
+ }
+ }
+ }
+
+ aFunctionList.Insert(pDesc, LIST_APPEND);
+ nStrLen = (*(pDesc->pFuncName)).getLength();
+ if ( nStrLen > nMaxFuncNameLen)
+ nMaxFuncNameLen = nStrLen;
+ }
+
+ // StarOne AddIns
+
+ ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection();
+ long nUnoCount = pUnoAddIns->GetFuncCount();
+ for (long nFunc=0; nFunc<nUnoCount; nFunc++)
+ {
+ pDesc = new ScFuncDesc;
+ pDesc->nFIndex = nNextId++;
+
+ if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) )
+ {
+ aFunctionList.Insert(pDesc, LIST_APPEND);
+ nStrLen = (*(pDesc->pFuncName)).getLength();
+ if (nStrLen > nMaxFuncNameLen)
+ nMaxFuncNameLen = nStrLen;
+ }
+ else
+ delete pDesc;
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionList::~ScFunctionList()
+{
+ const ScFuncDesc* pDesc = First();
+ while (pDesc)
+ {
+ delete pDesc;
+ pDesc = Next();
+ }
+}
+
+
+
+
+// -----------------------------------------------------------------------------
+sal_uInt32 ScFunctionCategory::getCount() const
+{
+ return m_pCategory->Count();
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
+{
+ return m_pMgr;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFunctionCategory::getName() const
+{
+ if ( !m_sName.getLength() )
+ m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1);
+ return m_sName;
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const
+{
+ const ScFuncDesc* pDesc = NULL;
+ sal_uInt32 i = 0;
+ for (pDesc = (const ScFuncDesc*)m_pCategory->First(); i < _nPos && pDesc; pDesc = (const ScFuncDesc*)m_pCategory->Next(),++i)
+ ;
+ return pDesc;
+}
+// -----------------------------------------------------------------------------
+sal_uInt32 ScFunctionCategory::getNumber() const
+{
+ return m_nCategory;
+}
+// -----------------------------------------------------------------------------
+
+
+//========================================================================
+// class ScFunctionMgr:
+
+ScFunctionMgr::ScFunctionMgr()
+ : pFuncList ( ScGlobal::GetStarCalcFunctionList() ),
+ pCurCatList ( NULL )
+{
+ DBG_ASSERT( pFuncList, "Funktionsliste nicht gefunden." );
+ ULONG nCount = pFuncList->GetCount();
+ const ScFuncDesc* pDesc;
+ List* pRootList;
+ ULONG n;
+
+ for ( USHORT i=0; i<MAX_FUNCCAT; i++ ) // Kategorie-Listen erstellen
+ aCatLists[i] = new List;
+
+ pRootList = aCatLists[0]; // Gesamtliste ("Alle") erstellen
+ CollatorWrapper* pCaseCollator = ScGlobal::GetCaseCollator();
+ for ( n=0; n<nCount; n++ )
+ {
+ ULONG nTmpCnt=0;
+ pDesc = pFuncList->GetFunction(n);
+ for (nTmpCnt = 0; nTmpCnt < n; nTmpCnt++)
+ {
+ // ist zwar case-sensitiv, aber Umlaute muessen richtig einsortiert werden
+
+ const ScFuncDesc* pTmpDesc = (const ScFuncDesc*)pRootList->GetObject(nTmpCnt);
+ if ( pCaseCollator->compareString(*pDesc->pFuncName, *pTmpDesc->pFuncName ) == COMPARE_LESS )
+ break;
+ }
+ pRootList->Insert((void*)pDesc, nTmpCnt); // Einsortieren
+ }
+
+ for ( n=0; n<nCount; n++ ) // in Gruppenlisten kopieren
+ {
+ pDesc = (const ScFuncDesc*)pRootList->GetObject(n);
+ DBG_ASSERT((pDesc->nCategory) < MAX_FUNCCAT, "Unbekannte Kategorie");
+ if ((pDesc->nCategory) < MAX_FUNCCAT)
+ aCatLists[pDesc->nCategory]->Insert((void*)pDesc, LIST_APPEND);
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScFunctionMgr::~ScFunctionMgr()
+{
+ for (USHORT i = 0; i < MAX_FUNCCAT; i++)
+ delete aCatLists[i];
+// delete pFuncList; // Macht spaeter die App
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::Get( const ::rtl::OUString& rFName ) const
+{
+ const ScFuncDesc* pDesc = NULL;
+ if (rFName.getLength() <= pFuncList->GetMaxFuncNameLen())
+ for (pDesc = First(0); pDesc; pDesc = Next())
+ if (rFName.equalsIgnoreAsciiCase(*pDesc->pFuncName))
+ break;
+ return pDesc;
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::Get( USHORT nFIndex ) const
+{
+ const ScFuncDesc* pDesc;
+ for (pDesc = First(0); pDesc; pDesc = Next())
+ if (pDesc->nFIndex == nFIndex)
+ break;
+ return pDesc;
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::First( USHORT nCategory ) const
+{
+ DBG_ASSERT( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" );
+
+ if ( nCategory < MAX_FUNCCAT )
+ {
+ pCurCatList = aCatLists[nCategory];
+ return (const ScFuncDesc*)pCurCatList->First();
+ }
+ else
+ {
+ pCurCatList = NULL;
+ return NULL;
+ }
+}
+
+//------------------------------------------------------------------------
+
+const ScFuncDesc* ScFunctionMgr::Next() const
+{
+ if ( pCurCatList )
+ return (const ScFuncDesc*)pCurCatList->Next();
+ else
+ return NULL;
+}
+sal_uInt32 ScFunctionMgr::getCount() const
+{
+ return MAX_FUNCCAT - 1;
+}
+const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
+{
+ formula::IFunctionCategory* pRet = NULL;
+ if ( nCategory < (MAX_FUNCCAT-1) )
+ {
+ pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all"
+ }
+ return pRet;
+}
+// -----------------------------------------------------------------------------
+const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
+{
+ return Get(_sFunctionName);
+}
+// -----------------------------------------------------------------------------
+void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const
+{
+#define LRU_MAX 10
+
+ const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
+ USHORT nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (USHORT)LRU_MAX );
+ USHORT* pLRUListIds = rAppOpt.GetLRUFuncList();
+
+ if ( pLRUListIds )
+ {
+ for ( USHORT i=0; i<nLRUFuncCount; i++ )
+ _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) );
+ }
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
+{
+ if ( _nCategoryNumber > SC_FUNCGROUP_COUNT )
+ {
+ DBG_ERROR("Invalid category number!");
+ return ::rtl::OUString();
+ }
+
+ ::std::auto_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) );
+ return ResId::toString(ScResId((USHORT)_nCategoryNumber));
+}
+sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
+{
+ switch(_eToken)
+ {
+ case eOk:
+ return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0);
+ case eClose:
+ return ScCompiler::GetNativeSymbol(ocClose).GetChar(0);
+ case eSep:
+ return ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
+ case eArrayOpen:
+ return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0);
+ case eArrayClose:
+ return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0);
+ }
+ return 0;
+}
+
+ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
+ : Resource(aRes)
+{
+ rbSuppressed = (bool)GetNum();
+ pDesc->nCategory = GetNum();
+ pDesc->nHelpId = GetNum() + 32768; //! Hack, see scfuncs.src
+ pDesc->nArgCount = GetNum();
+ USHORT nArgs = pDesc->nArgCount;
+ if (nArgs >= VAR_ARGS)
+ nArgs -= VAR_ARGS - 1;
+ if (nArgs)
+ {
+ pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
+ for (USHORT i = 0; i < nArgs; i++)
+ {
+ pDesc->pDefArgFlags[i].bOptional = (bool)GetNum();
+ }
+ }
+ // Need to read the value from the resource even if nArgs==0 to advance the
+ // resource position pointer, so this can't be in the if(nArgs) block above.
+ USHORT nSuppressed = GetNum();
+ if (nSuppressed)
+ {
+ if (nSuppressed > nArgs)
+ {
+ DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
+ aRes.GetId(), (int)nSuppressed, (int)nArgs);
+ nSuppressed = nArgs; // sanitize
+ }
+ for (USHORT i=0; i < nSuppressed; ++i)
+ {
+ USHORT nParam = GetNum();
+ if (nParam < nArgs)
+ {
+ if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
+ {
+ DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
+ aRes.GetId(), (int)nParam, (int)nArgs);
+ }
+ else
+ {
+ pDesc->pDefArgFlags[nParam].bSuppress = true;
+ pDesc->bHasSuppressedArgs = true;
+ }
+ }
+ else
+ {
+ DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
+ aRes.GetId(), (int)nParam, (int)nArgs);
+ }
+ }
+ }
+
+ pDesc->pFuncName = new ::rtl::OUString( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId())));
+ pDesc->pFuncDesc = new ::rtl::OUString( ResId::toString(ScResId(1)));
+
+ if (nArgs)
+ {
+ pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
+ pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
+ for (USHORT i = 0; i < nArgs; i++)
+ {
+ pDesc->ppDefArgNames[i] = new ::rtl::OUString(ResId::toString(ScResId(2*(i+1) )));
+ pDesc->ppDefArgDescs[i] = new ::rtl::OUString(ResId::toString(ScResId(2*(i+1)+1)));
+ }
+ }
+
+ FreeResource();
+}
+
+//------------------------------------------------------------------------
+
+USHORT ScFuncRes::GetNum()
+{
+ return ReadShortRes();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx
index e64b5b5164bb..e768e7c6bd24 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -1096,818 +1096,9 @@ void ScGlobal::AddLanguage( SfxItemSet& rSet, SvNumberFormatter& rFormatter )
}
-
-
-
-//===================================================================
-// class ScFunctionList:
-//===================================================================
-
-//===================================================================
-// class ScFuncRes
-// fuer temporaere Objekte zum Holen der Resourcen
-
-class ScFuncRes : public Resource
-{
-public:
- ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
-
-private:
- USHORT GetNum();
-};
-
//--------------------------------------------------------------------
-ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
- : Resource(aRes)
-{
- rbSuppressed = (bool)GetNum();
- pDesc->nCategory = GetNum();
- pDesc->nHelpId = GetNum() + 32768; //! Hack, see scfuncs.src
- pDesc->nArgCount = GetNum();
- USHORT nArgs = pDesc->nArgCount;
- if (nArgs >= VAR_ARGS)
- nArgs -= VAR_ARGS - 1;
- if (nArgs)
- {
- pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
- for (USHORT i = 0; i < nArgs; i++)
- {
- pDesc->pDefArgFlags[i].bOptional = (bool)GetNum();
- }
- }
- // Need to read the value from the resource even if nArgs==0 to advance the
- // resource position pointer, so this can't be in the if(nArgs) block above.
- USHORT nSuppressed = GetNum();
- if (nSuppressed)
- {
- if (nSuppressed > nArgs)
- {
- DBG_ERROR3( "ScFuncRes: suppressed parameters count mismatch on OpCode %u: suppressed %d > params %d",
- aRes.GetId(), (int)nSuppressed, (int)nArgs);
- nSuppressed = nArgs; // sanitize
- }
- for (USHORT i=0; i < nSuppressed; ++i)
- {
- USHORT nParam = GetNum();
- if (nParam < nArgs)
- {
- if (pDesc->nArgCount >= VAR_ARGS && nParam == nArgs-1)
- {
- DBG_ERROR3( "ScFuncRes: VAR_ARGS parameters can't be suppressed, on OpCode %u: param %d == arg %d-1",
- aRes.GetId(), (int)nParam, (int)nArgs);
- }
- else
- {
- pDesc->pDefArgFlags[nParam].bSuppress = true;
- pDesc->bHasSuppressedArgs = true;
- }
- }
- else
- {
- DBG_ERROR3( "ScFuncRes: suppressed parameter exceeds count on OpCode %u: param %d >= args %d",
- aRes.GetId(), (int)nParam, (int)nArgs);
- }
- }
- }
-
- pDesc->pFuncName = new ::rtl::OUString( ScCompiler::GetNativeSymbol( static_cast<OpCode>( aRes.GetId())));
- pDesc->pFuncDesc = new ::rtl::OUString( ResId::toString(ScResId(1)));
-
- if (nArgs)
- {
- pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
- pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
- for (USHORT i = 0; i < nArgs; i++)
- {
- pDesc->ppDefArgNames[i] = new ::rtl::OUString(ResId::toString(ScResId(2*(i+1) )));
- pDesc->ppDefArgDescs[i] = new ::rtl::OUString(ResId::toString(ScResId(2*(i+1)+1)));
- }
- }
-
- FreeResource();
-}
-
-//------------------------------------------------------------------------
-
-USHORT ScFuncRes::GetNum()
-{
- return ReadShortRes();
-}
-
-//=========================================================================
-
-// um an die protected von Resource ranzukommen
-class ScResourcePublisher : public Resource
-{
-private:
- void FreeResource() { Resource::FreeResource(); }
-public:
- ScResourcePublisher( const ScResId& rId ) : Resource( rId ) {}
- ~ScResourcePublisher() { FreeResource(); }
- BOOL IsAvailableRes( const ResId& rId ) const
- { return Resource::IsAvailableRes( rId ); }
-
-};
-
-
-ScFunctionList::ScFunctionList() :
- nMaxFuncNameLen ( 0 )
-{
- ScFuncDesc* pDesc = NULL;
- xub_StrLen nStrLen = 0;
- FuncCollection* pFuncColl;
- USHORT i,j;
- USHORT nDescBlock[] =
- {
- RID_SC_FUNCTION_DESCRIPTIONS1,
- RID_SC_FUNCTION_DESCRIPTIONS2
- };
-
- aFunctionList.Clear();
-
- for ( USHORT k = 0; k < SAL_N_ELEMENTS(nDescBlock); k++ )
- {
- ::std::auto_ptr<ScResourcePublisher> pBlock( new ScResourcePublisher( ScResId( nDescBlock[k] ) ) );
- // Browse for all possible OpCodes. This is not the fastest method, but
- // otherwise the sub resources within the resource blocks and the
- // resource blocks themselfs would had to be ordered according to
- // OpCodes, which is utopian..
- for (i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++)
- {
- ScResId aRes(i);
- aRes.SetRT(RSC_RESOURCE);
- // Sub resource of OpCode available?
- if (pBlock->IsAvailableRes(aRes))
- {
- pDesc = new ScFuncDesc;
- bool bSuppressed = false;
- ScFuncRes aSubRes( aRes, pDesc, bSuppressed);
- // Instead of dealing with this exceptional case at 1001 places
- // we simply don't add an entirely suppressed function to the
- // list and delete it.
- if (bSuppressed)
- delete pDesc;
- else
- {
- pDesc->nFIndex = i;
- aFunctionList.Insert( pDesc, LIST_APPEND );
-
- nStrLen = (*(pDesc->pFuncName)).getLength();
- if (nStrLen > nMaxFuncNameLen)
- nMaxFuncNameLen = nStrLen;
- }
- }
- }
- }
-
- USHORT nNextId = SC_OPCODE_LAST_OPCODE_ID + 1; // FuncID for AddIn functions
-
- // Auswertung AddIn-Liste
- String aDefArgNameValue(RTL_CONSTASCII_USTRINGPARAM("value"));
- String aDefArgNameString(RTL_CONSTASCII_USTRINGPARAM("string"));
- String aDefArgNameValues(RTL_CONSTASCII_USTRINGPARAM("values"));
- String aDefArgNameStrings(RTL_CONSTASCII_USTRINGPARAM("strings"));
- String aDefArgNameCells(RTL_CONSTASCII_USTRINGPARAM("cells"));
- String aDefArgNameNone(RTL_CONSTASCII_USTRINGPARAM("none"));
- String aDefArgDescValue(RTL_CONSTASCII_USTRINGPARAM("a value"));
- String aDefArgDescString(RTL_CONSTASCII_USTRINGPARAM("a string"));
- String aDefArgDescValues(RTL_CONSTASCII_USTRINGPARAM("array of values"));
- String aDefArgDescStrings(RTL_CONSTASCII_USTRINGPARAM("array of strings"));
- String aDefArgDescCells(RTL_CONSTASCII_USTRINGPARAM("range of cells"));
- String aDefArgDescNone(RTL_CONSTASCII_USTRINGPARAM("none"));
- String aArgName, aArgDesc;
- pFuncColl = ScGlobal::GetFuncCollection();
- for (i = 0; i < pFuncColl->GetCount(); i++)
- {
- pDesc = new ScFuncDesc;
- FuncData *pAddInFuncData = (FuncData*)pFuncColl->At(i);
- USHORT nArgs = pAddInFuncData->GetParamCount() - 1;
- pAddInFuncData->GetParamDesc( aArgName, aArgDesc, 0 );
- pDesc->nFIndex = nNextId++; // ??? OpCode vergeben
- pDesc->nCategory = ID_FUNCTION_GRP_ADDINS;
- pDesc->pFuncName = new ::rtl::OUString(pAddInFuncData->GetInternalName());
- pDesc->pFuncName->toAsciiUpperCase();
-
- OUStringBuffer aBuf(aArgDesc);
- aBuf.append(sal_Unicode('\n'));
- aBuf.appendAscii("( AddIn: ");
- aBuf.append(pAddInFuncData->GetModuleName());
- aBuf.appendAscii(" )");
- pDesc->pFuncDesc = new OUString(aBuf.makeStringAndClear());
-
- pDesc->nArgCount = nArgs;
- if (nArgs)
- {
- pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
- pDesc->ppDefArgNames = new ::rtl::OUString*[nArgs];
- pDesc->ppDefArgDescs = new ::rtl::OUString*[nArgs];
- for (j = 0; j < nArgs; j++)
- {
- pDesc->pDefArgFlags[j].bOptional = false;
- pDesc->pDefArgFlags[j].bSuppress = false;
- pAddInFuncData->GetParamDesc( aArgName, aArgDesc, j+1 );
- if ( aArgName.Len() )
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aArgName );
- else
- {
- switch (pAddInFuncData->GetParamType(j+1))
- {
- case PTR_DOUBLE:
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValue );
- break;
- case PTR_STRING:
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameString );
- break;
- case PTR_DOUBLE_ARR:
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameValues );
- break;
- case PTR_STRING_ARR:
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameStrings );
- break;
- case PTR_CELL_ARR:
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameCells );
- break;
- default:
- pDesc->ppDefArgNames[j] = new ::rtl::OUString( aDefArgNameNone );
- break;
- }
- }
- if ( aArgDesc.Len() )
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aArgDesc );
- else
- {
- switch (pAddInFuncData->GetParamType(j+1))
- {
- case PTR_DOUBLE:
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValue );
- break;
- case PTR_STRING:
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescString );
- break;
- case PTR_DOUBLE_ARR:
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescValues );
- break;
- case PTR_STRING_ARR:
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescStrings );
- break;
- case PTR_CELL_ARR:
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescCells );
- break;
- default:
- pDesc->ppDefArgDescs[j] = new ::rtl::OUString( aDefArgDescNone );
- break;
- }
- }
- }
- }
-
- aFunctionList.Insert(pDesc, LIST_APPEND);
- nStrLen = (*(pDesc->pFuncName)).getLength();
- if ( nStrLen > nMaxFuncNameLen)
- nMaxFuncNameLen = nStrLen;
- }
-
- // StarOne AddIns
-
- ScUnoAddInCollection* pUnoAddIns = ScGlobal::GetAddInCollection();
- long nUnoCount = pUnoAddIns->GetFuncCount();
- for (long nFunc=0; nFunc<nUnoCount; nFunc++)
- {
- pDesc = new ScFuncDesc;
- pDesc->nFIndex = nNextId++;
-
- if ( pUnoAddIns->FillFunctionDesc( nFunc, *pDesc ) )
- {
- aFunctionList.Insert(pDesc, LIST_APPEND);
- nStrLen = (*(pDesc->pFuncName)).getLength();
- if (nStrLen > nMaxFuncNameLen)
- nMaxFuncNameLen = nStrLen;
- }
- else
- delete pDesc;
- }
-}
-
-//------------------------------------------------------------------------
-
-ScFunctionList::~ScFunctionList()
-{
- const ScFuncDesc* pDesc = First();
- while (pDesc)
- {
- delete pDesc;
- pDesc = Next();
- }
-}
-
-
-//========================================================================
-// class ScFuncDesc:
-
-ScFuncDesc::ScFuncDesc() :
- pFuncName (NULL),
- pFuncDesc (NULL),
- ppDefArgNames (NULL),
- ppDefArgDescs (NULL),
- pDefArgFlags (NULL),
- nFIndex (0),
- nCategory (0),
- nArgCount (0),
- nHelpId (0),
- bIncomplete (false),
- bHasSuppressedArgs(false)
-{}
-
-//------------------------------------------------------------------------
-
-ScFuncDesc::~ScFuncDesc()
-{
- Clear();
-}
-
-//------------------------------------------------------------------------
-
-void ScFuncDesc::Clear()
-{
- USHORT nArgs = nArgCount;
- if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1;
- if (nArgs)
- {
- for (USHORT i=0; i<nArgs; i++ )
- {
- delete ppDefArgNames[i];
- delete ppDefArgDescs[i];
- }
- delete [] ppDefArgNames;
- delete [] ppDefArgDescs;
- delete [] pDefArgFlags;
- }
- nArgCount = 0;
- ppDefArgNames = NULL;
- ppDefArgDescs = NULL;
- pDefArgFlags = NULL;
-
- delete pFuncName;
- pFuncName = NULL;
-
- delete pFuncDesc;
- pFuncDesc = NULL;
-
- nFIndex = 0;
- nCategory = 0;
- nHelpId = 0;
- bIncomplete = false;
- bHasSuppressedArgs = false;
-}
-
-//------------------------------------------------------------------------
-
-::rtl::OUString ScFuncDesc::GetParamList() const
-{
- ::rtl::OUString sep(ScCompiler::GetNativeSymbol(ocSep));
-
- ::rtl::OUStringBuffer aSig;
-
- if ( nArgCount > 0 )
- {
- if ( nArgCount < VAR_ARGS )
- {
- USHORT nLastSuppressed = nArgCount;
- USHORT nLastAdded = nArgCount;
- for ( USHORT i=0; i<nArgCount; i++ )
- {
- if (pDefArgFlags[i].bSuppress)
- nLastSuppressed = i;
- else
- {
- nLastAdded = i;
- aSig.append(*(ppDefArgNames[i]));
- if ( i != nArgCount-1 )
- {
- aSig.append(sep);
- aSig.appendAscii( " " );
- }
- }
- }
- // If only suppressed parameters follow the last added parameter,
- // remove one "; "
- if (nLastSuppressed < nArgCount && nLastAdded < nLastSuppressed &&
- aSig.getLength() >= 2)
- aSig.setLength(aSig.getLength() - 2);
- }
- else
- {
- USHORT nFix = nArgCount - VAR_ARGS;
- for ( USHORT nArg = 0; nArg < nFix; nArg++ )
- {
- if (!pDefArgFlags[nArg].bSuppress)
- {
- aSig.append(*(ppDefArgNames[nArg]));
- aSig.append(sep);
- aSig.appendAscii( " " );
- }
- }
- /* NOTE: Currently there are no suppressed var args parameters. If
- * there were, we'd have to cope with it here and above for the fix
- * parameters. For now parameters are always added, so no special
- * treatment of a trailing "; " necessary. */
- aSig.append(*(ppDefArgNames[nFix]));
- aSig.append(sal_Unicode('1'));
- aSig.append(sep);
- aSig.append(sal_Unicode(' '));
- aSig.append(*(ppDefArgNames[nFix]));
- aSig.append(sal_Unicode('2'));
- aSig.append(sep);
- aSig.appendAscii(" ... ");
- }
- }
-
- return aSig.makeStringAndClear();
-}
-
-//------------------------------------------------------------------------
-
-::rtl::OUString ScFuncDesc::getSignature() const
-{
- ::rtl::OUStringBuffer aSig;
-
- if(pFuncName)
- {
- aSig.append(*pFuncName);
-
- ::rtl::OUString aParamList = GetParamList();
- if( aParamList.getLength() )
- {
- aSig.appendAscii( "( " );
- aSig.append(aParamList);
- // U+00A0 (NBSP) prevents automatic line break
- aSig.append( static_cast< sal_Unicode >(0xA0) );
- aSig.appendAscii( ")" );
- }
- else
- aSig.appendAscii( "()" );
- }
- return aSig.makeStringAndClear();
-}
-
-//------------------------------------------------------------------------
-
-::rtl::OUString ScFuncDesc::getFormula( const ::std::vector< ::rtl::OUString >& _aArguments ) const
-{
- const String& sep = ScCompiler::GetNativeSymbol(ocSep);
-
- ::rtl::OUStringBuffer aFormula;
-
- if(pFuncName)
- {
- aFormula.append( *pFuncName );
-
- aFormula.appendAscii( "(" );
- ::std::vector< ::rtl::OUString >::const_iterator aIter = _aArguments.begin();
- ::std::vector< ::rtl::OUString >::const_iterator aEnd = _aArguments.end();
-
- if ( nArgCount > 0 && aIter != aEnd )
- {
- BOOL bLastArg = ( aIter->getLength() == 0 );
-
- while( aIter != aEnd && !bLastArg )
- {
- aFormula.append( *(aIter) );
- if ( aIter != (aEnd-1) )
- {
- bLastArg = !( (aIter+1)->getLength() > 0 );
- if ( !bLastArg )
- aFormula.append( sep );
- }
-
- ++aIter;
- }
- }
-
- aFormula.appendAscii( ")" );
- }
- return aFormula.makeStringAndClear();
-}
-
-//------------------------------------------------------------------------
-
-USHORT ScFuncDesc::GetSuppressedArgCount() const
-{
- if (!bHasSuppressedArgs || !pDefArgFlags)
- return nArgCount;
-
- USHORT nArgs = nArgCount;
- if (nArgs >= VAR_ARGS)
- nArgs -= VAR_ARGS - 1;
- USHORT nCount = nArgs;
- for (USHORT i=0; i < nArgs; ++i)
- {
- if (pDefArgFlags[i].bSuppress)
- --nCount;
- }
- if (nArgCount >= VAR_ARGS)
- nCount += VAR_ARGS - 1;
- return nCount;
-}
-
-//------------------------------------------------------------------------
-
-::rtl::OUString ScFuncDesc::getFunctionName() const
-{
- ::rtl::OUString sRet;
- if ( pFuncName )
- sRet = *pFuncName;
- return sRet;
-}
-// -----------------------------------------------------------------------------
-const formula::IFunctionCategory* ScFuncDesc::getCategory() const
-{
- return ScGlobal::GetStarCalcFunctionMgr()->getCategory(nCategory);
-}
-// -----------------------------------------------------------------------------
-::rtl::OUString ScFuncDesc::getDescription() const
-{
- ::rtl::OUString sRet;
- if ( pFuncDesc )
- sRet = *pFuncDesc;
- return sRet;
-}
-// -----------------------------------------------------------------------------
-// GetSuppressedArgCount
-xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
-{
- return GetSuppressedArgCount();
-}
-// -----------------------------------------------------------------------------
-//
-void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<USHORT>& _rArguments) const
-{
- if (!bHasSuppressedArgs || !pDefArgFlags)
- {
- _rArguments.resize( nArgCount);
- ::std::iota( _rArguments.begin(), _rArguments.end(), 0);
- }
-
- _rArguments.reserve( nArgCount);
- USHORT nArgs = nArgCount;
- if (nArgs >= VAR_ARGS)
- nArgs -= VAR_ARGS - 1;
- for (USHORT i=0; i < nArgs; ++i)
- {
- if (!pDefArgFlags[i].bSuppress)
- _rArguments.push_back(i);
- }
-}
-// -----------------------------------------------------------------------------
-void ScFuncDesc::initArgumentInfo() const
-{
- // get the full argument description
- // (add-in has to be instantiated to get the type information)
-
- if ( bIncomplete && pFuncName )
- {
- ScUnoAddInCollection& rAddIns = *ScGlobal::GetAddInCollection();
- String aIntName = rAddIns.FindFunction( *pFuncName, TRUE ); // pFuncName is upper-case
-
- if ( aIntName.Len() )
- {
- // GetFuncData with bComplete=true loads the component and updates
- // the global function list if needed.
-
- rAddIns.GetFuncData( aIntName, true );
- }
-
- if ( bIncomplete )
- {
- DBG_ERRORFILE( "couldn't initialize add-in function" );
- const_cast<ScFuncDesc*>(this)->bIncomplete = FALSE; // even if there was an error, don't try again
- }
- }
-}
-// -----------------------------------------------------------------------------
-long ScFuncDesc::getHelpId() const
-{
- return nHelpId;
-}
-// -----------------------------------------------------------------------------
-
-// parameter
-sal_uInt32 ScFuncDesc::getParameterCount() const
-{
- return nArgCount;
-}
-// -----------------------------------------------------------------------------
-::rtl::OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
-{
- return *(ppDefArgNames[_nPos]);
-}
-// -----------------------------------------------------------------------------
-::rtl::OUString ScFuncDesc::getParameterDescription(sal_uInt32 _nPos) const
-{
- return *(ppDefArgDescs[_nPos]);
-}
-// -----------------------------------------------------------------------------
-bool ScFuncDesc::isParameterOptional(sal_uInt32 _nPos) const
-{
- return pDefArgFlags[_nPos].bOptional;
-}
-// -----------------------------------------------------------------------------
-//========================================================================
-// class ScFunctionMgr:
-
-ScFunctionMgr::ScFunctionMgr()
- : pFuncList ( ScGlobal::GetStarCalcFunctionList() ),
- pCurCatList ( NULL )
-{
- DBG_ASSERT( pFuncList, "Funktionsliste nicht gefunden." );
- ULONG nCount = pFuncList->GetCount();
- const ScFuncDesc* pDesc;
- List* pRootList;
- ULONG n;
-
- for ( USHORT i=0; i<MAX_FUNCCAT; i++ ) // Kategorie-Listen erstellen
- aCatLists[i] = new List;
-
- pRootList = aCatLists[0]; // Gesamtliste ("Alle") erstellen
- CollatorWrapper* pCaseCollator = ScGlobal::GetCaseCollator();
- for ( n=0; n<nCount; n++ )
- {
- ULONG nTmpCnt=0;
- pDesc = pFuncList->GetFunction(n);
- for (nTmpCnt = 0; nTmpCnt < n; nTmpCnt++)
- {
- // ist zwar case-sensitiv, aber Umlaute muessen richtig einsortiert werden
-
- const ScFuncDesc* pTmpDesc = (const ScFuncDesc*)pRootList->GetObject(nTmpCnt);
- if ( pCaseCollator->compareString(*pDesc->pFuncName, *pTmpDesc->pFuncName ) == COMPARE_LESS )
- break;
- }
- pRootList->Insert((void*)pDesc, nTmpCnt); // Einsortieren
- }
-
- for ( n=0; n<nCount; n++ ) // in Gruppenlisten kopieren
- {
- pDesc = (const ScFuncDesc*)pRootList->GetObject(n);
- DBG_ASSERT((pDesc->nCategory) < MAX_FUNCCAT, "Unbekannte Kategorie");
- if ((pDesc->nCategory) < MAX_FUNCCAT)
- aCatLists[pDesc->nCategory]->Insert((void*)pDesc, LIST_APPEND);
- }
-}
-//------------------------------------------------------------------------
-
-ScFunctionMgr::~ScFunctionMgr()
-{
- for (USHORT i = 0; i < MAX_FUNCCAT; i++)
- delete aCatLists[i];
-// delete pFuncList; // Macht spaeter die App
-}
-
-//------------------------------------------------------------------------
-
-const ScFuncDesc* ScFunctionMgr::Get( const ::rtl::OUString& rFName ) const
-{
- const ScFuncDesc* pDesc = NULL;
- if (rFName.getLength() <= pFuncList->GetMaxFuncNameLen())
- for (pDesc = First(0); pDesc; pDesc = Next())
- if (rFName.equalsIgnoreAsciiCase(*pDesc->pFuncName))
- break;
- return pDesc;
-}
-
-//------------------------------------------------------------------------
-
-const ScFuncDesc* ScFunctionMgr::Get( USHORT nFIndex ) const
-{
- const ScFuncDesc* pDesc;
- for (pDesc = First(0); pDesc; pDesc = Next())
- if (pDesc->nFIndex == nFIndex)
- break;
- return pDesc;
-}
-
-//------------------------------------------------------------------------
-
-const ScFuncDesc* ScFunctionMgr::First( USHORT nCategory ) const
-{
- DBG_ASSERT( nCategory < MAX_FUNCCAT, "Unbekannte Kategorie" );
-
- if ( nCategory < MAX_FUNCCAT )
- {
- pCurCatList = aCatLists[nCategory];
- return (const ScFuncDesc*)pCurCatList->First();
- }
- else
- {
- pCurCatList = NULL;
- return NULL;
- }
-}
-
-//------------------------------------------------------------------------
-
-const ScFuncDesc* ScFunctionMgr::Next() const
-{
- if ( pCurCatList )
- return (const ScFuncDesc*)pCurCatList->Next();
- else
- return NULL;
-}
-sal_uInt32 ScFunctionMgr::getCount() const
-{
- return MAX_FUNCCAT - 1;
-}
-const formula::IFunctionCategory* ScFunctionMgr::getCategory(sal_uInt32 nCategory) const
-{
- formula::IFunctionCategory* pRet = NULL;
- if ( nCategory < (MAX_FUNCCAT-1) )
- {
- pRet = new ScFunctionCategory(const_cast<ScFunctionMgr*>(this),aCatLists[nCategory+1],nCategory); // aCatLists[0] is "all"
- }
- return pRet;
-}
-// -----------------------------------------------------------------------------
-const formula::IFunctionDescription* ScFunctionMgr::getFunctionByName(const ::rtl::OUString& _sFunctionName) const
-{
- return Get(_sFunctionName);
-}
-// -----------------------------------------------------------------------------
-void ScFunctionMgr::fillLastRecentlyUsedFunctions(::std::vector< const formula::IFunctionDescription*>& _rLastRUFunctions) const
-{
-#define LRU_MAX 10
-
- const ScAppOptions& rAppOpt = SC_MOD()->GetAppOptions();
- USHORT nLRUFuncCount = Min( rAppOpt.GetLRUFuncListCount(), (USHORT)LRU_MAX );
- USHORT* pLRUListIds = rAppOpt.GetLRUFuncList();
-
- if ( pLRUListIds )
- {
- for ( USHORT i=0; i<nLRUFuncCount; i++ )
- _rLastRUFunctions.push_back( Get( pLRUListIds[i] ) );
- }
-}
-// -----------------------------------------------------------------------------
-::rtl::OUString ScFunctionMgr::GetCategoryName(sal_uInt32 _nCategoryNumber )
-{
- if ( _nCategoryNumber > SC_FUNCGROUP_COUNT )
- {
- DBG_ERROR("Invalid category number!");
- return ::rtl::OUString();
- }
-
- ::std::auto_ptr<ScResourcePublisher> pCategories( new ScResourcePublisher( ScResId( RID_FUNCTION_CATEGORIES ) ) );
- return ResId::toString(ScResId((USHORT)_nCategoryNumber));
-}
-sal_Unicode ScFunctionMgr::getSingleToken(const formula::IFunctionManager::EToken _eToken) const
-{
- switch(_eToken)
- {
- case eOk:
- return ScCompiler::GetNativeSymbol(ocOpen).GetChar(0);
- case eClose:
- return ScCompiler::GetNativeSymbol(ocClose).GetChar(0);
- case eSep:
- return ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
- case eArrayOpen:
- return ScCompiler::GetNativeSymbol(ocArrayOpen).GetChar(0);
- case eArrayClose:
- return ScCompiler::GetNativeSymbol(ocArrayClose).GetChar(0);
- }
- return 0;
-}
-// -----------------------------------------------------------------------------
-sal_uInt32 ScFunctionCategory::getCount() const
-{
- return m_pCategory->Count();
-}
-// -----------------------------------------------------------------------------
-const formula::IFunctionManager* ScFunctionCategory::getFunctionManager() const
-{
- return m_pMgr;
-}
-// -----------------------------------------------------------------------------
-::rtl::OUString ScFunctionCategory::getName() const
-{
- if ( !m_sName.getLength() )
- m_sName = ScFunctionMgr::GetCategoryName(m_nCategory+1);
- return m_sName;
-}
-// -----------------------------------------------------------------------------
-const formula::IFunctionDescription* ScFunctionCategory::getFunction(sal_uInt32 _nPos) const
-{
- const ScFuncDesc* pDesc = NULL;
- sal_uInt32 i = 0;
- for (pDesc = (const ScFuncDesc*)m_pCategory->First(); i < _nPos && pDesc; pDesc = (const ScFuncDesc*)m_pCategory->Next(),++i)
- ;
- return pDesc;
-}
-// -----------------------------------------------------------------------------
-sal_uInt32 ScFunctionCategory::getNumber() const
-{
- return m_nCategory;
-}
-// -----------------------------------------------------------------------------
//------------------------------------------------------------------------
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index 8ad87c34c1f8..efb3fca9e14e 100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -90,6 +90,7 @@ EXCEPTIONSFILES= \
$(SLO)$/drawpage.obj \
$(SLO)$/drwlayer.obj \
$(SLO)$/fillinfo.obj \
+ $(SLO)$/funcdesc.obj \
$(SLO)$/global.obj \
$(SLO)$/global2.obj \
$(SLO)$/globalx.obj \