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

New commits:
commit 4bf14305dfa22a3e4084b630b6924a718d7da3ce
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Feb 25 18:04:19 2021 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Mon Mar 1 12:51:51 2021 +0100

    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.
    
    Change-Id: I9ab205b4ef84169f4b5a16b86fe9a152e3370a6c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111560
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111595

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 c96ccbb7aa97..783420d56fea 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 638c590a52cd..5480ac1d86ce 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -1740,6 +1740,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*/)
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to