tdf#123388 sw: add PRODUCT table formula

for DOCX interoperability.

Change-Id: Icd19d1e0025e76bc3ff00a347fa2743ed7c8ee06
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/101306
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/inc/calc.hxx b/sw/inc/calc.hxx
index 979e68b..b0f45af 100644
--- a/sw/inc/calc.hxx
+++ b/sw/inc/calc.hxx
@@ -54,7 +54,7 @@ enum SwCalcOper
    CALC_COS=274,           CALC_TAN=275,           CALC_ASIN=276,
    CALC_ACOS=278,          CALC_ATAN=279,          CALC_TDIF=280,
    CALC_ROUND=281,         CALC_DATE=282,          CALC_MONTH=283,
    CALC_DAY=284
    CALC_DAY=284,           CALC_PRODUCT=285
};

// Calculate Operations Strings
@@ -77,6 +77,7 @@ extern const char sCalc_L[];
extern const char sCalc_G[];
extern const char sCalc_Sum[];
extern const char sCalc_Mean[];
extern const char sCalc_Product[];
extern const char sCalc_Min[];
extern const char sCalc_Max[];
extern const char sCalc_Sin[];
diff --git a/sw/qa/extras/ooxmlexport/data/tdf123388.docx b/sw/qa/extras/ooxmlexport/data/tdf123388.docx
new file mode 100644
index 0000000..7d1da2b
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf123388.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
index 19dc4a3a..05ad6a9 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport15.cxx
@@ -133,6 +133,18 @@ DECLARE_OOXMLEXPORT_TEST(testTdf123356, "tdf123356.docx")
    CPPUNIT_ASSERT_EQUAL(OUString("3"), xEnumerationAccess3->getPresentation(false).trim());
}

DECLARE_OOXMLEXPORT_TEST(testTdf123388, "tdf123388.docx")
{
    uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
    uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
    uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());

    // Tests new cell formula PRODUCT
    uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
    CPPUNIT_ASSERT_EQUAL(OUString("PRODUCT(<B2:B3>)"), xEnumerationAccess1->getPresentation(true).trim());
    CPPUNIT_ASSERT_EQUAL(OUString("640"), xEnumerationAccess1->getPresentation(false).trim());
}

DECLARE_OOXMLEXPORT_TEST(testTdf98000_changePageStyle, "tdf98000_changePageStyle.odt")
{
    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx
index 8d0bc3f..b604ff49 100644
--- a/sw/source/core/bastyp/calc.cxx
+++ b/sw/source/core/bastyp/calc.cxx
@@ -83,6 +83,7 @@ const char sCalc_Acos[] =   "acos";
const char sCalc_Atan[] =   "atan";
const char sCalc_Round[]=   "round";
const char sCalc_Date[] =   "date";
const char sCalc_Product[] = "product";

// ATTENTION: sorted list of all operators
struct CalcOp
@@ -117,6 +118,7 @@ CalcOp const aOpTable[] = {
/* OR */      {{sCalc_Or},         CALC_OR},    // log. OR
/* PHD */     {{sCalc_Phd},        CALC_PHD},   // Percentage
/* POW */     {{sCalc_Pow},        CALC_POW},   // Exponentiation
/* PRODUCT */ {{sCalc_Product},    CALC_PRODUCT}, // Product
/* ROUND */   {{sCalc_Round},      CALC_ROUND}, // Rounding
/* SIN */     {{sCalc_Sin},        CALC_SIN},   // Sine
/* SQRT */    {{sCalc_Sqrt},       CALC_SQRT},  // Square root
@@ -675,6 +677,9 @@ SwCalcOper SwCalc::GetToken()
                case CALC_DATE:
                    m_eCurrListOper = CALC_MONTH;
                    break;
                case CALC_PRODUCT:
                    m_eCurrListOper = CALC_MUL;
                    break;
                default:
                    break;
                }
@@ -1192,11 +1197,12 @@ SwSbxValue SwCalc::PrimFunc(bool &rChkPow)
            break;
        }
        case CALC_SUM:
        case CALC_PRODUCT:
        case CALC_DATE:
        case CALC_MIN:
        case CALC_MAX:
        {
            SAL_INFO("sw.calc", "sum/date/min/max");
            SAL_INFO("sw.calc", "sum/product/date/min/max");
            GetToken();
            SwSbxValue nErg = Expr();
            return nErg;
diff --git a/sw/uiconfig/swriter/ui/inputwinmenu.ui b/sw/uiconfig/swriter/ui/inputwinmenu.ui
index a86deca..7d1ff26 100644
--- a/sw/uiconfig/swriter/ui/inputwinmenu.ui
+++ b/sw/uiconfig/swriter/ui/inputwinmenu.ui
@@ -187,6 +187,14 @@
                <property name="use_underline">True</property>
              </object>
            </child>
            <child>
              <object class="GtkMenuItem" id="product">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes" context="inputwinmenu|product">Product</property>
                <property name="use_underline">True</property>
              </object>
            </child>
          </object>
        </child>
      </object>