officecfg/registry/schema/org/openoffice/Office/Calc.xcs | 7 + sc/inc/appoptio.hxx | 4 sc/inc/sc.hrc | 1 sc/source/core/data/validat.cxx | 6 - sc/source/core/tool/appoptio.cxx | 14 ++ sc/source/ui/app/inputhdl.cxx | 5 sc/source/ui/app/scmod.cxx | 10 + sc/source/ui/inc/tpcompatibility.hxx | 2 sc/source/ui/optdlg/tpcompatibility.cxx | 15 ++ sc/uiconfig/scalc/ui/optcompatibilitypage.ui | 82 +++++++++++++-- 10 files changed, 134 insertions(+), 12 deletions(-)
New commits: commit a6bc66ca8ddf23ede2807c2043d94f5c77adfe39 Author: Heiko Tietze <[email protected]> AuthorDate: Tue Dec 9 13:06:44 2025 +0100 Commit: Heiko Tietze <[email protected]> CommitDate: Wed Dec 10 07:39:03 2025 +0100 Resolves tdf#160096 - Allow invalid values regardless the validation Introduces a new compatibility option Makes c869fb5ea2fa1dbbfa7c17754aeac48ed7f77cc4 optionally Change-Id: I75c2a801f41a5e3d9688fdb1557f86506ed11697 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195288 Reviewed-by: Heiko Tietze <[email protected]> Tested-by: Jenkins diff --git a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs index 80e79448d344..7db98412d8d3 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Calc.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Calc.xcs @@ -1971,6 +1971,13 @@ </info> <value>false</value> </prop> + <prop oor:name="AcceptInvalidData" oor:type="xs:boolean" oor:nillable="false"> + <info> + <desc>If set, data are accepted regardless of being invalid (as known from Excel and LibreOffice before tdf#159595)</desc> + <label>Data Validity like Excel</label> + </info> + <value>false</value> + </prop> </group> <group oor:name="Defaults"> <info> diff --git a/sc/inc/appoptio.hxx b/sc/inc/appoptio.hxx index d4beeec78c06..1b9c4cc50439 100644 --- a/sc/inc/appoptio.hxx +++ b/sc/inc/appoptio.hxx @@ -86,6 +86,9 @@ public: void SetLinksInsertedLikeMSExcel(bool bNew) { mbLinksInsertedLikeMSExcel = bNew; } bool GetLinksInsertedLikeMSExcel() const { return mbLinksInsertedLikeMSExcel; } + void SetAllowInvalidData(bool bNew) { mbAllowInvalidData = bNew; } + bool GetAllowInvalidData() const { return mbAllowInvalidData; } + ScAppOptions& operator= ( const ScAppOptions& rOpt ); private: @@ -111,6 +114,7 @@ private: bool bClickChangeRotation; ScOptionsUtil::KeyBindingType meKeyBindingType; bool mbLinksInsertedLikeMSExcel; + bool mbAllowInvalidData; }; // Config Item containing app options diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 629289aef0bf..6cc35ba4fed8 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -638,6 +638,7 @@ static_assert(SID_PREVIEW_END < SID_KEYFUNC_START, "calc slots ids trampling inf #define SID_EDIT_SPARKLINE (SID_NEW_SLOTS+116) #define SID_SC_OPT_LINKS TypedWhichId<SfxBoolItem>(SID_NEW_SLOTS + 117) #define SID_CLEAR_AUTO_FILTER (SID_NEW_SLOTS+118) +#define SID_SC_OPT_ALLOWINVALIDDATA TypedWhichId<SfxBoolItem>(SID_NEW_SLOTS + 119) // idl parameter diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx index 7850c0e52304..4e0039f83141 100644 --- a/sc/source/core/data/validat.cxx +++ b/sc/source/core/data/validat.cxx @@ -37,6 +37,7 @@ #include <rtl/math.hxx> #include <osl/diagnose.h> +#include <appoptio.hxx> #include <document.hxx> #include <docsh.hxx> #include <formulacell.hxx> @@ -51,6 +52,7 @@ #include <scmatrix.hxx> #include <cellvalue.hxx> #include <simpleformulacalc.hxx> +#include <scmod.hxx> #include <math.h> #include <memory> @@ -383,7 +385,9 @@ void ScValidationData::DoError(weld::Window* pParent, const OUString& rInput, co } if (!bShowError) { - callback(true); + const bool bAcceptInvalidData = ScModule::get()->GetAppOptions().GetAllowInvalidData(); + if (!bAcceptInvalidData) + callback(true); return; } diff --git a/sc/source/core/tool/appoptio.cxx b/sc/source/core/tool/appoptio.cxx index 3825ccf8468b..14dc123689e1 100644 --- a/sc/source/core/tool/appoptio.cxx +++ b/sc/source/core/tool/appoptio.cxx @@ -83,6 +83,7 @@ void ScAppOptions::SetDefaults() meKeyBindingType = ScOptionsUtil::KEY_DEFAULT; mbLinksInsertedLikeMSExcel = false; + mbAllowInvalidData = false; } ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) @@ -107,6 +108,7 @@ ScAppOptions& ScAppOptions::operator=( const ScAppOptions& rCpy ) bClickChangeRotation = rCpy.bClickChangeRotation; meKeyBindingType = rCpy.meKeyBindingType; mbLinksInsertedLikeMSExcel = rCpy.mbLinksInsertedLikeMSExcel; + mbAllowInvalidData = rCpy.mbAllowInvalidData; return *this; } @@ -201,6 +203,8 @@ constexpr OUStringLiteral CFGPATH_COMPAT = u"Office.Calc/Compatibility"; #define SCCOMPATOPT_KEY_BINDING 0 #define SCCOMPATOPT_LINK_LIKE_MS 1 +#define SCCOMPATOPT_ALLOWINVALIDDATA 2 + // Default value of Layout/Other/StatusbarMultiFunction #define SCLAYOUTOPT_STATUSBARMULTI_DEFAULTVAL 514 @@ -270,7 +274,8 @@ Sequence<OUString> ScAppCfg::GetMiscPropertyNames() Sequence<OUString> ScAppCfg::GetCompatPropertyNames() { return {u"KeyBindings/BaseGroup"_ustr, // SCCOMPATOPT_KEY_BINDING - u"Links"_ustr }; // SCCOMPATOPT_LINK_LIKE_MS + u"Links"_ustr, // SCCOMPATOPT_LINK_LIKE_MS + u"AcceptInvalidData"_ustr}; // SCCOMPATOPT_ALLOWINVALIDDATA } ScAppCfg::ScAppCfg() : @@ -487,6 +492,10 @@ void ScAppCfg::ReadCompatCfg() if (aValues.getLength() > SCCOMPATOPT_LINK_LIKE_MS) SetLinksInsertedLikeMSExcel( ScUnoHelpFunctions::GetBoolFromAny(aValues[SCCOMPATOPT_LINK_LIKE_MS])); + + if (aValues.getLength() > SCCOMPATOPT_ALLOWINVALIDDATA) + SetAllowInvalidData( + ScUnoHelpFunctions::GetBoolFromAny(aValues[SCCOMPATOPT_ALLOWINVALIDDATA])); } IMPL_LINK_NOARG(ScAppCfg, LayoutCommitHdl, ScLinkConfigItem&, void) @@ -667,6 +676,9 @@ IMPL_LINK_NOARG(ScAppCfg, CompatCommitHdl, ScLinkConfigItem&, void) case SCCOMPATOPT_LINK_LIKE_MS: pValues[nProp] <<= GetLinksInsertedLikeMSExcel(); break; + case SCCOMPATOPT_ALLOWINVALIDDATA: + pValues[nProp] <<= GetAllowInvalidData(); + break; } } aCompatItem.PutProperties(aNames, aValues); diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index cf7b8d0c8d78..a714e1bbe019 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -3233,7 +3233,10 @@ void ScInputHandler::EnterHandler( ScEnterMode nBlockMode, bool bBeforeSavingInL pActiveViewSh->GetFrameWeld(), aString, aCursorPos, [this, nBlockMode, aString, aPreAutoCorrectString](bool bForget) { EnterHandler2(nBlockMode, bForget, aString, aPreAutoCorrectString); }); - return; + + const bool bAcceptInvalidData = ScModule::get()->GetAppOptions().GetAllowInvalidData(); + if (!bAcceptInvalidData) + return; } } } diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index d9d11e1a07e6..aee8b83c52ce 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -1024,6 +1024,12 @@ void ScModule::ModifyOptions( const SfxItemSet& rOptSet ) bSaveAppOptions = true; } + if (const SfxBoolItem* pItem = rOptSet.GetItemIfSet(SID_SC_OPT_ALLOWINVALIDDATA)) + { + aAppOptions.SetAllowInvalidData(pItem->GetValue()); + bSaveAppOptions = true; + } + // DefaultsOptions if (const ScTpDefaultsItem* pItem = rOptSet.GetItemIfSet(SID_SCDEFAULTSOPTIONS)) { @@ -2017,7 +2023,8 @@ std::optional<SfxItemSet> ScModule::CreateItemSet( sal_uInt16 nId ) SID_SC_INPUT_REPLCELLSWARN, SID_SC_INPUT_REPLCELLSWARN, // TP_VIEW: SID_SC_OPT_SYNCZOOM, SID_SC_OPT_KEY_BINDING_COMPAT, - SID_SC_OPT_LINKS, SID_SC_OPT_LINKS>); + SID_SC_OPT_LINKS, SID_SC_OPT_LINKS, + SID_SC_OPT_ALLOWINVALIDDATA, SID_SC_OPT_ALLOWINVALIDDATA>); const ScAppOptions& rAppOpt = GetAppOptions(); @@ -2090,6 +2097,7 @@ std::optional<SfxItemSet> ScModule::CreateItemSet( sal_uInt16 nId ) pRet->Put( SfxUInt16Item( SID_SC_OPT_KEY_BINDING_COMPAT, rAppOpt.GetKeyBindingType() ) ); pRet->Put( SfxBoolItem( SID_SC_OPT_LINKS, rAppOpt.GetLinksInsertedLikeMSExcel())); + pRet->Put( SfxBoolItem( SID_SC_OPT_ALLOWINVALIDDATA, rAppOpt.GetAllowInvalidData())); // TP_DEFAULTS pRet->Put( ScTpDefaultsItem( GetDefaultsOptions() ) ); diff --git a/sc/source/ui/inc/tpcompatibility.hxx b/sc/source/ui/inc/tpcompatibility.hxx index 0ab84d4d93e8..9a8aa2cdc8b5 100644 --- a/sc/source/ui/inc/tpcompatibility.hxx +++ b/sc/source/ui/inc/tpcompatibility.hxx @@ -29,6 +29,8 @@ private: std::unique_ptr<weld::Widget> m_xLbKeyBindingsImg; std::unique_ptr<weld::CheckButton> m_xBtnLink; std::unique_ptr<weld::Widget> m_xBtnLinkImg; + std::unique_ptr<weld::CheckButton> m_xBtnAcceptInvalidData; + std::unique_ptr<weld::Widget> m_xBtnAcceptInvalidDataImg; }; /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/optdlg/tpcompatibility.cxx b/sc/source/ui/optdlg/tpcompatibility.cxx index 02a287b339e6..ac2234c7911b 100644 --- a/sc/source/ui/optdlg/tpcompatibility.cxx +++ b/sc/source/ui/optdlg/tpcompatibility.cxx @@ -24,6 +24,8 @@ ScTpCompatOptions::ScTpCompatOptions(weld::Container* pPage, weld::DialogControl , m_xLbKeyBindingsImg(m_xBuilder->weld_widget(u"lockkeybindings"_ustr)) , m_xBtnLink(m_xBuilder->weld_check_button(u"cellLinkCB"_ustr)) , m_xBtnLinkImg(m_xBuilder->weld_widget(u"lockcellLinkCB"_ustr)) + , m_xBtnAcceptInvalidData(m_xBuilder->weld_check_button(u"cbAcceptInvalidData"_ustr)) + , m_xBtnAcceptInvalidDataImg(m_xBuilder->weld_widget(u"lockcbAcceptInvalidData"_ustr)) { } @@ -67,6 +69,11 @@ bool ScTpCompatOptions::FillItemSet(SfxItemSet *rCoreAttrs) rCoreAttrs->Put(SfxBoolItem(SID_SC_OPT_LINKS, m_xBtnLink->get_active())); bRet = true; } + if (m_xBtnAcceptInvalidData->get_state_changed_from_saved()) + { + rCoreAttrs->Put(SfxBoolItem(SID_SC_OPT_ALLOWINVALIDDATA, m_xBtnAcceptInvalidData->get_active())); + bRet = true; + } return bRet; } @@ -101,6 +108,14 @@ void ScTpCompatOptions::Reset(const SfxItemSet *rCoreAttrs) m_xBtnLink->set_sensitive(!officecfg::Office::Calc::Compatibility::Links::isReadOnly()); m_xBtnLinkImg->set_visible(officecfg::Office::Calc::Compatibility::Links::isReadOnly()); m_xBtnLink->save_state(); + + if (const SfxBoolItem* pbItem = rCoreAttrs->GetItemIfSet(SID_SC_OPT_ALLOWINVALIDDATA)) + { + m_xBtnAcceptInvalidData->set_active(pbItem->GetValue()); + } + m_xBtnAcceptInvalidData->set_sensitive(!officecfg::Office::Calc::Compatibility::AcceptInvalidData::isReadOnly()); + m_xBtnAcceptInvalidDataImg->set_visible(officecfg::Office::Calc::Compatibility::AcceptInvalidData::isReadOnly()); + m_xBtnAcceptInvalidData->save_state(); } DeactivateRC ScTpCompatOptions::DeactivatePage(SfxItemSet* /*pSet*/) diff --git a/sc/uiconfig/scalc/ui/optcompatibilitypage.ui b/sc/uiconfig/scalc/ui/optcompatibilitypage.ui index a826d1992287..44f4af928b1b 100644 --- a/sc/uiconfig/scalc/ui/optcompatibilitypage.ui +++ b/sc/uiconfig/scalc/ui/optcompatibilitypage.ui @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<!-- Generated with glade 3.38.2 --> +<!-- Generated with glade 3.40.0 --> <interface domain="sc"> <requires lib="gtk+" version="3.24"/> <object class="GtkBox" id="OptCompatibilityPage"> @@ -29,15 +29,11 @@ <object class="GtkLabel" id="label2"> <property name="visible">True</property> <property name="can-focus">False</property> - <property name="hexpand">True</property> - <property name="label" translatable="yes" context="optcompatibilitypage|label2">Select desired _key binding type. Changing the key binding type may overwrite some of the existing key bindings.</property> + <property name="tooltip-text" translatable="yes" context="optcompatibilitypage|label2|tooltip">Changing the key binding type may overwrite some of the existing key bindings</property> + <property name="label" translatable="yes" context="optcompatibilitypage|label2">Select desired _key binding type</property> <property name="use-underline">True</property> <property name="wrap">True</property> <property name="mnemonic-widget">keybindings</property> - <property name="width-chars">60</property> - <property name="max-width-chars">60</property> - <property name="xalign">0</property> - <property name="yalign">0</property> </object> <packing> <property name="left-attach">1</property> @@ -48,6 +44,7 @@ <object class="GtkComboBoxText" id="keybindings"> <property name="visible">True</property> <property name="can-focus">False</property> + <property name="halign">start</property> <property name="valign">start</property> <items> <item translatable="yes" context="optcompatibilitypage|keybindings">Default</item> @@ -111,7 +108,7 @@ <property name="column-spacing">12</property> <child> <object class="GtkCheckButton" id="cellLinkCB"> - <property name="label" translatable="yes" context="optcompatibilitypage|cellLinkCB">Insert _hyperlink for the cell, not for the text in the cell.</property> + <property name="label" translatable="yes" context="optcompatibilitypage|cellLinkCB">Insert _hyperlink for the cell, not for the text in the cell</property> <property name="visible">True</property> <property name="can-focus">True</property> <property name="receives-default">False</property> @@ -162,6 +159,75 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkFrame" id="frame3"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label-xalign">0</property> + <property name="shadow-type">none</property> + <child> + <!-- n-columns=3 n-rows=1 --> + <object class="GtkGrid" id="grid3"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="margin-start">12</property> + <property name="margin-top">6</property> + <property name="hexpand">True</property> + <property name="row-spacing">6</property> + <property name="column-spacing">12</property> + <child> + <object class="GtkCheckButton" id="cbAcceptInvalidData"> + <property name="label" translatable="yes" context="optcompatibilitypage|cbAcceptInvalidData">Allow inserting invalid values</property> + <property name="visible">True</property> + <property name="can-focus">True</property> + <property name="receives-default">False</property> + <property name="tooltip-text" translatable="yes" context="optcompatibilitypage|cbAcceptInvalidData|tooltip">By default, Excel accepts data that do not match the validation criteria</property> + <property name="use-underline">True</property> + <property name="draw-indicator">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="cbAcceptInvalidData-atkobject"> + <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|cellLinkCB">Calc can insert multiple hyperlinks in a cell as text fields, but multiple hyperlinks in a cell cannot be saved to Excel file formats. This option prevents inserting multiple hyperlinks in a cell when Excel files are edited, in order to be interoperable with Excel.</property> + </object> + </child> + </object> + <packing> + <property name="left-attach">1</property> + <property name="top-attach">0</property> + <property name="width">2</property> + </packing> + </child> + <child> + <object class="GtkImage" id="lockcbAcceptInvalidData"> + <property name="can-focus">False</property> + <property name="no-show-all">True</property> + <property name="halign">center</property> + <property name="valign">center</property> + <property name="icon-name">res/lock.png</property> + </object> + <packing> + <property name="left-attach">0</property> + <property name="top-attach">0</property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="lbAcceptInvalidData"> + <property name="visible">True</property> + <property name="can-focus">False</property> + <property name="label" translatable="yes" context="optcompatibilitypage|lbAcceptInvalidData">Data Validity</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> <child internal-child="accessible"> <object class="AtkObject" id="OptCompatibilityPage-atkobject"> <property name="AtkObject::accessible-description" translatable="yes" context="extended_tip|OptCompatibilityPage">Defines compatibility options for Calc.</property>
