[Libreoffice-commits] core.git: 2 commits - formula/source include/formula reportdesign/source sc/inc sc/qa sc/source

Eike Rathke erack at redhat.com
Thu Dec 17 06:15:37 PST 2015


 formula/source/core/resource/core_resource.src |    7 +++
 formula/source/ui/dlg/FormulaHelper.cxx        |    1 
 formula/source/ui/dlg/parawin.cxx              |   20 +++++---
 include/formula/IFunctionDescription.hxx       |    1 
 include/formula/compiler.hrc                   |    3 -
 include/formula/opcode.hxx                     |    1 
 reportdesign/source/ui/inc/FunctionHelper.hxx  |    1 
 reportdesign/source/ui/misc/FunctionHelper.cxx |   18 ++++++++
 sc/inc/funcdesc.hxx                            |   10 ++++
 sc/inc/helpids.h                               |    1 
 sc/qa/unit/ucalc.cxx                           |    1 
 sc/source/core/data/funcdesc.cxx               |   56 +++++++++++++++++++------
 sc/source/core/inc/interpre.hxx                |    1 
 sc/source/core/tool/interpr4.cxx               |    1 
 sc/source/core/tool/interpr6.cxx               |   23 ++++++++++
 sc/source/filter/excel/xlformula.cxx           |    3 -
 sc/source/filter/oox/formulabase.cxx           |    3 -
 sc/source/ui/src/scfuncs.src                   |   39 +++++++++++++++++
 18 files changed, 166 insertions(+), 24 deletions(-)

New commits:
commit 4eea9f214682008052424479a4b1f8cf90a79132
Author: Eike Rathke <erack at redhat.com>
Date:   Thu Dec 17 15:12:06 2015 +0100

    handle varargs with first required and subsequent optional, tdf#71459 related
    
    Change-Id: I56c66f516ba2a2e12cab4848c8c352315f27b3bb

diff --git a/formula/source/ui/dlg/FormulaHelper.cxx b/formula/source/ui/dlg/FormulaHelper.cxx
index 1e296f7..b2ff0c4 100644
--- a/formula/source/ui/dlg/FormulaHelper.cxx
+++ b/formula/source/ui/dlg/FormulaHelper.cxx
@@ -45,6 +45,7 @@ namespace formula
             virtual OUString getSignature() const override { return OUString(); }
             virtual OString getHelpId() const override { return ""; }
             virtual sal_uInt32 getParameterCount() const override { return 0; }
+            virtual sal_uInt32 getVarArgsStart() const override { return 0; }
             virtual OUString getParameterName(sal_uInt32 ) const override { return OUString(); }
             virtual OUString getParameterDescription(sal_uInt32 ) const override { return OUString(); }
             virtual bool isParameterOptional(sal_uInt32 ) const override { return false; }
diff --git a/formula/source/ui/dlg/parawin.cxx b/formula/source/ui/dlg/parawin.cxx
index e32d257..ee09472 100644
--- a/formula/source/ui/dlg/parawin.cxx
+++ b/formula/source/ui/dlg/parawin.cxx
@@ -136,8 +136,9 @@ void ParaWin::UpdateArgDesc( sal_uInt16 nArg )
                     aVisibleArgMapping[nPos] : aVisibleArgMapping.back());
             aArgDesc  = pFuncDesc->getParameterDescription(nRealArg);
             aArgName  = pFuncDesc->getParameterName(nRealArg);
-            if ( nArg >= nFix )
-                aArgName += OUString::number( nArg-nFix+1 );
+            sal_uInt16 nVarArgsStart = pFuncDesc->getVarArgsStart();
+            if ( nArg >= nVarArgsStart )
+                aArgName += OUString::number( nArg-nVarArgsStart+1 );
             aArgName += " ";
 
             aArgName += (nArg > nFix || pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
@@ -154,8 +155,9 @@ void ParaWin::UpdateArgDesc( sal_uInt16 nArg )
                     aVisibleArgMapping[nPos] : aVisibleArgMapping.back());
             aArgDesc  = pFuncDesc->getParameterDescription(nRealArg);
             aArgName  = pFuncDesc->getParameterName(nRealArg);
-            if ( nArg >= nFix )
-                aArgName += OUString::number( (nArg-nFix)/2 + 1 );
+            sal_uInt16 nVarArgsStart = pFuncDesc->getVarArgsStart();
+            if ( nArg >= nVarArgsStart )
+                aArgName += OUString::number( (nArg-nVarArgsStart)/2 + 1 );
             aArgName += " ";
 
             aArgName += (nArg > (nFix+1) || pFuncDesc->isParameterOptional(nRealArg)) ? m_sOptional : m_sRequired ;
@@ -188,10 +190,11 @@ void ParaWin::UpdateArgInput( sal_uInt16 nOffset, sal_uInt16 i )
         SetArgNameFont( i,
                 (nArg > nFix || pFuncDesc->isParameterOptional(nRealArg)) ?
                 aFntLight : aFntBold );
-        if ( nArg >= nFix )
+        sal_uInt16 nVarArgsStart = pFuncDesc->getVarArgsStart();
+        if ( nArg >= nVarArgsStart )
         {
             OUString aArgName( pFuncDesc->getParameterName(nRealArg) );
-            aArgName += OUString::number(nArg-nFix+1);
+            aArgName += OUString::number(nArg-nVarArgsStart+1);
             SetArgName( i, aArgName );
         }
         else
@@ -210,10 +213,11 @@ void ParaWin::UpdateArgInput( sal_uInt16 nOffset, sal_uInt16 i )
         SetArgNameFont( i,
                 (nArg > (nFix+1) || pFuncDesc->isParameterOptional(nRealArg)) ?
                 aFntLight : aFntBold );
-        if ( nArg >= nFix )
+        sal_uInt16 nVarArgsStart = pFuncDesc->getVarArgsStart();
+        if ( nArg >= nVarArgsStart )
         {
             OUString aArgName( pFuncDesc->getParameterName(nRealArg) );
-            aArgName += OUString::number( (nArg-nFix)/2 + 1 );
+            aArgName += OUString::number( (nArg-nVarArgsStart)/2 + 1 );
             SetArgName( i, aArgName );
         }
         else
diff --git a/include/formula/IFunctionDescription.hxx b/include/formula/IFunctionDescription.hxx
index 0d93429f..1c7ccb9 100644
--- a/include/formula/IFunctionDescription.hxx
+++ b/include/formula/IFunctionDescription.hxx
@@ -91,6 +91,7 @@ namespace formula
 
         // parameter
         virtual sal_uInt32 getParameterCount() const = 0;
+        virtual sal_uInt32 getVarArgsStart() const = 0;
         virtual OUString getParameterName(sal_uInt32 _nPos) const = 0;
         virtual OUString getParameterDescription(sal_uInt32 _nPos) const = 0;
         virtual bool isParameterOptional(sal_uInt32 _nPos) const = 0;
diff --git a/reportdesign/source/ui/inc/FunctionHelper.hxx b/reportdesign/source/ui/inc/FunctionHelper.hxx
index 73142dd..2302d75 100644
--- a/reportdesign/source/ui/inc/FunctionHelper.hxx
+++ b/reportdesign/source/ui/inc/FunctionHelper.hxx
@@ -72,6 +72,7 @@ public:
     virtual OUString getSignature() const override ;
     virtual OString getHelpId() const override ;
     virtual sal_uInt32 getParameterCount() const override ;
+    virtual sal_uInt32 getVarArgsStart() const override;
     virtual OUString getParameterName(sal_uInt32 _nPos) const override ;
     virtual OUString getParameterDescription(sal_uInt32 _nPos) const override ;
     virtual bool isParameterOptional(sal_uInt32 _nPos) const override ;
diff --git a/reportdesign/source/ui/misc/FunctionHelper.cxx b/reportdesign/source/ui/misc/FunctionHelper.cxx
index d14ee0a..a92fc49 100644
--- a/reportdesign/source/ui/misc/FunctionHelper.cxx
+++ b/reportdesign/source/ui/misc/FunctionHelper.cxx
@@ -198,6 +198,24 @@ sal_uInt32 FunctionDescription::getParameterCount() const
     return m_aParameter.getLength();
 }
 
+sal_uInt32 FunctionDescription::getVarArgsStart() const
+{
+    /* XXX there are no variable number of arguments, are there? Nevertheless
+     * consider the varargs handling of the Function Wizard and return a value
+     * within the bounds of parameters. */
+    // Don't use defines/constants that could change in future, parameter count
+    // could be part of an implicit stable API.
+    // offapi/com/sun/star/report/meta/XFunctionDescription.idl doesn't tell.
+    const sal_uInt32 nVarArgs = 30;         // ugly hard coded VAR_ARGS of formula::ParaWin
+    const sal_uInt32 nPairedVarArgs = 60;   // ugly hard coded PAIRED_VAR_ARGS of formula::ParaWin
+    sal_uInt32 nLen = m_aParameter.getLength();
+    if (nLen >= nPairedVarArgs)
+        nLen -= nPairedVarArgs;
+    else if (nLen >= nVarArgs)
+        nLen -= nVarArgs;
+    return nLen ? nLen - 1 : 0;
+}
+
 OUString FunctionDescription::getParameterName(sal_uInt32 _nPos) const
 {
     if ( _nPos < static_cast<sal_uInt32>(m_aParameter.getLength()) )
diff --git a/sc/inc/funcdesc.hxx b/sc/inc/funcdesc.hxx
index cda94fa..1c2bccd 100644
--- a/sc/inc/funcdesc.hxx
+++ b/sc/inc/funcdesc.hxx
@@ -105,11 +105,18 @@ public:
     /**
       Returns number of arguments
 
-      @return   help id of the function
+      @return   number of arguments
     */
     virtual sal_uInt32 getParameterCount() const override ;
 
     /**
+      Returns start of variable arguments
+
+      @return   start of variable arguments
+    */
+    virtual sal_uInt32 getVarArgsStart() const override ;
+
+    /**
       Returns description of parameter at given position
 
       @param _nPos
@@ -205,6 +212,7 @@ public:
     sal_uInt16            nFIndex;                /**< Unique function index */
     sal_uInt16            nCategory;              /**< Function category */
     sal_uInt16            nArgCount;              /**< All parameter count, suppressed and unsuppressed */
+    sal_uInt16            nVarArgsStart;          /**< Start of variable arguments, for numbering */
     OString          sHelpId;                /**< 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. */
diff --git a/sc/source/core/data/funcdesc.cxx b/sc/source/core/data/funcdesc.cxx
index b9c6e30..729590b 100644
--- a/sc/source/core/data/funcdesc.cxx
+++ b/sc/source/core/data/funcdesc.cxx
@@ -67,6 +67,7 @@ ScFuncDesc::ScFuncDesc() :
         nFIndex         (0),
         nCategory       (0),
         nArgCount       (0),
+        nVarArgsStart   (0),
         bIncomplete     (false),
         bHasSuppressedArgs(false)
 {}
@@ -88,6 +89,7 @@ void ScFuncDesc::Clear()
         delete [] pDefArgFlags;
     }
     nArgCount = 0;
+    nVarArgsStart = 0;
     maDefArgNames.clear();
     maDefArgDescs.clear();
     pDefArgFlags = nullptr;
@@ -140,8 +142,7 @@ OUString ScFuncDesc::GetParamList() const
         }
         else if ( nArgCount < PAIRED_VAR_ARGS)
         {
-            sal_uInt16 nFix = nArgCount - VAR_ARGS;
-            for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
+            for ( sal_uInt16 nArg = 0; nArg < nVarArgsStart; nArg++ )
             {
                 if (!pDefArgFlags[nArg].bSuppress)
                 {
@@ -154,19 +155,18 @@ OUString ScFuncDesc::GetParamList() const
              * 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(maDefArgNames[nFix]);
+            aSig.append(maDefArgNames[nVarArgsStart]);
             aSig.append('1');
             aSig.append(sep);
             aSig.append(' ');
-            aSig.append(maDefArgNames[nFix]);
+            aSig.append(maDefArgNames[nVarArgsStart]);
             aSig.append('2');
             aSig.append(sep);
             aSig.append(" ... ");
         }
         else
         {
-            sal_uInt16 nFix = nArgCount - PAIRED_VAR_ARGS;
-            for ( sal_uInt16 nArg = 0; nArg < nFix; nArg++ )
+            for ( sal_uInt16 nArg = 0; nArg < nVarArgsStart; nArg++ )
             {
                 if (!pDefArgFlags[nArg].bSuppress)
                 {
@@ -176,17 +176,17 @@ OUString ScFuncDesc::GetParamList() const
                 }
             }
 
-            aSig.append(maDefArgNames[nFix]);
+            aSig.append(maDefArgNames[nVarArgsStart]);
             aSig.append('1');
             aSig.append(sep);
-            aSig.append(maDefArgNames[nFix+1]);
+            aSig.append(maDefArgNames[nVarArgsStart+1]);
             aSig.append('1');
             aSig.append(sep);
             aSig.append( " " );
-            aSig.append(maDefArgNames[nFix]);
+            aSig.append(maDefArgNames[nVarArgsStart]);
             aSig.append('2');
             aSig.append(sep);
-            aSig.append(maDefArgNames[nFix+1]);
+            aSig.append(maDefArgNames[nVarArgsStart+1]);
             aSig.append('2');
             aSig.append(sep);
             aSig.append( " ... " );
@@ -359,6 +359,11 @@ sal_uInt32 ScFuncDesc::getParameterCount() const
     return nArgCount;
 }
 
+sal_uInt32 ScFuncDesc::getVarArgsStart() const
+{
+    return nVarArgsStart;
+}
+
 OUString ScFuncDesc::getParameterName(sal_uInt32 _nPos) const
 {
     return maDefArgNames[_nPos];
@@ -799,12 +804,20 @@ ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
     pDesc->sHelpId = ReadByteStringRes();
     pDesc->nArgCount = GetNum();
     sal_uInt16 nArgs = pDesc->nArgCount;
+    sal_uInt16 nVarArgsSet = 0;
     if (nArgs >= PAIRED_VAR_ARGS)
-        nArgs -= PAIRED_VAR_ARGS - 2;
+    {
+        nVarArgsSet = 2;
+        nArgs -= PAIRED_VAR_ARGS - nVarArgsSet;
+    }
     else if (nArgs >= VAR_ARGS)
-        nArgs -= VAR_ARGS - 1;
+    {
+        nVarArgsSet = 1;
+        nArgs -= VAR_ARGS - nVarArgsSet;
+    }
     if (nArgs)
     {
+        pDesc->nVarArgsStart = nArgs - nVarArgsSet;
         pDesc->pDefArgFlags = new ScFuncDesc::ParameterFlags[nArgs];
         for (sal_uInt16 i = 0; i < nArgs; ++i)
         {
@@ -864,6 +877,25 @@ ScFuncRes::ScFuncRes( ResId &aRes, ScFuncDesc* pDesc, bool & rbSuppressed )
         {
             pDesc->maDefArgNames[i] = SC_RESSTR(2*(i+1)  );
             pDesc->maDefArgDescs[i] = SC_RESSTR(2*(i+1)+1);
+            // If empty and variable number of arguments and last parameter and
+            // parameter is optional and the previous is not optional, repeat
+            // previous parameter name and description.
+            if ((pDesc->maDefArgNames[i].isEmpty() || pDesc->maDefArgDescs[i].isEmpty()) &&
+                    nVarArgsSet > 0 && i > nVarArgsSet && (i == nArgs-1 || i == nArgs-2) &&
+                    pDesc->pDefArgFlags[i].bOptional)
+            {
+                sal_uInt16 nPrev = i - nVarArgsSet;
+                if (!pDesc->pDefArgFlags[nPrev].bOptional)
+                {
+                    if (pDesc->maDefArgNames[i].isEmpty())
+                        pDesc->maDefArgNames[i] = pDesc->maDefArgNames[nPrev];
+                    if (pDesc->maDefArgDescs[i].isEmpty())
+                        pDesc->maDefArgDescs[i] = pDesc->maDefArgDescs[nPrev];
+                    // This also means that variable arguments start one
+                    // parameter set earlier.
+                    pDesc->nVarArgsStart -= nVarArgsSet;
+                }
+            }
         }
     }
 
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index 7a8d30f..e8f67e4 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -12392,7 +12392,7 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
         };
         String 2 // Name of Parameter 1
         {
-            Text [ en-US ] = "number" ;
+            Text [ en-US ] = "minuend" ;
         };
         String 3 // Description of Parameter 1
         {
@@ -12400,11 +12400,19 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
         };
         String 4 // Name of Parameter 2
         {
-            Text [ en-US ] = "number " ;
+            Text [ en-US ] = "subtrahend " ;
         };
         String 5 // Description of Parameter 2
         {
-            Text [ en-US ] = "Number 2, number 3, ... are arguments subtracted from first number." ;
+            Text [ en-US ] = "Subtrahend 1, subtrahend 2, ... are numerical arguments subtracted from the minuend." ;
+        };
+        String 6 // Name of Parameter 3, empty dummy to repeat Parameter 2, now optional
+        {
+            Text = "" ;
+        };
+        String 7 // Description of Parameter 3, empty dummy to repeat Parameter 2, now optional
+        {
+            Text = "" ;
         };
     };
 };
commit db1e34aecd4290623a74b9bbeb602e072b1a49ec
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Dec 16 22:22:13 2015 +0100

    add RAWSUBTRACT spreadsheet function, tdf#71459
    
    Change-Id: I2ae13771c85044b771e253a8189a30cb4aecb30f

diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index 90cd6e5..7b69e05 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -435,6 +435,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
     String SC_OPCODE_ERF_MS { Text = "COM.MICROSOFT.ERF.PRECISE" ; };
     String SC_OPCODE_ERFC_MS { Text = "COM.MICROSOFT.ERFC.PRECISE" ; };
     String SC_OPCODE_ENCODEURL     { Text = "COM.MICROSOFT.ENCODEURL"; };
+    String SC_OPCODE_RAWSUBTRACT    { Text = "ORG.LIBREOFFICE.RAWSUBTRACT"; };
 };
 
 /** These function names are used only in the XLSX import. */
@@ -857,6 +858,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_OOXML
     String SC_OPCODE_ERF_MS { Text = "_xlfn.ERF.PRECISE" ; };
     String SC_OPCODE_ERFC_MS { Text = "_xlfn.ERFC.PRECISE" ; };
     String SC_OPCODE_ENCODEURL     { Text = "_xlfn.ENCODEURL"; };
+    String SC_OPCODE_RAWSUBTRACT    { Text = "_xlfn.ORG.LIBREOFFICE.RAWSUBTRACT"; };
 };
 
 // DO NOT CHANGE NAMES! Only add functions.
@@ -1281,6 +1283,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH
     String SC_OPCODE_ERF_MS { Text = "ERF.PRECISE" ; };
     String SC_OPCODE_ERFC_MS { Text = "ERFC.PRECISE" ; };
     String SC_OPCODE_ENCODEURL     { Text = "ENCODEURL"; };
+    String SC_OPCODE_RAWSUBTRACT    { Text = "RAWSUBTRACT"; };
 };
 
 Resource RID_STRLIST_FUNCTION_NAMES
@@ -2879,6 +2882,10 @@ Resource RID_STRLIST_FUNCTION_NAMES
     {
         Text [ en-US ] = "ENCODEURL";
     };
+    String SC_OPCODE_RAWSUBTRACT
+    {
+        Text [ en-US ] = "RAWSUBTRACT";
+    };
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/compiler.hrc b/include/formula/compiler.hrc
index 984ec02..5e8f7b5 100644
--- a/include/formula/compiler.hrc
+++ b/include/formula/compiler.hrc
@@ -485,7 +485,8 @@
 #define SC_OPCODE_NETWORKDAYS       474
 #define SC_OPCODE_FLOOR_MATH        475
 #define SC_OPCODE_FLOOR_PRECISE     476
-#define SC_OPCODE_STOP_2_PAR        477     /* last function with two or more parameters' OpCode + 1 */
+#define SC_OPCODE_RAWSUBTRACT       477
+#define SC_OPCODE_STOP_2_PAR        478     /* last function with two or more parameters' OpCode + 1 */
 
 #define SC_OPCODE_STOP_FUNCTION     SC_OPCODE_STOP_2_PAR            /* last function's OpCode + 1 */
 #define SC_OPCODE_LAST_OPCODE_ID    (SC_OPCODE_STOP_FUNCTION - 1)   /* last OpCode */
diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx
index 0c4c8e8..a767dfc 100644
--- a/include/formula/opcode.hxx
+++ b/include/formula/opcode.hxx
@@ -281,6 +281,7 @@ enum OpCode : sal_uInt16
         ocEffective         = SC_OPCODE_EFFECTIVE,
         ocNominal           = SC_OPCODE_NOMINAL,
         ocSubTotal          = SC_OPCODE_SUB_TOTAL,
+        ocRawSubtract       = SC_OPCODE_RAWSUBTRACT,
     // Database functions
         ocDBSum             = SC_OPCODE_DB_SUM,
         ocDBCount           = SC_OPCODE_DB_COUNT,
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index 3b41eb8..6f2ab4e 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -632,5 +632,6 @@
 #define HID_FUNC_CEIL_MATH                                      "SC_HID_FUNC_CEIL_MATH"
 #define HID_FUNC_FLOOR_MATH                                     "SC_HID_FUNC_FLOOR_MATH"
 #define HID_FUNC_FLOOR_PRECISE                                  "SC_HID_FUNC_FLOOR_PRECISE"
+#define HID_FUNC_RAWSUBTRACT                                    "SC_HID_FUNC_RAWSUBTRACT"
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index bf22802..8de363a 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -2529,6 +2529,7 @@ void Test::testFunctionLists()
         "PRODUCT",
         "RADIANS",
         "RAND",
+        "RAWSUBTRACT",
         "ROUND",
         "ROUNDDOWN",
         "ROUNDUP",
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 9bdb461..eefd16a 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -515,6 +515,7 @@ void ScVar( bool bTextAsZero = false );
 void ScVarP( bool bTextAsZero = false );
 void ScStDev( bool bTextAsZero = false );
 void ScStDevP( bool bTextAsZero = false );
+void ScRawSubtract();
 void ScColumns();
 void ScRows();
 void ScSheets();
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index d6b9694..36047f8 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -3769,6 +3769,7 @@ StackVar ScInterpreter::Interpret()
                 case ocSumX2MY2         : ScSumX2MY2();                 break;
                 case ocSumX2DY2         : ScSumX2DY2();                 break;
                 case ocSumXMY2          : ScSumXMY2();                  break;
+                case ocRawSubtract      : ScRawSubtract();              break;
                 case ocLog              : ScLog();                      break;
                 case ocGCD              : ScGCD();                      break;
                 case ocLCM              : ScLCM();                      break;
diff --git a/sc/source/core/tool/interpr6.cxx b/sc/source/core/tool/interpr6.cxx
index 5bf4533..27d88c8 100644
--- a/sc/source/core/tool/interpr6.cxx
+++ b/sc/source/core/tool/interpr6.cxx
@@ -898,4 +898,27 @@ void ScInterpreter::ScCount2()
     PushDouble( IterateParameters( ifCOUNT2 ) );
 }
 
+void ScInterpreter::ScRawSubtract()
+{
+    short nParamCount = GetByte();
+    if (!MustHaveParamCountMin( nParamCount, 2))
+        return;
+
+    // Fish the 1st parameter from the stack and push it on top.
+    FormulaToken* p = pStack[ sp - nParamCount ];
+    PushWithoutError( *p );
+    // Obtain the minuend.
+    double fRes = GetDouble();
+
+    while (!nGlobalError && nParamCount-- > 1)
+    {
+        // Simple single values without matrix support.
+        fRes -= GetDouble();
+    }
+    while (nParamCount-- > 0)
+        PopError();
+
+    PushDouble( fRes);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/filter/excel/xlformula.cxx b/sc/source/filter/excel/xlformula.cxx
index 5d060cf..550d9e7 100644
--- a/sc/source/filter/excel/xlformula.cxx
+++ b/sc/source/filter/excel/xlformula.cxx
@@ -587,7 +587,8 @@ static const XclFunctionInfo saFuncTable_Odf[] =
 static const XclFunctionInfo saFuncTable_OOoLO[] =
 {
     EXC_FUNCENTRY_OOO( ocConvert,       3,  3,  0,  "ORG.OPENOFFICE.CONVERT" ),
-    EXC_FUNCENTRY_OOO( ocColor,         3,  4,  0,  "ORG.LIBREOFFICE.COLOR" )
+    EXC_FUNCENTRY_OOO( ocColor,         3,  4,  0,  "ORG.LIBREOFFICE.COLOR" ),
+    EXC_FUNCENTRY_OOO( ocRawSubtract,   2, MX,  0,  "ORG.LIBREOFFICE.RAWSUBTRACT" )
 };
 
 #undef EXC_FUNCENTRY_OOO
diff --git a/sc/source/filter/oox/formulabase.cxx b/sc/source/filter/oox/formulabase.cxx
index b17a896..bf894e1 100644
--- a/sc/source/filter/oox/formulabase.cxx
+++ b/sc/source/filter/oox/formulabase.cxx
@@ -925,7 +925,8 @@ static const FunctionData saFuncTableOOoLO[] =
     { "ORG.OPENOFFICE.ROT13",       "COM.SUN.STAR.SHEET.ADDIN.DATEFUNCTIONS.GETROT13",       NOID,   NOID,   1,  1,  V, { VR }, FUNCFLAG_IMPORTONLY | FUNCFLAG_EXTERNAL },
     // Other functions.
     { "ORG.OPENOFFICE.CONVERT",     "ORG.OPENOFFICE.CONVERT",   NOID,   NOID,   3,  3,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
-    { "ORG.LIBREOFFICE.COLOR",      "ORG.LIBREOFFICE.COLOR",    NOID,   NOID,   3,  4,  V, { VR }, FUNCFLAG_MACROCALL_NEW }
+    { "ORG.LIBREOFFICE.COLOR",      "ORG.LIBREOFFICE.COLOR",    NOID,   NOID,   3,  4,  V, { VR }, FUNCFLAG_MACROCALL_NEW },
+    { "ORG.LIBREOFFICE.RAWSUBTRACT","ORG.LIBREOFFICE.RAWSUBTRACT",NOID, NOID,   1, MX,  V, { RX }, FUNCFLAG_MACROCALL_NEW }
 };
 
 const sal_Unicode API_TOKEN_OPEN            = '(';
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index 44287c4..7a8d30f 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -12376,6 +12376,37 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
             Text [ en-US ] = "The lower limit for integration";
         };
     };
+    Resource SC_OPCODE_RAWSUBTRACT
+    {
+        String 1 // Description
+        {
+            Text [ en-US ] = "Returns the subtraction of numbers. Like a-b-c but without eliminating small roundoff errors." ;
+        };
+        ExtraData =
+        {
+            0;
+            ID_FUNCTION_GRP_MATH;
+            U2S( HID_FUNC_RAWSUBTRACT );
+            VAR_ARGS+2; 0; 0; 1;
+            0;
+        };
+        String 2 // Name of Parameter 1
+        {
+            Text [ en-US ] = "number" ;
+        };
+        String 3 // Description of Parameter 1
+        {
+            Text [ en-US ] = "Number from which following arguments are subtracted." ;
+        };
+        String 4 // Name of Parameter 2
+        {
+            Text [ en-US ] = "number " ;
+        };
+        String 5 // Description of Parameter 2
+        {
+            Text [ en-US ] = "Number 2, number 3, ... are arguments subtracted from first number." ;
+        };
+    };
 };
 
 #if defined(U2S)


More information about the Libreoffice-commits mailing list