summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-07-31 18:59:01 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-07-31 20:06:42 +0200
commit3ccbfaaf95005a34ca64ad250463ef5ce8842f43 (patch)
tree1219316d396736bf4890aac5f6694540229efcac /sc
parent730f6dac9eaad5b3ffda3032c184a671a9a16f72 (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>
Diffstat (limited to 'sc')
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx72
-rw-r--r--sc/source/ui/inc/undomanager.hxx4
-rw-r--r--sc/source/ui/undo/undobase.cxx15
-rw-r--r--sc/source/ui/view/tabvwshb.cxx5
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
{