2012-05-29 23:25:06 -04:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
|
|
/*
|
2013-04-19 21:10:42 +01:00
|
|
|
* This file is part of the LibreOffice project.
|
2012-05-29 23:25:06 -04:00
|
|
|
*
|
2013-04-19 21:10:42 +01:00
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
2012-05-29 23:25:06 -04:00
|
|
|
*/
|
|
|
|
|
2014-11-05 00:34:35 +02:00
|
|
|
#include <ostream>
|
|
|
|
#include <set>
|
|
|
|
|
|
|
|
#include <formula/FormulaCompiler.hxx>
|
|
|
|
#include <formula/grammar.hxx>
|
|
|
|
#include <formula/opcode.hxx>
|
|
|
|
#include <rtl/ustring.hxx>
|
|
|
|
#include <sfx2/objsh.hxx>
|
|
|
|
|
2012-05-29 23:25:06 -04:00
|
|
|
#include "calcconfig.hxx"
|
2014-11-05 00:34:35 +02:00
|
|
|
#include "compiler.hxx"
|
|
|
|
#include "docsh.hxx"
|
2012-05-29 23:25:06 -04:00
|
|
|
|
2015-10-14 19:28:47 +01:00
|
|
|
#include <comphelper/configurationlistener.hxx>
|
|
|
|
|
|
|
|
using comphelper::ConfigurationListener;
|
|
|
|
|
2016-07-18 09:22:27 +02:00
|
|
|
static rtl::Reference<ConfigurationListener> const & getMiscListener()
|
2015-10-14 19:28:47 +01:00
|
|
|
{
|
|
|
|
static rtl::Reference<ConfigurationListener> xListener;
|
|
|
|
if (!xListener.is())
|
2015-11-04 15:36:18 +02:00
|
|
|
xListener.set(new ConfigurationListener("/org.openoffice.Office.Common/Misc"));
|
2015-10-14 19:28:47 +01:00
|
|
|
return xListener;
|
|
|
|
}
|
|
|
|
|
2015-10-26 11:50:12 +00:00
|
|
|
bool ScCalcConfig::isOpenCLEnabled()
|
|
|
|
{
|
|
|
|
static comphelper::ConfigurationListenerProperty<bool> gOpenCLEnabled(getMiscListener(), OUString("UseOpenCL"));
|
|
|
|
return gOpenCLEnabled.get();
|
|
|
|
}
|
|
|
|
|
2015-11-30 09:44:19 +01:00
|
|
|
bool ScCalcConfig::isSwInterpreterEnabled()
|
|
|
|
{
|
|
|
|
static comphelper::ConfigurationListenerProperty<bool> gSwInterpreterEnabled(getMiscListener(), OUString("UseSwInterpreter"));
|
|
|
|
return gSwInterpreterEnabled.get();
|
|
|
|
}
|
|
|
|
|
2012-05-29 23:25:06 -04:00
|
|
|
ScCalcConfig::ScCalcConfig() :
|
2012-07-23 17:49:03 -04:00
|
|
|
meStringRefAddressSyntax(formula::FormulaGrammar::CONV_UNSPECIFIED),
|
2015-02-07 14:04:53 +02:00
|
|
|
meStringConversion(StringConversion::LOCALE), // old LibreOffice behavior
|
2015-07-23 09:52:59 +02:00
|
|
|
mbEmptyStringAsZero(false),
|
2015-10-26 11:50:12 +00:00
|
|
|
mbHasStringRefSyntax(false)
|
2014-11-05 00:34:35 +02:00
|
|
|
{
|
|
|
|
setOpenCLConfigToDefault();
|
2014-11-06 20:02:22 +02:00
|
|
|
|
|
|
|
// SAL _DEBUG(__FILE__ ":" << __LINE__ << ": ScCalcConfig::ScCalcConfig(): " << *this);
|
2014-11-05 00:34:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void ScCalcConfig::setOpenCLConfigToDefault()
|
2013-06-25 13:38:22 +01:00
|
|
|
{
|
2015-09-16 12:03:19 +03:00
|
|
|
// Keep in order of opcode value, is that clearest? (Random order,
|
|
|
|
// at least, would make no sense at all.)
|
2015-09-18 18:49:56 +03:00
|
|
|
static OpCodeSet pDefaultOpenCLSubsetOpCodes(new std::set<OpCode>({
|
2015-09-16 12:03:19 +03:00
|
|
|
ocAdd,
|
|
|
|
ocSub,
|
|
|
|
ocMul,
|
|
|
|
ocDiv,
|
|
|
|
ocRandom,
|
|
|
|
ocSin,
|
|
|
|
ocCos,
|
|
|
|
ocTan,
|
|
|
|
ocArcTan,
|
|
|
|
ocExp,
|
|
|
|
ocLn,
|
|
|
|
ocSqrt,
|
|
|
|
ocStdNormDist,
|
|
|
|
ocSNormInv,
|
|
|
|
ocRound,
|
|
|
|
ocPower,
|
|
|
|
ocSumProduct,
|
|
|
|
ocMin,
|
|
|
|
ocMax,
|
|
|
|
ocSum,
|
|
|
|
ocProduct,
|
|
|
|
ocAverage,
|
|
|
|
ocCount,
|
|
|
|
ocVar,
|
|
|
|
ocNormDist,
|
|
|
|
ocVLookup,
|
|
|
|
ocCorrel,
|
|
|
|
ocCovar,
|
|
|
|
ocPearson,
|
|
|
|
ocSlope,
|
2015-09-18 18:49:56 +03:00
|
|
|
ocSumIfs}));
|
2015-09-16 12:03:19 +03:00
|
|
|
|
2015-11-24 17:13:21 +01:00
|
|
|
// opcodes that are known to work well with the software interpreter
|
|
|
|
static OpCodeSet pDefaultSwInterpreterSubsetOpCodes(new std::set<OpCode>({
|
|
|
|
ocAdd,
|
|
|
|
ocSub,
|
|
|
|
ocMul,
|
|
|
|
ocDiv,
|
|
|
|
ocSum,
|
|
|
|
ocProduct}));
|
|
|
|
|
2014-11-05 00:34:35 +02:00
|
|
|
// Note that these defaults better be kept in sync with those in
|
|
|
|
// officecfg/registry/schema/org/openoffice/Office/Calc.xcs.
|
|
|
|
// Crazy.
|
|
|
|
mbOpenCLSubsetOnly = true;
|
|
|
|
mbOpenCLAutoSelect = true;
|
2015-01-13 17:07:29 +02:00
|
|
|
mnOpenCLMinimumFormulaGroupSize = 100;
|
2015-09-18 18:49:56 +03:00
|
|
|
mpOpenCLSubsetOpCodes = pDefaultOpenCLSubsetOpCodes;
|
2015-11-24 17:13:21 +01:00
|
|
|
mpSwInterpreterSubsetOpCodes = pDefaultSwInterpreterSubsetOpCodes;
|
2013-06-25 13:38:22 +01:00
|
|
|
}
|
2012-05-29 23:25:06 -04:00
|
|
|
|
2012-05-30 10:03:05 -04:00
|
|
|
void ScCalcConfig::reset()
|
|
|
|
{
|
|
|
|
*this = ScCalcConfig();
|
|
|
|
}
|
|
|
|
|
2014-03-14 23:00:25 +01:00
|
|
|
void ScCalcConfig::MergeDocumentSpecific( const ScCalcConfig& r )
|
|
|
|
{
|
|
|
|
// String conversion options are per document.
|
|
|
|
meStringConversion = r.meStringConversion;
|
|
|
|
mbEmptyStringAsZero = r.mbEmptyStringAsZero;
|
|
|
|
// INDIRECT ref syntax is per document.
|
|
|
|
meStringRefAddressSyntax = r.meStringRefAddressSyntax;
|
2015-07-23 09:52:59 +02:00
|
|
|
mbHasStringRefSyntax = r.mbHasStringRefSyntax;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ScCalcConfig::SetStringRefSyntax( formula::FormulaGrammar::AddressConvention eConv )
|
|
|
|
{
|
|
|
|
meStringRefAddressSyntax = eConv;
|
|
|
|
mbHasStringRefSyntax = true;
|
2014-03-14 23:00:25 +01:00
|
|
|
}
|
|
|
|
|
2012-05-29 23:25:06 -04:00
|
|
|
bool ScCalcConfig::operator== (const ScCalcConfig& r) const
|
|
|
|
{
|
2012-07-23 17:49:03 -04:00
|
|
|
return meStringRefAddressSyntax == r.meStringRefAddressSyntax &&
|
2014-03-13 19:50:14 +01:00
|
|
|
meStringConversion == r.meStringConversion &&
|
2013-06-25 13:38:22 +01:00
|
|
|
mbEmptyStringAsZero == r.mbEmptyStringAsZero &&
|
2015-07-23 09:52:59 +02:00
|
|
|
mbHasStringRefSyntax == r.mbHasStringRefSyntax &&
|
2014-10-30 15:40:54 +02:00
|
|
|
mbOpenCLSubsetOnly == r.mbOpenCLSubsetOnly &&
|
2013-09-16 13:52:51 +02:00
|
|
|
mbOpenCLAutoSelect == r.mbOpenCLAutoSelect &&
|
2014-10-30 15:40:54 +02:00
|
|
|
maOpenCLDevice == r.maOpenCLDevice &&
|
2014-11-03 10:57:39 +02:00
|
|
|
mnOpenCLMinimumFormulaGroupSize == r.mnOpenCLMinimumFormulaGroupSize &&
|
2015-09-18 12:11:41 +03:00
|
|
|
*mpOpenCLSubsetOpCodes == *r.mpOpenCLSubsetOpCodes &&
|
2015-11-24 17:13:21 +01:00
|
|
|
*mpSwInterpreterSubsetOpCodes == *r.mpSwInterpreterSubsetOpCodes &&
|
2014-11-13 15:24:40 +02:00
|
|
|
true;
|
2012-05-29 23:25:06 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool ScCalcConfig::operator!= (const ScCalcConfig& r) const
|
|
|
|
{
|
|
|
|
return !operator==(r);
|
|
|
|
}
|
|
|
|
|
2014-11-07 15:08:07 +02:00
|
|
|
OUString ScOpCodeSetToSymbolicString(const ScCalcConfig::OpCodeSet& rOpCodes)
|
2014-11-05 00:34:35 +02:00
|
|
|
{
|
|
|
|
OUStringBuffer result;
|
2015-01-23 12:47:52 +02:00
|
|
|
formula::FormulaCompiler aCompiler;
|
|
|
|
formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
|
2014-11-05 00:34:35 +02:00
|
|
|
|
2015-09-18 12:11:41 +03:00
|
|
|
for (auto i = rOpCodes->cbegin(); i != rOpCodes->cend(); ++i)
|
2014-11-05 00:34:35 +02:00
|
|
|
{
|
2015-09-18 12:11:41 +03:00
|
|
|
if (i != rOpCodes->cbegin())
|
2014-11-05 00:34:35 +02:00
|
|
|
result.append(';');
|
|
|
|
result.append(pOpCodeMap->getSymbol(*i));
|
|
|
|
}
|
|
|
|
|
|
|
|
return result.toString();
|
|
|
|
}
|
|
|
|
|
2014-11-07 15:08:07 +02:00
|
|
|
ScCalcConfig::OpCodeSet ScStringToOpCodeSet(const OUString& rOpCodes)
|
2014-11-05 00:34:35 +02:00
|
|
|
{
|
2015-09-18 12:11:41 +03:00
|
|
|
ScCalcConfig::OpCodeSet result(new std::set< OpCode >());
|
2015-01-23 12:47:52 +02:00
|
|
|
formula::FormulaCompiler aCompiler;
|
|
|
|
formula::FormulaCompiler::OpCodeMapPtr pOpCodeMap(aCompiler.GetOpCodeMap(css::sheet::FormulaLanguage::ENGLISH));
|
2014-11-05 00:34:35 +02:00
|
|
|
|
2015-01-23 12:47:52 +02:00
|
|
|
const formula::OpCodeHashMap *pHashMap(pOpCodeMap->getHashMap());
|
2014-11-05 00:34:35 +02:00
|
|
|
|
|
|
|
sal_Int32 fromIndex(0);
|
|
|
|
sal_Int32 semicolon;
|
2015-01-23 12:47:52 +02:00
|
|
|
OUString s(rOpCodes + ";");
|
|
|
|
|
2014-11-05 00:34:35 +02:00
|
|
|
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"))
|
2015-09-18 12:11:41 +03:00
|
|
|
result->insert(static_cast<OpCode>(n));
|
2015-01-23 12:47:52 +02:00
|
|
|
else
|
2014-11-05 00:34:35 +02:00
|
|
|
{
|
|
|
|
auto opcode(pHashMap->find(element));
|
|
|
|
if (opcode != pHashMap->end())
|
2015-09-18 12:11:41 +03:00
|
|
|
result->insert(static_cast<OpCode>(opcode->second));
|
2014-11-05 00:34:35 +02:00
|
|
|
else
|
|
|
|
SAL_WARN("sc.opencl", "Unrecognized OpCode " << element << " in OpCode set string");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fromIndex = semicolon+1;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2012-05-29 23:25:06 -04:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|