cppcanvas/source/wrapper/implpolypolygon.cxx | 12 +++++++++++- cppcanvas/source/wrapper/implpolypolygon.hxx | 4 ++++ include/cppcanvas/polypolygon.hxx | 4 ++++ sd/qa/unit/data/odp/tdf166647_userpaint.odp |binary sd/qa/unit/uiimpress.cxx | 19 +++++++++++++++++++ slideshow/source/engine/shapes/shapeimporter.cxx | 1 + slideshow/source/engine/slideshowimpl.cxx | 2 ++ 7 files changed, 41 insertions(+), 1 deletion(-)
New commits: commit a98b1523141a8c3bed01ee9781f6b4844960bd73 Author: Regina Henschel <rb.hensc...@t-online.de> AuthorDate: Fri Jul 25 22:13:00 2025 +0200 Commit: Thorsten Behrens <thorsten.behr...@collabora.com> CommitDate: Tue Aug 12 00:07:17 2025 +0200 tdf#166647 avoid duplicating slideshow user paint When a user enables 'mouse as pen' before starting the slideshow, then his paintings are saved as persistent shapes when he exits slideshow. These shapes were then converted back to paintings when the user starts the slideshow again, so that they are visible againg. But these old paintings were treated as new paintings when the user exits slideshow and were then saved again as shape to the page although the page contains these shapes already. Thus with every new start and exit of the slideshow the shapes were duplicated. Because the duplicates are at exactly the same place as the originals, you do not notice it immediately. But you can see the duplicates in the Navigator and notice it in the file size. The fix introduces a flag that is set at the paintings from the existing shapes when the slideshow is started. This flag is then used to skip those paintings from converting to shapes when slideshow is finished. Change-Id: I93324d157b1b802d7b8e24858034d2fdc5d71b45 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188364 Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@collabora.com> Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/189365 diff --git a/cppcanvas/source/wrapper/implpolypolygon.cxx b/cppcanvas/source/wrapper/implpolypolygon.cxx index 536bfa60a53b..412248f038d4 100644 --- a/cppcanvas/source/wrapper/implpolypolygon.cxx +++ b/cppcanvas/source/wrapper/implpolypolygon.cxx @@ -47,7 +47,8 @@ namespace cppcanvas::internal rendering::PathCapType::ROUND, rendering::PathJoinType::ROUND ), mbFillColorSet( false ), - mbStrokeColorSet( false ) + mbStrokeColorSet( false ), + mbIsFromPreviousSlideshow(false) { OSL_ENSURE( mxPolyPoly.is(), "PolyPolygonImpl::PolyPolygonImpl: no valid polygon" ); } @@ -128,6 +129,15 @@ namespace cppcanvas::internal return mxPolyPoly; } + void ImplPolyPolygon::setIsFromPreviousSlideshow(const bool& rFlag) + { + mbIsFromPreviousSlideshow = rFlag; + } + + bool ImplPolyPolygon::getIsFromPreviousSlideshow() const + { + return mbIsFromPreviousSlideshow; + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/cppcanvas/source/wrapper/implpolypolygon.hxx b/cppcanvas/source/wrapper/implpolypolygon.hxx index b69a54e3db83..6ae0466f8a9f 100644 --- a/cppcanvas/source/wrapper/implpolypolygon.hxx +++ b/cppcanvas/source/wrapper/implpolypolygon.hxx @@ -51,6 +51,9 @@ namespace cppcanvas::internal virtual css::uno::Reference< css::rendering::XPolyPolygon2D > getUNOPolyPolygon() const override; + virtual void setIsFromPreviousSlideshow(const bool& rFlag) override; + virtual bool getIsFromPreviousSlideshow() const override; + private: ImplPolyPolygon(const ImplPolyPolygon&) = delete; ImplPolyPolygon& operator= ( const ImplPolyPolygon& ) = delete; @@ -63,6 +66,7 @@ namespace cppcanvas::internal css::uno::Sequence< double > maStrokeColor; bool mbFillColorSet; bool mbStrokeColorSet; + bool mbIsFromPreviousSlideshow; }; } diff --git a/include/cppcanvas/polypolygon.hxx b/include/cppcanvas/polypolygon.hxx index 04e3a61d3411..fdb01d215ac4 100644 --- a/include/cppcanvas/polypolygon.hxx +++ b/include/cppcanvas/polypolygon.hxx @@ -65,6 +65,10 @@ namespace cppcanvas virtual css::uno::Reference< css::rendering::XPolyPolygon2D > getUNOPolyPolygon() const = 0; + + virtual void setIsFromPreviousSlideshow(const bool& rFlag) = 0; + virtual bool getIsFromPreviousSlideshow() const = 0; + }; typedef std::shared_ptr< ::cppcanvas::PolyPolygon > PolyPolygonSharedPtr; diff --git a/sd/qa/unit/data/odp/tdf166647_userpaint.odp b/sd/qa/unit/data/odp/tdf166647_userpaint.odp new file mode 100644 index 000000000000..2bc2788af861 Binary files /dev/null and b/sd/qa/unit/data/odp/tdf166647_userpaint.odp differ diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx index 57b6e6d0962c..f32b2d891529 100644 --- a/sd/qa/unit/uiimpress.cxx +++ b/sd/qa/unit/uiimpress.cxx @@ -1998,6 +1998,25 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf127696) CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0x4), nFillColor); }*/ +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf166647_userpaint) +{ + // The document contains two shapes on layer DrawnInSlideshow and is empty besides that. The + // running slideshow is displayed in window mode, otherwise its additional window would be + // suppressed by the test environment. + createSdImpressDoc("odp/tdf166647_userpaint.odp"); + auto pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pXImpressDocument); + + // Go in slideshow mode and back to edit mode + dispatchCommand(mxComponent, u".uno:Presentation"_ustr, {}); + typeKey(pXImpressDocument, KEY_ESCAPE); + + // Count shapes. Error was, that the shapes were duplicated and thus count was 4. + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pViewShell); + CPPUNIT_ASSERT_EQUAL(size_t(2), pViewShell->GetActualPage()->GetObjCount()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/slideshow/source/engine/shapes/shapeimporter.cxx b/slideshow/source/engine/shapes/shapeimporter.cxx index f3cea68d3f76..7504f908a9b9 100644 --- a/slideshow/source/engine/shapes/shapeimporter.cxx +++ b/slideshow/source/engine/shapes/shapeimporter.cxx @@ -444,6 +444,7 @@ void ShapeImporter::importPolygons(uno::Reference<beans::XPropertySet> const& xP pPolyPoly->setRGBALineColor( unoColor2RGBColor( nLineColor ).getIntegerColor() ); pPolyPoly->setStrokeWidth(fLineWidth); pPolyPoly->draw(); + pPolyPoly->setIsFromPreviousSlideshow(true); maPolygons.push_back(pPolyPoly); } } diff --git a/slideshow/source/engine/slideshowimpl.cxx b/slideshow/source/engine/slideshowimpl.cxx index b606c3f59794..df15f7ac7c32 100644 --- a/slideshow/source/engine/slideshowimpl.cxx +++ b/slideshow/source/engine/slideshowimpl.cxx @@ -1524,6 +1524,8 @@ void SlideShowImpl::registerUserPaintPolygons( const uno::Reference< lang::XMult cppcanvas::PolyPolygonSharedPtr pFirstPolyPoly = aPolygons.front(); // for style properties for (const auto& pPolyPoly : aPolygons) { + if (pPolyPoly->getIsFromPreviousSlideshow()) + continue; // Actually, each item in aPolygons has two points, but wrapped in a cppcanvas::PopyPolygon. ::basegfx::B2DPolyPolygon b2DPolyPoly = ::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(