summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--officecfg/registry/schema/org/openoffice/Office/Calc.xcs30
-rw-r--r--sc/inc/calcconfig.hxx14
-rw-r--r--sc/source/core/tool/calcconfig.cxx139
-rw-r--r--sc/source/core/tool/formulagroup.cxx2
-rw-r--r--sc/source/core/tool/formulaopt.cxx68
-rw-r--r--sc/source/core/tool/token.cxx4
-rw-r--r--sc/source/ui/optdlg/calcoptionsdlg.cxx143
-rw-r--r--sc/source/ui/optdlg/calcoptionsdlg.hxx20
-rw-r--r--sc/source/ui/unoobj/docuno.cxx5
-rw-r--r--sc/uiconfig/scalc/ui/formulacalculationoptions.ui117
10 files changed, 517 insertions, 25 deletions
diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs
index cb16b9b7a823..d0eb9d12e026 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 77e944dded6f..3a54efd56a1d 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 8bca2ac5e684..7d50d784a954 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 a5ad10bbfdfa..ab84aa7d82c4 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 346525db0466..22bf4520f484 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 93c3463eaafe..93b3778b1f3f 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 34fc04bffb72..b479aa3a0b6e 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 adac98a09681..5676cfc175b2 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 db2a626175a0..aa555196f025 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 08f2379c5b9f..0aaef4320061 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>