summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Cecchetti <marco.cecchetti@collabora.com>2017-01-06 18:35:08 +0100
committerJan Holesovsky <kendy@collabora.com>2017-03-29 16:24:24 +0200
commitbb69dc8feb4701d162713f4095656c98bb0d5f80 (patch)
treeb6532022d77228806cef47b7127d8b22cf772d96
parentf0c0d58467e28e24fedc6ce27b2db03e316dce9f (diff)
LOK: Calc: limiting undo and add support for repair mode
During collaborative editing changes can be undone regardless of who made them. This patch avoids this possibility and introduce support for repair mode, for cases where undo/redo of others' changes is intentional. Change-Id: I69fd435e96c4c675ffd1df81e936b5eae109daa0
-rw-r--r--sc/qa/unit/tiledrendering/tiledrendering.cxx133
-rw-r--r--sc/source/ui/view/tabvwshb.cxx28
2 files changed, 161 insertions, 0 deletions
diff --git a/sc/qa/unit/tiledrendering/tiledrendering.cxx b/sc/qa/unit/tiledrendering/tiledrendering.cxx
index cb9cd2bf3d8b..5e1ba9b3cec1 100644
--- a/sc/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sc/qa/unit/tiledrendering/tiledrendering.cxx
@@ -72,6 +72,8 @@ public:
void testInvalidateOnCopyPasteCells();
void testInvalidateOnInserRowCol();
void testCommentCallback();
+ void testUndoLimiting();
+ void testUndoRepairDispatch();
CPPUNIT_TEST_SUITE(ScTiledRenderingTest);
CPPUNIT_TEST(testRowColumnSelections);
@@ -94,6 +96,8 @@ public:
CPPUNIT_TEST(testInvalidateOnCopyPasteCells);
CPPUNIT_TEST(testInvalidateOnInserRowCol);
CPPUNIT_TEST(testCommentCallback);
+ CPPUNIT_TEST(testUndoLimiting);
+ CPPUNIT_TEST(testUndoRepairDispatch);
CPPUNIT_TEST_SUITE_END();
private:
@@ -1130,6 +1134,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 f06d7d3bde98..bfe407aca2e1 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;
@@ -496,6 +497,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)
+ {
+ sal_Int32 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 )