diff --git a/sd/qa/unit/data/tdf128651_CustomShapeUndo.odp b/sd/qa/unit/data/tdf128651_CustomShapeUndo.odp new file mode 100644 index 000000000000..9e820da094ab Binary files /dev/null and b/sd/qa/unit/data/tdf128651_CustomShapeUndo.odp differ diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx index 2125820c7c50..5923651c9db1 100644 --- a/sd/qa/unit/uiimpress.cxx +++ b/sd/qa/unit/uiimpress.cxx @@ -19,11 +19,14 @@ #include #include #include +#include #include +#include #include #include #include +#include #include #include @@ -151,6 +154,42 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf126197) // in SdrObjEditView::SdrEndTextEdit() pViewShell2->GetViewFrame()->GetDispatcher()->Execute(SID_DELETE, SfxCallMode::SYNCHRON); } + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf128651) +{ + // Error was, that undo and redo changes size of the shape. Affected actions were e.g. + // extrusion on/off, shadow on/off, changes on line or fill attributes. + // All these actions do not change the snap rectangle. + mxComponent = loadFromDesktop( + m_directories.getURLFromSrc("sd/qa/unit/data/tdf128651_CustomShapeUndo.odp")); + auto pXImpressDocument = dynamic_cast(mxComponent.get()); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + SdPage* pActualPage = pViewShell->GetActualPage(); + SdrObject* pObject = pActualPage->GetObj(0); + auto pCustomShape = dynamic_cast(pObject); + CPPUNIT_ASSERT_MESSAGE("No Shape", pCustomShape); + const sal_Int32 nOrigWidth(pCustomShape->GetSnapRect().GetWidth()); + + SdDrawDocument* pDocument = pXImpressDocument->GetDoc(); + sd::UndoManager* pUndoManager = pDocument->GetUndoManager(); + CPPUNIT_ASSERT_EQUAL(static_cast(0), pUndoManager->GetUndoActionCount()); + CPPUNIT_ASSERT_EQUAL(static_cast(0), pUndoManager->GetRedoActionCount()); + + SdrView* pView = pViewShell->GetView(); + pView->MarkObj(pCustomShape, pView->GetSdrPageView()); + pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_EXTRUSION_TOGGLE, + SfxCallMode::SYNCHRON); + CPPUNIT_ASSERT_EQUAL(static_cast(1), pUndoManager->GetUndoActionCount()); + + pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_UNDO, SfxCallMode::SYNCHRON); + const sal_Int32 nUndoWidth(pCustomShape->GetSnapRect().GetWidth()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Undo changes width", nOrigWidth, nUndoWidth); + + CPPUNIT_ASSERT_EQUAL(static_cast(1), pUndoManager->GetRedoActionCount()); + pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_REDO, SfxCallMode::SYNCHRON); + const sal_Int32 nRedoWidth(pCustomShape->GetSnapRect().GetWidth()); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Redo changes width", nUndoWidth, nRedoWidth); +} CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx index e27e6cf42c58..a29142a4a734 100644 --- a/svx/source/svdraw/svdundo.cxx +++ b/svx/source/svdraw/svdundo.cxx @@ -46,6 +46,7 @@ #include // #i124389# #include #include +#include // iterates over all views and unmarks this SdrObject if it is marked @@ -348,6 +349,8 @@ void SdrUndoAttrObj::Undo() // laid out again from AdjustTextFrameWidthAndHeight(). This makes // rescuing the size of the object necessary. const tools::Rectangle aSnapRect = pObj->GetSnapRect(); + // SdrObjCustomShape::NbcSetSnapRect needs logic instead of snap rect + const tools::Rectangle aLogicRect = pObj->GetLogicRect(); if(pUndoSet) { @@ -382,7 +385,10 @@ void SdrUndoAttrObj::Undo() // Restore previous size here when it was changed. if(aSnapRect != pObj->GetSnapRect()) { - pObj->NbcSetSnapRect(aSnapRect); + if(dynamic_cast(pObj)) + pObj->NbcSetSnapRect(aLogicRect); + else + pObj->NbcSetSnapRect(aSnapRect); } pObj->GetProperties().BroadcastItemChange(aItemChange); @@ -425,6 +431,7 @@ void SdrUndoAttrObj::Redo() sdr::properties::ItemChangeBroadcaster aItemChange(*pObj); const tools::Rectangle aSnapRect = pObj->GetSnapRect(); + const tools::Rectangle aLogicRect = pObj->GetLogicRect(); if(pRedoSet) { @@ -459,7 +466,10 @@ void SdrUndoAttrObj::Redo() // Restore previous size here when it was changed. if(aSnapRect != pObj->GetSnapRect()) { - pObj->NbcSetSnapRect(aSnapRect); + if(dynamic_cast(pObj)) + pObj->NbcSetSnapRect(aLogicRect); + else + pObj->NbcSetSnapRect(aSnapRect); } pObj->GetProperties().BroadcastItemChange(aItemChange);