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: */
