[Libreoffice-commits] core.git: Branch 'private/tml/opencl-default-1' - officecfg/registry sc/inc sc/source sc/uiconfig

Tor Lillqvist tml at collabora.com
Tue Nov 4 14:38:09 PST 2014


 officecfg/registry/schema/org/openoffice/Office/Calc.xcs |   30 +++
 sc/inc/calcconfig.hxx                                    |   14 +
 sc/source/core/tool/calcconfig.cxx                       |  139 +++++++++++++-
 sc/source/core/tool/formulagroup.cxx                     |    2 
 sc/source/core/tool/formulaopt.cxx                       |   68 ++++++-
 sc/source/core/tool/token.cxx                            |    4 
 sc/source/ui/optdlg/calcoptionsdlg.cxx                   |  143 ++++++++++++++-
 sc/source/ui/optdlg/calcoptionsdlg.hxx                   |   20 ++
 sc/source/ui/unoobj/docuno.cxx                           |    5 
 sc/uiconfig/scalc/ui/formulacalculationoptions.ui        |  117 ++++++++++++
 10 files changed, 517 insertions(+), 25 deletions(-)

New commits:
commit 24543f0ec25861b097d3672f265859ff396c4c26
Author: Tor Lillqvist <tml at collabora.com>
Date:   Wed Nov 5 00:34:35 2014 +0200

    More work on the new OpenCL options
    
    Now the new options show up in the "Detailed Calculation Settings" dialog and
    are saved and restored from the per-user configuration.
    
    The code that manipulates the "Detailed Calculation Settings" dialog is quite
    ugly with all its manual hiding and showing of widgets depending on which
    detail it is that is being edited. This also means that the dialog cannot be
    designed using Glade. But no time now to re-work this.
    
    Change-Id: I03a3a51d902084e73aab5a787b588d22ea7578f2

diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index cb16b9b..d0eb9d1 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
@@ -1340,12 +1340,40 @@
         <info>
           <desc>Contains settings for how to calculate formulae.</desc>
         </info>
+	<!-- Note: The default values below probably must correspond
+	to those assigned in setOpenCLConfigToDefault() in
+	sc/source/core/tool/calcconfig.cxx
+	-->
         <prop oor:name="OpenCL" oor:type="xs:boolean" oor:nillable="false">
           <!-- UIHints: Tools - Options  Spreadsheet  Formula -->
           <info>
             <desc>Whether to use OpenCL for formula computation, if available.</desc>
           </info>
-          <value>false</value>
+          <value>true</value>
+        </prop>
+        <prop oor:name="OpenCLSubsetOnly" oor:type="xs:boolean" oor:nillable="false">
+          <!-- UIHints: Tools - Options  Spreadsheet  Formula -->
+          <info>
+            <desc>Whether to use only a subset of OpenCL.</desc>
+          </info>
+          <value>true</value>
+        </prop>
+        <prop oor:name="OpenCLMinimumDataSize" oor:type="xs:int">
+          <!-- UIHints: Tools - Options  Spreadsheet  Formula -->
+          <info>
+            <desc>An approximate lower limit on the number of data cells a spreadsheet formula should use for OpenCL to be considered.</desc>
+          </info>
+          <value>20</value>
+        </prop>
+        <prop oor:name="OpenCLSubsetOpCodes" oor:type="xs:string" oor:nillable="false">
+          <!-- UIHints: Tools - Options  Spreadsheet  Formula -->
+          <info>
+            <desc>The list of operator and function opcodes for which to use OpenCL. If a
+	    formula contains only these operators and functions, it
+	    might be calculated using OpenCL.</desc>
+          </info>
+	  <!-- numeric values correspond to MIN;MAX;SUM;AVERAGE;SUMIFS -->
+          <value>222;223;224;226;403</value>
         </prop>
         <prop oor:name="OpenCLAutoSelect" oor:type="xs:boolean" oor:nillable="false">
           <!-- UIHints: Tools - Options  Spreadsheet  Formula -->
diff --git a/sc/inc/calcconfig.hxx b/sc/inc/calcconfig.hxx
index 77e944d..3a54efd 100644
--- a/sc/inc/calcconfig.hxx
+++ b/sc/inc/calcconfig.hxx
@@ -12,11 +12,11 @@
 
 #include "scdllapi.h"
 
+#include <ostream>
 #include <set>
 
 #include <formula/grammar.hxx>
 #include <formula/opcode.hxx>
-
 #include <rtl/ustring.hxx>
 
 // have to match the registry values
@@ -49,11 +49,13 @@ struct SC_DLLPUBLIC ScCalcConfig
     bool mbOpenCLSubsetOnly:1;
     bool mbOpenCLAutoSelect:1;
     OUString maOpenCLDevice;
-    int mnOpenCLMinimumFormulaGroupSize;
-    std::set<OpCodeEnum> maOpenCLSubsetFunctions;
+    sal_Int32 mnOpenCLMinimumFormulaGroupSize;
+    std::set<OpCodeEnum> maOpenCLSubsetOpCodes;
 
     ScCalcConfig();
 
+    void setOpenCLConfigToDefault();
+
     void reset();
     void MergeDocumentSpecific( const ScCalcConfig& r );
 
@@ -61,6 +63,12 @@ struct SC_DLLPUBLIC ScCalcConfig
     bool operator!= (const ScCalcConfig& r) const;
 };
 
+std::ostream& SC_DLLPUBLIC operator<<(std::ostream& rStream, const ScCalcConfig& rConfig);
+
+OUString SC_DLLPUBLIC ScOpCodeSetToNumberString(const std::set<OpCodeEnum>& rOpCodes);
+OUString SC_DLLPUBLIC ScOpCodeSetToSymbolicString(const std::set<OpCodeEnum>& rOpCodes);
+std::set<OpCodeEnum> SC_DLLPUBLIC ScStringToOpCodeSet(const OUString& rOpCodes);
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/calcconfig.cxx b/sc/source/core/tool/calcconfig.cxx
index 8bca2ac..7d50d78 100644
--- a/sc/source/core/tool/calcconfig.cxx
+++ b/sc/source/core/tool/calcconfig.cxx
@@ -7,18 +7,37 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include <ostream>
+#include <set>
+
+#include <formula/FormulaCompiler.hxx>
+#include <formula/grammar.hxx>
+#include <formula/opcode.hxx>
+#include <rtl/ustring.hxx>
+#include <sfx2/objsh.hxx>
+
 #include "calcconfig.hxx"
+#include "compiler.hxx"
+#include "docsh.hxx"
 
 ScCalcConfig::ScCalcConfig() :
     meStringRefAddressSyntax(formula::FormulaGrammar::CONV_UNSPECIFIED),
     meStringConversion(STRING_CONVERSION_LOCALE_DEPENDENT),     // old LibreOffice behavior
-    mbEmptyStringAsZero(false),
-    mbOpenCLEnabled(true),
-    mbOpenCLSubsetOnly(true),
-    mbOpenCLAutoSelect(true),
-    mnOpenCLMinimumFormulaGroupSize(4),
-    maOpenCLSubsetFunctions {ocAverage, ocMax, ocMin, ocSum, ocSumIfs}
+    mbEmptyStringAsZero(false)
+{
+    setOpenCLConfigToDefault();
+}
+
+void ScCalcConfig::setOpenCLConfigToDefault()
 {
+    // Note that these defaults better be kept in sync with those in
+    // officecfg/registry/schema/org/openoffice/Office/Calc.xcs.
+    // Crazy.
+    mbOpenCLEnabled = true;
+    mbOpenCLSubsetOnly = true;
+    mbOpenCLAutoSelect = true;
+    mnOpenCLMinimumFormulaGroupSize = 20;
+    maOpenCLSubsetOpCodes = {ocMin, ocMax, ocSum, ocAverage, ocSumIfs};
 }
 
 void ScCalcConfig::reset()
@@ -45,7 +64,7 @@ bool ScCalcConfig::operator== (const ScCalcConfig& r) const
            mbOpenCLAutoSelect == r.mbOpenCLAutoSelect &&
            maOpenCLDevice == r.maOpenCLDevice &&
            mnOpenCLMinimumFormulaGroupSize == r.mnOpenCLMinimumFormulaGroupSize &&
-           maOpenCLSubsetFunctions == r.maOpenCLSubsetFunctions;
+           maOpenCLSubsetOpCodes == r.maOpenCLSubsetOpCodes;
 }
 
 bool ScCalcConfig::operator!= (const ScCalcConfig& r) const
@@ -53,4 +72,110 @@ bool ScCalcConfig::operator!= (const ScCalcConfig& r) const
     return !operator==(r);
 }
 
+std::ostream& SC_DLLPUBLIC operator<<(std::ostream& rStream, const ScCalcConfig& rConfig)
+{
+    rStream << "{"
+        "StringRefAddressSyntax=" << rConfig.meStringRefAddressSyntax << ","
+        "StringConversion=" << rConfig.meStringConversion << ","
+        "EmptyStringAsZero=" << (rConfig.mbEmptyStringAsZero?"Y":"N") << ","
+        "OpenCLEnabled=" << (rConfig.mbOpenCLEnabled?"Y":"N") << ","
+        "OpenCLSubsetOnly=" << (rConfig.mbOpenCLSubsetOnly?"Y":"N") << ","
+        "OpenCLAutoSelect=" << (rConfig.mbOpenCLAutoSelect?"Y":"N") << ","
+        "OpenCLDevice='" << rConfig.maOpenCLDevice << "',"
+        "OpenCLMinimumFormulaGroupSize=" << rConfig.mnOpenCLMinimumFormulaGroupSize << ","
+        "OpenCLSubsetOpCodes={" << ScOpCodeSetToSymbolicString(rConfig.maOpenCLSubsetOpCodes) << "}"
+        "}";
+    return rStream;
+}
+
+namespace {
+
+formula::FormulaCompiler::OpCodeMapPtr setup()
+{
+    SfxObjectShell* pObjShell = SfxObjectShell::Current();
+    ScDocShell* pScDocShell = PTR_CAST(ScDocShell, pObjShell);
+
+    if (pScDocShell)
+    {
+        ScDocument& rDoc(pScDocShell->GetDocument());
+        ScCompiler* pComp(new ScCompiler(&rDoc, ScAddress()));
+        return pComp->GetOpCodeMap(css::sheet::FormulaLanguage::NATIVE);
+    }
+
+    return nullptr;
+}
+
+} // anonymous namespace
+
+OUString SC_DLLPUBLIC ScOpCodeSetToNumberString(const std::set<OpCodeEnum>& rOpCodes)
+{
+    OUStringBuffer result;
+
+    for (auto i = rOpCodes.cbegin(); i != rOpCodes.cend(); ++i)
+    {
+        if (i != rOpCodes.cbegin())
+            result.append(';');
+        result.append(static_cast<int>(*i));
+    }
+
+    return result.toString();
+}
+
+OUString SC_DLLPUBLIC ScOpCodeSetToSymbolicString(const std::set<OpCodeEnum>& rOpCodes)
+{
+    OUStringBuffer result;
+    formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(setup());
+
+    if (!pOpCodeMap)
+        return ScOpCodeSetToNumberString(rOpCodes);
+
+    for (auto i = rOpCodes.cbegin(); i != rOpCodes.cend(); ++i)
+    {
+        if (i != rOpCodes.cbegin())
+            result.append(';');
+        result.append(pOpCodeMap->getSymbol(*i));
+    }
+
+    return result.toString();
+}
+
+std::set<OpCodeEnum> SC_DLLPUBLIC ScStringToOpCodeSet(const OUString& rOpCodes)
+{
+    std::set<OpCodeEnum> result;
+    formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(setup());
+
+    OUString s(rOpCodes + ";");
+
+    const formula::OpCodeHashMap *pHashMap(nullptr);
+    if (pOpCodeMap)
+        pHashMap = pOpCodeMap->getHashMap();
+
+    sal_Int32 fromIndex(0);
+    sal_Int32 semicolon;
+    while ((semicolon = s.indexOf(';', fromIndex)) >= 0)
+    {
+        if (semicolon > fromIndex)
+        {
+            OUString element(s.copy(fromIndex, semicolon - fromIndex));
+            sal_Int32 n = element.toInt32();
+            if (n > 0 || (n == 0 && element == "0"))
+                result.insert(static_cast<OpCodeEnum>(n));
+            else if (pHashMap)
+            {
+                auto opcode(pHashMap->find(element));
+                if (opcode != pHashMap->end())
+                    result.insert(opcode->second);
+                else
+                    SAL_WARN("sc.opencl", "Unrecognized OpCode " << element << " in OpCode set string");
+            }
+            else
+            {
+                SAL_WARN("sc.opencl", "No current doc, can't convert from OpCode name to value");
+            }
+        }
+        fromIndex = semicolon+1;
+    }
+    return result;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index a5ad10b..ab84aa7 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -611,7 +611,7 @@ void FormulaGroupInterpreter::enableOpenCL(bool bEnable, bool bEnableCompletely,
     ScCalcConfig aConfig = ScInterpreter::GetGlobalConfig();
     aConfig.mbOpenCLEnabled = bEnable;
     aConfig.mbOpenCLSubsetOnly = !bEnableCompletely;
-    aConfig.maOpenCLSubsetFunctions = rSubsetToEnable;
+    aConfig.maOpenCLSubsetOpCodes = rSubsetToEnable;
     ScInterpreter::SetGlobalConfig(aConfig);
 }
 
diff --git a/sc/source/core/tool/formulaopt.cxx b/sc/source/core/tool/formulaopt.cxx
index 346525d..22bf452 100644
--- a/sc/source/core/tool/formulaopt.cxx
+++ b/sc/source/core/tool/formulaopt.cxx
@@ -200,7 +200,10 @@ SfxPoolItem* ScTpFormulaItem::Clone( SfxItemPool * ) const
 #define SCFORMULAOPT_OPENCL_ENABLED      10
 #define SCFORMULAOPT_OPENCL_AUTOSELECT   11
 #define SCFORMULAOPT_OPENCL_DEVICE       12
-#define SCFORMULAOPT_COUNT               13
+#define SCFORMULAOPT_OPENCL_SUBSET_ONLY  13
+#define SCFORMULAOPT_OPENCL_MIN_SIZE     14
+#define SCFORMULAOPT_OPENCL_SUBSET_OPS   15
+#define SCFORMULAOPT_COUNT               16
 
 Sequence<OUString> ScFormulaCfg::GetPropertyNames()
 {
@@ -218,7 +221,10 @@ Sequence<OUString> ScFormulaCfg::GetPropertyNames()
         "Load/ODFRecalcMode",            // SCFORMULAOPT_ODF_RECALC
         "Calculation/OpenCL",            // SCFORMULAOPT_OPENCL_ENABLED
         "Calculation/OpenCLAutoSelect",  // SCFORMULAOPT_OPENCL_AUTOSELECT
-        "Calculation/OpenCLDevice"   // SCFORMULAOPT_OPENCL_DEVICE
+        "Calculation/OpenCLDevice",      // SCFORMULAOPT_OPENCL_DEVICE
+        "Calculation/OpenCLSubsetOnly",  // SCFORMULAOPT_OPENCL_SUBSET_ONLY
+        "Calculation/OpenCLMinimumDataSize",  // SCFORMULAOPT_OPENCL_MIN_SIZE
+        "Calculation/OpenCLSubsetOpCodes",    // SCFORMULAOPT_OPENCL_SUBSET_OPS
     };
     Sequence<OUString> aNames(SCFORMULAOPT_COUNT);
     OUString* pNames = aNames.getArray();
@@ -231,7 +237,24 @@ Sequence<OUString> ScFormulaCfg::GetPropertyNames()
 ScFormulaCfg::PropsToIds ScFormulaCfg::GetPropNamesToId()
 {
     Sequence<OUString> aPropNames = GetPropertyNames();
-    static sal_uInt16 aVals[] = { SCFORMULAOPT_GRAMMAR, SCFORMULAOPT_ENGLISH_FUNCNAME, SCFORMULAOPT_SEP_ARG, SCFORMULAOPT_SEP_ARRAY_ROW, SCFORMULAOPT_SEP_ARRAY_COL, SCFORMULAOPT_STRING_REF_SYNTAX, SCFORMULAOPT_STRING_CONVERSION, SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO, SCFORMULAOPT_OOXML_RECALC, SCFORMULAOPT_ODF_RECALC, SCFORMULAOPT_OPENCL_ENABLED, SCFORMULAOPT_OPENCL_AUTOSELECT, SCFORMULAOPT_OPENCL_DEVICE };
+    static sal_uInt16 aVals[] = {
+        SCFORMULAOPT_GRAMMAR,
+        SCFORMULAOPT_ENGLISH_FUNCNAME,
+        SCFORMULAOPT_SEP_ARG,
+        SCFORMULAOPT_SEP_ARRAY_ROW,
+        SCFORMULAOPT_SEP_ARRAY_COL,
+        SCFORMULAOPT_STRING_REF_SYNTAX,
+        SCFORMULAOPT_STRING_CONVERSION,
+        SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO,
+        SCFORMULAOPT_OOXML_RECALC,
+        SCFORMULAOPT_ODF_RECALC,
+        SCFORMULAOPT_OPENCL_ENABLED,
+        SCFORMULAOPT_OPENCL_AUTOSELECT,
+        SCFORMULAOPT_OPENCL_DEVICE,
+        SCFORMULAOPT_OPENCL_SUBSET_ONLY,
+        SCFORMULAOPT_OPENCL_MIN_SIZE,
+        SCFORMULAOPT_OPENCL_SUBSET_OPS,
+    };
     OSL_ENSURE( SAL_N_ELEMENTS(aVals) == aPropNames.getLength(), "Properties and ids are out of Sync");
     PropsToIds aPropIdMap;
     for ( sal_uInt16 i=0; i<aPropNames.getLength(); ++i )
@@ -468,6 +491,27 @@ void ScFormulaCfg::UpdateFromProperties( const Sequence<OUString>& aNames )
                     GetCalcConfig().maOpenCLDevice = aOpenCLDevice;
                 }
                 break;
+                case SCFORMULAOPT_OPENCL_SUBSET_ONLY:
+                {
+                    bool bVal = GetCalcConfig().mbOpenCLSubsetOnly;
+                    pValues[nProp] >>= bVal;
+                    GetCalcConfig().mbOpenCLSubsetOnly = bVal;
+                }
+                break;
+                case SCFORMULAOPT_OPENCL_MIN_SIZE:
+                {
+                    sal_Int32 nVal = GetCalcConfig().mnOpenCLMinimumFormulaGroupSize;
+                    pValues[nProp] >>= nVal;
+                    GetCalcConfig().mnOpenCLMinimumFormulaGroupSize = nVal;
+                }
+                break;
+                case SCFORMULAOPT_OPENCL_SUBSET_OPS:
+                {
+                    OUString sVal = ScOpCodeSetToNumberString(GetCalcConfig().maOpenCLSubsetOpCodes);
+                    pValues[nProp] >>= sVal;
+                    GetCalcConfig().maOpenCLSubsetOpCodes = ScStringToOpCodeSet(sVal);
+                }
+                break;
                 default:
                     ;
                 }
@@ -605,6 +649,24 @@ void ScFormulaCfg::Commit()
                 bSetOpenCL = true;
             }
             break;
+            case SCFORMULAOPT_OPENCL_SUBSET_ONLY:
+            {
+                bool bVal = GetCalcConfig().mbOpenCLSubsetOnly;
+                pValues[nProp] <<= bVal;
+            }
+            break;
+            case SCFORMULAOPT_OPENCL_MIN_SIZE:
+            {
+                sal_Int32 nVal = GetCalcConfig().mnOpenCLMinimumFormulaGroupSize;
+                pValues[nProp] <<= nVal;
+            }
+            break;
+            case SCFORMULAOPT_OPENCL_SUBSET_OPS:
+            {
+                OUString sVal = ScOpCodeSetToNumberString(GetCalcConfig().maOpenCLSubsetOpCodes);
+                pValues[nProp] <<= sVal;
+            }
+            break;
             default:
                 ;
         }
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 93c3463..93b3778 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1219,7 +1219,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
 
     if (SC_OPCODE_START_FUNCTION <= eOp && eOp < SC_OPCODE_STOP_FUNCTION)
     {
-        if (ScInterpreter::GetGlobalConfig().mbOpenCLSubsetOnly && ScInterpreter::GetGlobalConfig().maOpenCLSubsetFunctions.find(eOp) == ScInterpreter::GetGlobalConfig().maOpenCLSubsetFunctions.end())
+        if (ScInterpreter::GetGlobalConfig().mbOpenCLSubsetOnly && ScInterpreter::GetGlobalConfig().maOpenCLSubsetOpCodes.find(eOp) == ScInterpreter::GetGlobalConfig().maOpenCLSubsetOpCodes.end())
         {
             meVectorState = FormulaVectorDisabled;
             return;
@@ -1460,7 +1460,7 @@ void ScTokenArray::CheckToken( const FormulaToken& r )
     if (eOp >= SC_OPCODE_START_BIN_OP &&
         eOp <= SC_OPCODE_STOP_UN_OP &&
         ScInterpreter::GetGlobalConfig().mbOpenCLSubsetOnly &&
-        ScInterpreter::GetGlobalConfig().maOpenCLSubsetFunctions.find(eOp) == ScInterpreter::GetGlobalConfig().maOpenCLSubsetFunctions.end())
+        ScInterpreter::GetGlobalConfig().maOpenCLSubsetOpCodes.find(eOp) == ScInterpreter::GetGlobalConfig().maOpenCLSubsetOpCodes.end())
     {
         meVectorState = FormulaVectorDisabled;
         return;
diff --git a/sc/source/ui/optdlg/calcoptionsdlg.cxx b/sc/source/ui/optdlg/calcoptionsdlg.cxx
index 34fc04b..b479aa3 100644
--- a/sc/source/ui/optdlg/calcoptionsdlg.cxx
+++ b/sc/source/ui/optdlg/calcoptionsdlg.cxx
@@ -7,6 +7,7 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  */
 
+#include "calcconfig.hxx"
 #include "calcoptionsdlg.hxx"
 #include "sc.hrc"
 #include "scresid.hxx"
@@ -22,10 +23,13 @@
 namespace {
 
 typedef enum {
-    CALC_OPTION_STRING_CONVERSION = 0,
-    CALC_OPTION_EMPTY_AS_ZERO     = 1,
-    CALC_OPTION_REF_SYNTAX        = 2,
-    CALC_OPTION_ENABLE_OPENCL     = 3
+    CALC_OPTION_STRING_CONVERSION,
+    CALC_OPTION_EMPTY_AS_ZERO,
+    CALC_OPTION_REF_SYNTAX,
+    CALC_OPTION_ENABLE_OPENCL,
+    CALC_OPTION_ENABLE_OPENCL_SUBSET,
+    CALC_OPTION_OPENCL_MIN_SIZE,
+    CALC_OPTION_OPENCL_SUBSET_OPS
 } CalcOptionOrder;
 
 class OptionString : public SvLBoxString
@@ -135,6 +139,8 @@ ScCalcOptionsDialog::ScCalcOptionsDialog(vcl::Window* pParent, const ScCalcConfi
     get(mpFtAnnotation, "annotation");
     get(mpBtnTrue, "true");
     get(mpBtnFalse, "false");
+    get(mpSpinButton, "spinbutton");
+    get(mpEditField, "entry");
     get(mpOpenclInfoList, "opencl_list");
     get(mpBtnAutomaticSelectionTrue, "automatic_select_true");
     get(mpBtnAutomaticSelectionFalse, "automatic_select_false");
@@ -142,6 +148,9 @@ ScCalcOptionsDialog::ScCalcOptionsDialog(vcl::Window* pParent, const ScCalcConfi
     get(mpFtComputeUnits, "compute_units");
     get(mpFtMemory, "memory");
 
+    mpSpinButton->SetModifyHdl(LINK(this, ScCalcOptionsDialog, NumModifiedHdl));
+    mpEditField->SetModifyHdl(LINK(this, ScCalcOptionsDialog, EditModifiedHdl));
+
     mpOpenclInfoList->set_height_request(4* mpOpenclInfoList->GetTextHeight());
     mpOpenclInfoList->SetStyle(mpOpenclInfoList->GetStyle() | WB_CLIPCHILDREN | WB_FORCE_MAKEVISIBLE);
     mpOpenclInfoList->SetHighlightRange();
@@ -166,6 +175,16 @@ ScCalcOptionsDialog::ScCalcOptionsDialog(vcl::Window* pParent, const ScCalcConfi
 
     maCaptionOpenCLEnabled = get<vcl::Window>("opencl_enabled")->GetText();
     maDescOpenCLEnabled = get<vcl::Window>("opencl_enabled_desc")->GetText();
+
+    maCaptionOpenCLSubsetEnabled = get<vcl::Window>("opencl_subset_enabled")->GetText();
+    maDescOpenCLSubsetEnabled = get<vcl::Window>("opencl_subset_enabled_desc")->GetText();
+
+    maCaptionOpenCLMinimumFormulaSize = get<vcl::Window>("opencl_minimum_size")->GetText();
+    maDescOpenCLMinimumFormulaSize = get<vcl::Window>("opencl_minimum_size_desc")->GetText();
+
+    maCaptionOpenCLSubsetOpCodes = get<vcl::Window>("opencl_subset_opcodes")->GetText();
+    maDescOpenCLSubsetOpCodes = get<vcl::Window>("opencl_subset_opcodes_desc")->GetText();
+
     maSoftware = get<vcl::Window>("software")->GetText();
 
     mpLbSettings->set_height_request(8 * mpLbSettings->GetTextHeight());
@@ -198,6 +217,26 @@ SvTreeListEntry *ScCalcOptionsDialog::createBoolItem(const OUString &rCaption, b
     return pEntry;
 }
 
+SvTreeListEntry *ScCalcOptionsDialog::createIntegerItem(const OUString &rCaption, sal_Int32 nValue) const
+{
+    SvTreeListEntry* pEntry = new SvTreeListEntry;
+    pEntry->AddItem(new SvLBoxString(pEntry, 0, OUString()));
+    pEntry->AddItem(new SvLBoxContextBmp(pEntry, 0, Image(), Image(), false));
+    OptionString* pItem = new OptionString(rCaption, toString(nValue));
+    pEntry->AddItem(pItem);
+    return pEntry;
+}
+
+SvTreeListEntry *ScCalcOptionsDialog::createStringItem(const OUString &rCaption, const OUString& sValue) const
+{
+    SvTreeListEntry* pEntry = new SvTreeListEntry;
+    pEntry->AddItem(new SvLBoxString(pEntry, 0, OUString()));
+    pEntry->AddItem(new SvLBoxContextBmp(pEntry, 0, Image(), Image(), false));
+    OptionString* pItem = new OptionString(rCaption, sValue);
+    pEntry->AddItem(pItem);
+    return pEntry;
+}
+
 void ScCalcOptionsDialog::setValueAt(size_t nPos, const OUString &rValue)
 {
     SvTreeList *pModel = mpLbSettings->GetModel();
@@ -296,6 +335,10 @@ void ScCalcOptionsDialog::FillOptionsList()
 
 #if HAVE_FEATURE_OPENCL
     pModel->Insert(createBoolItem(maCaptionOpenCLEnabled,maConfig.mbOpenCLEnabled));
+    pModel->Insert(createBoolItem(maCaptionOpenCLSubsetEnabled,maConfig.mbOpenCLSubsetOnly));
+    pModel->Insert(createIntegerItem(maCaptionOpenCLMinimumFormulaSize,maConfig.mnOpenCLMinimumFormulaGroupSize));
+    pModel->Insert(createStringItem(maCaptionOpenCLSubsetOpCodes,ScOpCodeSetToSymbolicString(maConfig.maOpenCLSubsetOpCodes)));
+
     fillOpenCLList();
 
     mpBtnAutomaticSelectionFalse->Check(!maConfig.mbOpenCLAutoSelect);
@@ -315,6 +358,8 @@ void ScCalcOptionsDialog::SelectionChanged()
             // Formula syntax for INDIRECT function.
             mpBtnTrue->Hide();
             mpBtnFalse->Hide();
+            mpSpinButton->Hide();
+            mpEditField->Hide();
             mpLbOptionEdit->Show();
             mpOpenclInfoList->GetParent()->Hide();
 
@@ -347,6 +392,8 @@ void ScCalcOptionsDialog::SelectionChanged()
             // String conversion for arithmetic operations.
             mpBtnTrue->Hide();
             mpBtnFalse->Hide();
+            mpSpinButton->Hide();
+            mpEditField->Hide();
             mpLbOptionEdit->Show();
             mpOpenclInfoList->GetParent()->Hide();
 
@@ -377,11 +424,14 @@ void ScCalcOptionsDialog::SelectionChanged()
         // booleans
         case CALC_OPTION_EMPTY_AS_ZERO:
         case CALC_OPTION_ENABLE_OPENCL:
+        case CALC_OPTION_ENABLE_OPENCL_SUBSET:
         {
             // Treat empty string as zero.
             mpLbOptionEdit->Hide();
             mpBtnTrue->Show();
             mpBtnFalse->Show();
+            mpSpinButton->Hide();
+            mpEditField->Hide();
 
             bool bValue = false;
             bool bEnable = true;
@@ -401,7 +451,7 @@ void ScCalcOptionsDialog::SelectionChanged()
                         break;  // nothing
                 }
             }
-            else
+            else if ( nSelectedPos == CALC_OPTION_ENABLE_OPENCL )
             {
                 bValue = maConfig.mbOpenCLEnabled;
                 mpFtAnnotation->SetText(maDescOpenCLEnabled);
@@ -414,6 +464,16 @@ void ScCalcOptionsDialog::SelectionChanged()
 
                 OpenCLAutomaticSelectionChanged();
             }
+            else if ( nSelectedPos == CALC_OPTION_ENABLE_OPENCL_SUBSET )
+            {
+                bValue = maConfig.mbOpenCLSubsetOnly;
+                mpFtAnnotation->SetText(maDescOpenCLSubsetEnabled);
+                mpOpenclInfoList->GetParent()->Hide();
+            }
+            else
+            {
+                assert(false);
+            }
 
             if ( bValue )
             {
@@ -437,8 +497,38 @@ void ScCalcOptionsDialog::SelectionChanged()
             }
         }
         break;
-        default:
-            ;
+
+        // numeric fields
+        case CALC_OPTION_OPENCL_MIN_SIZE:
+        {
+            // just one numeric field so far
+            sal_Int32 nValue = maConfig.mnOpenCLMinimumFormulaGroupSize;
+            mpLbOptionEdit->Hide();
+            mpBtnTrue->Hide();
+            mpBtnFalse->Hide();
+            mpSpinButton->Show();
+            mpEditField->Hide();
+            mpOpenclInfoList->GetParent()->Hide();
+            mpFtAnnotation->SetText(maDescOpenCLMinimumFormulaSize);
+            mpSpinButton->SetValue(nValue);
+        }
+        break;
+
+        // strings
+        case CALC_OPTION_OPENCL_SUBSET_OPS:
+        {
+            // just one string field so far
+            OUString sValue = ScOpCodeSetToSymbolicString(maConfig.maOpenCLSubsetOpCodes);
+            mpLbOptionEdit->Hide();
+            mpBtnTrue->Hide();
+            mpBtnFalse->Hide();
+            mpSpinButton->Hide();
+            mpEditField->Show();
+            mpOpenclInfoList->GetParent()->Hide();
+            mpFtAnnotation->SetText(maDescOpenCLSubsetOpCodes);
+            mpEditField->SetText(sValue);
+        }
+        break;
     }
 }
 
@@ -489,6 +579,9 @@ void ScCalcOptionsDialog::ListOptionValueChanged()
 
         case CALC_OPTION_EMPTY_AS_ZERO:
         case CALC_OPTION_ENABLE_OPENCL:
+        case CALC_OPTION_ENABLE_OPENCL_SUBSET:
+        case CALC_OPTION_OPENCL_MIN_SIZE:
+        case CALC_OPTION_OPENCL_SUBSET_OPS:
             break;
     }
 }
@@ -558,11 +651,30 @@ void ScCalcOptionsDialog::RadioValueChanged()
                 mpOpenclInfoList->GetParent()->Disable();
             OpenCLAutomaticSelectionChanged();
             break;
+        case CALC_OPTION_ENABLE_OPENCL_SUBSET:
+            maConfig.mbOpenCLSubsetOnly = bValue;
+            break;
     }
 
     setValueAt(nSelected, toString(bValue));
 }
 
+void ScCalcOptionsDialog::SpinButtonValueChanged()
+{
+    // We know that the mpSpinButton is used for only one thing at the moment,
+    // the OpenCL minimum formula size
+    sal_Int64 nVal = mpSpinButton->GetValue();
+    maConfig.mnOpenCLMinimumFormulaGroupSize = nVal;
+}
+
+void ScCalcOptionsDialog::EditFieldValueChanged()
+{
+    // We know that the mpEditField is used for only one thing at the moment,
+    // the OpenCL subset list of opcodes
+    OUString sVal = mpEditField->GetText();
+    maConfig.maOpenCLSubsetOpCodes = ScStringToOpCodeSet(sVal);
+}
+
 OUString ScCalcOptionsDialog::toString(formula::FormulaGrammar::AddressConvention eConv) const
 {
     switch (eConv)
@@ -601,6 +713,11 @@ OUString ScCalcOptionsDialog::toString(bool bVal) const
     return bVal ? maTrue : maFalse;
 }
 
+OUString ScCalcOptionsDialog::toString(sal_Int32 nVal) const
+{
+    return OUString::number(nVal);
+}
+
 IMPL_LINK(ScCalcOptionsDialog, SettingsSelHdl, Control*, pCtrl)
 {
     if (pCtrl == mpLbSettings)
@@ -629,4 +746,16 @@ IMPL_LINK_NOARG(ScCalcOptionsDialog, DeviceSelHdl)
     return 0;
 }
 
+IMPL_LINK_NOARG(ScCalcOptionsDialog, NumModifiedHdl)
+{
+    SpinButtonValueChanged();
+    return 0;
+}
+
+IMPL_LINK_NOARG(ScCalcOptionsDialog, EditModifiedHdl)
+{
+    EditFieldValueChanged();
+    return 0;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/optdlg/calcoptionsdlg.hxx b/sc/source/ui/optdlg/calcoptionsdlg.hxx
index adac98a..5676cfc 100644
--- a/sc/source/ui/optdlg/calcoptionsdlg.hxx
+++ b/sc/source/ui/optdlg/calcoptionsdlg.hxx
@@ -14,6 +14,8 @@
 
 #include <vcl/dialog.hxx>
 #include <vcl/button.hxx>
+#include <vcl/edit.hxx>
+#include <vcl/field.hxx>
 #include <vcl/fixed.hxx>
 #include <vcl/lstbox.hxx>
 #include <svx/checklbx.hxx>
@@ -35,6 +37,8 @@ public:
     DECL_LINK( BtnToggleHdl, void* );
     DECL_LINK( BtnAutomaticSelectHdl, void* );
     DECL_LINK( DeviceSelHdl, void* );
+    DECL_LINK( NumModifiedHdl, void * );
+    DECL_LINK( EditModifiedHdl, void * );
 
     const ScCalcConfig& GetConfig() const { return maConfig;}
 
@@ -45,6 +49,8 @@ private:
     void RadioValueChanged();
     void OpenCLAutomaticSelectionChanged();
     void SelectedDeviceChanged();
+    void SpinButtonValueChanged();
+    void EditFieldValueChanged();
 #if HAVE_FEATURE_OPENCL
     void fillOpenCLList();
 #endif
@@ -52,7 +58,10 @@ private:
     OUString toString(formula::FormulaGrammar::AddressConvention eConv) const;
     OUString toString(ScCalcConfig::StringConversion eConv) const;
     OUString toString(bool bVal) const;
+    OUString toString(sal_Int32 nVal) const;
     SvTreeListEntry *createBoolItem(const OUString &rCaption, bool bValue) const;
+    SvTreeListEntry *createIntegerItem(const OUString &rCaption, sal_Int32 nValue) const;
+    SvTreeListEntry *createStringItem(const OUString &rCaption, const OUString& sValue) const;
     void     setValueAt(size_t nPos, const OUString &rString);
 
 private:
@@ -61,6 +70,8 @@ private:
     ListBox* mpLbOptionEdit;
     RadioButton* mpBtnTrue;
     RadioButton* mpBtnFalse;
+    NumericField* mpSpinButton;
+    Edit* mpEditField;
 
     FixedText* mpFtAnnotation;
     FixedText* mpFtFrequency;
@@ -96,6 +107,15 @@ private:
     OUString maCaptionOpenCLEnabled;
     OUString maDescOpenCLEnabled;
 
+    OUString maCaptionOpenCLSubsetEnabled;
+    OUString maDescOpenCLSubsetEnabled;
+
+    OUString maCaptionOpenCLMinimumFormulaSize;
+    OUString maDescOpenCLMinimumFormulaSize;
+
+    OUString maCaptionOpenCLSubsetOpCodes;
+    OUString maDescOpenCLSubsetOpCodes;
+
     OUString maSoftware;
 
     ScCalcConfig maConfig;
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index db2a626..aa55519 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -2331,7 +2331,10 @@ void ScModelObj::enableOpenCL(sal_Bool bEnable)
     throw (uno::RuntimeException, std::exception)
 {
     ScCalcConfig aConfig = ScInterpreter::GetGlobalConfig();
-    aConfig.mbOpenCLEnabled = bEnable;
+    if (bEnable)
+        aConfig.setOpenCLConfigToDefault();
+    else
+        aConfig.mbOpenCLEnabled = false;
     ScInterpreter::SetGlobalConfig(aConfig);
 }
 
diff --git a/sc/uiconfig/scalc/ui/formulacalculationoptions.ui b/sc/uiconfig/scalc/ui/formulacalculationoptions.ui
index 08f2379..0aaef43 100644
--- a/sc/uiconfig/scalc/ui/formulacalculationoptions.ui
+++ b/sc/uiconfig/scalc/ui/formulacalculationoptions.ui
@@ -155,6 +155,35 @@
                         <property name="height">1</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkSpinButton" id="spinbutton">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="halign">start</property>
+                        <property name="invisible_char">●</property>
+                        <property name="adjustment">adjustment1</property>
+                        <property name="climb_rate">1</property>
+                        <property name="update_policy">if-valid</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">3</property>
+                        <property name="top_attach">0</property>
+                        <property name="width">1</property>
+                        <property name="height">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="valign">center</property>
+                        <property name="invisible_char">●</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">4</property>
+                        <property name="top_attach">0</property>
+                      </packing>
+                    </child>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
@@ -364,6 +393,94 @@
                 <property name="height">1</property>
               </packing>
             </child>
+
+            <child>
+              <object class="GtkLabel" id="opencl_subset_enabled">
+                <property name="can_focus">False</property>
+                <property name="no_show_all">True</property>
+                <property name="label" translatable="yes">Use OpenCL only for a subset of operations</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">17</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="opencl_subset_enabled_desc">
+                <property name="can_focus">False</property>
+                <property name="no_show_all">True</property>
+                <property name="label" translatable="yes">Use OpenCL only for some of the operations that spreadsheet formulas are translated to.</property>
+                <property name="wrap">True</property>
+                <property name="max_width_chars">56</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">18</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+
+            <child>
+              <object class="GtkLabel" id="opencl_minimum_size">
+                <property name="can_focus">False</property>
+                <property name="no_show_all">True</property>
+                <property name="label" translatable="yes">Minimum data size for OpenCL use</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">19</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="opencl_minimum_size_desc">
+                <property name="can_focus">False</property>
+                <property name="no_show_all">True</property>
+                <property name="label" translatable="yes">An approximate lower limit on the number of data cells a spreadsheet formula should use for OpenCL to be considered.</property>
+                <property name="wrap">True</property>
+                <property name="max_width_chars">56</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">20</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+
+            <child>
+              <object class="GtkLabel" id="opencl_subset_opcodes">
+                <property name="can_focus">False</property>
+                <property name="no_show_all">True</property>
+                <property name="label" translatable="yes">Subset of opcodes for which OpenCL is used</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">21</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="opencl_subset_opcodes_desc">
+                <property name="can_focus">False</property>
+                <property name="no_show_all">True</property>
+                <property name="label" translatable="yes">The list of operator and function opcodes for which to use OpenCL. If a formula contains only these operators and functions, it might be calculated using OpenCL.</property>
+                <property name="wrap">True</property>
+                <property name="max_width_chars">56</property>
+              </object>
+              <packing>
+                <property name="left_attach">0</property>
+                <property name="top_attach">22</property>
+                <property name="width">1</property>
+                <property name="height">1</property>
+              </packing>
+            </child>
+
             <child>
               <object class="GtkGrid" id="grid6">
                 <property name="can_focus">False</property>


More information about the Libreoffice-commits mailing list