Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


Hi Thorsten

Thank you very much for your review, I attached a new patch (the three
patches together contain the old patch and the fixes), and below
commented on some of your your remarks.

2011/1/12 Thorsten Behrens <thb@documentfoundation.org>:
Soeren Moeller wrote:
I have now splitted the implementation of funcdesc.hxx out into a new
source file funcdesc.cxx.

Hi Soeren,

first off, many thanks for going to clean this up, your work here is
much appreciated! That split so far looks good.

In the process I also have extracted two new header files for
classes previously defined in global.cxx.

That's not necessary - ScResourcePublisher and ScFuncRes are only
used inside global.cxx, thus need no extra header - in fact, this
would not be idiomatic for c++. Simply leave them next to the code
that's using them.
After moving the implementation of funcdesc.hxx to funcdesc.cxx, now
its only funcdesc.cxx which uses ScResourcePublisher and ScFuncRes,
while they aren't used in global.cxx anymore. So I have now moved both
declaration an implementation of these two classes into funcdesc.cxx.


See a few more comments inline of the actual patch:

diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index d94d9b2..5f3ca7e 100644
--- a/sc/inc/funcdesc.hxx
+++ b/sc/inc/funcdesc.hxx
@@ -34,39 +34,161 @@
  * global.cxx
  */

+#include "scfuncs.hrc"
+
 #include <tools/list.hxx>
-#include <tools/string.hxx>
+//#include <tools/string.hxx>

Please remove, don't comment out.
Sorry, this was an error, it seems I forgot to remove the line before comitting.


+/**
+  Contains description of a function
+*/
 class ScFuncDesc : public formula::IFunctionDescription
 {
 public:
+    /**
+      Constructor
+    */
+    ScFuncDesc();

-    virtual ::rtl::OUString getFunctionName() const ;
+    /**
+      Destructor
+    */
+    virtual ~ScFuncDesc();

Those doc-comments don't provide any value. Destructors and nullary
constructors seldomly need any comment at all, and for the class,
I'd suggest something along the lines of "Serves human-language
function descriptions within the calc formula parser framework" - or
somesuch. Did not look too closely, TBH. ;)

Two related golden rules for good comments/documentation:

Good comments don't repeat the code or explain it. They clarify its
intent. Comments should explain, at a higher level of abstraction
than the code, what it does.

 or, put bluntly:

Don’t insult the reader’s intelligence ;)
Thank you for your tips, I have now removed the non-informative
comments, and added a clearer description of the intention (as far as
I can see from the code) of this class


+    /**
+      Resets the object in a clean manner
+    */
+    void Clear();

For one-liners like this, I'd prefer this markup:

/// Resets the object as if it were newly constructed

(well, does clear() perform that? writing good comments usually
involves some detailed code review, or even debugging)
I have now added a more precise comment to Clear.


+    /**
+      Returns the category of the function
+
+      @return    the category of the function
+    */
     virtual const formula::IFunctionCategory* getCategory() const ;

Since these methods are inherited from the IFunctionDescription
interface, I'd rather document them there (in the formula module).
That way, all derived classes benefit from your documentation (and
doxygen is smart enough to link that).

+    /* Public variables */

I'd consider this redundant. If you want to comment on the fact that
this class exposes its data structures, try to reconstruct the
reason why this is so - e.g. a bug number, for which it was added,
e.g. in a hurry before a shipment, to keep changes minimal (and
later cleanup was forgotten). Else, the reason would be "programmer
lazyness / sloppy coding", and that's a default assumption that
needs no comment. ;)

-    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

Ok to change, but I'd then also adapt the other occurences. And
maybe make that a separate patch - makes review easier, and ensures
that uncontroversial changes get in right away. :)
Now I also have changed the types in the implementation in funcdesc.cxx

Regards
Sören Möller
(LGPLv3+ / MPL)


Could you quickly brush this up a bit & resend? As I said, otherwise
good & useful!

Cheers,

-- Thorsten

From 9211b96226535ee1df26e7e3111ed4d18a24f70b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20M=C3=B6ller?= <soerenmoeller2001@gmail.com>
Date: Tue, 11 Jan 2011 22:18:52 +0100
Subject: [PATCH 1/3] Moved funcdesc's implementations out of global.cxx

Added comments to one of the classes, created two necessary
headerfiles and made smaller code cleanups
---
 sc/inc/funcdesc.hxx              |  179 +++++++--
 sc/inc/funcres.hxx               |   45 +++
 sc/inc/resourcepublisher.hxx     |   54 +++
 sc/source/core/data/funcdesc.cxx |  761 ++++++++++++++++++++++++++++++++++++++
 sc/source/core/data/global.cxx   |  734 +------------------------------------
 sc/source/core/data/makefile.mk  |    1 +
 6 files changed, 1006 insertions(+), 768 deletions(-)
 create mode 100644 sc/inc/funcres.hxx
 create mode 100644 sc/inc/resourcepublisher.hxx
 create mode 100644 sc/source/core/data/funcdesc.cxx

diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index d94d9b2..5f3ca7e 100644
--- a/sc/inc/funcdesc.hxx
+++ b/sc/inc/funcdesc.hxx
@@ -34,39 +34,161 @@
  * global.cxx
  */
 
+#include "scfuncs.hrc"
+
 #include <tools/list.hxx>
-#include <tools/string.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 ScFunctionMgr;
+
+/**
+  Contains description of a function
+*/
 class ScFuncDesc : public formula::IFunctionDescription
 {
 public:
+    /**
+      Constructor
+    */
+    ScFuncDesc();
 
-    virtual ::rtl::OUString getFunctionName() const ;
+    /**
+      Destructor
+    */
+    virtual ~ScFuncDesc();
+
+    /**
+      Resets the object in a clean manner
+    */
+    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 +197,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;
 
+    /* Public variables */
     ::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/inc/funcres.hxx b/sc/inc/funcres.hxx
new file mode 100644
index 0000000..3c010dd
--- /dev/null
+++ b/sc/inc/funcres.hxx
@@ -0,0 +1,45 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_FUNCRES_HXX
+#define SC_FUNCRES_HXX
+
+//===================================================================
+//             class ScFuncRes
+// fuer temporaere Objekte zum Holen der Resourcen
+
+class ScFuncRes : public Resource
+{
+public:
+    ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
+
+private:
+    USHORT GetNum();
+};
+
+#endif //SC_FUNCRES_HXX
diff --git a/sc/inc/resourcepublisher.hxx b/sc/inc/resourcepublisher.hxx
new file mode 100644
index 0000000..9d3d6e3
--- /dev/null
+++ b/sc/inc/resourcepublisher.hxx
@@ -0,0 +1,54 @@
+/* -*- 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_RESOURCEPUBLISHER_HXX
+#define SC_RESOURCEPUBLISHER_HXX
+
+#include "scresid.hxx"
+
+#include <tools/rc.hxx>
+
+//=========================================================================
+
+// 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 ); }
+
+};
+
+#endif // SC_RESOURCEPUBLISHER_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
new file mode 100644
index 0000000..cd2fd2f
--- /dev/null
+++ b/sc/source/core/data/funcdesc.cxx
@@ -0,0 +1,761 @@
+/* -*- 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 "funcres.hxx"
+#include "global.hxx"
+#include "resourcepublisher.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 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 (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;
+}
+
+/* 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..6d42ad2 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -84,6 +84,7 @@
 #include "compiler.hxx"
 #include "parclass.hxx"
 #include "funcdesc.hxx"
+#include "funcres.hxx"
 #include "globstr.hrc"
 #include "scfuncs.hrc"
 #include "sc.hrc"
@@ -1096,26 +1097,6 @@ 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 )
@@ -1195,719 +1176,6 @@ 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 \
-- 
1.7.0.4

From 16829cefa5d84b0a15b0ea3c5ab9b19f54ac25d9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20M=C3=B6ller?= <soerenmoeller2001@gmail.com>
Date: Wed, 12 Jan 2011 20:39:58 +0100
Subject: [PATCH 2/3] Minor fixes to the previous patch

---
 sc/inc/funcres.hxx           |   45 -----------------------------------
 sc/inc/resourcepublisher.hxx |   54 ------------------------------------------
 2 files changed, 0 insertions(+), 99 deletions(-)
 delete mode 100644 sc/inc/funcres.hxx
 delete mode 100644 sc/inc/resourcepublisher.hxx

diff --git a/sc/inc/funcres.hxx b/sc/inc/funcres.hxx
deleted file mode 100644
index 3c010dd..0000000
--- a/sc/inc/funcres.hxx
+++ /dev/null
@@ -1,45 +0,0 @@
-/* -*- 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.
- *
- ************************************************************************/
-
-#ifndef SC_FUNCRES_HXX
-#define SC_FUNCRES_HXX
-
-//===================================================================
-//             class ScFuncRes
-// fuer temporaere Objekte zum Holen der Resourcen
-
-class ScFuncRes : public Resource
-{
-public:
-    ScFuncRes( ResId&, ScFuncDesc*, bool & rbSuppressed );
-
-private:
-    USHORT GetNum();
-};
-
-#endif //SC_FUNCRES_HXX
diff --git a/sc/inc/resourcepublisher.hxx b/sc/inc/resourcepublisher.hxx
deleted file mode 100644
index 9d3d6e3..0000000
--- a/sc/inc/resourcepublisher.hxx
+++ /dev/null
@@ -1,54 +0,0 @@
-/* -*- 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.
- *
- ************************************************************************/
-
-#ifndef SC_RESOURCEPUBLISHER_HXX
-#define SC_RESOURCEPUBLISHER_HXX
-
-#include "scresid.hxx"
-
-#include <tools/rc.hxx>
-
-//=========================================================================
-
-// 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 ); }
-
-};
-
-#endif // SC_RESOURCEPUBLISHER_HXX
-
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-- 
1.7.0.4

From 55866022ba71f0e87520d72ac8555a3345b4a989 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=B6ren=20M=C3=B6ller?= <soerenmoeller2001@gmail.com>
Date: Wed, 12 Jan 2011 20:43:48 +0100
Subject: [PATCH 3/3] Minor fixes to the previous patches

---
 sc/inc/funcdesc.hxx              |   21 +++---
 sc/source/core/data/funcdesc.cxx |  129 +++++++++++++++++++++++++++++++++-----
 sc/source/core/data/global.cxx   |   77 ----------------------
 3 files changed, 123 insertions(+), 104 deletions(-)

diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index 5f3ca7e..f204571 100644
--- a/sc/inc/funcdesc.hxx
+++ b/sc/inc/funcdesc.hxx
@@ -37,33 +37,32 @@
 #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;
 
 /**
-  Contains description of a function
+  Stores and generates human readable descriptions for spreadsheet-functions,
+  e.g. functions used in formulas in calc
 */
 class ScFuncDesc : public formula::IFunctionDescription
 {
 public:
-    /**
-      Constructor
-    */
     ScFuncDesc();
-
-    /**
-      Destructor
-    */
     virtual ~ScFuncDesc();
 
     /**
-      Resets the object in a clean manner
+      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();
 
@@ -198,7 +197,7 @@ public:
     };
 
 
-    /* Public variables */
+
     ::rtl::OUString      *pFuncName;              // Function name
     ::rtl::OUString      *pFuncDesc;              // Description of function
     ::rtl::OUString     **ppDefArgNames;          // Parameter name(s)
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
index cd2fd2f..e12081a 100644
--- a/sc/source/core/data/funcdesc.cxx
+++ b/sc/source/core/data/funcdesc.cxx
@@ -32,9 +32,7 @@
 #include "appoptio.hxx"
 #include "callform.hxx"
 #include "compiler.hxx"
-#include "funcres.hxx"
 #include "global.hxx"
-#include "resourcepublisher.hxx"
 #include "sc.hrc"
 #include "scmod.hxx"
 #include "scresid.hxx"
@@ -49,6 +47,28 @@
 
 #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:
 
@@ -77,11 +97,11 @@ ScFuncDesc::~ScFuncDesc()
 
 void ScFuncDesc::Clear()
 {
-    USHORT nArgs = nArgCount;
+    sal_uInt16 nArgs = nArgCount;
     if (nArgs >= VAR_ARGS) nArgs -= VAR_ARGS-1;
     if (nArgs)
     {
-        for (USHORT i=0; i<nArgs; i++ )
+        for (sal_uInt16 i=0; i<nArgs; i++ )
         {
             delete ppDefArgNames[i];
             delete ppDefArgDescs[i];
@@ -120,9 +140,9 @@ void ScFuncDesc::Clear()
     {
         if ( nArgCount < VAR_ARGS )
         {
-            USHORT nLastSuppressed = nArgCount;
-            USHORT nLastAdded = nArgCount;
-            for ( USHORT i=0; i<nArgCount; i++ )
+            sal_uInt16 nLastSuppressed = nArgCount;
+            sal_uInt16 nLastAdded = nArgCount;
+            for ( sal_uInt16 i=0; i<nArgCount; i++ )
             {
                 if (pDefArgFlags[i].bSuppress)
                     nLastSuppressed = i;
@@ -145,8 +165,8 @@ void ScFuncDesc::Clear()
         }
         else
         {
-            USHORT nFix = nArgCount - VAR_ARGS;
-            for ( USHORT nArg = 0; nArg < nFix; nArg++ )
+            sal_uInt16 nFix = nArgCount - VAR_ARGS;
+            for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
             {
                 if (!pDefArgFlags[nArg].bSuppress)
                 {
@@ -239,16 +259,16 @@ void ScFuncDesc::Clear()
 
 //------------------------------------------------------------------------
 
-USHORT ScFuncDesc::GetSuppressedArgCount() const
+sal_uInt16 ScFuncDesc::GetSuppressedArgCount() const
 {
     if (!bHasSuppressedArgs || !pDefArgFlags)
         return nArgCount;
 
-    USHORT nArgs = nArgCount;
+    sal_uInt16 nArgs = nArgCount;
     if (nArgs >= VAR_ARGS)
         nArgs -= VAR_ARGS - 1;
-    USHORT nCount = nArgs;
-    for (USHORT i=0; i < nArgs; ++i)
+    sal_uInt16 nCount = nArgs;
+    for (sal_uInt16 i=0; i < nArgs; ++i)
     {
         if (pDefArgFlags[i].bSuppress)
             --nCount;
@@ -288,7 +308,7 @@ xub_StrLen ScFuncDesc::getSuppressedArgumentCount() const
 }
 // -----------------------------------------------------------------------------
 //
-void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<USHORT>& _rArguments) const
+void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<sal_uInt16>& _rArguments) const
 {
     if (!bHasSuppressedArgs || !pDefArgFlags)
     {
@@ -297,10 +317,10 @@ void ScFuncDesc::fillVisibleArgumentMapping(::std::vector<USHORT>& 
_rArguments)
     }
 
     _rArguments.reserve( nArgCount);
-    USHORT nArgs = nArgCount;
+    sal_uInt16 nArgs = nArgCount;
     if (nArgs >= VAR_ARGS)
         nArgs -= VAR_ARGS - 1;
-    for (USHORT i=0; i < nArgs; ++i)
+    for (sal_uInt16 i=0; i < nArgs; ++i)
     {
         if (!pDefArgFlags[i].bSuppress)
             _rArguments.push_back(i);
@@ -758,4 +778,81 @@ sal_Unicode ScFunctionMgr::getSingleToken(const 
formula::IFunctionManager::EToke
     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 6d42ad2..6e04c9d 100644
--- a/sc/source/core/data/global.cxx
+++ b/sc/source/core/data/global.cxx
@@ -84,7 +84,6 @@
 #include "compiler.hxx"
 #include "parclass.hxx"
 #include "funcdesc.hxx"
-#include "funcres.hxx"
 #include "globstr.hrc"
 #include "scfuncs.hrc"
 #include "sc.hrc"
@@ -1099,82 +1098,6 @@ void ScGlobal::AddLanguage( SfxItemSet& rSet, SvNumberFormatter& rFormatter )
 
 //--------------------------------------------------------------------
 
-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();
-}
 
 
 //------------------------------------------------------------------------
-- 
1.7.0.4


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.