diff options
author | Henry Castro <hcastro@collabora.com> | 2016-11-24 07:09:38 -0400 |
---|---|---|
committer | Henry Castro <hcastro@collabora.com> | 2016-11-28 02:26:23 +0000 |
commit | 2db42ab241d0852d89a470b18727c22d0fc06745 (patch) | |
tree | 40af961c0846fdd68a657938d5d1fd61f3c69024 | |
parent | e2d5f1ba3fd0db00276cf48b0d9be9b16dcbf7a0 (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.cxx | 8 | ||||
-rw-r--r-- | sw/inc/editsh.hxx | 1 | ||||
-rw-r--r-- | sw/inc/swundo.hxx | 3 | ||||
-rw-r--r-- | sw/qa/extras/tiledrendering/tiledrendering.cxx | 99 | ||||
-rw-r--r-- | sw/source/core/edit/edws.cxx | 3 | ||||
-rw-r--r-- | sw/source/core/undo/docundo.cxx | 12 | ||||
-rw-r--r-- | sw/source/uibase/shells/annotsh.cxx | 30 | ||||
-rw-r--r-- | sw/source/uibase/shells/basesh.cxx | 50 | ||||
-rw-r--r-- | sw/source/uibase/wrtsh/wrtundo.cxx | 2 |
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 } |