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>

Reply via email to