summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-08-09 18:13:37 +0200
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-08-09 16:44:27 +0000
commit5d8639aaf2f60157c99c3ee3a8bfa78e4efd010a (patch)
treefc3e431ce0398bff382ff792a97e0588a8ca31b0 /sw
parente328cab3c987a057411264209d1393440504a2cd (diff)
sw lok: limit undo/redo access to undo actions created by the same view
So one view can't undo the changes of an other view by accident. If this is found to be useful in the desktop case, perhaps a dedicated config option can be added for it; for now the behavior is LOK-only. Change-Id: I7ff505d021bd6f6be36953ecc8f8bb971ce8927e Reviewed-on: https://gerrit.libreoffice.org/28007 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Jenkins <ci@libreoffice.org>
Diffstat (limited to 'sw')
-rw-r--r--sw/inc/IDocumentUndoRedo.hxx9
-rw-r--r--sw/inc/editsh.hxx7
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx28
-rw-r--r--sw/source/core/edit/edws.cxx14
-rw-r--r--sw/source/core/inc/UndoManager.hxx6
-rw-r--r--sw/source/core/undo/docundo.cxx22
-rw-r--r--sw/source/uibase/shells/basesh.cxx4
-rw-r--r--sw/source/uibase/wrtsh/wrtundo.cxx4
8 files changed, 78 insertions, 16 deletions
diff --git a/sw/inc/IDocumentUndoRedo.hxx b/sw/inc/IDocumentUndoRedo.hxx
index d30d4c3aa5a3..6c044f618a5b 100644
--- a/sw/inc/IDocumentUndoRedo.hxx
+++ b/sw/inc/IDocumentUndoRedo.hxx
@@ -27,6 +27,7 @@
class SwRewriter;
class SwNodes;
class SwUndo;
+class SwView;
namespace sw {
class RepeatContext;
@@ -135,10 +136,12 @@ public:
/** Get Id and comment of last Undo action.
@param o_pStr if not 0, receives comment of last Undo action.
@param o_pId if not 0, receives Id of last Undo action.
+ @param pView if not nullptr, get the info for this view
@return true if there is a Undo action, false if none
*/
virtual bool GetLastUndoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId) const = 0;
+ SwUndoId *const o_pId,
+ const SwView* pView = nullptr) const = 0;
/** Get comments of Undo actions.
@return comments of all top-level Undo actions.
@@ -154,10 +157,12 @@ public:
/** Get Id and comment of first Redo action.
@param o_pStr if not 0, receives comment of first Redo action.
@param o_pId if not 0, receives Id of first Redo action.
+ @param pView if not nullptr, get the info for this view
@return true if there is a Redo action, false if none
*/
virtual bool GetFirstRedoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId = nullptr) const = 0;
+ SwUndoId *const o_pId = nullptr,
+ const SwView* pView = nullptr) const = 0;
/** Get comments of Redo actions.
@return comments of all top-level Redo actions.
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 47afea423e08..619ac2d4cf1e 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -97,6 +97,7 @@ class SwEndNoteInfo;
class SwLineNumberInfo;
class SwAuthEntry;
class SwRewriter;
+class SwView;
struct SwConversionArgs;
enum class SvtScriptType;
enum class SfxClassificationPolicyType;
@@ -558,8 +559,10 @@ public:
SwUndoId EndUndo( SwUndoId eUndoId = UNDO_EMPTY, const SwRewriter * pRewriter = nullptr );
bool GetLastUndoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId) const;
- bool GetFirstRedoInfo(OUString *const o_pStr) const;
+ SwUndoId *const o_pId,
+ const SwView* pView = nullptr) const;
+ bool GetFirstRedoInfo(OUString *const o_pStr,
+ const SwView* pView = nullptr) const;
SwUndoId GetRepeatInfo(OUString *const o_pStr) const;
/// is it forbidden to modify cursors via API calls?
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index b2b97bd0f064..766268285747 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -60,6 +60,7 @@ public:
void testViewLock();
void testTextEditViewInvalidations();
void testUndoInvalidations();
+ void testUndoLimiting();
void testShapeTextUndoShells();
void testShapeTextUndoGroupShells();
@@ -87,6 +88,7 @@ public:
CPPUNIT_TEST(testViewLock);
CPPUNIT_TEST(testTextEditViewInvalidations);
CPPUNIT_TEST(testUndoInvalidations);
+ CPPUNIT_TEST(testUndoLimiting);
CPPUNIT_TEST(testShapeTextUndoShells);
CPPUNIT_TEST(testShapeTextUndoGroupShells);
CPPUNIT_TEST_SUITE_END();
@@ -868,10 +870,12 @@ void SwTiledRenderingTest::testUndoInvalidations()
SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
ViewCallback aView1;
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView1);
+ int nView1 = SfxLokHelper::getView();
SfxLokHelper::createView();
pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
ViewCallback aView2;
SfxViewShell::Current()->registerLibreOfficeKitViewCallback(&ViewCallback::callback, &aView2);
+ SfxLokHelper::setView(nView1);
// Insert a character the end of the document.
SwWrtShell* pWrtShell = pXTextDocument->GetDocShell()->GetWrtShell();
@@ -895,6 +899,30 @@ void SwTiledRenderingTest::testUndoInvalidations()
comphelper::LibreOfficeKit::setActive(false);
}
+void SwTiledRenderingTest::testUndoLimiting()
+{
+ // Load a document and create two views.
+ comphelper::LibreOfficeKit::setActive();
+ SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+ SwWrtShell* pWrtShell1 = pXTextDocument->GetDocShell()->GetWrtShell();
+ SfxLokHelper::createView();
+ pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+
+ // Insert a character the end of the document in the second view.
+ SwWrtShell* pWrtShell2 = pXTextDocument->GetDocShell()->GetWrtShell();
+ pWrtShell2->EndDoc();
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'c', 0);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'c', 0);
+ SwShellCursor* pShellCursor = pWrtShell2->getShellCursor(false);
+ CPPUNIT_ASSERT_EQUAL(OUString("Aaa bbb.c"), pShellCursor->GetPoint()->nNode.GetNode().GetTextNode()->GetText());
+
+ // Assert that the first view can't undo, but the second view can.
+ CPPUNIT_ASSERT(!pWrtShell1->GetLastUndoInfo(nullptr, nullptr, &pWrtShell1->GetView()));
+ CPPUNIT_ASSERT(pWrtShell2->GetLastUndoInfo(nullptr, nullptr, &pWrtShell2->GetView()));
+
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
void SwTiledRenderingTest::testShapeTextUndoShells()
{
// Load a document and create a view.
diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx
index ae5c6815bdf1..6c9ac8689a8a 100644
--- a/sw/source/core/edit/edws.cxx
+++ b/sw/source/core/edit/edws.cxx
@@ -224,11 +224,17 @@ SwUndoId SwEditShell::EndUndo(SwUndoId eUndoId, const SwRewriter *pRewriter)
{ return GetDoc()->GetIDocumentUndoRedo().EndUndo(eUndoId, pRewriter); }
bool SwEditShell::GetLastUndoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId) const
-{ return GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(o_pStr, o_pId); }
+ SwUndoId *const o_pId,
+ const SwView* pView) const
+{
+ return GetDoc()->GetIDocumentUndoRedo().GetLastUndoInfo(o_pStr, o_pId, pView);
+}
-bool SwEditShell::GetFirstRedoInfo(OUString *const o_pStr) const
-{ return GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(o_pStr); }
+bool SwEditShell::GetFirstRedoInfo(OUString *const o_pStr,
+ const SwView* pView) const
+{
+ return GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(o_pStr, nullptr, pView);
+}
SwUndoId SwEditShell::GetRepeatInfo(OUString *const o_pStr) const
{ return GetDoc()->GetIDocumentUndoRedo().GetRepeatInfo(o_pStr); }
diff --git a/sw/source/core/inc/UndoManager.hxx b/sw/source/core/inc/UndoManager.hxx
index 68774c47d003..5092e95a34ab 100644
--- a/sw/source/core/inc/UndoManager.hxx
+++ b/sw/source/core/inc/UndoManager.hxx
@@ -61,10 +61,12 @@ public:
SwRewriter const*const pRewriter) override;
virtual void DelAllUndoObj() override;
virtual bool GetLastUndoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId) const override;
+ SwUndoId *const o_pId,
+ const SwView* pView = nullptr) const override;
virtual SwUndoComments_t GetUndoComments() const override;
virtual bool GetFirstRedoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId = nullptr) const override;
+ SwUndoId *const o_pId = nullptr,
+ const SwView* pView = nullptr) const override;
virtual SwUndoComments_t GetRedoComments() const override;
virtual bool Repeat(::sw::RepeatContext & rContext,
sal_uInt16 const nRepeatCnt) override;
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
index 9f70fa0d1768..ba4aeff8d575 100644
--- a/sw/source/core/undo/docundo.cxx
+++ b/sw/source/core/undo/docundo.cxx
@@ -39,6 +39,7 @@
#include <IDocumentDrawModelAccess.hxx>
#include <IDocumentRedlineAccess.hxx>
#include <IDocumentState.hxx>
+#include <comphelper/lok.hxx>
using namespace ::com::sun::star;
@@ -296,7 +297,7 @@ UndoManager::EndUndo(SwUndoId const i_eUndoId, SwRewriter const*const pRewriter)
bool
UndoManager::GetLastUndoInfo(
- OUString *const o_pStr, SwUndoId *const o_pId) const
+ OUString *const o_pStr, SwUndoId *const o_pId, const SwView* pView) const
{
// this is actually expected to work on the current level,
// but that was really not obvious from the previous implementation...
@@ -307,6 +308,14 @@ UndoManager::GetLastUndoInfo(
SfxUndoAction *const pAction( SdrUndoManager::GetUndoAction() );
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // If an other view created the undo action, prevent undoing it from this view.
+ sal_Int32 nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId();
+ if (pAction->GetViewShellId() != nViewShellId)
+ return false;
+ }
+
if (o_pStr)
{
*o_pStr = pAction->GetComment();
@@ -338,7 +347,8 @@ SwUndoComments_t UndoManager::GetUndoComments() const
}
bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr,
- SwUndoId *const o_pId) const
+ SwUndoId *const o_pId,
+ const SwView* pView) const
{
if (!SdrUndoManager::GetRedoActionCount())
{
@@ -351,6 +361,14 @@ bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr,
return false;
}
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ // If an other view created the undo action, prevent redoing it from this view.
+ sal_Int32 nViewShellId = pView ? pView->GetViewShellId() : m_pDocShell->GetView()->GetViewShellId();
+ if (pAction->GetViewShellId() != nViewShellId)
+ return false;
+ }
+
if (o_pStr)
{
*o_pStr = pAction->GetComment();
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index fc2bfb1d963b..6f802bed355f 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -527,7 +527,7 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet)
{
case SID_UNDO:
{
- if (rSh.GetLastUndoInfo(nullptr, nullptr))
+ if (rSh.GetLastUndoInfo(nullptr, nullptr, &rSh.GetView()))
{
rSet.Put( SfxStringItem(nWhich,
rSh.GetDoString(SwWrtShell::UNDO)));
@@ -538,7 +538,7 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet)
}
case SID_REDO:
{
- if (rSh.GetFirstRedoInfo(nullptr))
+ if (rSh.GetFirstRedoInfo(nullptr, &rSh.GetView()))
{
rSet.Put(SfxStringItem(nWhich,
rSh.GetDoString(SwWrtShell::REDO)));
diff --git a/sw/source/uibase/wrtsh/wrtundo.cxx b/sw/source/uibase/wrtsh/wrtundo.cxx
index ea1c37e32783..1260d8902b15 100644
--- a/sw/source/uibase/wrtsh/wrtundo.cxx
+++ b/sw/source/uibase/wrtsh/wrtundo.cxx
@@ -102,11 +102,11 @@ OUString SwWrtShell::GetDoString( DoType eDoType ) const
{
case UNDO:
nResStr = STR_UNDO;
- (void)GetLastUndoInfo(&aUndoStr, nullptr);
+ (void)GetLastUndoInfo(&aUndoStr, nullptr, &m_rView);
break;
case REDO:
nResStr = STR_REDO;
- (void)GetFirstRedoInfo(&aUndoStr);
+ (void)GetFirstRedoInfo(&aUndoStr, &m_rView);
break;
default:;//prevent warning
}