Related: tdf#89365 sd UI, from numbering to bullet: fix defaults

Open the bugdoc, start text edit on the only slide, in the only shape.
Use the toolbar button to change from no numbering to bullet, some very
small bullet with no spacing between the bullet and the text shows up.

This happens since commit f60ee00edcc5b0fdee5227bb695448119cddb013
(tdf#89365 sd UI: fix transitioning from a numbered list to a bulleted
list, 2025-11-04), previously the numbering to bullet transitioning was
broken and you had to click on the "turn on bullets" button twice. A
side effect of the old two-step transitioning was that no formatting
from the old numbering was kept, so better defaults were used (but the
numbering level was lost).

Keep the old use-case fixed and fix the new use-case by looking at how
this works on master pages: there TextObjectBar::ExecuteImpl()'s
FN_NUM_BULLET_ON block calls
SdStyleSheetPool::setDefaultOutlineNumberFormatBulletAndIndent() before
setting the number format for a specific level of the numbering rule. Do
the same for non-master pages in
FuBulletAndPosition::SetCurrentBulletsNumbering(): if we transition to a
bullet, then use the same defaults in the non-master-page case, too.

Note that turning bullets on or off as direct formatting is not ideal: a
better style is to assign bullets (or no bullets) to different outline
levels in the master page, and then just change the list level of
paragraphs in the outliner shape, which avoids this sort of problem in
the first place.

Change-Id: I4227988593baeaa91cc21525fb895c3acaf3afd7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195839
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
This commit is contained in:
Miklos Vajna
2025-12-18 13:34:33 +01:00
parent fdf541b6db
commit fe9fab9702
7 changed files with 203 additions and 20 deletions
+88
View File
@@ -0,0 +1,88 @@
# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
#*************************************************************************
#
# 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/.
#
#*************************************************************************
$(eval $(call gb_CppunitTest_CppunitTest,sd_ui_func))
$(eval $(call gb_CppunitTest_use_externals,sd_ui_func,\
boost_headers \
libxml2 \
))
$(eval $(call gb_CppunitTest_use_common_precompiled_header,sd_ui_func))
$(eval $(call gb_CppunitTest_add_exception_objects,sd_ui_func, \
sd/qa/ui/func/func \
))
$(eval $(call gb_CppunitTest_use_libraries,sd_ui_func, \
basegfx \
canvastools \
comphelper \
cppcanvas \
cppu \
cppuhelper \
docmodel \
drawinglayer \
editeng \
for \
forui \
i18nlangtag \
i18nutil \
msfilter \
oox \
sal \
salhelper \
sax \
sb \
sd \
sfx \
sot \
subsequenttest \
svl \
svt \
svx \
svxcore \
test \
tl \
tk \
ucbhelper \
unotest \
utl \
vcl \
xo \
))
$(eval $(call gb_CppunitTest_set_include,sd_ui_func,\
-I$(SRCDIR)/sd/inc \
-I$(SRCDIR)/sd/source/ui/inc \
-I$(SRCDIR)/sd/source/ui/slidesorter/inc \
-I$(SRCDIR)/sd/qa/unit \
$$(INCLUDE) \
))
$(eval $(call gb_CppunitTest_use_sdk_api,sd_ui_func))
$(eval $(call gb_CppunitTest_use_ure,sd_ui_func))
$(eval $(call gb_CppunitTest_use_vcl,sd_ui_func))
$(eval $(call gb_CppunitTest_use_rdb,sd_ui_func,services))
$(eval $(call gb_CppunitTest_use_custom_headers,sd_ui_func,\
officecfg/registry \
))
$(eval $(call gb_CppunitTest_use_configuration,sd_ui_func))
$(eval $(call gb_CppunitTest_add_arguments,sd_ui_func, \
-env:arg-env=$(gb_Helper_LIBRARY_PATH_VAR)"$$$${$(gb_Helper_LIBRARY_PATH_VAR)+=$$$$$(gb_Helper_LIBRARY_PATH_VAR)}" \
))
# vim: set noet sw=4 ts=4:
+1
View File
@@ -45,6 +45,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sd,\
CppunitTest_sd_layout_tests \
CppunitTest_sd_misc_tests \
CppunitTest_sd_uiimpress \
CppunitTest_sd_ui_func \
CppunitTest_sd_html_export_tests \
CppunitTest_sd_activex_controls_tests \
CppunitTest_sd_pdf_import_test \
+88
View File
@@ -0,0 +1,88 @@
/* -*- 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 <sdmodeltestbase.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/XDrawPage.hpp>
#include <comphelper/sequenceashashmap.hxx>
#include <vcl/scheduler.hxx>
#include <DrawDocShell.hxx>
#include <ViewShell.hxx>
#include <sdpage.hxx>
#include <unomodel.hxx>
using namespace com::sun::star;
namespace
{
/// Covers sd/source/ui/func/ fixes.
class Test : public SdModelTestBase
{
public:
Test()
: SdModelTestBase(u"/sd/qa/unit/data/"_ustr)
{
}
};
CPPUNIT_TEST_FIXTURE(Test, testNoneToBullet)
{
// Given a document with a shape, the only paragraph has a numbering of type "none":
createSdImpressDoc("odp/none-to-bullet.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 "none" numbering to a bullet:
// Start text edit:
auto pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
typeString(pImpressDocument, u"x");
CPPUNIT_ASSERT(pView->IsTextEdit());
// Do the switch:
dispatchCommand(mxComponent, u".uno:DefaultBullet"_ustr, {});
// End text edit:
typeKey(pImpressDocument, KEY_ESCAPE);
// Then make sure we switch to a bullet with reasonable defaults:
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);
uno::Reference<beans::XPropertySet> xParagraph(getParagraphFromShape(0, xShape),
uno::UNO_QUERY);
// Check the list level 1 properties:
uno::Reference<container::XIndexAccess> xNumberingRules;
xParagraph->getPropertyValue(u"NumberingRules"_ustr) >>= xNumberingRules;
comphelper::SequenceAsHashMap aNumberingRule(xNumberingRules->getByIndex(0));
sal_Int32 nLeftMargin{};
aNumberingRule[u"LeftMargin"_ustr] >>= nLeftMargin;
// Without the accompanying fix in place, this test would have failed with:
// - Expected: 1200
// - Actual : 0
// i.e. there was no left margin at all, first and later lines did not match on the left hand
// side.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1200), nLeftMargin);
sal_Int32 nFirstLineOffset{};
aNumberingRule[u"FirstLineOffset"_ustr] >>= nFirstLineOffset;
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(-900), nFirstLineOffset);
}
}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Binary file not shown.
+19
View File
@@ -34,6 +34,8 @@
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/packages/zip/ZipFileAccess.hpp>
#include <drawinglayer/XShapeDumper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <vcl/scheduler.hxx>
#include <com/sun/star/text/XTextField.hpp>
using namespace ::com::sun::star;
@@ -184,6 +186,23 @@ public:
return pXmlDoc;
}
void typeString(SdXImpressDocument* rImpressDocument, std::u16string_view rStr)
{
for (const char16_t c : rStr)
{
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, c, 0);
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, c, 0);
Scheduler::ProcessEventsToIdle();
}
}
void typeKey(SdXImpressDocument* rImpressDocument, const sal_uInt16 nKey)
{
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, nKey);
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, nKey);
Scheduler::ProcessEventsToIdle();
}
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
-19
View File
@@ -80,8 +80,6 @@ public:
}
void checkCurrentPageNumber(sal_uInt16 nNum);
void typeString(SdXImpressDocument* rImpressDocument, std::u16string_view rStr);
void typeKey(SdXImpressDocument* rImpressDocument, const sal_uInt16 nKey);
void insertStringToObject(sal_uInt16 nObj, std::u16string_view rStr, bool bUseEscape);
sd::slidesorter::SlideSorterViewShell* getSlideSorterViewShell();
void lcl_search(const OUString& rKey, bool bFindAll = false, bool bBackwards = false);
@@ -99,23 +97,6 @@ void SdUiImpressTest::checkCurrentPageNumber(sal_uInt16 nNum)
CPPUNIT_ASSERT_EQUAL(nNum, nPageNumber);
}
void SdUiImpressTest::typeKey(SdXImpressDocument* rImpressDocument, const sal_uInt16 nKey)
{
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, nKey);
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, nKey);
Scheduler::ProcessEventsToIdle();
}
void SdUiImpressTest::typeString(SdXImpressDocument* rImpressDocument, std::u16string_view rStr)
{
for (const char16_t c : rStr)
{
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, c, 0);
rImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, c, 0);
Scheduler::ProcessEventsToIdle();
}
}
void SdUiImpressTest::insertStringToObject(sal_uInt16 nObj, std::u16string_view rStr,
bool bUseEscape)
{
+7 -1
View File
@@ -206,7 +206,13 @@ void FuBulletAndPosition::SetCurrentBulletsNumbering(SfxRequest& rReq)
{
if(nActNumLvl & nMask)
{
const SvxNumberFormat& aFmt(aTmpRule.GetLevel(i));
SvxNumberFormat aFmt(aTmpRule.GetLevel(i));
if (nSId == FN_SVX_SET_BULLET)
{
// If changing to a bullet, then make its format and indent has a good
// default, similar to what the master page offers:
SdStyleSheetPool::setDefaultOutlineNumberFormatBulletAndIndent(i, aFmt);
}
pNumRule->SetLevel(i, aFmt);
}
nMask <<= 1;