diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-08-15 17:27:45 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-08-15 20:00:56 +0200 |
commit | 40231526b6a0d6d8713932b3ae60d665f615833c (patch) | |
tree | 973dc78c6ff6935a02efb1ea252b9b0060a4862a | |
parent | bf882eb5719ed1d1119a1ec8f2f7cad32af39322 (diff) |
sw lok: limit undo/redo in SwDrawTextShell
So that one view can only undo/redo its own changes. This is used when
editing shape text, as that doesn't use
sw::UndoManager::GetLastUndoInfo().
Change-Id: Ibc3d6fcbd18398569190f06ed9b7399c54bb7d41
-rw-r--r-- | sw/inc/IDocumentUndoRedo.hxx | 8 | ||||
-rw-r--r-- | sw/qa/extras/tiledrendering/tiledrendering.cxx | 34 | ||||
-rw-r--r-- | sw/source/core/inc/UndoManager.hxx | 4 | ||||
-rw-r--r-- | sw/source/core/undo/docundo.cxx | 52 | ||||
-rw-r--r-- | sw/source/uibase/shells/drwtxtsh.cxx | 11 |
5 files changed, 106 insertions, 3 deletions
diff --git a/sw/inc/IDocumentUndoRedo.hxx b/sw/inc/IDocumentUndoRedo.hxx index 2266f3018afc..15e3d0aa7842 100644 --- a/sw/inc/IDocumentUndoRedo.hxx +++ b/sw/inc/IDocumentUndoRedo.hxx @@ -207,6 +207,14 @@ public: */ virtual size_t GetUndoActionCount(const bool bCurrentLevel = true) const = 0; + /** Get the number of Redo actions. + */ + virtual size_t GetRedoActionCount(const bool bCurrentLevel = true) const = 0; + + /** Return undo/redo info for this view. + */ + virtual void SetView(SwView* pView) = 0; + protected: virtual ~IDocumentUndoRedo() {}; }; diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx index 504de6c5321f..c568ddf3c9ca 100644 --- a/sw/qa/extras/tiledrendering/tiledrendering.cxx +++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx @@ -61,6 +61,7 @@ public: void testTextEditViewInvalidations(); void testUndoInvalidations(); void testUndoLimiting(); + void testUndoShapeLimiting(); void testUndoDispatch(); void testUndoRepairDispatch(); void testShapeTextUndoShells(); @@ -91,6 +92,7 @@ public: CPPUNIT_TEST(testTextEditViewInvalidations); CPPUNIT_TEST(testUndoInvalidations); CPPUNIT_TEST(testUndoLimiting); + CPPUNIT_TEST(testUndoShapeLimiting); CPPUNIT_TEST(testUndoDispatch); CPPUNIT_TEST(testUndoRepairDispatch); CPPUNIT_TEST(testShapeTextUndoShells); @@ -927,6 +929,38 @@ void SwTiledRenderingTest::testUndoLimiting() comphelper::LibreOfficeKit::setActive(false); } +void SwTiledRenderingTest::testUndoShapeLimiting() +{ + // Load a document and create a view. + comphelper::LibreOfficeKit::setActive(); + SwXTextDocument* pXTextDocument = createDoc("shape.fodt"); + SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell(); + SfxLokHelper::createView(); + pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>()); + SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell(); + + // Start shape text in the second view. + SdrPage* pPage = pWrtShell2->GetDoc()->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + SdrObject* pObject = pPage->GetObj(0); + SdrView* pView = pWrtShell2->GetDrawView(); + pWrtShell2->GetView().BeginTextEdit(pObject, pView->GetSdrPageView(), pWrtShell2->GetWin()); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'x', 0); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'x', 0); + + // Assert that the first view can't and the second view can undo the insertion. + SwDoc* pDoc = pXTextDocument->GetDocShell()->GetDoc(); + sw::UndoManager& rUndoManager = pDoc->GetUndoManager(); + rUndoManager.SetView(&pWrtShell1->GetView()); + // This was 1: first view could undo the change of the second view. + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rUndoManager.GetUndoActionCount()); + rUndoManager.SetView(&pWrtShell2->GetView()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), rUndoManager.GetUndoActionCount()); + + pWrtShell2->EndTextEdit(); + rUndoManager.SetView(nullptr); + comphelper::LibreOfficeKit::setActive(false); +} + void SwTiledRenderingTest::testUndoDispatch() { // Load a document and create two views. diff --git a/sw/source/core/inc/UndoManager.hxx b/sw/source/core/inc/UndoManager.hxx index 00132625bdcd..b81dabcfe32a 100644 --- a/sw/source/core/inc/UndoManager.hxx +++ b/sw/source/core/inc/UndoManager.hxx @@ -29,6 +29,7 @@ class IDocumentDrawModelAccess; class IDocumentRedlineAccess; class IDocumentState; class SwDocShell; +class SwView; namespace sw { @@ -77,6 +78,8 @@ public: virtual void ClearRedo() override; virtual bool IsUndoNodes(SwNodes const& rNodes) const override; virtual size_t GetUndoActionCount(const bool bCurrentLevel = true) const override; + size_t GetRedoActionCount(const bool bCurrentLevel = true) const override; + void SetView(SwView* pView) override; // ::svl::IUndoManager virtual void AddUndoAction(SfxUndoAction *pAction, @@ -108,6 +111,7 @@ private: /// position in Undo-Array at which Doc was saved (and is not modified) UndoStackMark m_UndoSaveMark; SwDocShell* m_pDocShell; + SwView* m_pView; typedef enum { UNDO = int(true), REDO = int(false) } UndoOrRedo_t; bool impl_DoUndoRedo(UndoOrRedo_t const undoOrRedo); diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx index 127d92827b1e..f7bb4d0e776a 100644 --- a/sw/source/core/undo/docundo.cxx +++ b/sw/source/core/undo/docundo.cxx @@ -61,6 +61,8 @@ UndoManager::UndoManager(std::shared_ptr<SwNodes> xUndoNodes, , m_bRepair(false) , m_bLockUndoNoModifiedPosition(false) , m_UndoSaveMark(MARK_INVALID) + , m_pDocShell(nullptr) + , m_pView(nullptr) { OSL_ASSERT(m_xUndoNodes.get()); // writer expects it to be disabled initially @@ -88,9 +90,57 @@ void UndoManager::SetDocShell(SwDocShell* pDocShell) m_pDocShell = pDocShell; } +void UndoManager::SetView(SwView* pView) +{ + m_pView = pView; +} + size_t UndoManager::GetUndoActionCount(const bool bCurrentLevel) const { - return SdrUndoManager::GetUndoActionCount(bCurrentLevel); + size_t nRet = SdrUndoManager::GetUndoActionCount(bCurrentLevel); + if (!comphelper::LibreOfficeKit::isActive() || !m_pView) + return nRet; + + if (!nRet || !SdrUndoManager::GetUndoActionCount()) + return nRet; + + const SfxUndoAction* pAction = SdrUndoManager::GetUndoAction(); + if (!pAction) + return nRet; + + if (!m_bRepair) + { + // If an other view created the last undo action, prevent undoing it from this view. + sal_Int32 nViewShellId = m_pView->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() || !m_pView) + return nRet; + + if (!nRet || !SdrUndoManager::GetRedoActionCount()) + return nRet; + + const SfxUndoAction* pAction = SdrUndoManager::GetRedoAction(); + if (!pAction) + return nRet; + + if (m_pView && !m_bRepair) + { + // If an other view created the first redo action, prevent redoing it from this view. + sal_Int32 nViewShellId = m_pView->GetViewShellId(); + if (pAction->GetViewShellId() != nViewShellId) + nRet = 0; + } + + return nRet; } void UndoManager::DoUndo(bool const bDoUndo) diff --git a/sw/source/uibase/shells/drwtxtsh.cxx b/sw/source/uibase/shells/drwtxtsh.cxx index 9905653d81b2..e9f10ba08f12 100644 --- a/sw/source/uibase/shells/drwtxtsh.cxx +++ b/sw/source/uibase/shells/drwtxtsh.cxx @@ -74,6 +74,7 @@ #include <comphelper/processfactory.hxx> #include "swabstdlg.hxx" #include "misc.hrc" +#include "IDocumentUndoRedo.hxx" #include <memory> using namespace ::com::sun::star; @@ -606,8 +607,14 @@ void SwDrawTextShell::StateUndo(SfxItemSet &rSet) break; default: - pSfxViewFrame->GetSlotState( nWhich, - pSfxViewFrame->GetInterface(), &rSet ); + { + auto* pUndoManager = dynamic_cast<IDocumentUndoRedo*>(GetUndoManager()); + if (pUndoManager) + pUndoManager->SetView(&GetView()); + pSfxViewFrame->GetSlotState(nWhich, pSfxViewFrame->GetInterface(), &rSet); + if (pUndoManager) + pUndoManager->SetView(nullptr); + } } nWhich = aIter.NextWhich(); |