summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Lillqvist <tml@collabora.com>2014-11-05 00:34:35 +0200
committerTor Lillqvist <tml@collabora.com>2014-11-06 11:49:24 +0200
commitef809ce9480182ea5c4f77843f72d1d45bd48c35 (patch)
tree6c6693039986ff1f60cdee07a3184ee0c5180914
parentc78b58e1a1950ea78dc0f9a5d8abe2fc228b08c2 (diff)
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
-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>