/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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/.
 */
 
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/lang/Locale.hpp>
#include <osl/diagnose.h>
#include <sal/log.hxx>
#include <unotools/localedatawrapper.hxx>
#include <formulaopt.hxx>
#include <global.hxx>
#include <formulagroup.hxx>
#include <sc.hrc>
#include <utility>
 
using namespace utl;
using namespace com::sun::star::uno;
namespace lang = ::com::sun::star::lang;
 
 
ScFormulaOptions::ScFormulaOptions()
{
    SetDefaults();
}
 
void ScFormulaOptions::SetDefaults()
{
    bUseEnglishFuncName = false;
    eFormulaGrammar     = ::formula::FormulaGrammar::GRAM_NATIVE;
    mbWriteCalcConfig = true;
    meOOXMLRecalc = RECALC_ASK;
    meODFRecalc = RECALC_ASK;
    meReCalcOptiRowHeights = RECALC_ASK;
 
    // unspecified means use the current formula syntax.
    aCalcConfig.reset();
 
    ResetFormulaSeparators();
}
 
void ScFormulaOptions::ResetFormulaSeparators()
{
    GetDefaultFormulaSeparators(aFormulaSepArg, aFormulaSepArrayCol, aFormulaSepArrayRow);
}
 
void ScFormulaOptions::GetDefaultFormulaSeparators(
    OUString& rSepArg, OUString& rSepArrayCol, OUString& rSepArrayRow)
{
    // Defaults to the old separator values.
    rSepArg = ";";
    rSepArrayCol = ";";
    rSepArrayRow = "|";
 
    const lang::Locale& rLocale = ScGlobal::GetLocale();
    const OUString& rLang = rLocale.Language;
    if (rLang == "ru")
        // Don't do automatic guess for these languages, and fall back to
        // the old separator set.
        return;
 
    const LocaleDataWrapper& rLocaleData = ScGlobal::getLocaleData();
    const OUString& rDecSep  = rLocaleData.getNumDecimalSep();
    const OUString& rListSep = rLocaleData.getListSep();
 
    if (rDecSep.isEmpty() || rListSep.isEmpty())
        // Something is wrong.  Stick with the default separators.
        return;
 
    sal_Unicode cDecSep  = rDecSep[0];
    sal_Unicode cListSep = rListSep[0];
    sal_Unicode cDecSepAlt = rLocaleData.getNumDecimalSepAlt().toChar();    // usually 0 (empty)
 
    // Excel by default uses system's list separator as the parameter
    // separator, which in English locales is a comma.  However, OOo's list
    // separator value is set to ';' for all English locales.  Because of this
    // discrepancy, we will hardcode the separator value here, for now.
    // Similar for decimal separator alternative.
    // However, if the decimal separator alternative is '.' and the decimal
    // separator is ',' this makes no sense, fall back to ';' in that case.
    if (cDecSep == '.' || (cDecSepAlt == '.' && cDecSep != ','))
        cListSep = ',';
    else if (cDecSep == ',' && cDecSepAlt == '.')
        cListSep = ';';
 
    // Special case for de_CH locale.
    if (rLocale.Language == "de" && rLocale.Country == "CH")
        cListSep = ';';
 
    // by default, the parameter separator equals the locale-specific
    // list separator.
    rSepArg = OUString(cListSep);
 
    if (cDecSep == cListSep && cDecSep != ';')
        // if the decimal and list separators are equal, set the
        // parameter separator to be ';', unless they are both
        // semicolon in which case don't change the decimal separator.
        rSepArg = ";";
 
    rSepArrayCol = ",";
    if (cDecSep == ',')
        rSepArrayCol = ".";
    rSepArrayRow = ";";
}
 
bool ScFormulaOptions::operator==( const ScFormulaOptions& rOpt ) const
{
    return bUseEnglishFuncName == rOpt.bUseEnglishFuncName
        && eFormulaGrammar     == rOpt.eFormulaGrammar
        && aCalcConfig == rOpt.aCalcConfig
        && mbWriteCalcConfig   == rOpt.mbWriteCalcConfig
        && aFormulaSepArg      == rOpt.aFormulaSepArg
        && aFormulaSepArrayRow == rOpt.aFormulaSepArrayRow
        && aFormulaSepArrayCol == rOpt.aFormulaSepArrayCol
        && meOOXMLRecalc       == rOpt.meOOXMLRecalc
        && meODFRecalc         == rOpt.meODFRecalc
        && meReCalcOptiRowHeights == rOpt.meReCalcOptiRowHeights;
}
 
bool ScFormulaOptions::operator!=( const ScFormulaOptions& rOpt ) const
{
    return !(operator==(rOpt));
}
 
ScTpFormulaItem::ScTpFormulaItem( ScFormulaOptions aOpt ) :
    SfxPoolItem ( SID_SCFORMULAOPTIONS, SfxItemType::ScTpFormulaItemType ),
    theOptions  (std::move( aOpt ))
{
}
 
ScTpFormulaItem::~ScTpFormulaItem()
{
}
 
bool ScTpFormulaItem::operator==( const SfxPoolItem& rItem ) const
{
    assert(SfxPoolItem::operator==(rItem));
 
    const ScTpFormulaItem& rPItem = static_cast<const ScTpFormulaItem&>(rItem);
    return ( theOptions == rPItem.theOptions );
}
 
ScTpFormulaItem* ScTpFormulaItem::Clone( SfxItemPool * ) const
{
    return new ScTpFormulaItem( *this );
}
 
constexpr OUStringLiteral CFGPATH_FORMULA = u"Office.Calc/Formula";
 
#define SCFORMULAOPT_GRAMMAR              0
#define SCFORMULAOPT_ENGLISH_FUNCNAME     1
#define SCFORMULAOPT_SEP_ARG              2
#define SCFORMULAOPT_SEP_ARRAY_ROW        3
#define SCFORMULAOPT_SEP_ARRAY_COL        4
#define SCFORMULAOPT_STRING_REF_SYNTAX    5
#define SCFORMULAOPT_STRING_CONVERSION    6
#define SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO 7
#define SCFORMULAOPT_OOXML_RECALC         8
#define SCFORMULAOPT_ODF_RECALC           9
#define SCFORMULAOPT_ROW_HEIGHT_RECALC   10
#define SCFORMULAOPT_OPENCL_AUTOSELECT   11
#define SCFORMULAOPT_OPENCL_DEVICE       12
#define SCFORMULAOPT_OPENCL_SUBSET_ONLY  13
#define SCFORMULAOPT_OPENCL_MIN_SIZE     14
#define SCFORMULAOPT_OPENCL_SUBSET_OPS   15
 
Sequence<OUString> ScFormulaCfg::GetPropertyNames()
{
    return {u"Syntax/Grammar"_ustr,                       // SCFORMULAOPT_GRAMMAR
            u"Syntax/EnglishFunctionName"_ustr,           // SCFORMULAOPT_ENGLISH_FUNCNAME
            u"Syntax/SeparatorArg"_ustr,                  // SCFORMULAOPT_SEP_ARG
            u"Syntax/SeparatorArrayRow"_ustr,             // SCFORMULAOPT_SEP_ARRAY_ROW
            u"Syntax/SeparatorArrayCol"_ustr,             // SCFORMULAOPT_SEP_ARRAY_COL
            u"Syntax/StringRefAddressSyntax"_ustr,        // SCFORMULAOPT_STRING_REF_SYNTAX
            u"Syntax/StringConversion"_ustr,              // SCFORMULAOPT_STRING_CONVERSION
            u"Syntax/EmptyStringAsZero"_ustr,             // SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO
            u"Load/OOXMLRecalcMode"_ustr,                 // SCFORMULAOPT_OOXML_RECALC
            u"Load/ODFRecalcMode"_ustr,                   // SCFORMULAOPT_ODF_RECALC
            u"Load/RecalcOptimalRowHeightMode"_ustr,      // SCFORMULAOPT_ROW_HEIGHT_RECALC
            u"Calculation/OpenCLAutoSelect"_ustr,         // SCFORMULAOPT_OPENCL_AUTOSELECT
            u"Calculation/OpenCLDevice"_ustr,             // SCFORMULAOPT_OPENCL_DEVICE
            u"Calculation/OpenCLSubsetOnly"_ustr,         // SCFORMULAOPT_OPENCL_SUBSET_ONLY
            u"Calculation/OpenCLMinimumDataSize"_ustr,    // SCFORMULAOPT_OPENCL_MIN_SIZE
            u"Calculation/OpenCLSubsetOpCodes"_ustr};     // SCFORMULAOPT_OPENCL_SUBSET_OPS
}
 
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_ROW_HEIGHT_RECALC,
        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_Int32 i=0; i<aPropNames.getLength(); ++i )
        aPropIdMap[aPropNames[i]] = aVals[ i ];
    return aPropIdMap;
}
 
ScFormulaCfg::ScFormulaCfg() :
    ConfigItem( CFGPATH_FORMULA )
{
    Sequence<OUString> aNames = GetPropertyNames();
    UpdateFromProperties( aNames );
    EnableNotification( aNames );
}
 
void ScFormulaCfg::UpdateFromProperties( const Sequence<OUString>& aNames )
{
    Sequence<Any> aValues = GetProperties(aNames);
    const Any* pValues = aValues.getConstArray();
    OSL_ENSURE(aValues.getLength() == aNames.getLength(), "GetProperties failed");
    PropsToIds aPropMap = GetPropNamesToId();
    if(aValues.getLength() != aNames.getLength())
        return;
 
    sal_Int32 nIntVal = 0;
    for(int nProp = 0; nProp < aNames.getLength(); nProp++)
    {
        PropsToIds::iterator it_end = aPropMap.end();
        PropsToIds::iterator it = aPropMap.find( aNames[nProp] );
        if(pValues[nProp].hasValue() && it != it_end )
        {
            switch(it->second)
            {
            case SCFORMULAOPT_GRAMMAR:
            {
                // Get default value in case this option is not set.
                ::formula::FormulaGrammar::Grammar eGram = GetFormulaSyntax();
 
                do
                {
                    if (!(pValues[nProp] >>= nIntVal))
                        // extracting failed.
                        break;
 
                    switch (nIntVal)
                    {
                        case 0: // Calc A1
                            eGram = ::formula::FormulaGrammar::GRAM_NATIVE;
                        break;
                        case 1: // Excel A1
                            eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1;
                        break;
                        case 2: // Excel R1C1
                            eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
                        break;
                        default:
                            ;
                    }
                }
                while (false);
                SetFormulaSyntax(eGram);
            }
            break;
            case SCFORMULAOPT_ENGLISH_FUNCNAME:
            {
                bool bEnglish = false;
                if (pValues[nProp] >>= bEnglish)
                    SetUseEnglishFuncName(bEnglish);
            }
            break;
            case SCFORMULAOPT_SEP_ARG:
            {
                OUString aSep;
                if ((pValues[nProp] >>= aSep) && !aSep.isEmpty())
                    SetFormulaSepArg(aSep);
            }
            break;
            case SCFORMULAOPT_SEP_ARRAY_ROW:
            {
                OUString aSep;
                if ((pValues[nProp] >>= aSep) && !aSep.isEmpty())
                    SetFormulaSepArrayRow(aSep);
            }
            break;
            case SCFORMULAOPT_SEP_ARRAY_COL:
            {
                OUString aSep;
                if ((pValues[nProp] >>= aSep) && !aSep.isEmpty())
                    SetFormulaSepArrayCol(aSep);
            }
            break;
            case SCFORMULAOPT_STRING_REF_SYNTAX:
            {
                // Get default value in case this option is not set.
                ::formula::FormulaGrammar::AddressConvention eConv = GetCalcConfig().meStringRefAddressSyntax;
 
                do
                {
                    if (!(pValues[nProp] >>= nIntVal))
                        // extraction failed.
                        break;
 
                    switch (nIntVal)
                    {
                        case -1: // Same as the formula grammar.
                            eConv = formula::FormulaGrammar::CONV_UNSPECIFIED;
                        break;
                        case 0: // Calc A1
                            eConv = formula::FormulaGrammar::CONV_OOO;
                        break;
                        case 1: // Excel A1
                            eConv = formula::FormulaGrammar::CONV_XL_A1;
                        break;
                        case 2: // Excel R1C1
                            eConv = formula::FormulaGrammar::CONV_XL_R1C1;
                        break;
                        case 3: // Calc A1 | Excel A1
                            eConv = formula::FormulaGrammar::CONV_A1_XL_A1;
                        break;
                        default:
                            ;
                    }
                }
                while (false);
                GetCalcConfig().meStringRefAddressSyntax = eConv;
            }
            break;
            case SCFORMULAOPT_STRING_CONVERSION:
            {
                // Get default value in case this option is not set.
                ScCalcConfig::StringConversion eConv = GetCalcConfig().meStringConversion;
 
                do
                {
                    if (!(pValues[nProp] >>= nIntVal))
                        // extraction failed.
                        break;
 
                    switch (nIntVal)
                    {
                        case 0:
                            eConv = ScCalcConfig::StringConversion::ILLEGAL;
                        break;
                        case 1:
                            eConv = ScCalcConfig::StringConversion::ZERO;
                        break;
                        case 2:
                            eConv = ScCalcConfig::StringConversion::UNAMBIGUOUS;
                        break;
                        case 3:
                            eConv = ScCalcConfig::StringConversion::LOCALE;
                        break;
                        default:
                            SAL_WARN("sc", "unknown string conversion option!");
                    }
                }
                while (false);
                GetCalcConfig().meStringConversion = eConv;
            }
            break;
            case SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO:
            {
                bool bVal = GetCalcConfig().mbEmptyStringAsZero;
                pValues[nProp] >>= bVal;
                GetCalcConfig().mbEmptyStringAsZero = bVal;
            }
            break;
            case SCFORMULAOPT_OOXML_RECALC:
            {
                ScRecalcOptions eOpt = RECALC_ASK;
                if (pValues[nProp] >>= nIntVal)
                {
                    switch (nIntVal)
                    {
                        case 0:
                            eOpt = RECALC_ALWAYS;
                            break;
                        case 1:
                            eOpt = RECALC_NEVER;
                            break;
                        case 2:
                            eOpt = RECALC_ASK;
                            break;
                        default:
                            SAL_WARN("sc", "unknown ooxml recalc option!");
                    }
                }
 
                SetOOXMLRecalcOptions(eOpt);
            }
            break;
            case SCFORMULAOPT_ODF_RECALC:
            {
                ScRecalcOptions eOpt = RECALC_ASK;
                if (pValues[nProp] >>= nIntVal)
                {
                    switch (nIntVal)
                    {
                        case 0:
                            eOpt = RECALC_ALWAYS;
                            break;
                        case 1:
                            eOpt = RECALC_NEVER;
                            break;
                        case 2:
                            eOpt = RECALC_ASK;
                            break;
                        default:
                            SAL_WARN("sc", "unknown odf recalc option!");
                    }
                }
 
                SetODFRecalcOptions(eOpt);
            }
            break;
            case SCFORMULAOPT_ROW_HEIGHT_RECALC:
            {
                ScRecalcOptions eOpt = RECALC_ASK;
                if (pValues[nProp] >>= nIntVal)
                {
                    switch (nIntVal)
                    {
                    case 0:
                        eOpt = RECALC_ALWAYS;
                        break;
                    case 1:
                        eOpt = RECALC_NEVER;
                        break;
                    case 2:
                        eOpt = RECALC_ASK;
                        break;
                    default:
                        SAL_WARN("sc", "unknown optimal row height recalc option!");
                    }
                }
 
                SetReCalcOptiRowHeights(eOpt);
            }
            break;
            case SCFORMULAOPT_OPENCL_AUTOSELECT:
            {
                bool bVal = GetCalcConfig().mbOpenCLAutoSelect;
                pValues[nProp] >>= bVal;
                GetCalcConfig().mbOpenCLAutoSelect = bVal;
            }
            break;
            case SCFORMULAOPT_OPENCL_DEVICE:
            {
                OUString aOpenCLDevice = GetCalcConfig().maOpenCLDevice;
                pValues[nProp] >>= aOpenCLDevice;
                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 = ScOpCodeSetToSymbolicString(GetCalcConfig().mpOpenCLSubsetOpCodes);
                pValues[nProp] >>= sVal;
                GetCalcConfig().mpOpenCLSubsetOpCodes = ScStringToOpCodeSet(sVal);
            }
            break;
            }
        }
    }
}
 
void ScFormulaCfg::ImplCommit()
{
    Sequence<OUString> aNames = GetPropertyNames();
    Sequence<Any> aValues(aNames.getLength());
    Any* pValues = aValues.getArray();
 
    Sequence<Any> aOldValues = GetProperties(aNames);
    Any* pOldValues = aOldValues.getArray();
 
    bool bSetOpenCL = false;
 
    for (int nProp = 0; nProp < aNames.getLength(); ++nProp)
    {
        switch (nProp)
        {
            case SCFORMULAOPT_GRAMMAR :
            {
                sal_Int32 nVal = 0;
                switch (GetFormulaSyntax())
                {
                    case ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1:    nVal = 1; break;
                    case ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1:  nVal = 2; break;
                    default: break;
                }
                pValues[nProp] <<= nVal;
            }
            break;
            case SCFORMULAOPT_ENGLISH_FUNCNAME:
            {
                bool b = GetUseEnglishFuncName();
                pValues[nProp] <<= b;
            }
            break;
            case SCFORMULAOPT_SEP_ARG:
                pValues[nProp] <<= GetFormulaSepArg();
            break;
            case SCFORMULAOPT_SEP_ARRAY_ROW:
                pValues[nProp] <<= GetFormulaSepArrayRow();
            break;
            case SCFORMULAOPT_SEP_ARRAY_COL:
                pValues[nProp] <<= GetFormulaSepArrayCol();
            break;
            case SCFORMULAOPT_STRING_REF_SYNTAX:
            {
                sal_Int32 nVal = -1;
 
                if (GetWriteCalcConfig())
                {
                    switch (GetCalcConfig().meStringRefAddressSyntax)
                    {
                        case ::formula::FormulaGrammar::CONV_OOO:     nVal = 0; break;
                        case ::formula::FormulaGrammar::CONV_XL_A1:   nVal = 1; break;
                        case ::formula::FormulaGrammar::CONV_XL_R1C1: nVal = 2; break;
                        case ::formula::FormulaGrammar::CONV_A1_XL_A1: nVal = 3; break;
                        default: break;
                    }
                    pValues[nProp] <<= nVal;
                }
                else
                {
                    pValues[nProp] = pOldValues[nProp];
                }
            }
            break;
            case SCFORMULAOPT_STRING_CONVERSION:
            {
                if (GetWriteCalcConfig())
                {
                    sal_Int32 nVal = 3;
 
                    switch (GetCalcConfig().meStringConversion)
                    {
                        case ScCalcConfig::StringConversion::ILLEGAL:     nVal = 0; break;
                        case ScCalcConfig::StringConversion::ZERO:        nVal = 1; break;
                        case ScCalcConfig::StringConversion::UNAMBIGUOUS: nVal = 2; break;
                        case ScCalcConfig::StringConversion::LOCALE:      nVal = 3; break;
                    }
                    pValues[nProp] <<= nVal;
                }
                else
                {
                    pValues[nProp] = pOldValues[nProp];
                }
            }
            break;
            case SCFORMULAOPT_EMPTY_OUSTRING_AS_ZERO:
            {
                if (GetWriteCalcConfig())
                {
                    bool bVal = GetCalcConfig().mbEmptyStringAsZero;
                    pValues[nProp] <<= bVal;
                }
                else
                {
                    pValues[nProp] = pOldValues[nProp];
                }
            }
            break;
            case SCFORMULAOPT_OOXML_RECALC:
            {
                sal_Int32 nVal = 2;
                switch (GetOOXMLRecalcOptions())
                {
                    case RECALC_ALWAYS:
                        nVal = 0;
                        break;
                    case RECALC_NEVER:
                        nVal = 1;
                        break;
                    case RECALC_ASK:
                        nVal = 2;
                        break;
                }
 
                pValues[nProp] <<= nVal;
            }
            break;
            case SCFORMULAOPT_ODF_RECALC:
            {
                sal_Int32 nVal = 2;
                switch (GetODFRecalcOptions())
                {
                    case RECALC_ALWAYS:
                        nVal = 0;
                        break;
                    case RECALC_NEVER:
                        nVal = 1;
                        break;
                    case RECALC_ASK:
                        nVal = 2;
                        break;
                }
 
                pValues[nProp] <<= nVal;
            }
            break;
            case SCFORMULAOPT_ROW_HEIGHT_RECALC:
            {
                sal_Int32 nVal = 2;
                switch (GetReCalcOptiRowHeights())
                {
                    case RECALC_ALWAYS:
                        nVal = 0;
                        break;
                    case RECALC_NEVER:
                        nVal = 1;
                        break;
                    case RECALC_ASK:
                        nVal = 2;
                        break;
                    default:
                        SAL_WARN("sc", "unknown optimal row height recalc option!");
                }
 
                pValues[nProp] <<= nVal;
            }
            break;
            case SCFORMULAOPT_OPENCL_AUTOSELECT:
            {
                bool bVal = GetCalcConfig().mbOpenCLAutoSelect;
                pValues[nProp] <<= bVal;
                bSetOpenCL = true;
            }
            break;
            case SCFORMULAOPT_OPENCL_DEVICE:
            {
                OUString aOpenCLDevice = GetCalcConfig().maOpenCLDevice;
                pValues[nProp] <<= aOpenCLDevice;
                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 = ScOpCodeSetToSymbolicString(GetCalcConfig().mpOpenCLSubsetOpCodes);
                pValues[nProp] <<= sVal;
            }
            break;
        }
    }
#if !HAVE_FEATURE_OPENCL
    (void) bSetOpenCL;
#else
    if(bSetOpenCL)
        sc::FormulaGroupInterpreter::switchOpenCLDevice(
                GetCalcConfig().maOpenCLDevice, GetCalcConfig().mbOpenCLAutoSelect);
#endif
    PutProperties(aNames, aValues);
}
 
void ScFormulaCfg::SetOptions( const ScFormulaOptions& rNew )
{
    *static_cast<ScFormulaOptions*>(this) = rNew;
    SetModified();
}
 
void ScFormulaCfg::Notify( const css::uno::Sequence< OUString >& rNames)
{
    UpdateFromProperties( rNames );
}
 
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

V1048 The 'eOpt' variable was assigned the same value.

V1048 The 'eOpt' variable was assigned the same value.

V1048 The 'eOpt' variable was assigned the same value.

V1048 The 'nVal' variable was assigned the same value.

V1048 The 'nVal' variable was assigned the same value.

V1048 The 'nVal' variable was assigned the same value.

V1048 The 'nVal' variable was assigned the same value.