sd/inc/sdpage.hxx | 2 sd/qa/unit/data/TestImage1.png |binary sd/qa/unit/data/TestImage2.png |binary sd/qa/unit/data/TestImage3.png |binary sd/qa/unit/data/TestImage4.png |binary sd/qa/unit/misc-tests.cxx | 147 +++++++++++++++++++++++++++++++++++++ sd/source/ui/inc/DrawViewShell.hxx | 4 - svx/source/xoutdev/xattr.cxx | 4 - 8 files changed, 152 insertions(+), 5 deletions(-)
New commits: commit c2cc4c4782107da0c1c32d0645b6b295376a83cb Author: Tomaž Vajngerl <[email protected]> AuthorDate: Fri May 23 12:18:28 2025 +0900 Commit: Tomaž Vajngerl <[email protected]> CommitDate: Mon May 26 14:03:33 2025 +0200 tdf#149207 fix image not getting a unique name Using "background" as the name, CheckNamedItem doesn't correctly determine that another XFillBitmapItem exists with an same "background" name already, which is then a problem when exporting the document and from all "background" images only one will be exported. regression from commit ec7ba61a6164c805f5a71b077715b7e1521a2d62 Author: Noel Grandin <[email protected]> Date: Wed Apr 17 15:19:25 2019 +0200 simplify SfxPoolItemArray_Impl (tdf#81765 related) I am not sure why the above commit caused this problem. Right now, the reason CheckNamedItem doesn't work is because with other subsequent changes to the pool infrastructure, the new PoolItem is already in the surrogates/NameOrIndex array and so it finds itself when scanning the array. But back then, the new PoolItem should not have been inserted yet. Any way, fix it by making CheckNamedItem exclude itself when scanning the surrogates data. Added a test for uniqueness of names. Change-Id: I3c04065a4875a21649ad8141243cc39a8d1a5b3c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185719 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <[email protected]> (cherry picked from commit cb5a4314c3561179e556107b81830a9949b20517) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185723 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Noel Grandin <[email protected]> diff --git a/sd/inc/sdpage.hxx b/sd/inc/sdpage.hxx index 492db5ea56dc..ace5daa0e478 100644 --- a/sd/inc/sdpage.hxx +++ b/sd/inc/sdpage.hxx @@ -343,7 +343,7 @@ public: /** @return the presentation style with the given helpid from this masterpage or this slides masterpage */ - SdStyleSheet* getPresentationStyle( sal_uInt32 nHelpId ) const; + SD_DLLPUBLIC SdStyleSheet* getPresentationStyle( sal_uInt32 nHelpId ) const; /** removes all empty presentation objects from this slide */ void RemoveEmptyPresentationObjects(); diff --git a/sd/qa/unit/data/TestImage1.png b/sd/qa/unit/data/TestImage1.png new file mode 100644 index 000000000000..e698130c6eb3 Binary files /dev/null and b/sd/qa/unit/data/TestImage1.png differ diff --git a/sd/qa/unit/data/TestImage2.png b/sd/qa/unit/data/TestImage2.png new file mode 100644 index 000000000000..c89b2d8cc170 Binary files /dev/null and b/sd/qa/unit/data/TestImage2.png differ diff --git a/sd/qa/unit/data/TestImage3.png b/sd/qa/unit/data/TestImage3.png new file mode 100644 index 000000000000..0e26be50ef46 Binary files /dev/null and b/sd/qa/unit/data/TestImage3.png differ diff --git a/sd/qa/unit/data/TestImage4.png b/sd/qa/unit/data/TestImage4.png new file mode 100644 index 000000000000..4a22e6ea9366 Binary files /dev/null and b/sd/qa/unit/data/TestImage4.png differ diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx index dc61d3275ed1..f08c7ab31b92 100644 --- a/sd/qa/unit/misc-tests.cxx +++ b/sd/qa/unit/misc-tests.cxx @@ -41,10 +41,13 @@ #include <editeng/outlobj.hxx> #include <editeng/editobj.hxx> #include <comphelper/base64.hxx> +#include <comphelper/propertysequence.hxx> #include <docmodel/uno/UnoGradientTools.hxx> #include <undo/undomanager.hxx> #include <GraphicViewShell.hxx> #include <sdpage.hxx> +#include <app.hrc> +#include <DrawViewShell.hxx> #include <LayerTabBar.hxx> #include <vcl/event.hxx> #include <vcl/keycodes.hxx> @@ -53,6 +56,8 @@ #include <svx/view3d.hxx> #include <svx/scene3d.hxx> #include <svx/sdmetitm.hxx> +#include <svx/xfillit0.hxx> +#include <svx/xbtmpit.hxx> #include <unomodel.hxx> using namespace ::com::sun::star; @@ -90,6 +95,7 @@ public: void testTdf164284(); void testEncodedTableStyles(); void testTdf157117(); + void testPageBackgroundImages(); CPPUNIT_TEST_SUITE(SdMiscTest); CPPUNIT_TEST(testTdf99396); @@ -116,6 +122,7 @@ public: CPPUNIT_TEST(testTdf164284); CPPUNIT_TEST(testEncodedTableStyles); CPPUNIT_TEST(testTdf157117); + CPPUNIT_TEST(testPageBackgroundImages); CPPUNIT_TEST_SUITE_END(); }; @@ -1092,6 +1099,146 @@ void SdMiscTest::testTdf157117() CPPUNIT_ASSERT_EQUAL(1, (nPageNum - 1) / 2); } +void SdMiscTest::testPageBackgroundImages() +{ + // Create empty document + createSdDrawDoc(); + + auto pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pViewShell); + + auto* pDrawViewShell = dynamic_cast<sd::DrawViewShell*>(pViewShell); + CPPUNIT_ASSERT(pDrawViewShell); + + SdDrawDocument* pDocument = pXImpressDocument->GetDocShell()->GetDoc(); + CPPUNIT_ASSERT(pDocument); + + // Check we have 1 Page + CPPUNIT_ASSERT_EQUAL(sal_uInt16(1), pDocument->GetSdPageCount(PageKind::Standard)); + + // Add 3 pages + dispatchCommand(mxComponent, u".uno:InsertPage"_ustr, {}); + dispatchCommand(mxComponent, u".uno:InsertPage"_ustr, {}); + dispatchCommand(mxComponent, u".uno:InsertPage"_ustr, {}); + + // Check we have 4 Pages now + CPPUNIT_ASSERT_EQUAL(sal_uInt16(4), pDocument->GetSdPageCount(PageKind::Standard)); + + // Add a background graphic to page 1 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(0)); + uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence({ + { "FileName", uno::Any(createFileURL(u"TestImage1.png")) }, + })); + + dispatchCommand(mxComponent, u".uno:SelectBackground"_ustr, aArgs); + } + + // Add a background graphic to page 2 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(1)); + uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence({ + { "FileName", uno::Any(createFileURL(u"TestImage2.png")) }, + })); + + dispatchCommand(mxComponent, u".uno:SelectBackground"_ustr, aArgs); + } + + // Add a background graphic to page 3 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(2)); + uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence({ + { "FileName", uno::Any(createFileURL(u"TestImage3.png")) }, + })); + + dispatchCommand(mxComponent, u".uno:SelectBackground"_ustr, aArgs); + } + + // Add a background graphic to page 4 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(3)); + uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence({ + { "FileName", uno::Any(createFileURL(u"TestImage4.png")) }, + })); + + dispatchCommand(mxComponent, u".uno:SelectBackground"_ustr, aArgs); + } + + // Store graphic names + std::unordered_set<OUString> aGraphicNames; + + // Check page 1 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(0)); + SdPage* pPage = pViewShell->GetActualPage(); + + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aMergedAttr(pDocument->GetPool()); + SdStyleSheet* pStyleSheet = pPage->getPresentationStyle(HID_PSEUDOSHEET_BACKGROUND); + sd::MergePageBackgroundFilling(pPage, pStyleSheet, false, aMergedAttr); + + // Style should be "BITMAP" + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, + aMergedAttr.Get(XATTR_FILLSTYLE).GetValue()); + auto aItem = aMergedAttr.Get<XFillBitmapItem>(XATTR_FILLBITMAP); + aGraphicNames.insert(aItem.GetName()); + } + + // Check page 2 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(1)); + SdPage* pPage = pViewShell->GetActualPage(); + + // Style should be "BITMAP" + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aMergedAttr(pDocument->GetPool()); + SdStyleSheet* pStyleSheet = pPage->getPresentationStyle(HID_PSEUDOSHEET_BACKGROUND); + sd::MergePageBackgroundFilling(pPage, pStyleSheet, false, aMergedAttr); + + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, + aMergedAttr.Get(XATTR_FILLSTYLE).GetValue()); + auto aItem = aMergedAttr.Get<XFillBitmapItem>(XATTR_FILLBITMAP); + aGraphicNames.insert(aItem.GetName()); + } + + // Check page 3 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(2)); + SdPage* pPage = pViewShell->GetActualPage(); + + // Style should be "BITMAP" + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aMergedAttr(pDocument->GetPool()); + SdStyleSheet* pStyleSheet = pPage->getPresentationStyle(HID_PSEUDOSHEET_BACKGROUND); + sd::MergePageBackgroundFilling(pPage, pStyleSheet, false, aMergedAttr); + + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, + aMergedAttr.Get(XATTR_FILLSTYLE).GetValue()); + auto aItem = aMergedAttr.Get<XFillBitmapItem>(XATTR_FILLBITMAP); + aGraphicNames.insert(aItem.GetName()); + } + + // Check page 4 + { + CPPUNIT_ASSERT_EQUAL(true, pDrawViewShell->SwitchPage(3)); + SdPage* pPage = pViewShell->GetActualPage(); + + SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aMergedAttr(pDocument->GetPool()); + SdStyleSheet* pStyleSheet = pPage->getPresentationStyle(HID_PSEUDOSHEET_BACKGROUND); + sd::MergePageBackgroundFilling(pPage, pStyleSheet, false, aMergedAttr); + + // Style should be "BITMAP" + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_BITMAP, + aMergedAttr.Get(XATTR_FILLSTYLE).GetValue()); + auto aItem = aMergedAttr.Get<XFillBitmapItem>(XATTR_FILLBITMAP); + aGraphicNames.insert(aItem.GetName()); + } + + // Size of graphic names should be 4 - this means each page has a unique name + CPPUNIT_ASSERT_EQUAL(size_t(4), aGraphicNames.size()); + // Check none of the graphic names is empty + for (OUString const& rName : aGraphicNames) + CPPUNIT_ASSERT(!rName.isEmpty()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sd/source/ui/inc/DrawViewShell.hxx b/sd/source/ui/inc/DrawViewShell.hxx index e2f9296c1ce7..e7022a61ca42 100644 --- a/sd/source/ui/inc/DrawViewShell.hxx +++ b/sd/source/ui/inc/DrawViewShell.hxx @@ -513,8 +513,8 @@ private: css::uno::Reference<css::presentation::XSlideShow> mxSlideShow; }; - /// Merge the background properties together and deposit the result in rMergeAttr - void MergePageBackgroundFilling(SdPage *pPage, SdStyleSheet *pStyleSheet, bool bMasterPage, SfxItemSet& rMergedAttr); +/// Merge the background properties together and deposit the result in rMergeAttr +SD_DLLPUBLIC void MergePageBackgroundFilling(SdPage *pPage, SdStyleSheet *pStyleSheet, bool bMasterPage, SfxItemSet& rMergedAttr); } // end of namespace sd diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx index b0fbc7bf7043..54d0c1464e0a 100644 --- a/svx/source/xoutdev/xattr.cxx +++ b/svx/source/xoutdev/xattr.cxx @@ -153,7 +153,7 @@ OUString NameOrIndex::CheckNamedItem(const sal_uInt16 nWhich, const SfxItemPool* const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem); // need to check for WhichID, GetItemSurrogatesForItem does buffer on type only - if( pNameOrIndex->Which() == nWhich && pNameOrIndex->GetName() == GetName() ) + if( pNameOrIndex != this && pNameOrIndex->Which() == nWhich && pNameOrIndex->GetName() == GetName() ) { // if there is already an item with the same name and the same // value it's ok to set it @@ -242,7 +242,7 @@ OUString NameOrIndex::CheckNamedItem(const sal_uInt16 nWhich, const SfxItemPool* const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem); // need to check for WhichID, GetItemSurrogatesForItem does buffer on type only - if( pNameOrIndex->Which() == nWhich && !pNameOrIndex->GetName().isEmpty() ) + if( pNameOrIndex != this && pNameOrIndex->Which() == nWhich && !pNameOrIndex->GetName().isEmpty() ) { if( !bForceNew && pCompareValueFunc( pNameOrIndex, this ) ) return pNameOrIndex->GetName();
