summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/svx/svdedtv.hxx1
-rw-r--r--include/svx/svdedxv.hxx13
-rw-r--r--sc/qa/unit/uicalc/uicalc.cxx3
-rw-r--r--sc/source/ui/inc/drawview.hxx4
-rw-r--r--sc/source/ui/view/drawview.cxx9
-rw-r--r--sd/qa/uitest/impress_tests/tdf130440.py13
-rw-r--r--sd/qa/unit/misc-tests.cxx34
-rw-r--r--sd/qa/unit/tiledrendering/data/TextBoxAndRect.odgbin0 -> 10474 bytes
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx341
-rw-r--r--sd/source/ui/inc/View.hxx3
-rw-r--r--sd/source/ui/view/drviews1.cxx4
-rw-r--r--sd/source/ui/view/sdview.cxx10
-rw-r--r--svx/source/svdraw/svddrgmt.cxx2
-rw-r--r--svx/source/svdraw/svdedtv.cxx12
-rw-r--r--svx/source/svdraw/svdedtv1.cxx24
-rw-r--r--svx/source/svdraw/svdedxv.cxx17
-rw-r--r--sw/qa/extras/tiledrendering/data/shape.fodt20
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx16
-rw-r--r--sw/source/core/draw/dview.cxx10
-rw-r--r--sw/source/core/inc/dview.hxx4
20 files changed, 471 insertions, 69 deletions
diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx
index a21eeb3e0a43..6f80c3aca0fa 100644
--- a/include/svx/svdedtv.hxx
+++ b/include/svx/svdedtv.hxx
@@ -188,6 +188,7 @@ public:
* Checks if this or other views have an active text edit, if true, end them.
*/
void EndTextEditAllViews() const;
+ void EndTextEditCurrentView();
std::vector< std::unique_ptr<SdrUndoAction> > CreateConnectorUndo( const SdrObject& rO );
void AddUndoActions( std::vector< std::unique_ptr<SdrUndoAction> > );
diff --git a/include/svx/svdedxv.hxx b/include/svx/svdedxv.hxx
index a4f457c9aeba..a05a61c36c8d 100644
--- a/include/svx/svdedxv.hxx
+++ b/include/svx/svdedxv.hxx
@@ -109,18 +109,15 @@ protected:
private:
SfxUndoManager* mpOldTextEditUndoManager;
+ std::unique_ptr<SdrUndoManager> mpLocalTextEditUndoManager;
protected:
- // central method to get an SdrUndoManager for enhanced TextEdit. Default will
- // try to return a dynamic_casted GetModel()->GetSdrUndoManager(). Applications
- // which want to use this feature will need to override this virtual method,
- // provide their document UndoManager and derive it from SdrUndoManager.
- virtual SdrUndoManager* getSdrUndoManagerForEnhancedTextEdit() const;
+ // Create a local UndoManager that is used for text editing.
+ virtual std::unique_ptr<SdrUndoManager> createLocalTextUndoManager();
void ImpMoveCursorAfterChainingEvent(TextChainCursorManager *pCursorManager);
std::unique_ptr<TextChainCursorManager> ImpHandleMotionThroughBoxesKeyInput(const KeyEvent& rKEvt, bool *bOutHandled);
-
OutlinerView* ImpFindOutlinerView(vcl::Window const * pWin) const;
// Create a new OutlinerView at the heap and initialize all required parameters.
@@ -180,6 +177,10 @@ public:
virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override;
virtual void ModelHasChanged() override;
+ const std::unique_ptr<SdrUndoManager>& getViewLocalUndoManager() const
+ {
+ return mpLocalTextEditUndoManager;
+ }
// TextEdit over an outliner
diff --git a/sc/qa/unit/uicalc/uicalc.cxx b/sc/qa/unit/uicalc/uicalc.cxx
index 3c3d15f1d399..46c430c7e087 100644
--- a/sc/qa/unit/uicalc/uicalc.cxx
+++ b/sc/qa/unit/uicalc/uicalc.cxx
@@ -951,6 +951,9 @@ CPPUNIT_TEST_FIXTURE(ScUiCalcTest, testTdf119793)
pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
Scheduler::ProcessEventsToIdle();
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_ESCAPE);
+ pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_ESCAPE);
+ Scheduler::ProcessEventsToIdle();
dispatchCommand(mxComponent, ".uno:Undo", {});
Scheduler::ProcessEventsToIdle();
diff --git a/sc/source/ui/inc/drawview.hxx b/sc/source/ui/inc/drawview.hxx
index 7e0db5eb0a0d..816a3428aacf 100644
--- a/sc/source/ui/inc/drawview.hxx
+++ b/sc/source/ui/inc/drawview.hxx
@@ -51,8 +51,8 @@ class ScDrawView final : public FmFormView
void ImplClearCalcDropMarker();
- // support enhanced text edit for draw objects
- virtual SdrUndoManager* getSdrUndoManagerForEnhancedTextEdit() const override;
+ // Create a local UndoManager
+ std::unique_ptr<SdrUndoManager> createLocalTextUndoManager() override;
public:
ScDrawView(
diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx
index ed0cf254ba10..0254e62fb2be 100644
--- a/sc/source/ui/view/drawview.cxx
+++ b/sc/source/ui/view/drawview.cxx
@@ -1107,10 +1107,13 @@ bool ScDrawView::calculateGridOffsetForB2DRange(
return true;
}
-// support enhanced text edit for draw objects
-SdrUndoManager* ScDrawView::getSdrUndoManagerForEnhancedTextEdit() const
+// Create a new view-local UndoManager manager for Calc
+std::unique_ptr<SdrUndoManager> ScDrawView::createLocalTextUndoManager()
{
- return dynamic_cast<SdrUndoManager*>(rDoc.GetUndoManager());
+ std::unique_ptr<SdrUndoManager> pUndoManager(new SdrUndoManager);
+ ScDocShell* pDocShell = pViewData ? pViewData->GetDocShell() : nullptr;
+ pUndoManager->SetDocShell(pDocShell);
+ return pUndoManager;
}
// #i123922# helper to apply a Graphic to an existing SdrObject
diff --git a/sd/qa/uitest/impress_tests/tdf130440.py b/sd/qa/uitest/impress_tests/tdf130440.py
index ea6b398a2841..0672e14f2f59 100644
--- a/sd/qa/uitest/impress_tests/tdf130440.py
+++ b/sd/qa/uitest/impress_tests/tdf130440.py
@@ -24,24 +24,31 @@ class tdf129346(UITestCase):
xDoc = self.xUITest.getTopFocusWindow()
xEdit = xDoc.getChild("impress_win")
+ # Type "test" into the text box
xEdit.executeAction("TYPE", mkPropertyValues({"TEXT":"test"}))
-
- self.xUITest.executeCommand(".uno:Undo")
+ # Go to Page 1, which also forces to end edit box
+ xEdit.executeAction("GOTO", mkPropertyValues({"PAGE": "1"}))
xToolkit.processEventsToIdle()
- self.assertEqual(document.CurrentController.getCurrentPage().Number, 2)
+ # We should be at Page 1
+ self.assertEqual(document.CurrentController.getCurrentPage().Number, 1)
+
+ # Undo sends us to Page 2 and undo-es the text edit
self.xUITest.executeCommand(".uno:Undo")
xToolkit.processEventsToIdle()
self.assertEqual(document.CurrentController.getCurrentPage().Number, 2)
+ # Undo sends us to page 1 and undo-es command ".uno:DuplicatePage"
self.xUITest.executeCommand(".uno:Undo")
xToolkit.processEventsToIdle()
self.assertEqual(document.CurrentController.getCurrentPage().Number, 1)
+ # Redo ".uno:DuplicatePage" - we go to Page 2
self.xUITest.executeCommand(".uno:Redo")
xToolkit.processEventsToIdle()
self.assertEqual(document.CurrentController.getCurrentPage().Number, 2)
+ # Redo text edit
self.xUITest.executeCommand(".uno:Redo")
xDoc = self.xUITest.getTopFocusWindow()
diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
index ba888c280601..dc2f4324c240 100644
--- a/sd/qa/unit/misc-tests.cxx
+++ b/sd/qa/unit/misc-tests.cxx
@@ -70,7 +70,7 @@ public:
void testTdf96206();
void testTdf96708();
void testTdf99396();
- void testTdf99396TextEdit();
+ void testTableObjectUndoTest();
void testFillGradient();
void testTdf44774();
void testTdf38225();
@@ -93,7 +93,7 @@ public:
CPPUNIT_TEST(testTdf96206);
CPPUNIT_TEST(testTdf96708);
CPPUNIT_TEST(testTdf99396);
- CPPUNIT_TEST(testTdf99396TextEdit);
+ CPPUNIT_TEST(testTableObjectUndoTest);
CPPUNIT_TEST(testFillGradient);
CPPUNIT_TEST(testTdf44774);
CPPUNIT_TEST(testTdf38225);
@@ -251,8 +251,10 @@ void SdMiscTest::testTdf99396()
xDocSh->DoClose();
}
-void SdMiscTest::testTdf99396TextEdit()
+void SdMiscTest::testTableObjectUndoTest()
{
+ // See tdf#99396 for the issue
+
// Load the document and select the table.
sd::DrawDocShellRef xDocSh = Load(m_directories.getURLFromSrc(u"/sd/qa/unit/data/tdf99396.odp"), ODP);
sd::ViewShell* pViewShell = xDocSh->GetViewShell();
@@ -278,14 +280,26 @@ void SdMiscTest::testTdf99396TextEdit()
const SfxItemSet* pArgs = aRequest.GetArgs();
pView->SetAttributes(*pArgs);
}
+ const auto& pLocalUndoManager = pView->getViewLocalUndoManager();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pLocalUndoManager->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Apply attributes"), pLocalUndoManager->GetUndoActionComment());
{
auto pTableController = dynamic_cast<sdr::table::SvxTableController*>(pView->getSelectionController().get());
CPPUNIT_ASSERT(pTableController);
SfxRequest aRequest(pViewShell->GetViewFrame(), SID_TABLE_VERT_BOTTOM);
pTableController->Execute(aRequest);
}
+ // Global change "Format cell" is applied only - Change the vertical alignment to "Bottom"
+ CPPUNIT_ASSERT_EQUAL(size_t(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment());
+
pView->SdrEndTextEdit();
+ // End of text edit, so the text edit action is added to the undo stack
+ CPPUNIT_ASSERT_EQUAL(size_t(2), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Edit text of Table"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(1));
+
// Check that the result is what we expect.
{
uno::Reference<table::XTable> xTable = pTableObject->getTable();
@@ -303,6 +317,10 @@ void SdMiscTest::testTdf99396TextEdit()
// Now undo.
xDocSh->GetUndoManager()->Undo();
+ // Undoing the last action - one left
+ CPPUNIT_ASSERT_EQUAL(size_t(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+
// Check again that the result is what we expect.
{
uno::Reference<table::XTable> xTable = pTableObject->getTable();
@@ -318,6 +336,9 @@ void SdMiscTest::testTdf99396TextEdit()
CPPUNIT_ASSERT_EQUAL(SvxAdjust::Center, pAdjust->GetAdjust());
}
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
/*
* now test tdf#103950 - Undo does not revert bundled font size changes for table cells
@@ -328,8 +349,11 @@ void SdMiscTest::testTdf99396TextEdit()
SfxRequest aRequest(pViewShell->GetViewFrame(), SID_GROW_FONT_SIZE);
static_cast<sd::DrawViewShell*>(pViewShell)->ExecChar(aRequest);
}
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
-
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(3), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Apply attributes to Table"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(0));
+ CPPUNIT_ASSERT_EQUAL(OUString("Grow font size"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(1));
+ CPPUNIT_ASSERT_EQUAL(OUString("Format cell"), xDocSh->GetDoc()->GetUndoManager()->GetUndoActionComment(2));
xDocSh->DoClose();
}
diff --git a/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg b/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg
new file mode 100644
index 000000000000..aa1a37b83147
--- /dev/null
+++ b/sd/qa/unit/tiledrendering/data/TextBoxAndRect.odg
Binary files differ
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 89ab2d62b815..a41e050bac06 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -139,6 +139,7 @@ public:
void testMoveShapeHandle();
void testDeleteTable();
void testPasteUndo();
+ void testShapeEditInMultipleViews();
CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
CPPUNIT_TEST(testCreateDestroy);
@@ -197,7 +198,7 @@ public:
CPPUNIT_TEST(testMoveShapeHandle);
CPPUNIT_TEST(testDeleteTable);
CPPUNIT_TEST(testPasteUndo);
-
+ CPPUNIT_TEST(testShapeEditInMultipleViews);
CPPUNIT_TEST_SUITE_END();
virtual void libreOfficeKitViewCallback(int nType, const char* pPayload) override;
@@ -1325,6 +1326,38 @@ void SdTiledRenderingTest::testUndoLimiting()
Scheduler::ProcessEventsToIdle();
CPPUNIT_ASSERT(pViewShell1->GetView()->IsTextEdit());
+ // View2 UNDO stack should be empty
+ {
+ SfxRequest aReq2(SID_UNDO, SfxCallMode::SLOT, pXImpressDocument->GetDocShell()->GetDoc()->GetPool());
+ aReq2.AppendItem(SfxUInt16Item(SID_UNDO, 1));
+ pViewShell2->ExecuteSlot(aReq2);
+ const auto* pReturnValue = aReq2.GetReturnValue();
+ CPPUNIT_ASSERT(!pReturnValue);
+ }
+
+ // View1 can UNDO
+ {
+ SfxRequest aReq1(SID_UNDO, SfxCallMode::SLOT, pXImpressDocument->GetDocShell()->GetDoc()->GetPool());
+ aReq1.AppendItem(SfxUInt16Item(SID_UNDO, 1));
+ pViewShell1->ExecuteSlot(aReq1);
+ CPPUNIT_ASSERT(aReq1.IsDone());
+ }
+
+ // View1 can REDO
+ {
+ SfxRequest aReq1(SID_REDO, SfxCallMode::SLOT, pXImpressDocument->GetDocShell()->GetDoc()->GetPool());
+ aReq1.AppendItem(SfxUInt16Item(SID_REDO, 1));
+ pViewShell1->ExecuteSlot(aReq1);
+ CPPUNIT_ASSERT(aReq1.IsDone());
+ }
+
+ // Exit text edit mode
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::ESCAPE);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::ESCAPE);
+ Scheduler::ProcessEventsToIdle();
+
+ CPPUNIT_ASSERT(!pViewShell1->GetView()->IsTextEdit());
+
// Now check view2 cannot undo actions.
{
SfxRequest aReq2(SID_UNDO, SfxCallMode::SLOT, pXImpressDocument->GetDocShell()->GetDoc()->GetPool());
@@ -2062,11 +2095,19 @@ void SdTiledRenderingTest::testDisableUndoRepair()
{
// Load the document.
SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp");
+
+ // Create View 1
SfxViewShell* pView1 = SfxViewShell::Current();
+ sd::ViewShell* pViewShell1 = pXImpressDocument->GetDocShell()->GetViewShell();
int nView1 = SfxLokHelper::getView();
+
+ // Create View 2
SfxLokHelper::createView();
SfxViewShell* pView2 = SfxViewShell::Current();
+ sd::ViewShell* pViewShell2 = pXImpressDocument->GetDocShell()->GetViewShell();
int nView2 = SfxLokHelper::getView();
+
+ // Check UNDO is disabled
{
std::unique_ptr<SfxPoolItem> pItem1;
std::unique_ptr<SfxPoolItem> pItem2;
@@ -2081,15 +2122,24 @@ void SdTiledRenderingTest::testDisableUndoRepair()
pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'h', 0);
pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'h', 0);
Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(pViewShell1->GetView()->IsTextEdit());
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::ESCAPE);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::ESCAPE);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(!pViewShell1->GetView()->IsTextEdit());
+
+ // Check
{
std::unique_ptr<SfxPoolItem> xItem1;
- std::unique_ptr<SfxPoolItem> xItem2;
pView1->GetViewFrame()->GetBindings().QueryState(SID_UNDO, xItem1);
+ const auto* pUInt32Item1 = dynamic_cast<const SfxUInt32Item*>(xItem1.get());
+ CPPUNIT_ASSERT(!pUInt32Item1);
+
+ std::unique_ptr<SfxPoolItem> xItem2;
pView2->GetViewFrame()->GetBindings().QueryState(SID_UNDO, xItem2);
- CPPUNIT_ASSERT(!dynamic_cast< const SfxUInt32Item* >(xItem1.get()));
- const SfxUInt32Item* pUInt32Item = dynamic_cast<const SfxUInt32Item*>(xItem2.get());
- CPPUNIT_ASSERT(pUInt32Item);
- CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(SID_REPAIRPACKAGE), pUInt32Item->GetValue());
+ const auto* pUInt32Item2 = dynamic_cast<const SfxUInt32Item*>(xItem2.get());
+ CPPUNIT_ASSERT(pUInt32Item2);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(SID_REPAIRPACKAGE), pUInt32Item2->GetValue());
}
// Insert a character in the second view.
@@ -2100,15 +2150,23 @@ void SdTiledRenderingTest::testDisableUndoRepair()
pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0);
pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0);
Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(pViewShell2->GetView()->IsTextEdit());
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::ESCAPE);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::ESCAPE);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(!pViewShell2->GetView()->IsTextEdit());
+
+ // Check
{
std::unique_ptr<SfxPoolItem> xItem1;
- std::unique_ptr<SfxPoolItem> xItem2;
pView1->GetViewFrame()->GetBindings().QueryState(SID_UNDO, xItem1);
- pView2->GetViewFrame()->GetBindings().QueryState(SID_UNDO, xItem2);
- CPPUNIT_ASSERT(!dynamic_cast< const SfxUInt32Item* >(xItem2.get()));
const SfxUInt32Item* pUInt32Item = dynamic_cast<const SfxUInt32Item*>(xItem1.get());
CPPUNIT_ASSERT(pUInt32Item);
CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(SID_REPAIRPACKAGE), pUInt32Item->GetValue());
+
+ std::unique_ptr<SfxPoolItem> xItem2;
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_UNDO, xItem2);
+ CPPUNIT_ASSERT(!dynamic_cast< const SfxUInt32Item* >(xItem2.get()));
}
}
@@ -2125,17 +2183,20 @@ void SdTiledRenderingTest::testDocumentRepair()
SfxLokHelper::createView();
SfxViewShell* pView2 = SfxViewShell::Current();
int nView2 = SfxLokHelper::getView();
+ sd::ViewShell* pViewShell2 = pXImpressDocument->GetDocShell()->GetViewShell();
+
CPPUNIT_ASSERT(pView1 != pView2);
{
std::unique_ptr<SfxPoolItem> xItem1;
- std::unique_ptr<SfxPoolItem> xItem2;
pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, xItem1);
- pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, xItem2);
const SfxBoolItem* pItem1 = dynamic_cast<const SfxBoolItem*>(xItem1.get());
- const SfxBoolItem* pItem2 = dynamic_cast<const SfxBoolItem*>(xItem2.get());
CPPUNIT_ASSERT(pItem1);
- CPPUNIT_ASSERT(pItem2);
CPPUNIT_ASSERT_EQUAL(false, pItem1->GetValue());
+
+ std::unique_ptr<SfxPoolItem> xItem2;
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, xItem2);
+ const SfxBoolItem* pItem2 = dynamic_cast<const SfxBoolItem*>(xItem2.get());
+ CPPUNIT_ASSERT(pItem2);
CPPUNIT_ASSERT_EQUAL(false, pItem2->GetValue());
}
@@ -2147,16 +2208,23 @@ void SdTiledRenderingTest::testDocumentRepair()
pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0);
pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0);
Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(pViewShell2->GetView()->IsTextEdit());
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::ESCAPE);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::ESCAPE);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(!pViewShell2->GetView()->IsTextEdit());
+
{
std::unique_ptr<SfxPoolItem> xItem1;
- std::unique_ptr<SfxPoolItem> xItem2;
pView1->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, xItem1);
- pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, xItem2);
const SfxBoolItem* pItem1 = dynamic_cast<const SfxBoolItem*>(xItem1.get());
- const SfxBoolItem* pItem2 = dynamic_cast<const SfxBoolItem*>(xItem2.get());
CPPUNIT_ASSERT(pItem1);
- CPPUNIT_ASSERT(pItem2);
CPPUNIT_ASSERT_EQUAL(true, pItem1->GetValue());
+
+ std::unique_ptr<SfxPoolItem> xItem2;
+ pView2->GetViewFrame()->GetBindings().QueryState(SID_DOC_REPAIR, xItem2);
+ const SfxBoolItem* pItem2 = dynamic_cast<const SfxBoolItem*>(xItem2.get());
+ CPPUNIT_ASSERT(pItem2);
CPPUNIT_ASSERT_EQUAL(true, pItem2->GetValue());
}
}
@@ -2681,7 +2749,6 @@ void SdTiledRenderingTest::testMoveShapeHandle()
CPPUNIT_ASSERT_EQUAL(x-1, oldX);
CPPUNIT_ASSERT_EQUAL(y-1, oldY);
}
-
}
void SdTiledRenderingTest::testPasteUndo()
@@ -2718,6 +2785,244 @@ void SdTiledRenderingTest::testPasteUndo()
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), aSelection.nStartPos);
}
+void SdTiledRenderingTest::testShapeEditInMultipleViews()
+{
+ SdXImpressDocument* pXImpressDocument = createDoc("TextBoxAndRect.odg");
+ pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+ SdDrawDocument* pDocument = pXImpressDocument->GetDoc();
+
+ // Create view 1
+ const int nView1 = SfxLokHelper::getView();
+ sd::ViewShell* pViewShell1 = pXImpressDocument->GetDocShell()->GetViewShell();
+ SdrView* pView1 = pViewShell1->GetView();
+ Scheduler::ProcessEventsToIdle();
+
+ // Create view 2
+ SfxLokHelper::createView();
+ const int nView2 = SfxLokHelper::getView();
+ CPPUNIT_ASSERT(nView1 != nView2);
+
+ sd::ViewShell* pViewShell2 = pXImpressDocument->GetDocShell()->GetViewShell();
+ SdrView* pView2 = pViewShell2->GetView();
+ Scheduler::ProcessEventsToIdle();
+
+ // Switch to view 1
+ SfxLokHelper::setView(nView1);
+
+ SdPage* pPage1 = pViewShell1->GetActualPage();
+
+ SdrObject* pTextBoxObject = pPage1->GetObj(0);
+ CPPUNIT_ASSERT_EQUAL(OUString("Text Box"), pTextBoxObject->GetName());
+
+ SdrObject* pRectangleObject = pPage1->GetObj(1);
+ CPPUNIT_ASSERT_EQUAL(OUString("Rect"), pRectangleObject->GetName());
+
+ SdrObject* pTableObject = pPage1->GetObj(2);
+ CPPUNIT_ASSERT_EQUAL(OUString("Table1"), pTableObject->GetName());
+
+ // Scenario 1
+ // 2 shapes - "Text Box" and "Rect"
+ // View1 - "Text Box" enters text edit mode, View 2 - moves the "Rect" around
+ {
+ sd::UndoManager* pUndoManager = pDocument->GetUndoManager();
+ CPPUNIT_ASSERT_EQUAL(size_t(0), pUndoManager->GetUndoActionCount());
+
+ pView1->SdrBeginTextEdit(pTextBoxObject);
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // Local undo count for View1 is 0
+ CPPUNIT_ASSERT_EQUAL(size_t(0), pView1->getViewLocalUndoManager()->GetUndoActionCount());
+ // Write 'test' in View1
+ SfxStringItem aInputString(SID_ATTR_CHAR, "test");
+ pViewShell1->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, { &aInputString });
+ // Local undo count for View1 is now 1
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pView1->getViewLocalUndoManager()->GetUndoActionCount());
+
+ // Mark rectangle object
+ pView2->MarkObj(pRectangleObject, pView2->GetSdrPageView());
+
+ // Check the initial position of the object
+ tools::Rectangle aRectangle = pRectangleObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(6250L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(7000L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(6501L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(4501L, aRectangle.GetHeight());
+
+ // On View2 - Move handle 0 on the shape to a new mosition - resize
+ Point aNewPosition = aRectangle.TopLeft() + Point(-1250, -1000);
+ pView2->MoveShapeHandle(0, aNewPosition, -1);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pUndoManager->GetUndoActionCount());
+
+ // Check the object has a new size
+ aRectangle = pRectangleObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(5000L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(6000L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(7751L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(5501L, aRectangle.GetHeight());
+
+ // View1 is still in text edit mode...
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // On View2 - relative move the shape to a different position
+ pView2->MoveMarkedObj(Size(1000, 2000), /*bCopy=*/false);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pUndoManager->GetUndoActionCount());
+
+ // Check the object is at a different position
+ aRectangle = pRectangleObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(6000L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(8000L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(7751L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(5501L, aRectangle.GetHeight());
+
+ // View1 is still in text edit mode...
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // End Text edit - check undo count increase from 2 -> 3
+ CPPUNIT_ASSERT_EQUAL(size_t(2), pUndoManager->GetUndoActionCount());
+ pView1->SdrEndTextEdit();
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), pUndoManager->GetUndoActionCount());
+
+ // Check that both views exited the text edit mode
+ CPPUNIT_ASSERT_EQUAL(false, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+ }
+
+ // Scenario 2
+ // 1 shapes - "Text Box"
+ // View1 - "Text Box" enters text edit mode, View 2 - moves the "Text Box" around
+ {
+ sd::UndoManager* pUndoManager = pDocument->GetUndoManager();
+ CPPUNIT_ASSERT_EQUAL(size_t(3), pUndoManager->GetUndoActionCount());
+
+ pView1->SdrBeginTextEdit(pTextBoxObject);
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // Local undo count for View1 is 0
+ CPPUNIT_ASSERT_EQUAL(size_t(0), pView1->getViewLocalUndoManager()->GetUndoActionCount());
+ // Write 'test' in View1
+ SfxStringItem aInputString(SID_ATTR_CHAR, "test");
+ pViewShell1->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, { &aInputString });
+ // Local undo count for View1 is now 1
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pView1->getViewLocalUndoManager()->GetUndoActionCount());
+
+ // Mark rectangle object
+ pView2->MarkObj(pTextBoxObject, pView2->GetSdrPageView());
+
+ // Check the initial position of the object
+ tools::Rectangle aRectangle = pTextBoxObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(2250L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(2000L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(4501L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(2001L, aRectangle.GetHeight());
+
+ // On View2 - Move handle 0 on the shape to a new mosition - resize
+ Point aNewPosition = aRectangle.TopLeft() + Point(-1250, -1000);
+ pView2->MoveShapeHandle(0, aNewPosition, -1);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(4), pUndoManager->GetUndoActionCount());
+
+ // Check the object has a new size
+ aRectangle = pTextBoxObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(1000L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(1000L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(4990L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(2175L, aRectangle.GetHeight());
+
+ // View1 is still in text edit mode...
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // On View2 - relative move the shape to a different position
+ pView2->MoveMarkedObj(Size(1000, 2000), /*bCopy=*/false);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(5), pUndoManager->GetUndoActionCount());
+
+ // Check the object is at a different position
+ aRectangle = pTextBoxObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(2000L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(3000L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(4990L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(2175L, aRectangle.GetHeight());
+
+ // View1 is still in text edit mode...
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // End Text edit - check undo count increase from 5 -> 6
+ CPPUNIT_ASSERT_EQUAL(size_t(5), pUndoManager->GetUndoActionCount());
+ pView1->SdrEndTextEdit();
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(6), pUndoManager->GetUndoActionCount());
+
+ // Check that both views exited the text edit mode
+ CPPUNIT_ASSERT_EQUAL(false, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+ }
+
+ // Scenario 3
+ // 1 shapes - "Table1"
+ // View1 - "Table1" enters text edit mode, View 2 - moves the "Table1" around
+ {
+ sd::UndoManager* pUndoManager = pDocument->GetUndoManager();
+ CPPUNIT_ASSERT_EQUAL(size_t(6), pUndoManager->GetUndoActionCount());
+
+ pView1->SdrBeginTextEdit(pTableObject);
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // Local undo count for View1 is 0
+ CPPUNIT_ASSERT_EQUAL(size_t(0), pView1->getViewLocalUndoManager()->GetUndoActionCount());
+ // Write 'test' in View1
+ SfxStringItem aInputString(SID_ATTR_CHAR, "test");
+ pViewShell1->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_CHAR, SfxCallMode::SYNCHRON, { &aInputString });
+ // Local undo count for View1 is now 1
+ CPPUNIT_ASSERT_EQUAL(size_t(1), pView1->getViewLocalUndoManager()->GetUndoActionCount());
+
+ // Mark rectangle object
+ pView2->MarkObj(pTableObject, pView2->GetSdrPageView());
+
+ // Check the initial position of the table
+ tools::Rectangle aRectangle = pTableObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(2919L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(18063L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(14099L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(5999L, aRectangle.GetHeight());
+
+ // On View2 - relative move the shape to a different position
+ pView2->MoveMarkedObj(Size(1000, 2000), /*bCopy=*/false);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(7), pUndoManager->GetUndoActionCount());
+
+ // Check the object is at a different position
+ aRectangle = pTableObject->GetLogicRect();
+ CPPUNIT_ASSERT_EQUAL(3919L, aRectangle.TopLeft().X());
+ CPPUNIT_ASSERT_EQUAL(20063L, aRectangle.TopLeft().Y());
+ CPPUNIT_ASSERT_EQUAL(14099L, aRectangle.GetWidth());
+ CPPUNIT_ASSERT_EQUAL(5999L, aRectangle.GetHeight());
+
+ // View1 is still in text edit mode...
+ CPPUNIT_ASSERT_EQUAL(true, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+
+ // End Text edit - check undo count increase from 7 -> 8
+ CPPUNIT_ASSERT_EQUAL(size_t(7), pUndoManager->GetUndoActionCount());
+ pView1->SdrEndTextEdit();
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(size_t(8), pUndoManager->GetUndoActionCount());
+
+ // Check that both views exited the text edit mode
+ CPPUNIT_ASSERT_EQUAL(false, pView1->IsTextEdit());
+ CPPUNIT_ASSERT_EQUAL(false, pView2->IsTextEdit());
+ }
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/ui/inc/View.hxx b/sd/source/ui/inc/View.hxx
index 744023acb573..b0ad4ca2ff87 100644
--- a/sd/source/ui/inc/View.hxx
+++ b/sd/source/ui/inc/View.hxx
@@ -142,6 +142,9 @@ public:
ViewShell* GetViewShell() const { return mpViewSh; }
SfxViewShell* GetSfxViewShell() const override;
+ // Create a local UndoManager
+ std::unique_ptr<SdrUndoManager> createLocalTextUndoManager() override;
+
virtual bool SdrBeginTextEdit(SdrObject* pObj, SdrPageView* pPV = nullptr, vcl::Window* pWin = nullptr, bool bIsNewObj = false,
SdrOutliner* pGivenOutliner = nullptr, OutlinerView* pGivenOutlinerView = nullptr,
bool bDontDeleteOutliner = false, bool bOnlyOneView = false, bool bGrabFocus = true) override;
diff --git a/sd/source/ui/view/drviews1.cxx b/sd/source/ui/view/drviews1.cxx
index 6c1df14a3961..4c3e446963a5 100644
--- a/sd/source/ui/view/drviews1.cxx
+++ b/sd/source/ui/view/drviews1.cxx
@@ -344,7 +344,9 @@ void DrawViewShell::ChangeEditMode(EditMode eEMode, bool bIsLayerModeActive)
if ( mpDrawView->IsTextEdit() )
{
- mpDrawView->SdrEndTextEdit();
+ // This exits the text edit mode when going in and out of window focus, which is not needed
+ // Let's keep this call as comment for now as it probably just needs a better conditional.
+ // mpDrawView->SdrEndTextEdit();
}
LayerTabBar* pLayerBar = GetLayerTabControl();
diff --git a/sd/source/ui/view/sdview.cxx b/sd/source/ui/view/sdview.cxx
index d977334013f1..fadd89b99033 100644
--- a/sd/source/ui/view/sdview.cxx
+++ b/sd/source/ui/view/sdview.cxx
@@ -82,6 +82,8 @@
#include <DrawController.hxx>
#include <svtools/optionsdrawinglayer.hxx>
+#include <undo/undomanager.hxx>
+
#include <memory>
#include <numeric>
@@ -624,6 +626,14 @@ SfxViewShell* View::GetSfxViewShell() const
return pRet;
}
+// Create a new view-local UndoManager manager for Impress/Draw
+std::unique_ptr<SdrUndoManager> View::createLocalTextUndoManager()
+{
+ std::unique_ptr<SdrUndoManager> pUndoManager(new sd::UndoManager);
+ pUndoManager->SetDocShell(mpDocSh);
+ return pUndoManager;
+}
+
bool View::SdrBeginTextEdit(
SdrObject* pObj, SdrPageView* pPV, vcl::Window* pWin,
bool bIsNewObj,
diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx
index 7d5fb61569b7..bdba8aa0d7f4 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -1345,7 +1345,7 @@ bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/)
if( bUndo )
{
- getSdrDragView().EndTextEditAllViews();
+ getSdrDragView().EndTextEditCurrentView();
if(!getSdrDragView().IsInsObjPoint() && pObj->IsInserted() )
{
if (DragStat().IsEndDragChangesAttributes())
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index 0d4bb55d09f5..47f5c971e543 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -1000,7 +1000,7 @@ bool SdrEditView::InsertObjectAtView(SdrObject* pObj, SdrPageView& rPV, SdrInser
}
if( IsUndoEnabled())
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj));
}
@@ -1080,4 +1080,14 @@ void SdrEditView::EndTextEditAllViews() const
}
}
+void SdrEditView::EndTextEditCurrentView()
+{
+ if (IsTextEdit())
+ {
+ SdrView* pSdrView = dynamic_cast<SdrView*>(this);
+ if (pSdrView)
+ pSdrView->SdrEndTextEdit();
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx
index 81cf6e6f0b0b..852d160ccd98 100644
--- a/svx/source/svdraw/svdedtv1.cxx
+++ b/svx/source/svdraw/svdedtv1.cxx
@@ -95,7 +95,7 @@ void SdrEditView::SetMarkedObjRect(const tools::Rectangle& rRect)
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
BegUndo(ImpGetDescriptionString(STR_EditPosSize));
}
@@ -186,7 +186,7 @@ void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy)
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr(SvxResId(STR_EditMove));
if (bCopy)
aStr += SvxResId(STR_EditWithCopy);
@@ -219,7 +219,7 @@ void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, cons
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr {ImpGetDescriptionString(STR_EditResize)};
if (bCopy)
aStr+=SvxResId(STR_EditWithCopy);
@@ -254,7 +254,7 @@ void SdrEditView::ResizeMultMarkedObj(const Point& rRef,
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
BegUndo(ImpGetDescriptionString(STR_EditResize));
}
@@ -301,7 +301,7 @@ void SdrEditView::RotateMarkedObj(const Point& rRef, Degree100 nAngle, bool bCop
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr {ImpGetDescriptionString(STR_EditRotate)};
if (bCopy) aStr+=SvxResId(STR_EditWithCopy);
BegUndo(aStr);
@@ -358,7 +358,7 @@ void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool b
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr;
Point aDif(rRef2-rRef1);
if (aDif.X()==0)
@@ -458,7 +458,7 @@ void SdrEditView::ShearMarkedObj(const Point& rRef, Degree100 nAngle, bool bVShe
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr {ImpGetDescriptionString(STR_EditShear)};
if (bCopy)
aStr+=SvxResId(STR_EditWithCopy);
@@ -574,7 +574,7 @@ void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookM
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr {ImpGetDescriptionString(bNoContortion ? STR_EditCrook : STR_EditCrookContortion)};
if (bCopy)
aStr+=SvxResId(STR_EditWithCopy);
@@ -648,7 +648,7 @@ void SdrEditView::DistortMarkedObj(const tools::Rectangle& rRef, const XPolygon&
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr {ImpGetDescriptionString(STR_EditDistort)};
if (bCopy)
aStr+=SvxResId(STR_EditWithCopy);
@@ -1098,7 +1098,7 @@ void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, bool bReplaceAll)
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
BegUndo(ImpGetDescriptionString(STR_EditSetAttributes));
}
@@ -1277,7 +1277,7 @@ void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, bool bDontRe
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr;
if (pStyleSheet!=nullptr)
aStr = ImpGetDescriptionString(STR_EditSetStylesheet);
@@ -1844,7 +1844,7 @@ void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert)
const bool bUndo = IsUndoEnabled();
if( bUndo )
{
- EndTextEditAllViews();
+ EndTextEditCurrentView();
OUString aStr(GetDescriptionOfMarkedObjects());
if (eHor==SdrHorAlign::NONE)
{
diff --git a/svx/source/svdraw/svdedxv.cxx b/svx/source/svdraw/svdedxv.cxx
index db0ccf6ea486..3717fdce2c08 100644
--- a/svx/source/svdraw/svdedxv.cxx
+++ b/svx/source/svdraw/svdedxv.cxx
@@ -1060,10 +1060,11 @@ IMPL_LINK(SdrObjEditView, ImpOutlinerCalcFieldValueHdl, EditFieldInfo*, pFI, voi
IMPL_LINK_NOARG(SdrObjEditView, EndTextEditHdl, SdrUndoManager*, void) { SdrEndTextEdit(); }
-SdrUndoManager* SdrObjEditView::getSdrUndoManagerForEnhancedTextEdit() const
+// Default implementation - null UndoManager
+std::unique_ptr<SdrUndoManager> SdrObjEditView::createLocalTextUndoManager()
{
- // default returns registered UndoManager
- return GetModel() ? dynamic_cast<SdrUndoManager*>(GetModel()->GetSdrUndoManager()) : nullptr;
+ SAL_WARN("svx", "SdrObjEditView::createLocalTextUndoManager needs to be overridden");
+ return std::unique_ptr<SdrUndoManager>();
}
bool SdrObjEditView::SdrBeginTextEdit(SdrObject* pObj_, SdrPageView* pPV, vcl::Window* pWin,
@@ -1360,7 +1361,11 @@ bool SdrObjEditView::SdrBeginTextEdit(SdrObject* pObj_, SdrPageView* pPV, vcl::W
if (GetModel() && IsUndoEnabled()
&& !GetModel()->GetDisableTextEditUsesCommonUndoManager())
{
- SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit();
+ SdrUndoManager* pSdrUndoManager = nullptr;
+ mpLocalTextEditUndoManager = createLocalTextUndoManager();
+
+ if (mpLocalTextEditUndoManager)
+ pSdrUndoManager = mpLocalTextEditUndoManager.get();
if (pSdrUndoManager)
{
@@ -1434,7 +1439,7 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
if (pOriginal)
{
// check if we got back our document undo manager
- SdrUndoManager* pSdrUndoManager = getSdrUndoManagerForEnhancedTextEdit();
+ SdrUndoManager* pSdrUndoManager = mpLocalTextEditUndoManager.get();
if (pSdrUndoManager && dynamic_cast<SdrUndoManager*>(pOriginal) == pSdrUndoManager)
{
@@ -1467,6 +1472,8 @@ SdrEndTextEditKind SdrObjEditView::SdrEndTextEdit(bool bDontDeleteReally)
"expected document UndoManager (!)");
delete pOriginal;
}
+
+ mpLocalTextEditUndoManager.reset();
}
}
else
diff --git a/sw/qa/extras/tiledrendering/data/shape.fodt b/sw/qa/extras/tiledrendering/data/shape.fodt
index feefe48bcde3..4e9a7f629ba4 100644
--- a/sw/qa/extras/tiledrendering/data/shape.fodt
+++ b/sw/qa/extras/tiledrendering/data/shape.fodt
@@ -1,5 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
-<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:xforms="http://www.w3.org/2002/xforms" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rpt="http://openoffice.org/2005/report" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+
+<office:document xmlns:officeooo="http://openoffice.org/2009/office" xmlns:css3t="http://www.w3.org/TR/css3-text/" xmlns:grddl="http://www.w3.org/2003/g/data-view#" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:oooc="http://openoffice.org/2004/calc" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:ooow="http://openoffice.org/2004/writer" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rpt="http://openoffice.org/2005/report" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0" xmlns:tableooo="http://openoffice.org/2009/table" xmlns:drawooo="http://openoffice.org/2010/draw" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" xmlns:dom="http://www.w3.org/2001/xml-events" xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML" xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+ <style:default-style style:family="graphic">
+ <style:graphic-properties svg:stroke-color="#3465a4" draw:fill-color="#729fcf" fo:wrap-option="no-wrap" draw:shadow-offset-x="0.3cm" draw:shadow-offset-y="0.3cm" draw:start-line-spacing-horizontal="0.283cm" draw:start-line-spacing-vertical="0.283cm" draw:end-line-spacing-horizontal="0.283cm" draw:end-line-spacing-vertical="0.283cm" style:flow-with-text="false"/>
+ <style:paragraph-properties style:text-autospace="ideograph-alpha" style:line-break="strict" style:writing-mode="lr-tb" style:font-independent-line-spacing="false">
+ <style:tab-stops/>
+ </style:paragraph-properties>
+ <style:text-properties style:use-window-font-color="true" loext:opacity="0%" style:font-name="Liberation Serif" fo:font-size="12pt" fo:language="en" fo:country="GB" style:letter-kerning="true" style:font-name-asian="Noto Serif CJK SC" style:font-size-asian="10.5pt" style:language-asian="zh" style:country-asian="CN" style:font-name-complex="Droid Sans Devanagari1" style:font-size-complex="12pt" style:language-complex="hi" style:country-complex="IN"/>
+ </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+ <style:style style:name="gr1" style:family="graphic">
+ <style:graphic-properties draw:textarea-horizontal-align="justify" draw:textarea-vertical-align="middle" draw:auto-grow-height="false" fo:min-height="1.9cm" fo:min-width="3.471cm" style:run-through="foreground" style:wrap="run-through" style:number-wrapped-paragraphs="no-limit" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph"/>
+ </style:style>
+ </office:automatic-styles>
<office:body>
<office:text>
<text:sequence-decls>
@@ -7,8 +22,9 @@
<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
+ <text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
</text:sequence-decls>
- <text:p><draw:custom-shape text:anchor-type="paragraph" draw:z-index="0" svg:width="4.883cm" svg:height="3.225cm" svg:x="2.602cm" svg:y="1.178cm">
+ <text:p text:style-name="Standard"><draw:custom-shape text:anchor-type="paragraph" draw:z-index="0" draw:name="Shape1" draw:style-name="gr1" svg:width="4.908cm" svg:height="2.687cm" svg:x="1.575cm" svg:y="-0.132cm">
<text:p/>
<draw:enhanced-geometry svg:viewBox="0 0 21600 21600" draw:glue-points="10800 0 3163 3163 0 10800 3163 18437 10800 21600 18437 18437 21600 10800 18437 3163" draw:text-areas="3163 3163 18437 18437" draw:type="ellipse" draw:enhanced-path="U 10800 10800 10800 10800 0 360 Z N"/>
</draw:custom-shape>Hello.</text:p>
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 8f637753d1d4..9eaca7d123a7 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -1311,6 +1311,7 @@ void SwTiledRenderingTest::testUndoShapeLimiting()
pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
Scheduler::ProcessEventsToIdle();
+ pWrtShell2->EndTextEdit();
// Assert that the first view can't and the second view can undo the insertion.
SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc();
@@ -1321,7 +1322,6 @@ void SwTiledRenderingTest::testUndoShapeLimiting()
rUndoManager.SetView(&pWrtShell2->GetView());
CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rUndoManager.GetUndoActionCount());
- pWrtShell2->EndTextEdit();
rUndoManager.SetView(nullptr);
SfxLokHelper::setView(nView1);
@@ -1426,11 +1426,14 @@ void SwTiledRenderingTest::testShapeTextUndoShells()
pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
Scheduler::ProcessEventsToIdle();
+ pWrtShell->EndTextEdit();
// Make sure that the undo item remembers who created it.
SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc();
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rUndoManager.GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(size_t(1), rUndoManager.GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Edit text of Shape 'Shape1'"), rUndoManager.GetUndoActionComment(0));
+
// This was -1: the view shell id for the undo action wasn't known.
CPPUNIT_ASSERT_EQUAL(ViewShellId(nView1), rUndoManager.GetUndoAction()->GetViewShellId());
}
@@ -1457,7 +1460,14 @@ void SwTiledRenderingTest::testShapeTextUndoGroupShells()
// Make sure that the undo item remembers who created it.
SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc();
sw::UndoManager& rUndoManager = pDoc->GetUndoManager();
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rUndoManager.GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(size_t(0), rUndoManager.GetUndoActionCount());
+
+ pWrtShell->EndTextEdit();
+ pWrtShell->GetView().BeginTextEdit(pObject, pView->GetSdrPageView(), pWrtShell->GetWin());
+
+ CPPUNIT_ASSERT_EQUAL(size_t(1), rUndoManager.GetUndoActionCount());
+ CPPUNIT_ASSERT_EQUAL(OUString("Edit text of Shape 'Shape1'"), rUndoManager.GetUndoActionComment(0));
+
// This was -1: the view shell id for the (top) undo list action wasn't known.
CPPUNIT_ASSERT_EQUAL(ViewShellId(nView1), rUndoManager.GetUndoAction()->GetViewShellId());
diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx
index 33d6a83fb1f8..510addf10a9c 100644
--- a/sw/source/core/draw/dview.cxx
+++ b/sw/source/core/draw/dview.cxx
@@ -998,12 +998,12 @@ void SwDrawView::DeleteMarked()
pTmpRoot->EndAllAction();
}
-// support enhanced text edit for draw objects
-SdrUndoManager* SwDrawView::getSdrUndoManagerForEnhancedTextEdit() const
+// Create a new view-local UndoManager manager for Writer
+std::unique_ptr<SdrUndoManager> SwDrawView::createLocalTextUndoManager()
{
- SwDoc* pDoc = Imp().GetShell()->GetDoc();
-
- return pDoc ? &(pDoc->GetUndoManager()) : nullptr;
+ std::unique_ptr<SdrUndoManager> pUndoManager(new SdrUndoManager);
+ pUndoManager->SetDocShell(SfxObjectShell::Current());
+ return pUndoManager;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/inc/dview.hxx b/sw/source/core/inc/dview.hxx
index 3e9f4e6c9864..cdcf3f265985 100644
--- a/sw/source/core/inc/dview.hxx
+++ b/sw/source/core/inc/dview.hxx
@@ -75,8 +75,8 @@ class SwDrawView final : public FmFormView
using FmFormView::CheckSingleSdrObjectHit;
virtual SdrObject* CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nTol, SdrObject* pObj, SdrPageView* pPV, SdrSearchOptions nOptions, const SdrLayerIDSet* pMVisLay) const override;
- // support enhanced text edit for draw objects
- virtual SdrUndoManager* getSdrUndoManagerForEnhancedTextEdit() const override;
+ // Create a local UndoManager
+ std::unique_ptr<SdrUndoManager> createLocalTextUndoManager() override;
public:
SwDrawView(