include/svx/sdr/contact/objectcontact.hxx              |    3 +
 sd/qa/unit/SVGExportTests.cxx                          |   32 ++++++++---------
 sd/qa/unit/layout-tests.cxx                            |    2 -
 svx/inc/sdr/primitive2d/sdrrectangleprimitive2d.hxx    |    9 +++-
 svx/source/sdr/contact/objectcontactofpageview.cxx     |   12 +++++-
 svx/source/sdr/contact/viewcontactofsdrrectobj.cxx     |    3 +
 svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx |   25 +++++++++++--
 7 files changed, 60 insertions(+), 26 deletions(-)

New commits:
commit 9106d4fced90da8a3117d0a87da272939abb6cee
Author:     Balazs Varga <[email protected]>
AuthorDate: Thu Dec 18 16:23:37 2025 +0100
Commit:     Balazs Varga <[email protected]>
CommitDate: Tue Dec 23 07:58:08 2025 +0100

    tdf#168110 - sd fix Placeholder default text is visible
    
    in presentation mode
    
    Do not render empty pres objects texts in slideshow.
    
    follow-up of commits:
    e136900e7a971385be9367a3dcaedea54d1e7207
    (tdf#159258 sd: fix to show objects in slideshow if they have)
    d323976fd6d560a9b91da3e7833dfbe9f6b78f39
    (tdf#159258 SD: SS: disable placeholdertext in image)
    
    co-author: Armin Le Grand <[email protected]>
    
    Change-Id: I6127cdc36a27dfeac79881b57b9b8cbf963c9d3a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/195857
    Tested-by: Jenkins CollaboraOffice <[email protected]>
    Reviewed-by: Balazs Varga <[email protected]>

diff --git a/include/svx/sdr/contact/objectcontact.hxx 
b/include/svx/sdr/contact/objectcontact.hxx
index 8d2dc8c6ad8c..9f5fc127ffae 100644
--- a/include/svx/sdr/contact/objectcontact.hxx
+++ b/include/svx/sdr/contact/objectcontact.hxx
@@ -88,6 +88,9 @@ protected:
     // interface to allow derivates to set ViewInformation2D
     void updateViewInformation2D(const 
drawinglayer::geometry::ViewInformation2D& rViewInformation2D) { 
maViewInformation2D = rViewInformation2D; }
 
+    // Allow to set EditViewActive early at local ViewInformation2D from 
ObjectContactOfPageView
+    void setEditViewActiveEarly() { 
maViewInformation2D.setEditViewActive(true); }
+
 public:
     // basic constructor
     ObjectContact();
diff --git a/sd/qa/unit/SVGExportTests.cxx b/sd/qa/unit/SVGExportTests.cxx
index 68d73bee89db..f15420e68e9c 100644
--- a/sd/qa/unit/SVGExportTests.cxx
+++ b/sd/qa/unit/SVGExportTests.cxx
@@ -131,20 +131,20 @@ public:
         xmlDocUniquePtr svgDoc = parseXml(maTempFile);
         CPPUNIT_ASSERT(svgDoc);
 
-        assertXPath(svgDoc, SAL_STRINGIFY( /SVG_SVG/SVG_DEFS[9]/SVG_G[2] ), 
"class", u"Master_Slide");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2] ), "class", u"BackgroundObjects");
+        assertXPath(svgDoc, SAL_STRINGIFY( /SVG_SVG/SVG_DEFS[8]/SVG_G[2] ), 
"class", u"Master_Slide");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2] ), "class", u"BackgroundObjects");
         // Current Date Field
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[4] ), "class", u"TextShape");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[4]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText Date");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[4] ), "class", u"TextShape");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[4]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText Date");
         // Current Time Field
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[5] ), "class", u"TextShape");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[5]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText Time");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[5] ), "class", u"TextShape");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[5]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText Time");
         // Slide Name Field
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[6] ), "class", u"TextShape");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[6]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageName");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[6] ), "class", u"TextShape");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[6]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageName");
         // Slide Number Field
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[7] ), "class", u"TextShape");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[7]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageNumber");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[7] ), "class", u"TextShape");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[7]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageNumber");
     }
 
     void testSVGExportEmbeddedVideo()
@@ -280,15 +280,15 @@ public:
         xmlDocUniquePtr svgDoc = parseXml(maTempFile);
         CPPUNIT_ASSERT(svgDoc);
 
-        assertXPath(svgDoc, SAL_STRINGIFY( /SVG_SVG/SVG_DEFS[9]/SVG_G[2] ), 
"class", u"Master_Slide");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2] ), "class", u"BackgroundObjects");
+        assertXPath(svgDoc, SAL_STRINGIFY( /SVG_SVG/SVG_DEFS[8]/SVG_G[2] ), 
"class", u"Master_Slide");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2] ), "class", u"BackgroundObjects");
 
         // Slide Name Field
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[6] ), "class", u"TextShape");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[6]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageName");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[6] ), "class", u"TextShape");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[6]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageName");
         // Slide Number Field
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[7] ), "class", u"TextShape");
-        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[9]/SVG_G[2]/SVG_G[2]/SVG_G[7]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageNumber");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[7] ), "class", u"TextShape");
+        assertXPath(svgDoc, SAL_STRINGIFY( 
/SVG_SVG/SVG_DEFS[8]/SVG_G[2]/SVG_G[2]/SVG_G[7]/SVG_G/SVG_TEXT/SVG_TSPAN/SVG_TSPAN/SVG_TSPAN
 ), "class", u"PlaceholderText PageNumber");
     }
 
     CPPUNIT_TEST_SUITE(SdSVGFilterTest);
diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx
index 9a593b611da0..dd35a446ba92 100644
--- a/sd/qa/unit/layout-tests.cxx
+++ b/sd/qa/unit/layout-tests.cxx
@@ -337,7 +337,7 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf156955)
     xmlDocUniquePtr pXmlDoc = load("odp/tdf156955.odp");
 
     // Make sure text box has the right size - without the fix it was 2759.
-    assertXPath(pXmlDoc, "/metafile/push/push/textarray[5]", "y", u"3183");
+    assertXPath(pXmlDoc, "/metafile/push/push/textarray[3]", "y", u"3183");
 }
 
 CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf148966)
diff --git a/svx/inc/sdr/primitive2d/sdrrectangleprimitive2d.hxx 
b/svx/inc/sdr/primitive2d/sdrrectangleprimitive2d.hxx
index 07600202ee83..6a614ec192ce 100644
--- a/svx/inc/sdr/primitive2d/sdrrectangleprimitive2d.hxx
+++ b/svx/inc/sdr/primitive2d/sdrrectangleprimitive2d.hxx
@@ -33,13 +33,15 @@ namespace drawinglayer::primitive2d
         {
         private:
             basegfx::B2DHomMatrix                       maTransform;
-            attribute::SdrLineFillEffectsTextAttribute   maSdrLFSTAttribute;
+            attribute::SdrLineFillEffectsTextAttribute  maSdrLFSTAttribute;
             double                                      mfCornerRadiusX;    // 
[0.0..1.0] relative to 1/2 width
             double                                      mfCornerRadiusY;    // 
[0.0..1.0] relative to 1/2 height
 
             // flag which decides if the HitArea should be the filled geometry
             bool                                        mbForceFillForHitTest 
: 1;
 
+            // flag which decides if the presentation object has empty 
placeholder text or not
+            bool                                        mbPlaceholderText : 1;
             // local decomposition.
             virtual Primitive2DReference create2DDecomposition(const 
geometry::ViewInformation2D& aViewInformation) const override;
 
@@ -49,7 +51,8 @@ namespace drawinglayer::primitive2d
                 const attribute::SdrLineFillEffectsTextAttribute& 
rSdrLFSTAttribute,
                 double fCornerRadiusX,
                 double fCornerRadiusY,
-                bool bForceFillForHitTest);
+                bool bForceFillForHitTest,
+                bool bPlaceholderText = false);
 
             // data access
             const basegfx::B2DHomMatrix& getTransform() const { return 
maTransform; }
@@ -57,6 +60,8 @@ namespace drawinglayer::primitive2d
             double getCornerRadiusX() const { return mfCornerRadiusX; }
             double getCornerRadiusY() const { return mfCornerRadiusY; }
             bool getForceFillForHitTest() const { return 
mbForceFillForHitTest; }
+            bool getPlaceholderText() const { return mbPlaceholderText; }
+
 
             // compare operator
             virtual bool operator==(const BasePrimitive2D& rPrimitive) const 
override;
diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx 
b/svx/source/sdr/contact/objectcontactofpageview.cxx
index 28b40a56d59e..21a1103569ab 100644
--- a/svx/source/sdr/contact/objectcontactofpageview.cxx
+++ b/svx/source/sdr/contact/objectcontactofpageview.cxx
@@ -60,6 +60,14 @@ namespace sdr::contact
             : Idle(pDebugName)
             , mrPageWindow(rPageWindow)
         {
+            // Set EditViewActive early at local ViewInformation2D. Usually 
this
+            // gets updated at the 1st paint (see updateViewInformation2D 
calls).
+            // To be independent of this mechanism and prepared for cases where
+            // e.g. a HitTest is used before paint, initialize it here already.
+            // This is the ObjectContact of PageView, so usage is bound to
+            // EditView visualization anyways
+            setEditViewActiveEarly();
+
             // init PreviewRenderer flag
             
setPreviewRenderer(static_cast<SdrPaintView&>(rPageWindow.GetPageView().GetView()).IsPreviewRenderer());
 
@@ -225,8 +233,8 @@ namespace sdr::contact
                 aNewViewInformation2D.setTextEditActive(true);
 
             // this is the EditView repaint, provide that information,
-            // but only if we do not export to metafile
-            if (!isOutputToRecordingMetaFile())
+            // but only if we do not export to metafile and do not prepare a 
SlideShow
+            if (!isOutputToRecordingMetaFile() && 
!comphelper::LibreOfficeKit::isSlideshowRendering())
                 aNewViewInformation2D.setEditViewActive(true);
 
             updateViewInformation2D(aNewViewInformation2D);
diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx 
b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx
index 46cdd21ad0c2..be3cebabbd53 100644
--- a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx
+++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx
@@ -78,7 +78,8 @@ void 
ViewContactOfSdrRectObj::createViewIndependentPrimitive2DSequence(drawingla
             fCornerRadiusX,
             fCornerRadiusY,
             // #i105856# use fill for HitTest when TextFrame and not 
PickThrough
-            GetRectObj().IsTextFrame() && !bPickThroughTransparentTextFrames));
+            GetRectObj().IsTextFrame() && !bPickThroughTransparentTextFrames,
+            GetRectObj().IsEmptyPresObj() && !GetRectObj().IsReallyEdited() 
/*bPlaceholderText*/));
 
     rVisitor.visit(xReference);
 }
diff --git a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx 
b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx
index 60cfa24bd8db..d6eb5bb303ae 100644
--- a/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx
+++ b/svx/source/sdr/primitive2d/sdrrectangleprimitive2d.cxx
@@ -23,6 +23,7 @@
 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx>
 #include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx>
 #include <drawinglayer/primitive2d/groupprimitive2d.hxx>
+#include <drawinglayer/primitive2d/exclusiveeditviewprimitive2d.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <basegfx/polygon/b2dpolypolygon.hxx>
 #include <utility>
@@ -122,7 +123,20 @@ namespace drawinglayer::primitive2d
                     // add text glow
                     aTempContentText = 
createEmbeddedTextGlowPrimitive(std::move(aTempContentText), 
getSdrLFSTAttribute().getGlowText());
                 }
-                aRetval.append(std::move(aTempContentText));
+
+                if (mbPlaceholderText)
+                {
+                    // PlaceholderText is exclusive to e.g. EditView, so embed 
it
+                    // accordingly
+                    drawinglayer::primitive2d::Primitive2DReference aEmbedded(
+                        new 
drawinglayer::primitive2d::ExclusiveEditViewPrimitive2D(
+                            std::move(aTempContentText)));
+                    aRetval.append(std::move(aEmbedded));
+                }
+                else
+                {
+                    aRetval.append(std::move(aTempContentText));
+                }
             }
 
             // add shadow
@@ -141,12 +155,14 @@ namespace drawinglayer::primitive2d
             const attribute::SdrLineFillEffectsTextAttribute& 
rSdrLFSTAttribute,
             double fCornerRadiusX,
             double fCornerRadiusY,
-            bool bForceFillForHitTest)
+            bool bForceFillForHitTest,
+            bool bPlaceholderText)
         :   maTransform(std::move(aTransform)),
             maSdrLFSTAttribute(rSdrLFSTAttribute),
             mfCornerRadiusX(fCornerRadiusX),
             mfCornerRadiusY(fCornerRadiusY),
-            mbForceFillForHitTest(bForceFillForHitTest)
+            mbForceFillForHitTest(bForceFillForHitTest),
+            mbPlaceholderText(bPlaceholderText)
         {
         }
 
@@ -160,7 +176,8 @@ namespace drawinglayer::primitive2d
                     && getCornerRadiusY() == rCompare.getCornerRadiusY()
                     && getTransform() == rCompare.getTransform()
                     && getSdrLFSTAttribute() == rCompare.getSdrLFSTAttribute()
-                    && getForceFillForHitTest() == 
rCompare.getForceFillForHitTest());
+                    && getForceFillForHitTest() == 
rCompare.getForceFillForHitTest()
+                    && getPlaceholderText() == rCompare.getPlaceholderText());
             }
 
             return false;

Reply via email to