summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-08-15 17:27:45 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-08-16 11:49:20 +0200
commit7b8c4aa152e89e00f706906cbd5c40099749554b (patch)
tree317f123de08c3d3102ca848262b99ef1ce00148e
parent89206e27368249985f05957e833a20f03a945221 (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 (cherry picked from commit 40231526b6a0d6d8713932b3ae60d665f615833c)
-rw-r--r--sw/inc/IDocumentUndoRedo.hxx8
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx34
-rw-r--r--sw/source/core/inc/UndoManager.hxx4
-rw-r--r--sw/source/core/undo/docundo.cxx52
-rw-r--r--sw/source/uibase/shells/drwtxtsh.cxx11
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 a51d0c8919f2..72f6f1c3bcef 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -62,6 +62,7 @@ public:
void testTextEditViewInvalidations();
void testUndoInvalidations();
void testUndoLimiting();
+ void testUndoShapeLimiting();
void testUndoDispatch();
void testUndoRepairDispatch();
void testShapeTextUndoShells();
@@ -92,6 +93,7 @@ public:
CPPUNIT_TEST(testTextEditViewInvalidations);
CPPUNIT_TEST(testUndoInvalidations);
CPPUNIT_TEST(testUndoLimiting);
+ CPPUNIT_TEST(testUndoShapeLimiting);
CPPUNIT_TEST(testUndoDispatch);
CPPUNIT_TEST(testUndoRepairDispatch);
CPPUNIT_TEST(testShapeTextUndoShells);
@@ -928,6 +930,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 943de4b20219..18669a52b952 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 6072b7ef53dc..33edba6214cc 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();