File bsc1181644.diff of Package libreoffice

From 164c65278a4c1d271d1ab5f5d31aa0de5bc36c9b Mon Sep 17 00:00:00 2001
From: Miklos Vajna <vmiklos@collabora.com>
Date: Thu, 25 Feb 2021 18:04:19 +0100
Subject: [PATCH] bsc1181644.diff

tdf#132368 svx: empty the interop grab-bag on ending text edit

Regression from commit aafaf1f55fa413ad49d4556cf7c0a713dd206ae4 (PPTX
export: save SmartArt as diagram instead of group of shapes,
2019-03-13), the idea of interop grab-bag was to carry additional
information around as long as the object is not changed.

However, actual clearing of the grab-bag was never implemented, do this
when editing shape text.

An alternative would be to do this in SdrObject::SetChanged(), but
Writer sets the layer of SdrObjects during layout (when the import
filter is already finished and undo is enabled), so that would mean loss
of the smartart metadata for DOCX.

(cherry picked from commit a01ae07740e5c311fcc37f2ac2e2a0a2a1935920)

Conflicts:
	svx/qa/unit/svdraw.cxx

Change-Id: I9ab205b4ef84169f4b5a16b86fe9a152e3370a6c
---
 svx/CppunitTest_svx_unit.mk  |  1 +
 svx/qa/unit/svdraw.cxx       | 55 ++++++++++++++++++++++++++++++++++++
 svx/source/svdraw/svdobj.cxx | 20 +++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/svx/CppunitTest_svx_unit.mk b/svx/CppunitTest_svx_unit.mk
index ac9f3e4531ad..892490265261 100644
--- a/svx/CppunitTest_svx_unit.mk
+++ b/svx/CppunitTest_svx_unit.mk
@@ -36,6 +36,7 @@ $(eval $(call gb_CppunitTest_add_exception_objects,svx_unit, \
 $(eval $(call gb_CppunitTest_use_libraries,svx_unit, \
 	basegfx \
 	drawinglayer \
+	editeng \
 	sal \
 	sfx \
 	svxcore \
diff --git a/svx/qa/unit/svdraw.cxx b/svx/qa/unit/svdraw.cxx
index 5a0f46bba995..5e30c36f6a05 100644
--- a/svx/qa/unit/svdraw.cxx
+++ b/svx/qa/unit/svdraw.cxx
@@ -25,6 +25,12 @@
 #include <svx/svdpage.hxx>
 #include <svx/unopage.hxx>
 #include <vcl/virdev.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svx/svdview.hxx>
+#include <svx/unoapi.hxx>
+#include <sal/log.hxx>
+
 #include <sdr/contact/objectcontactofobjlistpainter.hxx>
 
 using namespace ::com::sun::star;
@@ -105,6 +111,55 @@ CPPUNIT_TEST_FIXTURE(SvdrawTest, testSemiTransparentText)
     CPPUNIT_ASSERT_EQUAL(nTransparence,
                          static_cast<sal_Int16>(basegfx::fround(fTransparence * 100)));
 }
+
+CPPUNIT_TEST_FIXTURE(SvdrawTest, testTextEditEmptyGrabBag)
+{
+    // Given a document with a groupshape, which has 2 children.
+    getComponent() = loadFromDesktop("private:factory/sdraw");
+    uno::Reference<lang::XMultiServiceFactory> xFactory(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XShape> xRect1(
+        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+    xRect1->setPosition(awt::Point(1000, 1000));
+    xRect1->setSize(awt::Size(10000, 10000));
+    uno::Reference<drawing::XShape> xRect2(
+        xFactory->createInstance("com.sun.star.drawing.RectangleShape"), uno::UNO_QUERY);
+    xRect2->setPosition(awt::Point(1000, 1000));
+    xRect2->setSize(awt::Size(10000, 10000));
+    uno::Reference<drawing::XShapes> xGroup(
+        xFactory->createInstance("com.sun.star.drawing.GroupShape"), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(getComponent(), uno::UNO_QUERY);
+    uno::Reference<drawing::XDrawPage> xDrawPage(xDrawPagesSupplier->getDrawPages()->getByIndex(0),
+                                                 uno::UNO_QUERY);
+    uno::Reference<drawing::XShape> xGroupShape(xGroup, uno::UNO_QUERY);
+    xDrawPage->add(xGroupShape);
+    xGroup->add(xRect1);
+    xGroup->add(xRect2);
+    uno::Reference<text::XTextRange> xRect2Text(xRect2, uno::UNO_QUERY);
+    xRect2Text->setString("x");
+    uno::Sequence<beans::PropertyValue> aGrabBag = {
+        comphelper::makePropertyValue("OOXLayout", true),
+    };
+    uno::Reference<beans::XPropertySet> xGroupProps(xGroup, uno::UNO_QUERY);
+    xGroupProps->setPropertyValue("InteropGrabBag", uno::makeAny(aGrabBag));
+
+    // When editing the shape text of the 2nd rectangle (insert a char at the start).
+    SfxViewShell* pViewShell = SfxViewShell::Current();
+    SdrView* pSdrView = pViewShell->GetDrawView();
+    SdrObject* pObject = GetSdrObjectFromXShape(xRect2);
+    pSdrView->SdrBeginTextEdit(pObject);
+    EditView& rEditView = pSdrView->GetTextEditOutlinerView()->GetEditView();
+    rEditView.InsertText("y");
+    pSdrView->SdrEndTextEdit();
+
+    // Then make sure that grab-bag is empty to avoid loosing the new text.
+    xGroupProps->getPropertyValue("InteropGrabBag") >>= aGrabBag;
+    // Without the accompanying fix in place, this test would have failed with:
+    // assertion failed
+    // - Expression: !aGrabBag.hasElements()
+    // i.e. the grab-bag was still around after modifying the shape, and that grab-bag contained the
+    // old text.
+    CPPUNIT_ASSERT(!aGrabBag.hasElements());
+}
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 7b1b5cc5db61..6052d96a3ce6 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1734,6 +1734,26 @@ void SdrObject::SetOutlinerParaObject(std::unique_ptr<OutlinerParaObject> pTextO
     if (GetCurrentBoundRect()!=aBoundRect0) {
         SendUserCall(SdrUserCallType::Resize,aBoundRect0);
     }
+
+    if (getSdrModelFromSdrObject().IsUndoEnabled())
+    {
+        // Don't do this during import.
+        SdrObject* pTopGroupObj = nullptr;
+        if (getParentSdrObjectFromSdrObject())
+        {
+            pTopGroupObj = getParentSdrObjectFromSdrObject();
+            while (pTopGroupObj->getParentSdrObjectFromSdrObject())
+            {
+                pTopGroupObj = pTopGroupObj->getParentSdrObjectFromSdrObject();
+            }
+        }
+        if (pTopGroupObj)
+        {
+            // A shape was modified, which is in a group shape. Empty the group shape's grab-bag,
+            // which potentially contains the old text of the shapes in case of diagrams.
+            pTopGroupObj->SetGrabBagItem(uno::makeAny(uno::Sequence<beans::PropertyValue>()));
+        }
+    }
 }
 
 void SdrObject::NbcSetOutlinerParaObject(std::unique_ptr<OutlinerParaObject> /*pTextObject*/)
-- 
2.26.2
openSUSE Build Service is sponsored by