diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-08-17 07:53:16 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-08-17 07:53:49 +0200 |
commit | e0a3269183bf145511361a3968dca07824923dd4 (patch) | |
tree | cae911ea3fa01fc6be867fdc3e0461fe532b5f57 /sd | |
parent | f36406bf441704d8904f860d81774f0f89ab270a (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
Diffstat (limited to 'sd')
-rw-r--r-- | sd/inc/undo/undomanager.hxx | 10 | ||||
-rw-r--r-- | sd/qa/unit/tiledrendering/tiledrendering.cxx | 39 | ||||
-rw-r--r-- | sd/source/core/undo/undomanager.cxx | 50 | ||||
-rw-r--r-- | sd/source/ui/view/viewshe3.cxx | 11 |
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 391366aaa09f..b5de22266b72 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: @@ -1071,6 +1073,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 a23c752b5670..dbf6037a3165 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> @@ -128,10 +129,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) @@ -155,10 +161,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) |