diff options
author | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-07-31 18:59:01 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2022-07-31 20:06:42 +0200 |
commit | 3ccbfaaf95005a34ca64ad250463ef5ce8842f43 (patch) | |
tree | 1219316d396736bf4890aac5f6694540229efcac | |
parent | 730f6dac9eaad5b3ffda3032c184a671a9a16f72 (diff) |
sc, out of order undo: allow multiple actions from other view
this is the calc equivalent of
commit c88c2d40d1a4aebc46b25368b80c02bc2f136658
Date: Fri Nov 12 08:39:35 2021 +0100
sw, out of order undo: allow multiple actions from other views
Change-Id: I5acbd1e1cacef7c2e2a549f4d2270e961f576a65
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/137652
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
-rw-r--r-- | sc/qa/unit/tiledrendering/tiledrendering.cxx | 72 | ||||
-rw-r--r-- | sc/source/ui/inc/undomanager.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/undo/undobase.cxx | 15 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwshb.cxx | 5 |
4 files changed, 88 insertions, 8 deletions
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx index 9ed5cf471269..559769c0c251 100644 --- a/sc/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx @@ -130,6 +130,7 @@ public: void testInvalidEntrySave(); void testUndoReordering(); void testUndoReorderingRedo(); + void testUndoReorderingMulti(); CPPUNIT_TEST_SUITE(ScTiledRenderingTest); CPPUNIT_TEST(testRowColumnHeaders); @@ -189,6 +190,7 @@ public: CPPUNIT_TEST(testInvalidEntrySave); CPPUNIT_TEST(testUndoReordering); CPPUNIT_TEST(testUndoReorderingRedo); + CPPUNIT_TEST(testUndoReorderingMulti); CPPUNIT_TEST_SUITE_END(); private: @@ -3127,6 +3129,76 @@ void ScTiledRenderingTest::testUndoReorderingRedo() CPPUNIT_ASSERT_EQUAL(OUString("CC"), pDoc->GetString(ScAddress(0, 2, 0))); } +void ScTiledRenderingTest::testUndoReorderingMulti() +{ + ScModelObj* pModelObj = createDoc("empty.ods"); + CPPUNIT_ASSERT(pModelObj); + ScDocument* pDoc = pModelObj->GetDocument(); + CPPUNIT_ASSERT(pDoc); + ScUndoManager* pUndoManager = pDoc->GetUndoManager(); + CPPUNIT_ASSERT(pUndoManager); + CPPUNIT_ASSERT_EQUAL(std::size_t(0), pUndoManager->GetUndoActionCount()); + + // view #1 + int nView1 = SfxLokHelper::getView(); + ViewCallback aView1; + + // view #2 + SfxLokHelper::createView(); + int nView2 = SfxLokHelper::getView(); + pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + ViewCallback aView2; + + // text edit a cell in view #1 + SfxLokHelper::setView(nView1); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(std::size_t(1), pUndoManager->GetUndoActionCount()); + + // text edit a different cell in view #2 + SfxLokHelper::setView(nView2); + ScTabViewShell* pView2 = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + pView2->SetCursor(0, 2); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'C', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'C', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'C', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'C', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(std::size_t(2), pUndoManager->GetUndoActionCount()); + CPPUNIT_ASSERT_EQUAL(OUString("xx"), pDoc->GetString(ScAddress(0, 0, 0))); + CPPUNIT_ASSERT_EQUAL(OUString("CC"), pDoc->GetString(ScAddress(0, 2, 0))); + + // and another cell in view #2 + pView2->SetCursor(0, 3); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'D', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'D', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'D', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 'D', 0); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::RETURN); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(std::size_t(3), pUndoManager->GetUndoActionCount()); + CPPUNIT_ASSERT_EQUAL(OUString("xx"), pDoc->GetString(ScAddress(0, 0, 0))); + CPPUNIT_ASSERT_EQUAL(OUString("CC"), pDoc->GetString(ScAddress(0, 2, 0))); + CPPUNIT_ASSERT_EQUAL(OUString("DD"), pDoc->GetString(ScAddress(0, 3, 0))); + + // View 1 presses undo + SfxLokHelper::setView(nView1); + dispatchCommand(mxComponent, ".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + CPPUNIT_ASSERT_EQUAL(std::size_t(2), pUndoManager->GetUndoActionCount()); + CPPUNIT_ASSERT_EQUAL(OUString(""), pDoc->GetString(ScAddress(0, 0, 0))); + CPPUNIT_ASSERT_EQUAL(OUString("CC"), pDoc->GetString(ScAddress(0, 2, 0))); + CPPUNIT_ASSERT_EQUAL(OUString("DD"), pDoc->GetString(ScAddress(0, 3, 0))); +} + } CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest); diff --git a/sc/source/ui/inc/undomanager.hxx b/sc/source/ui/inc/undomanager.hxx index da254a02d294..7ec3db645ffe 100644 --- a/sc/source/ui/inc/undomanager.hxx +++ b/sc/source/ui/inc/undomanager.hxx @@ -20,9 +20,9 @@ public: /** * Checks if the topmost undo action owned by pView is independent from the topmost action undo - * action. + * action. Sets rOffset to the offset of that independent undo action on success. */ - bool IsViewUndoActionIndependent(const SfxViewShell* pView) const; + bool IsViewUndoActionIndependent(const SfxViewShell* pView, sal_uInt16& rOffset) const; /// Make these public using SdrUndoManager::UndoWithContext; diff --git a/sc/source/ui/undo/undobase.cxx b/sc/source/ui/undo/undobase.cxx index 250c78619ef8..31f1e4152a0d 100644 --- a/sc/source/ui/undo/undobase.cxx +++ b/sc/source/ui/undo/undobase.cxx @@ -621,7 +621,7 @@ ScUndoManager::~ScUndoManager() {} * Checks if the topmost undo action owned by pView is independent from the topmost action undo * action. */ -bool ScUndoManager::IsViewUndoActionIndependent(const SfxViewShell* pView) const +bool ScUndoManager::IsViewUndoActionIndependent(const SfxViewShell* pView, sal_uInt16& rOffset) const { if (GetUndoActionCount() <= 1) { @@ -641,10 +641,16 @@ bool ScUndoManager::IsViewUndoActionIndependent(const SfxViewShell* pView) const // Earlier undo action that belongs to the view, but is not the top one. const SfxUndoAction* pViewAction = nullptr; - const SfxUndoAction* pAction = GetUndoAction(1); - if (pAction->GetViewShellId() == nViewId) + size_t nOffset = 0; + for (size_t i = 0; i < GetUndoActionCount(); ++i) { - pViewAction = pAction; + const SfxUndoAction* pAction = GetUndoAction(i); + if (pAction->GetViewShellId() == nViewId) + { + pViewAction = pAction; + nOffset = i; + break; + } } if (!pViewAction) @@ -679,6 +685,7 @@ bool ScUndoManager::IsViewUndoActionIndependent(const SfxViewShell* pView) const } } + rOffset = nOffset; return true; } diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx index 02ea57f74a5e..7052820099c9 100644 --- a/sc/source/ui/view/tabvwshb.cxx +++ b/sc/source/ui/view/tabvwshb.cxx @@ -756,11 +756,12 @@ void ScTabViewShell::ExecuteUndo(SfxRequest& rReq) ViewShellId nViewShellId = GetViewShellId(); if (pAction->GetViewShellId() != nViewShellId) { - if (pUndoManager->IsViewUndoActionIndependent(this)) + sal_uInt16 nOffset = 0; + if (pUndoManager->IsViewUndoActionIndependent(this, nOffset)) { // Execute the undo with an offset: don't undo the top action, but an // earlier one, since it's independent and that belongs to our view. - nUndoOffset = 1; + nUndoOffset += nOffset; } else { |