sw/CppunitTest_sw_core_doc.mk               |    1 
 sw/qa/core/doc/data/bad-heading-indent.docx |binary
 sw/qa/core/doc/number.cxx                   |   51 ++++++++++++++++++++++++++++
 sw/source/core/doc/number.cxx               |    3 +
 sw/source/ui/misc/outline.cxx               |    8 ++++
 5 files changed, 63 insertions(+)

New commits:
commit 4436f98aaecf00df92a5ddcfd188fcf4b28f5ee8
Author:     Miklos Vajna <[email protected]>
AuthorDate: Mon Dec 15 08:44:05 2025 +0100
Commit:     Xisco Fauli <[email protected]>
CommitDate: Mon Dec 22 11:05:30 2025 +0100

    tdf#169949 sw num rule defaults: let numbering type none imply follow by 
none
    
    Load the document, press Ctrl-1 to set a heading 1 paragraph style, an
    unexpected leading tab shows up before the paragraph text.
    
    This went wrong with commit a7d9837a8aa6d1233f4c21e4db5d32428a3ffc58
    (tdf#148360: sw: do not ignore list label followed by, 2022-08-02),
    previously "followed by" was ignored by the layout if the numbering
    portion before the separator was empty. This is needed to correctly lay
    out DOCX files.
    
    Fix the problem by changing the default Outline numbering rule in
    Writer: the numbering type is set to "none", so also set the "label
    followed by" property to "nothing". Note that this doesn't affect DOCX
    files which already have heading styles configured, nor documents where
    the DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY compatibility option
    is off.
    
    There was one handy side-effect of having "followed by" as "tab": once
    the UI was used to change the numbering type from "none" to e.g. Arabic,
    the user didn't have to explicitly ask for the tab separator, which is
    usually wanted. Continue supporting this scenario by checking for the
    "number type none + followed by nothing" scenario: if the number type
    changes to something else, then also change "followed by" to the old
    "tab" default.
    
    Change-Id: I60905623e6c4b6ded56a1a089ae0fb3af3b2bd3a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195706
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <[email protected]>
    (cherry picked from commit a4514488d92be420c4bfac0e0c0dea4c48bec37c)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/196068
    Reviewed-by: Xisco Fauli <[email protected]>

diff --git a/sw/CppunitTest_sw_core_doc.mk b/sw/CppunitTest_sw_core_doc.mk
index 9e12126c1c7a..6c0aec27e9aa 100644
--- a/sw/CppunitTest_sw_core_doc.mk
+++ b/sw/CppunitTest_sw_core_doc.mk
@@ -15,6 +15,7 @@ $(eval $(call 
gb_CppunitTest_use_common_precompiled_header,sw_core_doc))
 
 $(eval $(call gb_CppunitTest_add_exception_objects,sw_core_doc, \
     sw/qa/core/doc/doc \
+    sw/qa/core/doc/number \
     sw/qa/core/doc/DocumentRedlineManager \
 ))
 
diff --git a/sw/qa/core/doc/data/bad-heading-indent.docx 
b/sw/qa/core/doc/data/bad-heading-indent.docx
new file mode 100644
index 000000000000..65ec57ab12c4
Binary files /dev/null and b/sw/qa/core/doc/data/bad-heading-indent.docx differ
diff --git a/sw/qa/core/doc/number.cxx b/sw/qa/core/doc/number.cxx
new file mode 100644
index 000000000000..7396b1c262a0
--- /dev/null
+++ b/sw/qa/core/doc/number.cxx
@@ -0,0 +1,51 @@
+/* -*- 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 <swmodeltestbase.hxx>
+
+#include <comphelper/propertyvalue.hxx>
+
+namespace
+{
+/// Covers sw/source/core/doc/number.cxx fixes.
+class Test : public SwModelTestBase
+{
+public:
+    Test()
+        : SwModelTestBase(u"/sw/qa/core/doc/data/"_ustr)
+    {
+    }
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testBadHeadingIndent)
+{
+    // Given a DOCX file with a single paragraph, no heading styles present:
+    createSwDoc("bad-heading-indent.docx");
+
+    // When marking that paragraph heading 1:
+    uno::Sequence<beans::PropertyValue> aPropertyValues = {
+        comphelper::makePropertyValue(u"Style"_ustr, uno::Any(u"Heading 
1"_ustr)),
+        comphelper::makePropertyValue(u"FamilyName"_ustr, 
uno::Any(u"ParagraphStyles"_ustr)),
+    };
+    dispatchCommand(mxComponent, u".uno:StyleApply"_ustr, aPropertyValues);
+
+    // Then make sure that doesn't result in unexpected indent:
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    int nTabCount
+        = getXPathContent(pXmlDoc, 
"count(//SwLineLayout/child::*[@type='PortionType::TabLeft'])")
+              .toInt32();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 0
+    // - Actual  : 1
+    // i.e. an unexpected tab portion was inserted before the paragraph text.
+    CPPUNIT_ASSERT_EQUAL(0, nTabCount);
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/doc/number.cxx b/sw/source/core/doc/number.cxx
index fd5d0431ce2e..dc12bf7d5f36 100644
--- a/sw/source/core/doc/number.cxx
+++ b/sw/source/core/doc/number.cxx
@@ -475,6 +475,9 @@ SwNumRule::SwNumRule( UIName aNm,
         {
             pFormat = new SwNumFormat;
             pFormat->SetNumberingType(SVX_NUM_NUMBER_NONE);
+            // SVX_NUM_NUMBER_NONE with the default SvxNumberFormat::LISTTAB 
would lead to an
+            // unexpected leading tab for the 
DocumentSettingId::NO_NUMBERING_SHOW_FOLLOWBY case.
+            pFormat->SetLabelFollowedBy(SvxNumberFormat::NOTHING);
             pFormat->SetIncludeUpperLevels( MAXLEVEL );
             pFormat->SetStart( 1 );
             pFormat->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT 
);
diff --git a/sw/source/ui/misc/outline.cxx b/sw/source/ui/misc/outline.cxx
index 3631d98251d3..cebdd5cf843c 100644
--- a/sw/source/ui/misc/outline.cxx
+++ b/sw/source/ui/misc/outline.cxx
@@ -629,7 +629,15 @@ IMPL_LINK_NOARG(SwOutlineSettingsTabPage, NumberSelect, 
weld::ComboBox&, void)
         if(m_nActLevel & nMask)
         {
             SwNumFormat aNumFormat(m_pNumRule->Get(i));
+            SvxNumType nOldNumberType = aNumFormat.GetNumberingType();
             aNumFormat.SetNumberingType(nNumberType);
+            if (nOldNumberType == SVX_NUM_NUMBER_NONE && nNumberType != 
SVX_NUM_NUMBER_NONE
+                && aNumFormat.GetLabelFollowedBy() == SvxNumberFormat::NOTHING)
+            {
+                // Transitioning from "no" numbering, also set the followed by 
setting to the
+                // default from "empty".
+                aNumFormat.SetLabelFollowedBy(SvxNumberFormat::LISTTAB);
+            }
             // ensure that HasListFormat
             aNumFormat.SetListFormat(aNumFormat.GetPrefix(), 
aNumFormat.GetSuffix(), i);
             m_pNumRule->Set(i, aNumFormat);

Reply via email to