summaryrefslogtreecommitdiffstats
path: root/sc/source/ui/optdlg/tpformula.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/optdlg/tpformula.cxx')
-rw-r--r--sc/source/ui/optdlg/tpformula.cxx411
1 files changed, 411 insertions, 0 deletions
diff --git a/sc/source/ui/optdlg/tpformula.cxx b/sc/source/ui/optdlg/tpformula.cxx
new file mode 100644
index 000000000..f4815d17c
--- /dev/null
+++ b/sc/source/ui/optdlg/tpformula.cxx
@@ -0,0 +1,411 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#undef SC_DLLIMPLEMENTATION
+
+#include <global.hxx>
+#include <tpformula.hxx>
+#include <formulaopt.hxx>
+#include <sc.hrc>
+#include <strings.hrc>
+#include <scresid.hxx>
+#include <formula/grammar.hxx>
+#include <officecfg/Office/Calc.hxx>
+#include "calcoptionsdlg.hxx"
+
+#include <unotools/localedatawrapper.hxx>
+
+ScTpFormulaOptions::ScTpFormulaOptions(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "modules/scalc/ui/optformula.ui", "OptFormula", &rCoreAttrs)
+ , mnDecSep(0)
+ , mxLbFormulaSyntax(m_xBuilder->weld_combo_box("formulasyntax"))
+ , mxCbEnglishFuncName(m_xBuilder->weld_check_button("englishfuncname"))
+ , mxBtnCustomCalcDefault(m_xBuilder->weld_radio_button("calcdefault"))
+ , mxBtnCustomCalcCustom(m_xBuilder->weld_radio_button("calccustom"))
+ , mxBtnCustomCalcDetails(m_xBuilder->weld_button("details"))
+ , mxEdSepFuncArg(m_xBuilder->weld_entry("function"))
+ , mxEdSepArrayCol(m_xBuilder->weld_entry("arraycolumn"))
+ , mxEdSepArrayRow(m_xBuilder->weld_entry("arrayrow"))
+ , mxBtnSepReset(m_xBuilder->weld_button("reset"))
+ , mxLbOOXMLRecalcOptions(m_xBuilder->weld_combo_box("ooxmlrecalc"))
+ , mxLbODFRecalcOptions(m_xBuilder->weld_combo_box("odfrecalc"))
+{
+ mxLbFormulaSyntax->append_text(ScResId(SCSTR_FORMULA_SYNTAX_CALC_A1));
+ mxLbFormulaSyntax->append_text(ScResId(SCSTR_FORMULA_SYNTAX_XL_A1));
+ mxLbFormulaSyntax->append_text(ScResId(SCSTR_FORMULA_SYNTAX_XL_R1C1));
+
+ Link<weld::Button&,void> aLink2 = LINK( this, ScTpFormulaOptions, ButtonHdl );
+ mxBtnSepReset->connect_clicked(aLink2);
+ mxBtnCustomCalcDetails->connect_clicked(aLink2);
+
+ Link<weld::Toggleable&,void> aToggleLink = LINK( this, ScTpFormulaOptions, ToggleHdl );
+ mxBtnCustomCalcDefault->connect_toggled(aToggleLink);
+ mxBtnCustomCalcCustom->connect_toggled(aToggleLink);
+
+ mxEdSepFuncArg->connect_insert_text(LINK( this, ScTpFormulaOptions, SepInsertTextHdl ));
+ mxEdSepArrayCol->connect_insert_text(LINK( this, ScTpFormulaOptions, ColSepInsertTextHdl ));
+ mxEdSepArrayRow->connect_insert_text(LINK( this, ScTpFormulaOptions, RowSepInsertTextHdl ));
+
+ Link<weld::Entry&,void> aLink = LINK( this, ScTpFormulaOptions, SepModifyHdl );
+ mxEdSepFuncArg->connect_changed(aLink);
+ mxEdSepArrayCol->connect_changed(aLink);
+ mxEdSepArrayRow->connect_changed(aLink);
+
+ Link<weld::Widget&,void> aLink3 = LINK( this, ScTpFormulaOptions, SepEditOnFocusHdl );
+ mxEdSepFuncArg->connect_focus_in(aLink3);
+ mxEdSepArrayCol->connect_focus_in(aLink3);
+ mxEdSepArrayRow->connect_focus_in(aLink3);
+
+ // Get the decimal separator for current locale.
+ OUString aSep = ScGlobal::getLocaleData().getNumDecimalSep();
+ mnDecSep = aSep.isEmpty() ? u'.' : aSep[0];
+
+ maSavedDocOptions = rCoreAttrs.Get(SID_SCDOCOPTIONS).GetDocOptions();
+}
+
+ScTpFormulaOptions::~ScTpFormulaOptions()
+{
+}
+
+void ScTpFormulaOptions::ResetSeparators()
+{
+ OUString aFuncArg, aArrayCol, aArrayRow;
+ ScFormulaOptions::GetDefaultFormulaSeparators(aFuncArg, aArrayCol, aArrayRow);
+ mxEdSepFuncArg->set_text(aFuncArg);
+ mxEdSepArrayCol->set_text(aArrayCol);
+ mxEdSepArrayRow->set_text(aArrayRow);
+}
+
+void ScTpFormulaOptions::OnFocusSeparatorInput(weld::Entry* pEdit)
+{
+ if (!pEdit)
+ return;
+
+ // Make sure the entire text is selected.
+ pEdit->select_region(0, -1);
+ OUString sSepValue = pEdit->get_text();
+ if (!sSepValue.isEmpty())
+ maOldSepValue = sSepValue;
+}
+
+void ScTpFormulaOptions::UpdateCustomCalcRadioButtons(bool bDefault)
+{
+ if (bDefault)
+ {
+ mxBtnCustomCalcDefault->set_active(true);
+ mxBtnCustomCalcCustom->set_active(false);
+ mxBtnCustomCalcDetails->set_sensitive(false);
+ }
+ else
+ {
+ mxBtnCustomCalcDefault->set_active(false);
+ mxBtnCustomCalcCustom->set_active(true);
+ mxBtnCustomCalcDetails->set_sensitive(true);
+ }
+}
+
+void ScTpFormulaOptions::LaunchCustomCalcSettings()
+{
+ ScCalcOptionsDialog aDlg(GetFrameWeld(), maCurrentConfig, maCurrentDocOptions.IsWriteCalcConfig());
+ if (aDlg.run() == RET_OK)
+ {
+ maCurrentConfig = aDlg.GetConfig();
+ maCurrentDocOptions.SetWriteCalcConfig(aDlg.GetWriteCalcConfig());
+ }
+}
+
+bool ScTpFormulaOptions::IsValidSeparator(const OUString& rSep, bool bArray) const
+{
+ if (rSep.getLength() != 1)
+ // Must be one-character long.
+ return false;
+
+ const sal_Unicode c = rSep[0];
+
+ if (c == mnDecSep)
+ // decimal separator is not allowed.
+ return false;
+
+ if (c <= 0x20 || c == 0x7f)
+ // Disallow non-printables including space and DEL.
+ return false;
+
+ if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9'))
+ // Disallow alphanumeric.
+ return false;
+
+ if (bArray)
+ {
+ switch (c)
+ {
+ case '+':
+ case '-':
+ case '{':
+ case '}':
+ case '"':
+ // All following just to prevent confusion, they are not
+ // evaluated in inline arrays and theoretically would be
+ // possible.
+ case '%':
+ case '/':
+ case '*':
+ case '=':
+ case '<':
+ case '>':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ case '\'':
+ // Disallowed characters. Anything else we want to disallow ?
+ return false;
+ }
+ }
+ else if (c <= 0x7f)
+ {
+ switch (c)
+ {
+ default:
+ // Anything bad except the knowns.
+ return false;
+ case ';':
+ case ',':
+ ; // nothing
+ }
+ }
+ else
+ {
+ // Any Unicode character, would have to ask the compiler's localized
+ // symbol map whether it's a known symbol but not a separator
+ // (ocSep,ocArrayRowSep,ocArrayColSep), which we're about to set here.
+ // But really..
+ return false;
+ }
+
+ return true;
+}
+
+IMPL_LINK( ScTpFormulaOptions, ButtonHdl, weld::Button&, rBtn, void )
+{
+ if (&rBtn == mxBtnSepReset.get())
+ ResetSeparators();
+ else if (&rBtn == mxBtnCustomCalcDetails.get())
+ LaunchCustomCalcSettings();
+}
+
+IMPL_LINK( ScTpFormulaOptions, ToggleHdl, weld::Toggleable&, rBtn, void )
+{
+ if (!rBtn.get_active())
+ return;
+ if (mxBtnCustomCalcDefault->get_active())
+ UpdateCustomCalcRadioButtons(true);
+ else if (mxBtnCustomCalcCustom->get_active())
+ UpdateCustomCalcRadioButtons(false);
+}
+
+IMPL_LINK(ScTpFormulaOptions, SepInsertTextHdl, OUString&, rTest, bool)
+{
+ if (!IsValidSeparator(rTest, false) && !maOldSepValue.isEmpty())
+ // Invalid separator. Restore the old value.
+ rTest = maOldSepValue;
+ return true;
+}
+
+IMPL_LINK(ScTpFormulaOptions, RowSepInsertTextHdl, OUString&, rTest, bool)
+{
+ // Invalid separator or same as ColStr - Restore the old value.
+ if ((!IsValidSeparator(rTest, true) || rTest == mxEdSepArrayCol->get_text()) && !maOldSepValue.isEmpty())
+ rTest = maOldSepValue;
+ return true;
+}
+
+IMPL_LINK(ScTpFormulaOptions, ColSepInsertTextHdl, OUString&, rTest, bool)
+{
+ // Invalid separator or same as RowStr - Restore the old value.
+ if ((!IsValidSeparator(rTest, true) || rTest == mxEdSepArrayRow->get_text()) && !maOldSepValue.isEmpty())
+ rTest = maOldSepValue;
+ return true;
+}
+
+IMPL_LINK( ScTpFormulaOptions, SepModifyHdl, weld::Entry&, rEdit, void )
+{
+ OnFocusSeparatorInput(&rEdit);
+}
+
+IMPL_LINK( ScTpFormulaOptions, SepEditOnFocusHdl, weld::Widget&, rControl, void )
+{
+ OnFocusSeparatorInput(dynamic_cast<weld::Entry*>(&rControl));
+}
+
+std::unique_ptr<SfxTabPage> ScTpFormulaOptions::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rCoreSet)
+{
+ return std::make_unique<ScTpFormulaOptions>(pPage, pController, *rCoreSet);
+}
+
+bool ScTpFormulaOptions::FillItemSet(SfxItemSet* rCoreSet)
+{
+ bool bRet = false;
+ ScFormulaOptions aOpt;
+ bool bEnglishFuncName = mxCbEnglishFuncName->get_active();
+ sal_Int16 aSyntaxPos = mxLbFormulaSyntax->get_active();
+ OUString aSep = mxEdSepFuncArg->get_text();
+ OUString aSepArrayCol = mxEdSepArrayCol->get_text();
+ OUString aSepArrayRow = mxEdSepArrayRow->get_text();
+ sal_Int16 nOOXMLRecalcMode = mxLbOOXMLRecalcOptions->get_active();
+ sal_Int16 nODFRecalcMode = mxLbODFRecalcOptions->get_active();
+
+ if (mxBtnCustomCalcDefault->get_active())
+ {
+ // When Default is selected, reset all the calc config settings to default.
+ maCurrentConfig.reset();
+ }
+
+ if ( mxLbFormulaSyntax->get_saved_value() != mxLbFormulaSyntax->get_text(aSyntaxPos)
+ || mxCbEnglishFuncName->get_saved_state() != (bEnglishFuncName ? 1 : 0)
+ || mxEdSepFuncArg->get_saved_value() != aSep
+ || mxEdSepArrayCol->get_saved_value() != aSepArrayCol
+ || mxEdSepArrayRow->get_saved_value() != aSepArrayRow
+ || mxLbOOXMLRecalcOptions->get_saved_value() != mxLbOOXMLRecalcOptions->get_text(nOOXMLRecalcMode)
+ || mxLbODFRecalcOptions->get_saved_value() != mxLbODFRecalcOptions->get_text(nODFRecalcMode)
+ || maSavedConfig != maCurrentConfig
+ || maSavedDocOptions != maCurrentDocOptions )
+ {
+ ::formula::FormulaGrammar::Grammar eGram = ::formula::FormulaGrammar::GRAM_DEFAULT;
+
+ switch (aSyntaxPos)
+ {
+ case 0:
+ eGram = ::formula::FormulaGrammar::GRAM_NATIVE;
+ break;
+ case 1:
+ eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1;
+ break;
+ case 2:
+ eGram = ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1;
+ break;
+ }
+
+ ScRecalcOptions eOOXMLRecalc = static_cast<ScRecalcOptions>(nOOXMLRecalcMode);
+ ScRecalcOptions eODFRecalc = static_cast<ScRecalcOptions>(nODFRecalcMode);
+
+ aOpt.SetFormulaSyntax(eGram);
+ aOpt.SetUseEnglishFuncName(bEnglishFuncName);
+ aOpt.SetFormulaSepArg(aSep);
+ aOpt.SetFormulaSepArrayCol(aSepArrayCol);
+ aOpt.SetFormulaSepArrayRow(aSepArrayRow);
+ aOpt.SetCalcConfig(maCurrentConfig);
+ aOpt.SetOOXMLRecalcOptions(eOOXMLRecalc);
+ aOpt.SetODFRecalcOptions(eODFRecalc);
+ aOpt.SetWriteCalcConfig( maCurrentDocOptions.IsWriteCalcConfig());
+
+ rCoreSet->Put( ScTpFormulaItem( aOpt ) );
+ rCoreSet->Put( ScTpCalcItem( SID_SCDOCOPTIONS, maCurrentDocOptions ) );
+
+ bRet = true;
+ }
+ return bRet;
+}
+
+void ScTpFormulaOptions::Reset(const SfxItemSet* rCoreSet)
+{
+ ScFormulaOptions aOpt;
+ if(const ScTpFormulaItem* pItem = rCoreSet->GetItemIfSet(SID_SCFORMULAOPTIONS, false))
+ aOpt = pItem->GetFormulaOptions();
+
+ // formula grammar.
+ ::formula::FormulaGrammar::Grammar eGram = aOpt.GetFormulaSyntax();
+
+ switch (eGram)
+ {
+ case ::formula::FormulaGrammar::GRAM_NATIVE:
+ mxLbFormulaSyntax->set_active(0);
+ break;
+ case ::formula::FormulaGrammar::GRAM_NATIVE_XL_A1:
+ mxLbFormulaSyntax->set_active(1);
+ break;
+ case ::formula::FormulaGrammar::GRAM_NATIVE_XL_R1C1:
+ mxLbFormulaSyntax->set_active(2);
+ break;
+ default:
+ mxLbFormulaSyntax->set_active(0);
+ }
+
+ mxLbFormulaSyntax->save_value();
+ mxLbFormulaSyntax->set_sensitive( !officecfg::Office::Calc::Formula::Syntax::Grammar::isReadOnly() );
+
+ ScRecalcOptions eOOXMLRecalc = aOpt.GetOOXMLRecalcOptions();
+ mxLbOOXMLRecalcOptions->set_active(static_cast<sal_uInt16>(eOOXMLRecalc));
+ mxLbOOXMLRecalcOptions->save_value();
+ mxLbOOXMLRecalcOptions->set_sensitive( !officecfg::Office::Calc::Formula::Load::OOXMLRecalcMode::isReadOnly() );
+
+ ScRecalcOptions eODFRecalc = aOpt.GetODFRecalcOptions();
+ mxLbODFRecalcOptions->set_active(static_cast<sal_uInt16>(eODFRecalc));
+ mxLbODFRecalcOptions->save_value();
+ mxLbODFRecalcOptions->set_sensitive( !officecfg::Office::Calc::Formula::Load::ODFRecalcMode::isReadOnly() );
+
+ // english function name.
+ mxCbEnglishFuncName->set_active( aOpt.GetUseEnglishFuncName() );
+ mxCbEnglishFuncName->save_state();
+ mxCbEnglishFuncName->set_sensitive( !officecfg::Office::Calc::Formula::Syntax::EnglishFunctionName::isReadOnly() );
+
+ // Separators
+ OUString aSep = aOpt.GetFormulaSepArg();
+ OUString aSepArrayRow = aOpt.GetFormulaSepArrayRow();
+ OUString aSepArrayCol = aOpt.GetFormulaSepArrayCol();
+
+ if (IsValidSeparator(aSep, false) && IsValidSeparator(aSepArrayRow, true) && IsValidSeparator(aSepArrayCol, true))
+ {
+ // Each and all separators must be valid.
+ mxEdSepFuncArg->set_text(aSep);
+ mxEdSepArrayCol->set_text(aSepArrayCol);
+ mxEdSepArrayRow->set_text(aSepArrayRow);
+
+ mxEdSepFuncArg->save_value();
+ mxEdSepArrayCol->save_value();
+ mxEdSepArrayRow->save_value();
+ }
+ else
+ ResetSeparators();
+
+ mxEdSepFuncArg->set_sensitive( !officecfg::Office::Calc::Formula::Syntax::SeparatorArg::isReadOnly() );
+ mxEdSepArrayCol->set_sensitive( !officecfg::Office::Calc::Formula::Syntax::SeparatorArrayCol::isReadOnly() );
+ mxEdSepArrayRow->set_sensitive( !officecfg::Office::Calc::Formula::Syntax::SeparatorArrayRow::isReadOnly() );
+ mxBtnSepReset->set_sensitive ( !officecfg::Office::Calc::Formula::Syntax::SeparatorArg::isReadOnly() &&
+ !officecfg::Office::Calc::Formula::Syntax::SeparatorArrayCol::isReadOnly() &&
+ !officecfg::Office::Calc::Formula::Syntax::SeparatorArrayRow::isReadOnly() );
+
+ // detailed calc settings.
+ ScFormulaOptions aDefaults;
+
+ maSavedConfig = aOpt.GetCalcConfig();
+ bool bDefault = aDefaults.GetCalcConfig() == maSavedConfig;
+ UpdateCustomCalcRadioButtons(bDefault);
+
+ maCurrentConfig = maSavedConfig;
+
+ maCurrentDocOptions = maSavedDocOptions;
+}
+
+DeactivateRC ScTpFormulaOptions::DeactivatePage(SfxItemSet* /*pSet*/)
+{
+ // What's this method for ?
+ return DeactivateRC::KeepPage;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */