summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenry Castro <hcastro@collabora.com>2016-11-24 07:09:38 -0400
committerHenry Castro <hcastro@collabora.com>2016-11-28 02:26:23 +0000
commit2db42ab241d0852d89a470b18727c22d0fc06745 (patch)
tree40af961c0846fdd68a657938d5d1fd61f3c69024
parente2d5f1ba3fd0db00276cf48b0d9be9b16dcbf7a0 (diff)
sw lok: notify repair when exist a conflict of multiple users undo/redo
Change-Id: I026f4df6239fa87ee191f92127f9fa98ac2993eb Reviewed-on: https://gerrit.libreoffice.org/31161 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Henry Castro <hcastro@collabora.com>
-rw-r--r--desktop/source/lib/init.cxx8
-rw-r--r--sw/inc/editsh.hxx1
-rw-r--r--sw/inc/swundo.hxx3
-rw-r--r--sw/qa/extras/tiledrendering/tiledrendering.cxx99
-rw-r--r--sw/source/core/edit/edws.cxx3
-rw-r--r--sw/source/core/undo/docundo.cxx12
-rw-r--r--sw/source/uibase/shells/annotsh.cxx30
-rw-r--r--sw/source/uibase/shells/basesh.cxx50
-rw-r--r--sw/source/uibase/wrtsh/wrtundo.cxx2
9 files changed, 186 insertions, 22 deletions
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 2ecfddcecd88..fa3446e39b41 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -329,6 +329,11 @@ static boost::property_tree::ptree unoAnyToPropertyTree(const uno::Any& anyItem)
if (aType == "string")
aTree.put("value", anyItem.get<OUString>().toUtf8().getStr());
+ else if (aType == "unsigned long")
+ aTree.put("value", OString::number(anyItem.get<sal_uInt32>()).getStr());
+ else if (aType == "long")
+ aTree.put("value", OString::number(anyItem.get<sal_Int32>()).getStr());
+
// TODO: Add more as required
return aTree;
@@ -1806,8 +1811,7 @@ public:
aTree.put("success", bSuccess);
}
- // TODO UNO Any rEvent.Result -> JSON
- // aTree.put("result": "...");
+ aTree.add_child("result", unoAnyToPropertyTree(rEvent.Result));
std::stringstream aStream;
boost::property_tree::write_json(aStream, aTree);
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index 2bc0d307c915..c65d4e5df500 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -564,6 +564,7 @@ public:
SwUndoId *const o_pId,
const SwView* pView = nullptr) const;
bool GetFirstRedoInfo(OUString *const o_pStr,
+ SwUndoId *const o_pId,
const SwView* pView = nullptr) const;
SwUndoId GetRepeatInfo(OUString *const o_pStr) const;
diff --git a/sw/inc/swundo.hxx b/sw/inc/swundo.hxx
index e33ee7bd48d6..c87b5e57194b 100644
--- a/sw/inc/swundo.hxx
+++ b/sw/inc/swundo.hxx
@@ -171,7 +171,8 @@ enum SwUndoId
UNDO_UI_REPLACE_STYLE,
UNDO_UI_DELETE_PAGE_BREAK,
UNDO_UI_TEXT_CORRECTION,
- UNDO_UI_TABLE_DELETE
+ UNDO_UI_TABLE_DELETE,
+ UNDO_CONFLICT
};
#endif
diff --git a/sw/qa/extras/tiledrendering/tiledrendering.cxx b/sw/qa/extras/tiledrendering/tiledrendering.cxx
index 19a40665d2df..c9829f2a84a6 100644
--- a/sw/qa/extras/tiledrendering/tiledrendering.cxx
+++ b/sw/qa/extras/tiledrendering/tiledrendering.cxx
@@ -10,6 +10,7 @@
#include <string>
#include <boost/property_tree/json_parser.hpp>
+#include <com/sun/star/frame/DispatchResultState.hpp>
#include <swmodeltestbase.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <comphelper/dispatchcommand.hxx>
@@ -78,6 +79,9 @@ public:
void testCommentEndTextEdit();
void testCursorPosition();
void testPaintCallbacks();
+ void testUndoRepairResult();
+ void testRedoRepairResult();
+
CPPUNIT_TEST_SUITE(SwTiledRenderingTest);
CPPUNIT_TEST(testRegisterCallback);
@@ -120,6 +124,9 @@ public:
CPPUNIT_TEST(testCommentEndTextEdit);
CPPUNIT_TEST(testCursorPosition);
CPPUNIT_TEST(testPaintCallbacks);
+ CPPUNIT_TEST(testUndoRepairResult);
+ CPPUNIT_TEST(testRedoRepairResult);
+
CPPUNIT_TEST_SUITE_END();
private:
@@ -754,6 +761,30 @@ public:
}
};
+class TestResultListener : public cppu::WeakImplHelper<css::frame::XDispatchResultListener>
+{
+public:
+ sal_uInt32 m_nDocRepair;
+
+ TestResultListener() : m_nDocRepair(0)
+ {
+ }
+
+ virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& rEvent)
+ throw(css::uno::RuntimeException, std::exception) override
+ {
+ if (rEvent.State == frame::DispatchResultState::SUCCESS)
+ {
+ rEvent.Result >>= m_nDocRepair;
+ }
+ }
+
+ virtual void SAL_CALL disposing(const css::lang::EventObject&)
+ throw (css::uno::RuntimeException, std::exception) override
+ {
+ }
+};
+
void SwTiledRenderingTest::testMissingInvalidation()
{
comphelper::LibreOfficeKit::setActive();
@@ -1572,6 +1603,74 @@ void SwTiledRenderingTest::testPaintCallbacks()
comphelper::LibreOfficeKit::setActive(false);
}
+void SwTiledRenderingTest::testUndoRepairResult()
+{
+ // Load a document and create two views.
+ comphelper::LibreOfficeKit::setActive();
+ SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+ int nView1 = SfxLokHelper::getView();
+ SfxLokHelper::createView();
+ TestResultListener* pResult2 = new TestResultListener();
+ css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pResult2), css::uno::UNO_QUERY);
+ pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+ int nView2 = SfxLokHelper::getView();
+
+ // Insert a character in the second view.
+ SfxLokHelper::setView(nView2);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'b', 0);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'b', 0);
+
+ // Insert a character in the first view.
+ SfxLokHelper::setView(nView1);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'a', 0);
+
+ // Assert that by default the second view can't undo the action.
+ SfxLokHelper::setView(nView2);
+ comphelper::dispatchCommand(".uno:Undo", {}, xListener);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(UNDO_CONFLICT), pResult2->m_nDocRepair);
+
+ mxComponent->dispose();
+ mxComponent.clear();
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
+void SwTiledRenderingTest::testRedoRepairResult()
+{
+ // Load a document and create two views.
+ comphelper::LibreOfficeKit::setActive();
+ SwXTextDocument* pXTextDocument = createDoc("dummy.fodt");
+ int nView1 = SfxLokHelper::getView();
+ SfxLokHelper::createView();
+ TestResultListener* pResult2 = new TestResultListener();
+ css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pResult2), css::uno::UNO_QUERY);
+ pXTextDocument->initializeForTiledRendering(uno::Sequence<beans::PropertyValue>());
+ int nView2 = SfxLokHelper::getView();
+
+ // Insert a character in the second view.
+ SfxLokHelper::setView(nView2);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'b', 0);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'b', 0);
+
+ // Insert a character in the first view.
+ SfxLokHelper::setView(nView1);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 'a', 0);
+ pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 'a', 0);
+ comphelper::dispatchCommand(".uno:Undo", {}, xListener);
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(0), pResult2->m_nDocRepair);
+
+ // Assert that by default the second view can't redo the action.
+ SfxLokHelper::setView(nView2);
+ comphelper::dispatchCommand(".uno:Redo", {}, xListener);
+ Scheduler::ProcessEventsToIdle();
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_uInt32>(UNDO_CONFLICT), pResult2->m_nDocRepair);
+
+ mxComponent->dispose();
+ mxComponent.clear();
+ comphelper::LibreOfficeKit::setActive(false);
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwTiledRenderingTest);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/edit/edws.cxx b/sw/source/core/edit/edws.cxx
index 8cb0c59498cf..25c890628e11 100644
--- a/sw/source/core/edit/edws.cxx
+++ b/sw/source/core/edit/edws.cxx
@@ -229,9 +229,10 @@ bool SwEditShell::GetLastUndoInfo(OUString *const o_pStr,
}
bool SwEditShell::GetFirstRedoInfo(OUString *const o_pStr,
+ SwUndoId *const o_pId,
const SwView* pView) const
{
- return GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(o_pStr, nullptr, pView);
+ return GetDoc()->GetIDocumentUndoRedo().GetFirstRedoInfo(o_pStr, o_pId, pView);
}
SwUndoId SwEditShell::GetRepeatInfo(OUString *const o_pStr) const
diff --git a/sw/source/core/undo/docundo.cxx b/sw/source/core/undo/docundo.cxx
index 56c9e3aa9212..4d117dac50ae 100644
--- a/sw/source/core/undo/docundo.cxx
+++ b/sw/source/core/undo/docundo.cxx
@@ -372,7 +372,13 @@ UndoManager::GetLastUndoInfo(
// 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)
+ {
+ if (o_pId)
+ {
+ *o_pId = UNDO_CONFLICT;
+ }
return false;
+ }
}
if (o_pStr)
@@ -425,7 +431,13 @@ bool UndoManager::GetFirstRedoInfo(OUString *const o_pStr,
// 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)
+ {
+ if (o_pId)
+ {
+ *o_pId = UNDO_CONFLICT;
+ }
return false;
+ }
}
if (o_pStr)
diff --git a/sw/source/uibase/shells/annotsh.cxx b/sw/source/uibase/shells/annotsh.cxx
index dde917cf0c45..a012b2649793 100644
--- a/sw/source/uibase/shells/annotsh.cxx
+++ b/sw/source/uibase/shells/annotsh.cxx
@@ -1488,6 +1488,7 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq)
const SfxItemSet* pArgs = rReq.GetArgs();
::svl::IUndoManager* pUndoManager = GetUndoManager();
SwWrtShell &rSh = rView.GetWrtShell();
+ SwUndoId nUndoId(UNDO_EMPTY);
long aOldHeight = rView.GetPostItMgr()->HasActiveSidebarWin()
? rView.GetPostItMgr()->GetActiveSidebarWin()->GetPostItTextHeight()
@@ -1502,6 +1503,13 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq)
{
case SID_UNDO:
{
+ rSh.GetLastUndoInfo(nullptr, &nUndoId);
+ if (nUndoId == UNDO_CONFLICT)
+ {
+ rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(nUndoId)) );
+ break;
+ }
+
if ( pUndoManager )
{
sal_uInt16 nCount = pUndoManager->GetUndoActionCount();
@@ -1526,6 +1534,13 @@ void SwAnnotationShell::ExecUndo(SfxRequest &rReq)
case SID_REDO:
{
+ rSh.GetFirstRedoInfo(nullptr, &nUndoId);
+ if (nUndoId == UNDO_CONFLICT)
+ {
+ rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(nUndoId)) );
+ break;
+ }
+
if ( pUndoManager )
{
sal_uInt16 nCount = pUndoManager->GetRedoActionCount();
@@ -1562,6 +1577,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet)
return;
SfxWhichIter aIter(rSet);
+ SwUndoId nUndoId(UNDO_EMPTY);
sal_uInt16 nWhich = aIter.FirstWhich();
::svl::IUndoManager* pUndoManager = GetUndoManager();
SfxViewFrame *pSfxViewFrame = rView.GetViewFrame();
@@ -1576,10 +1592,14 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet)
sal_uInt16 nCount = pUndoManager ? pUndoManager->GetUndoActionCount() : 0;
if ( nCount )
pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet );
- else if (rSh.GetLastUndoInfo(nullptr, nullptr))
+ else if (rSh.GetLastUndoInfo(nullptr, &nUndoId))
{
rSet.Put( SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::UNDO)) );
}
+ else if (nUndoId == UNDO_CONFLICT)
+ {
+ rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) );
+ }
else
rSet.DisableItem(nWhich);
break;
@@ -1589,10 +1609,14 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet)
sal_uInt16 nCount = pUndoManager ? pUndoManager->GetRedoActionCount() : 0;
if ( nCount )
pSfxViewFrame->GetSlotState( nWhich, pSfxViewFrame->GetInterface(), &rSet );
- else if (rSh.GetFirstRedoInfo(nullptr))
+ else if (rSh.GetFirstRedoInfo(nullptr, &nUndoId))
{
rSet.Put(SfxStringItem( nWhich, rSh.GetDoString(SwWrtShell::REDO)) );
}
+ else if (nUndoId == UNDO_CONFLICT)
+ {
+ rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) );
+ }
else
rSet.DisableItem(nWhich);
break;
@@ -1630,7 +1654,7 @@ void SwAnnotationShell::StateUndo(SfxItemSet &rSet)
rSh.GetDoStrings( SwWrtShell::UNDO, aItem );
}
else if ((nWhich == SID_GETREDOSTRINGS) &&
- (rSh.GetFirstRedoInfo(nullptr)))
+ (rSh.GetFirstRedoInfo(nullptr, nullptr)))
{
rSh.GetDoStrings( SwWrtShell::UNDO, aItem );
}
diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx
index f7daef9602c6..3127b1f25beb 100644
--- a/sw/source/uibase/shells/basesh.cxx
+++ b/sw/source/uibase/shells/basesh.cxx
@@ -478,6 +478,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
{
SwWrtShell &rWrtShell = GetShell();
+ SwUndoId nUndoId(UNDO_EMPTY);
sal_uInt16 nId = rReq.GetSlot(), nCnt = 1;
const SfxItemSet* pArgs = rReq.GetArgs();
const SfxPoolItem* pItem;
@@ -504,19 +505,25 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
switch( nId )
{
case SID_UNDO:
- for (SwViewShell& rShell : rWrtShell.GetRingContainer())
- rShell.LockPaint();
- rWrtShell.Do( SwWrtShell::UNDO, nCnt );
- for (SwViewShell& rShell : rWrtShell.GetRingContainer())
- rShell.UnlockPaint();
+ if (rUndoRedo.GetLastUndoInfo(nullptr, &nUndoId, &rWrtShell.GetView()))
+ {
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.LockPaint();
+ rWrtShell.Do( SwWrtShell::UNDO, nCnt );
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.UnlockPaint();
+ }
break;
case SID_REDO:
- for (SwViewShell& rShell : rWrtShell.GetRingContainer())
- rShell.LockPaint();
- rWrtShell.Do( SwWrtShell::REDO, nCnt );
- for (SwViewShell& rShell : rWrtShell.GetRingContainer())
- rShell.UnlockPaint();
+ if (rUndoRedo.GetFirstRedoInfo(nullptr, &nUndoId, &rWrtShell.GetView()))
+ {
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.LockPaint();
+ rWrtShell.Do( SwWrtShell::REDO, nCnt );
+ for (SwViewShell& rShell : rWrtShell.GetRingContainer())
+ rShell.UnlockPaint();
+ }
break;
case SID_REPEAT:
@@ -526,6 +533,11 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
OSL_FAIL("wrong Dispatcher");
}
+ if (nUndoId == UNDO_CONFLICT)
+ {
+ rReq.SetReturnValue( SfxUInt32Item(nId, static_cast<sal_uInt32>(nUndoId)) );
+ }
+
if (pViewFrame) { pViewFrame->GetBindings().InvalidateAll(false); }
}
@@ -533,6 +545,7 @@ void SwBaseShell::ExecUndo(SfxRequest &rReq)
void SwBaseShell::StateUndo(SfxItemSet &rSet)
{
+ SwUndoId nUndoId(UNDO_EMPTY);
SwWrtShell &rSh = GetShell();
SfxWhichIter aIter(rSet);
sal_uInt16 nWhich = aIter.FirstWhich();
@@ -542,29 +555,38 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet)
{
case SID_UNDO:
{
- if (rSh.GetLastUndoInfo(nullptr, nullptr, &rSh.GetView()))
+ if (rSh.GetLastUndoInfo(nullptr, &nUndoId, &rSh.GetView()))
{
rSet.Put( SfxStringItem(nWhich,
rSh.GetDoString(SwWrtShell::UNDO)));
}
+ else if (nUndoId == UNDO_CONFLICT)
+ {
+ rSet.Put( SfxUInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) );
+ }
else
rSet.DisableItem(nWhich);
+
break;
}
case SID_REDO:
{
- if (rSh.GetFirstRedoInfo(nullptr, &rSh.GetView()))
+ if (rSh.GetFirstRedoInfo(nullptr, &nUndoId, &rSh.GetView()))
{
rSet.Put(SfxStringItem(nWhich,
rSh.GetDoString(SwWrtShell::REDO)));
}
+ else if (nUndoId == UNDO_CONFLICT)
+ {
+ rSet.Put( SfxInt32Item(nWhich, static_cast<sal_uInt32>(nUndoId)) );
+ }
else
rSet.DisableItem(nWhich);
break;
}
case SID_REPEAT:
{ // Repeat is only possible if no REDO is possible - UI-Restriction
- if ((!rSh.GetFirstRedoInfo(nullptr)) &&
+ if ((!rSh.GetFirstRedoInfo(nullptr, nullptr)) &&
!rSh.IsSelFrameMode() &&
(UNDO_EMPTY != rSh.GetRepeatInfo(nullptr)))
{
@@ -587,7 +609,7 @@ void SwBaseShell::StateUndo(SfxItemSet &rSet)
break;
case SID_GETREDOSTRINGS:
- if (rSh.GetFirstRedoInfo(nullptr))
+ if (rSh.GetFirstRedoInfo(nullptr, nullptr))
{
SfxStringListItem aStrLst( nWhich );
rSh.GetDoStrings( SwWrtShell::REDO, aStrLst );
diff --git a/sw/source/uibase/wrtsh/wrtundo.cxx b/sw/source/uibase/wrtsh/wrtundo.cxx
index 1260d8902b15..0e437bac5760 100644
--- a/sw/source/uibase/wrtsh/wrtundo.cxx
+++ b/sw/source/uibase/wrtsh/wrtundo.cxx
@@ -106,7 +106,7 @@ OUString SwWrtShell::GetDoString( DoType eDoType ) const
break;
case REDO:
nResStr = STR_REDO;
- (void)GetFirstRedoInfo(&aUndoStr, &m_rView);
+ (void)GetFirstRedoInfo(&aUndoStr, nullptr, &m_rView);
break;
default:;//prevent warning
}