tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / core / tool / calcconfig.cxx
blobdda6af3c0fc8d3861ab77295e045a154ebce529e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <ostream>
12 #include <formula/FormulaCompiler.hxx>
13 #include <formula/grammar.hxx>
14 #include <formula/opcode.hxx>
15 #include <rtl/ustring.hxx>
16 #include <sal/log.hxx>
17 #include <comphelper/configuration.hxx>
19 #include <calcconfig.hxx>
21 #include <comphelper/configurationlistener.hxx>
23 using comphelper::ConfigurationListener;
25 static rtl::Reference<ConfigurationListener> const & getMiscListener()
27 static rtl::Reference<ConfigurationListener> xListener(new ConfigurationListener(u"/org.openoffice.Office.Common/Misc"_ustr));
28 return xListener;
31 static rtl::Reference<ConfigurationListener> const & getFormulaCalculationListener()
33 static rtl::Reference<ConfigurationListener> xListener(new ConfigurationListener(u"/org.openoffice.Office.Calc/Formula/Calculation"_ustr));
34 return xListener;
37 static ForceCalculationType forceCalculationTypeInit()
39 const char* env = getenv( "SC_FORCE_CALCULATION" );
40 if( env != nullptr )
42 if( strcmp( env, "opencl" ) == 0 )
44 SAL_INFO("sc.core.formulagroup", "Forcing calculations to use OpenCL");
45 return ForceCalculationOpenCL;
47 if( strcmp( env, "threads" ) == 0 )
49 SAL_INFO("sc.core.formulagroup", "Forcing calculations to use threads");
50 return ForceCalculationThreads;
52 if( strcmp( env, "core" ) == 0 )
54 SAL_INFO("sc.core.formulagroup", "Forcing calculations to use core");
55 return ForceCalculationCore;
57 SAL_WARN("sc.core.formulagroup", "Unrecognized value of SC_FORCE_CALCULATION");
58 abort();
60 return ForceCalculationNone;
63 ForceCalculationType ScCalcConfig::getForceCalculationType()
65 static const ForceCalculationType type = forceCalculationTypeInit();
66 return type;
69 bool ScCalcConfig::isOpenCLEnabled()
71 if (comphelper::IsFuzzing())
72 return false;
73 static ForceCalculationType force = getForceCalculationType();
74 if( force != ForceCalculationNone )
75 return force == ForceCalculationOpenCL;
76 static comphelper::ConfigurationListenerProperty<bool> gOpenCLEnabled(getMiscListener(), u"UseOpenCL"_ustr);
77 return gOpenCLEnabled.get();
80 bool ScCalcConfig::isThreadingEnabled()
82 if (comphelper::IsFuzzing())
83 return false;
84 static ForceCalculationType force = getForceCalculationType();
85 if( force != ForceCalculationNone )
86 return force == ForceCalculationThreads;
87 static comphelper::ConfigurationListenerProperty<bool> gThreadingEnabled(getFormulaCalculationListener(), u"UseThreadedCalculationForFormulaGroups"_ustr);
88 return gThreadingEnabled.get();
91 ScCalcConfig::ScCalcConfig() :
92 meStringRefAddressSyntax(formula::FormulaGrammar::CONV_UNSPECIFIED),
93 meStringConversion(StringConversion::LOCALE), // old LibreOffice behavior
94 mbEmptyStringAsZero(false),
95 mbHasStringRefSyntax(false)
97 setOpenCLConfigToDefault();
100 void ScCalcConfig::setOpenCLConfigToDefault()
102 // Keep in order of opcode value, is that clearest? (Random order,
103 // at least, would make no sense at all.)
104 static const OpCodeSet pDefaultOpenCLSubsetOpCodes(new o3tl::sorted_vector<OpCode>({
105 ocAdd,
106 ocSub,
107 ocNegSub,
108 ocMul,
109 ocDiv,
110 ocPow,
111 ocRandom,
112 ocSin,
113 ocCos,
114 ocTan,
115 ocArcTan,
116 ocExp,
117 ocLn,
118 ocSqrt,
119 ocStdNormDist,
120 ocSNormInv,
121 ocRound,
122 ocPower,
123 ocSumProduct,
124 ocMin,
125 ocMax,
126 ocSum,
127 ocProduct,
128 ocAverage,
129 ocCount,
130 ocVar,
131 ocNormDist,
132 ocVLookup,
133 ocCorrel,
134 ocCovar,
135 ocPearson,
136 ocSlope,
137 ocSumIfs}));
139 // Note that these defaults better be kept in sync with those in
140 // officecfg/registry/schema/org/openoffice/Office/Calc.xcs.
141 // Crazy.
142 mbOpenCLSubsetOnly = true;
143 mbOpenCLAutoSelect = true;
144 mnOpenCLMinimumFormulaGroupSize = 100;
145 mpOpenCLSubsetOpCodes = pDefaultOpenCLSubsetOpCodes;
148 void ScCalcConfig::reset()
150 *this = ScCalcConfig();
153 void ScCalcConfig::MergeDocumentSpecific( const ScCalcConfig& r )
155 // String conversion options are per document.
156 meStringConversion = r.meStringConversion;
157 mbEmptyStringAsZero = r.mbEmptyStringAsZero;
158 // INDIRECT ref syntax is per document.
159 meStringRefAddressSyntax = r.meStringRefAddressSyntax;
160 mbHasStringRefSyntax = r.mbHasStringRefSyntax;
163 void ScCalcConfig::SetStringRefSyntax( formula::FormulaGrammar::AddressConvention eConv )
165 meStringRefAddressSyntax = eConv;
166 mbHasStringRefSyntax = true;
169 bool ScCalcConfig::operator== (const ScCalcConfig& r) const
171 return meStringRefAddressSyntax == r.meStringRefAddressSyntax &&
172 meStringConversion == r.meStringConversion &&
173 mbEmptyStringAsZero == r.mbEmptyStringAsZero &&
174 mbHasStringRefSyntax == r.mbHasStringRefSyntax &&
175 mbOpenCLSubsetOnly == r.mbOpenCLSubsetOnly &&
176 mbOpenCLAutoSelect == r.mbOpenCLAutoSelect &&
177 maOpenCLDevice == r.maOpenCLDevice &&
178 mnOpenCLMinimumFormulaGroupSize == r.mnOpenCLMinimumFormulaGroupSize &&
179 *mpOpenCLSubsetOpCodes == *r.mpOpenCLSubsetOpCodes;
182 bool ScCalcConfig::operator!= (const ScCalcConfig& r) const
184 return !operator==(r);
187 OUString ScOpCodeSetToSymbolicString(const ScCalcConfig::OpCodeSet& rOpCodes)
189 OUStringBuffer result(256);
190 formula::FormulaCompiler aCompiler;
191 formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
193 for (auto i = rOpCodes->begin(); i != rOpCodes->end(); ++i)
195 if (i != rOpCodes->begin())
196 result.append(';');
197 result.append(pOpCodeMap->getSymbol(*i));
200 return result.makeStringAndClear();
203 ScCalcConfig::OpCodeSet ScStringToOpCodeSet(std::u16string_view rOpCodes)
205 ScCalcConfig::OpCodeSet result = std::make_shared<o3tl::sorted_vector< OpCode >>();
206 formula::FormulaCompiler aCompiler;
207 formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
209 const formula::OpCodeHashMap& rHashMap(pOpCodeMap->getHashMap());
211 sal_Int32 fromIndex(0);
212 sal_Int32 semicolon;
213 OUString s(OUString::Concat(rOpCodes) + ";");
215 while ((semicolon = s.indexOf(';', fromIndex)) >= 0)
217 if (semicolon > fromIndex)
219 OUString element(s.copy(fromIndex, semicolon - fromIndex));
220 sal_Int32 n = element.toInt32();
221 if (n > 0 || (n == 0 && element == "0"))
222 result->insert(static_cast<OpCode>(n));
223 else
225 auto opcode(rHashMap.find(element));
226 if (opcode != rHashMap.end())
227 result->insert(opcode->second);
228 else
229 SAL_WARN("sc.opencl", "Unrecognized OpCode " << element << " in OpCode set string");
232 fromIndex = semicolon+1;
234 // HACK: Both unary and binary minus have the same string but different opcodes.
235 if( result->find( ocSub ) != result->end())
236 result->insert( ocNegSub );
238 return result;
241 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */