summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-08-17 07:53:16 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-08-17 09:02:03 +0200
commit5c99ed5f6524deb58f5a2ef4b91f69bfa0d21b25 (patch)
tree6c199ff4aabb8b05ebbe55aedd397915cc755d1f
parent5e04584d20629e84c6c9446032caba77ef596791 (diff)
sd lok: limit undo/redo access to undo actions created by the same view
Unlike in Writer, the state and the exec method of .uno:Undo is different codepath so for now ignore the Repair argument of the command, assuming that the command is only dispatched if the command is enabled. Change-Id: I3bfe8d72522f32efe436e21c383c99b3612eab6b (cherry picked from commit e0a3269183bf145511361a3968dca07824923dd4)
-rw-r--r--sd/inc/undo/undomanager.hxx10
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx39
-rw-r--r--sd/source/core/undo/undomanager.cxx50
-rw-r--r--sd/source/ui/view/viewshe3.cxx11
4 files changed, 109 insertions, 1 deletions
diff --git a/sd/inc/undo/undomanager.hxx b/sd/inc/undo/undomanager.hxx
index a0200382ae27..5c3a0824973f 100644
--- a/sd/inc/undo/undomanager.hxx
+++ b/sd/inc/undo/undomanager.hxx
@@ -22,11 +22,14 @@
#include <misc/scopelock.hxx>
#include <svx/sdrundomanager.hxx>
+#include "sddllapi.h"
+
+class SfxViewShell;
namespace sd
{
-class UndoManager : public SdrUndoManager
+class SD_DLLPUBLIC UndoManager : public SdrUndoManager
{
public:
UndoManager( sal_uInt16 nMaxUndoActionCount = 20 );
@@ -34,6 +37,9 @@ public:
virtual void EnterListAction(const OUString &rComment, const OUString& rRepeatComment, sal_uInt16 nId, sal_Int32 nViewShellId) override;
virtual void AddUndoAction( SfxUndoAction *pAction, bool bTryMerg=false ) override;
+ size_t GetUndoActionCount(const bool bCurrentLevel = true) const override;
+ size_t GetRedoActionCount(const bool bCurrentLevel = true) const override;
+ void SetViewShell(SfxViewShell* pViewShell);
/** Set or reset the undo manager linked with the called undo manager.
*/
@@ -47,6 +53,8 @@ private:
synchronize the undo managers.
*/
::svl::IUndoManager* mpLinkedUndoManager;
+ /// Return undo/redo info for this view.
+ SfxViewShell* mpViewShell;
/** Call ClearRedo() at the linked undo manager, when present.
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 93c67d9df12f..77f4ab196a47 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -69,6 +69,7 @@ public:
void testViewCursorParts();
void testCursorViews();
void testViewLock();
+ void testUndoLimiting();
CPPUNIT_TEST_SUITE(SdTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -93,6 +94,7 @@ public:
CPPUNIT_TEST(testViewCursorParts);
CPPUNIT_TEST(testCursorViews);
CPPUNIT_TEST(testViewLock);
+ CPPUNIT_TEST(testUndoLimiting);
CPPUNIT_TEST_SUITE_END();
private:
@@ -1067,6 +1069,43 @@ void SdTiledRenderingTest::testViewLock()
comphelper::LibreOfficeKit::setActive(false);
}
+void SdTiledRenderingTest::testUndoLimiting()
+{
+ comphelper::LibreOfficeKit::setActive();
+
+ // Create the first view.
+ SdXImpressDocument* pXImpressDocument = createDoc("title-shape.odp");
+ SfxViewShell& rViewShell1 = pXImpressDocument->GetDocShell()->GetViewShell()->GetViewShellBase();
+ SfxLokHelper::createView();
+ pXImpressDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+ SfxViewShell& rViewShell2 = pXImpressDocument->GetDocShell()->GetViewShell()->GetViewShellBase();
+
+ // Begin text edit on the only object on the slide.
+ sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
+ SdrView* pView = pViewShell->GetView();
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0);
+ pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT(pView->IsTextEdit());
+
+ // Now check what views see the undo action.
+ SdDrawDocument* pDocument = pXImpressDocument->GetDoc();
+ sd::UndoManager* pUndoManager = pDocument->GetUndoManager();
+ pUndoManager->SetViewShell(&rViewShell1);
+ // This was 1, undo action was visible to the first view, even if the
+ // action belongs to the second view.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pUndoManager->GetUndoActionCount());
+ pUndoManager->SetViewShell(&rViewShell2);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pUndoManager->GetUndoActionCount());
+ pUndoManager->SetViewShell(nullptr);
+
+ mxComponent->dispose();
+ mxComponent.clear();
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/core/undo/undomanager.cxx b/sd/source/core/undo/undomanager.cxx
index bbf2069ce75b..b0b9b68e52e9 100644
--- a/sd/source/core/undo/undomanager.cxx
+++ b/sd/source/core/undo/undomanager.cxx
@@ -17,6 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <comphelper/lok.hxx>
+#include <sfx2/viewsh.hxx>
#include <undo/undomanager.hxx>
using namespace sd;
@@ -24,6 +26,7 @@ using namespace sd;
UndoManager::UndoManager( sal_uInt16 nMaxUndoActionCount /* = 20 */ )
: SdrUndoManager( nMaxUndoActionCount )
, mpLinkedUndoManager(nullptr)
+ , mpViewShell(nullptr)
{
}
@@ -49,6 +52,53 @@ void UndoManager::AddUndoAction( SfxUndoAction *pAction, bool bTryMerg /* = sal_
}
}
+size_t UndoManager::GetUndoActionCount(const bool bCurrentLevel) const
+{
+ size_t nRet = SdrUndoManager::GetUndoActionCount(bCurrentLevel);
+ if (!comphelper::LibreOfficeKit::isActive() || !mpViewShell)
+ return nRet;
+
+ if (!nRet || !SdrUndoManager::GetUndoActionCount())
+ return nRet;
+
+ const SfxUndoAction* pAction = SdrUndoManager::GetUndoAction();
+ if (!pAction)
+ return nRet;
+
+ // If an other view created the last undo action, prevent undoing it from this view.
+ sal_Int32 nViewShellId = mpViewShell->GetViewShellId();
+ if (pAction->GetViewShellId() != nViewShellId)
+ nRet = 0;
+
+ return nRet;
+}
+
+size_t UndoManager::GetRedoActionCount(const bool bCurrentLevel) const
+{
+ size_t nRet = SdrUndoManager::GetRedoActionCount(bCurrentLevel);
+ if (!comphelper::LibreOfficeKit::isActive() || !mpViewShell)
+ return nRet;
+
+ if (!nRet || !SdrUndoManager::GetRedoActionCount())
+ return nRet;
+
+ const SfxUndoAction* pAction = SdrUndoManager::GetRedoAction();
+ if (!pAction)
+ return nRet;
+
+ // If an other view created the first redo action, prevent redoing it from this view.
+ sal_Int32 nViewShellId = mpViewShell->GetViewShellId();
+ if (pAction->GetViewShellId() != nViewShellId)
+ nRet = 0;
+
+ return nRet;
+}
+
+void UndoManager::SetViewShell(SfxViewShell* pViewShell)
+{
+ mpViewShell = pViewShell;
+}
+
void UndoManager::SetLinkedUndoManager (::svl::IUndoManager* pLinkedUndoManager)
{
mpLinkedUndoManager = pLinkedUndoManager;
diff --git a/sd/source/ui/view/viewshe3.cxx b/sd/source/ui/view/viewshe3.cxx
index a10aae8cf344..b9e09874adab 100644
--- a/sd/source/ui/view/viewshe3.cxx
+++ b/sd/source/ui/view/viewshe3.cxx
@@ -71,6 +71,7 @@
#include "framework/FrameworkHelper.hxx"
#include "optsitem.hxx"
#include "sdresid.hxx"
+#include "undo/undomanager.hxx"
#include <svx/svxids.hrc>
#include <sfx2/request.hxx>
@@ -130,10 +131,15 @@ void ViewShell::GetMenuState( SfxItemSet &rSet )
if(pUndoManager)
{
+ auto pSdUndoManager = dynamic_cast<sd::UndoManager*>(pUndoManager);
+ if (pSdUndoManager)
+ pSdUndoManager->SetViewShell(&GetViewShellBase());
if(pUndoManager->GetUndoActionCount() != 0)
{
bActivate = true;
}
+ if (pSdUndoManager)
+ pSdUndoManager->SetViewShell(nullptr);
}
if(bActivate)
@@ -157,10 +163,15 @@ void ViewShell::GetMenuState( SfxItemSet &rSet )
if(pUndoManager)
{
+ auto pSdUndoManager = dynamic_cast<sd::UndoManager*>(pUndoManager);
+ if (pSdUndoManager)
+ pSdUndoManager->SetViewShell(&GetViewShellBase());
if(pUndoManager->GetRedoActionCount() != 0)
{
bActivate = true;
}
+ if (pSdUndoManager)
+ pSdUndoManager->SetViewShell(nullptr);
}
if(bActivate)