diff options
-rw-r--r-- | sc/qa/unit/tiledrendering/tiledrendering.cxx | 133 | ||||
-rw-r--r-- | sc/source/ui/view/tabvwshb.cxx | 28 |
2 files changed, 161 insertions, 0 deletions
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx index 6186ab9964ce..2510d161387a 100644 --- a/sc/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx @@ -77,6 +77,8 @@ public: void testInvalidateOnCopyPasteCells(); void testInvalidateOnInserRowCol(); void testCommentCallback(); + void testUndoLimiting(); + void testUndoRepairDispatch(); CPPUNIT_TEST_SUITE(ScTiledRenderingTest); CPPUNIT_TEST(testRowColumnSelections); @@ -99,6 +101,8 @@ public: CPPUNIT_TEST(testInvalidateOnCopyPasteCells); CPPUNIT_TEST(testInvalidateOnInserRowCol); CPPUNIT_TEST(testCommentCallback); + CPPUNIT_TEST(testUndoLimiting); + CPPUNIT_TEST(testUndoRepairDispatch); CPPUNIT_TEST_SUITE_END(); private: @@ -1135,6 +1139,135 @@ void ScTiledRenderingTest::testCommentCallback() comphelper::LibreOfficeKit::setActive(false); } +void ScTiledRenderingTest::testUndoLimiting() +{ + comphelper::LibreOfficeKit::setActive(); + + ScModelObj* pModelObj = createDoc("small.ods"); + CPPUNIT_ASSERT(pModelObj); + ScDocument* pDoc = pModelObj->GetDocument(); + CPPUNIT_ASSERT(pDoc); + SfxUndoManager* pUndoManager = pDoc->GetUndoManager(); + CPPUNIT_ASSERT(pUndoManager); + + // view #1 + ViewCallback aView1; + int nView1 = SfxLokHelper::getView(); + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1); + + // view #2 + SfxLokHelper::createView(); + ViewCallback aView2; + int nView2 = SfxLokHelper::getView(); + pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &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, 0, awt::Key::RETURN); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN); + Scheduler::ProcessEventsToIdle(); + + // check that undo action count in not 0 + CPPUNIT_ASSERT(pUndoManager->GetUndoActionCount() == 1); + + // try to execute undo in view #2 + SfxLokHelper::setView(nView2); + comphelper::dispatchCommand(".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + // check that undo has not been executed on view #2 + CPPUNIT_ASSERT(pUndoManager->GetUndoActionCount() == 1); + + // try to execute undo in view #1 + SfxLokHelper::setView(nView1); + comphelper::dispatchCommand(".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + // check that undo has been executed on view #1 + CPPUNIT_ASSERT(pUndoManager->GetUndoActionCount() == 0); + + // check that redo action count in not 0 + CPPUNIT_ASSERT(pUndoManager->GetRedoActionCount() == 1); + + // try to execute redo in view #2 + SfxLokHelper::setView(nView2); + comphelper::dispatchCommand(".uno:Redo", {}); + Scheduler::ProcessEventsToIdle(); + // check that redo has not been executed on view #2 + CPPUNIT_ASSERT(pUndoManager->GetRedoActionCount() == 1); + + // try to execute redo in view #1 + SfxLokHelper::setView(nView1); + comphelper::dispatchCommand(".uno:Redo", {}); + Scheduler::ProcessEventsToIdle(); + // check that redo has been executed on view #1 + CPPUNIT_ASSERT(pUndoManager->GetRedoActionCount() == 0); + + mxComponent->dispose(); + mxComponent.clear(); + + comphelper::LibreOfficeKit::setActive(false); +} + +void ScTiledRenderingTest::testUndoRepairDispatch() +{ + comphelper::LibreOfficeKit::setActive(); + + ScModelObj* pModelObj = createDoc("small.ods"); + CPPUNIT_ASSERT(pModelObj); + ScDocument* pDoc = pModelObj->GetDocument(); + CPPUNIT_ASSERT(pDoc); + SfxUndoManager* pUndoManager = pDoc->GetUndoManager(); + CPPUNIT_ASSERT(pUndoManager); + + // view #1 + ViewCallback aView1; + int nView1 = SfxLokHelper::getView(); + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1); + + // view #2 + SfxLokHelper::createView(); + ViewCallback aView2; + int nView2 = SfxLokHelper::getView(); + pModelObj->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &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, 0, awt::Key::RETURN); + pModelObj->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::RETURN); + Scheduler::ProcessEventsToIdle(); + + // check that undo action count in not 0 + CPPUNIT_ASSERT(pUndoManager->GetUndoActionCount() == 1); + + // try to execute undo in view #2 + SfxLokHelper::setView(nView2); + comphelper::dispatchCommand(".uno:Undo", {}); + Scheduler::ProcessEventsToIdle(); + // check that undo has not been executed on view #2 + CPPUNIT_ASSERT(pUndoManager->GetUndoActionCount() == 1); + + // try to execute undo in view #2 in repair mode + SfxLokHelper::setView(nView2); + uno::Sequence<beans::PropertyValue> aPropertyValues(comphelper::InitPropertySequence( + { + {"Repair", uno::makeAny(true)} + })); + comphelper::dispatchCommand(".uno:Undo", aPropertyValues); + Scheduler::ProcessEventsToIdle(); + // check that undo has been executed on view #2 in repair mode + CPPUNIT_ASSERT(pUndoManager->GetUndoActionCount() == 0); + + mxComponent->dispose(); + mxComponent.clear(); + + comphelper::LibreOfficeKit::setActive(false); +} + } CPPUNIT_TEST_SUITE_REGISTRATION(ScTiledRenderingTest); diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx index 23b1ec9532de..ee81fab78563 100644 --- a/sc/source/ui/view/tabvwshb.cxx +++ b/sc/source/ui/view/tabvwshb.cxx @@ -62,6 +62,7 @@ #include <tools/urlobj.hxx> #include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <comphelper/lok.hxx> using namespace com::sun::star; @@ -522,6 +523,33 @@ void ScTabViewShell::ExecuteUndo(SfxRequest& rReq) if ( pReqArgs && pReqArgs->GetItemState( nSlot, true, &pItem ) == SfxItemState::SET ) nCount = static_cast<const SfxUInt16Item*>(pItem)->GetValue(); + // Repair mode: allow undo/redo of all undo actions, even if access would + // be limited based on the view shell ID. + bool bRepair = false; + if (pReqArgs && pReqArgs->GetItemState(SID_REPAIRPACKAGE, false, &pItem) == SfxItemState::SET) + bRepair = static_cast<const SfxBoolItem*>(pItem)->GetValue(); + + if (comphelper::LibreOfficeKit::isActive() && !bRepair) + { + SfxUndoAction* pAction = nullptr; + if (bIsUndo) + { + if (pUndoManager->GetUndoActionCount() != 0) + pAction = pUndoManager->GetUndoAction(); + } + else + { + if (pUndoManager->GetRedoActionCount() != 0) + pAction = pUndoManager->GetRedoAction(); + } + if (pAction) + { + ViewShellId nViewShellId = GetViewShellId(); + if (pAction->GetViewShellId() != nViewShellId) + return; + } + } + // lock paint for more than one cell undo action (not for editing within a cell) bool bLockPaint = ( nCount > 1 && pUndoManager == GetUndoManager() ); if ( bLockPaint ) |