[Libreoffice-commits] .: sc/inc sc/source

Thorsten Behrens thorsten at kemper.freedesktop.org
Wed Jan 12 15:42:16 PST 2011


 sc/inc/funcdesc.hxx              |  176 ++++++--
 sc/source/core/data/funcdesc.cxx |  858 +++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/global.cxx   |  809 ------------------------------------
 sc/source/core/data/makefile.mk  |    1 
 4 files changed, 1001 insertions(+), 843 deletions(-)

New commits:
commit c09aa3ef07038b2cbc2efce3a965933fcc0f2a34
Author: Sören Möller <soerenmoeller2001 at gmail.com>
Date:   Tue Jan 11 22:18:52 2011 +0100

    Moved funcdesc's implementations out of global.cxx
    
    Added comments to one of the classes, created two necessary
    headerfiles and made smaller code cleanups

diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index d94d9b2..f204571 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
@@ -75,36 +196,23 @@ public:
         ParameterFlags() : bOptional(false), bSuppress(false) {}
     };
 
-    
-    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 0000000..e12081a
--- /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 b1240ff..6e04c9d 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 8ad87c3..efb3fca 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 \


More information about the Libreoffice-commits mailing list