editeng/source/outliner/outlvw.cxx    |    8 +++++
 sd/qa/unit/data/odp/bullet-off-on.odp |binary
 sd/qa/unit/uiimpress.cxx              |   49 ++++++++++++++++++++++++++++++++++
 3 files changed, 57 insertions(+)

New commits:
commit 258155a54cb94527638d4ece8a4674cb4a7b8308
Author:     Miklos Vajna <[email protected]>
AuthorDate: Thu Nov 6 10:48:07 2025 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Mon Nov 10 08:09:56 2025 +0100

    tdf#169275 sd UI: clear direct format when turning off bullet/num
    
    Open the bugdoc, go to the last paragraph of the only shape in the
    document, press 'Toggle Unordered List', bullet disappears, press it
    again, bullet appears and the indent is 0cm, even if the master page
    defines Level 1 to have 0.30cm indent and Level 2 to have 1.5cm indent,
    so we end up with a third, unexpected indent.
    
    What happens is that the last paragraph is technically level 3, but it
    has direct formatting to look like level 2. Turning off bullets resets
    the level to 0 (no bullets), but the numbering rules as direct format is
    still there. Once the bullet is toggled on, the level 1 indent of this
    numbering rules gets applied, which is confusing and is inconsistent
    with the numbering rules from the master page.
    
    Fix the problem by removing the numbering rules from the selected
    paragraph(s) when you toggle off a bullet or numbering. The numbering
    level will be lost anyway, and this gives "toggle on" a chance to again
    connect to the outline style of the master page, resulting in a
    consistent indent of Level 1 (0.30cm in the bugdoc case).
    
    This keeps the "to numbering" case unchanged, which has to be direct
    formatting (for the bugdoc case), since the master page declares
    bullets. This only changes editing for the non-masterpage case, since
    TextObjectBar::ExecuteImpl() won't dispatch FN_SVX_SET_BULLET for master
    pages. Finally, only do this for outline shapes, leave the behavior
    unchanged for other shape types, which are not connected to master page
    styles.
    
    Change-Id: I4df409e450862fc472d115d196c47fa2d7f17c7b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/193542
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <[email protected]>

diff --git a/editeng/source/outliner/outlvw.cxx 
b/editeng/source/outliner/outlvw.cxx
index 29221978de2d..c5d90d0713fd 100644
--- a/editeng/source/outliner/outlvw.cxx
+++ b/editeng/source/outliner/outlvw.cxx
@@ -1201,6 +1201,14 @@ void OutlinerView::SwitchOffBulletsNumbering(
             {
                 SfxItemSet aAttrs(rAttrs);
                 aAttrs.ClearItem( EE_PARA_BULLETSTATE );
+
+                if (rOwner.GetOutlinerMode() == OutlinerMode::OutlineObject)
+                {
+                    // Outliner shape: also clear the SvxNumRule, so a next 
"switch on" will again
+                    // work with styles from the master page.
+                    aAttrs.ClearItem(EE_PARA_NUMBULLET);
+                }
+
                 rOwner.SetParaAttribs( nPara, aAttrs );
             }
         }
diff --git a/sd/qa/unit/data/odp/bullet-off-on.odp 
b/sd/qa/unit/data/odp/bullet-off-on.odp
new file mode 100644
index 000000000000..48aed310b337
Binary files /dev/null and b/sd/qa/unit/data/odp/bullet-off-on.odp differ
diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx
index 95ab12508b97..4348f0e35e87 100644
--- a/sd/qa/unit/uiimpress.cxx
+++ b/sd/qa/unit/uiimpress.cxx
@@ -2130,6 +2130,55 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testNumToBullet)
     CPPUNIT_ASSERT_EQUAL(style::NumberingType::CHAR_SPECIAL, nNumberingType);
 }
 
+CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testBulletOffOn)
+{
+    // Given a document with a shape, last paragraph is has a bullet:
+    createSdImpressDoc("odp/bullet-off-on.odp");
+    sd::ViewShell* pViewShell = getSdDocShell()->GetViewShell();
+    SdPage* pPage = pViewShell->GetActualPage();
+    SdrObject* pShape = pPage->GetObj(0);
+    CPPUNIT_ASSERT(pShape);
+    SdrView* pView = pViewShell->GetView();
+    pView->MarkObj(pShape, pView->GetSdrPageView());
+    Scheduler::ProcessEventsToIdle();
+    CPPUNIT_ASSERT(!pView->IsTextEdit());
+
+    // When turning the bullet off & then back on again:
+    // Start text edit:
+    auto pImpressDocument = 
dynamic_cast<SdXImpressDocument*>(mxComponent.get());
+    typeString(pImpressDocument, u"x");
+    CPPUNIT_ASSERT(pView->IsTextEdit());
+    // Toggle off:
+    dispatchCommand(mxComponent, u".uno:DefaultBullet"_ustr, {});
+    // Toggle on:
+    dispatchCommand(mxComponent, u".uno:DefaultBullet"_ustr, {});
+    // End text edit:
+    typeKey(pImpressDocument, KEY_ESCAPE);
+
+    // Then make sure the result is Level 1 from the master page:
+    CPPUNIT_ASSERT(!pView->IsTextEdit());
+    uno::Reference<drawing::XDrawPagesSupplier> 
xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> 
xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xShape(xDrawPage->getByIndex(0), 
uno::UNO_QUERY);
+    // 5th, last paragraph.
+    uno::Reference<beans::XPropertySet> xParagraph(getParagraphFromShape(4, 
xShape),
+                                                   uno::UNO_QUERY);
+    uno::Reference<container::XIndexAccess> xNumberingRules;
+    xParagraph->getPropertyValue(u"NumberingRules"_ustr) >>= xNumberingRules;
+    // Level 1.
+    comphelper::SequenceAsHashMap 
aNumberingRule(xNumberingRules->getByIndex(0));
+    sal_Int32 nLeftMargin = 0;
+    aNumberingRule[u"LeftMargin"_ustr] >>= nLeftMargin;
+    sal_Int32 nFirstLineOffset = 0;
+    aNumberingRule[u"FirstLineOffset"_ustr] >>= nFirstLineOffset;
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 300
+    // - Actual  : 0
+    // i.e. the indent was 0cm, even if Level1 and Level2 had other values.
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(300), nLeftMargin + 
nFirstLineOffset);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to