summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/editsh.hxx3
-rw-r--r--sw/qa/core/edit/edit.cxx50
-rw-r--r--sw/source/core/edit/edredln.cxx68
-rw-r--r--sw/source/uibase/uiview/view2.cxx5
4 files changed, 122 insertions, 4 deletions
diff --git a/sw/inc/editsh.hxx b/sw/inc/editsh.hxx
index c9444a3e0f78..2e2c6b1f3c65 100644
--- a/sw/inc/editsh.hxx
+++ b/sw/inc/editsh.hxx
@@ -156,6 +156,8 @@ class SAL_DLLPUBLIC_RTTI SwEditShell : public SwCursorShell
void SetSectionAttr_( SwSectionFormat& rSectFormat, const SfxItemSet& rSet );
+ void ReinstatePaM(const SwRangeRedline& rRedline, SwPaM& rPaM);
+
using SwViewShell::UpdateFields;
using sw::BroadcastingModify::GetInfo;
@@ -960,6 +962,7 @@ public:
bool AcceptRedlinesInSelection();
bool RejectRedlinesInSelection();
void ReinstateRedline(SwRedlineTable::size_type nPos);
+ void ReinstateRedlinesInSelection();
/** Search Redline for this Data and @return position in array.
If not found, return SwRedlineTable::npos. */
diff --git a/sw/qa/core/edit/edit.cxx b/sw/qa/core/edit/edit.cxx
index 10705063a001..89d596d88989 100644
--- a/sw/qa/core/edit/edit.cxx
+++ b/sw/qa/core/edit/edit.cxx
@@ -117,6 +117,56 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlineReinstateSingleInsert)
CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rInnerRedlineData.GetType());
}
+CPPUNIT_TEST_FIXTURE(Test, testRedlineReinstateInsertsInSelection)
+{
+ // Given a document with two insertions:
+ createSwDoc();
+ SwWrtShell* pWrtShell = getSwDocShell()->GetWrtShell();
+ pWrtShell->Insert("aaa");
+ SwModule* pModule = SwModule::get();
+ pModule->SetRedlineAuthor("Alice");
+ RedlineFlags nMode = pWrtShell->GetRedlineFlags();
+ pWrtShell->SetRedlineFlags(nMode | RedlineFlags::On);
+ pWrtShell->Insert("bbb");
+ pWrtShell->SetRedlineFlags(nMode);
+ pWrtShell->Insert("ccc");
+ pWrtShell->SetRedlineFlags(nMode | RedlineFlags::On);
+ pWrtShell->Insert("ddd");
+ pWrtShell->SetRedlineFlags(nMode);
+ pWrtShell->Insert("eee");
+
+ // When a 2nd user reinstates those changes with a selection:
+ pModule->SetRedlineAuthor("Bob");
+ // Create a selection that excludes the initial "a" and the last "e":
+ pWrtShell->SttPara(/*bSelect=*/false);
+ pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/false, 1, /*bBasicCall=*/false);
+ pWrtShell->EndPara(/*bSelect=*/true);
+ pWrtShell->Left(SwCursorSkipMode::Chars, /*bSelect=*/true, 1, /*bBasicCall=*/false);
+ dispatchCommand(mxComponent, ".uno:ReinstateTrackedChange", {});
+
+ // Then make sure this results in deletes on top of inserts:
+ SwDoc* pDoc = pWrtShell->GetDoc();
+ IDocumentRedlineAccess& rIDRA = pDoc->getIDocumentRedlineAccess();
+ SwRedlineTable& rRedlines = rIDRA.GetRedlineTable();
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 2
+ // - Actual : 0
+ // i.e. a reject was performed instead of a reinstate.
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rRedlines.size());
+ const SwRangeRedline* pRedline1 = rRedlines[0];
+ const SwRedlineData& rRedlineData1 = pRedline1->GetRedlineData(0);
+ CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlineData1.GetType());
+ CPPUNIT_ASSERT(rRedlineData1.Next());
+ const SwRedlineData& rInnerRedlineData1 = *rRedlineData1.Next();
+ CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rInnerRedlineData1.GetType());
+ const SwRangeRedline* pRedline2 = rRedlines[1];
+ const SwRedlineData& rRedlineData2 = pRedline2->GetRedlineData(0);
+ CPPUNIT_ASSERT_EQUAL(RedlineType::Delete, rRedlineData2.GetType());
+ CPPUNIT_ASSERT(rRedlineData2.Next());
+ const SwRedlineData& rInnerRedlineData2 = *rRedlineData2.Next();
+ CPPUNIT_ASSERT_EQUAL(RedlineType::Insert, rInnerRedlineData2.GetType());
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/sw/source/core/edit/edredln.cxx b/sw/source/core/edit/edredln.cxx
index 8d992e56ddef..71bf47e60fc3 100644
--- a/sw/source/core/edit/edredln.cxx
+++ b/sw/source/core/edit/edredln.cxx
@@ -80,6 +80,14 @@ bool SwEditShell::AcceptRedline( SwRedlineTable::size_type nPos )
return bRet;
}
+void SwEditShell::ReinstatePaM(const SwRangeRedline& rRedline, SwPaM& rPaM)
+{
+ if (rRedline.GetType() == RedlineType::Insert)
+ {
+ DeleteSel(rPaM, /*isArtificialSelection=*/true);
+ }
+}
+
void SwEditShell::ReinstateRedline(SwRedlineTable::size_type nPos)
{
CurrShell aCurr(this);
@@ -95,10 +103,7 @@ void SwEditShell::ReinstateRedline(SwRedlineTable::size_type nPos)
SwPaM aPaM(*rRedline.GetPoint());
aPaM.SetMark();
*aPaM.GetMark() = *rRedline.GetMark();
- if (rRedline.GetType() == RedlineType::Insert)
- {
- DeleteSel(aPaM, /*isArtificialSelection=*/true);
- }
+ ReinstatePaM(rRedline, aPaM);
EndAllAction();
}
@@ -174,6 +179,61 @@ bool SwEditShell::RejectRedlinesInSelection()
return bRet;
}
+void SwEditShell::ReinstateRedlinesInSelection()
+{
+ CurrShell aCurr( this );
+ StartAllAction();
+ if (!IsRedlineOn())
+ {
+ RedlineFlags nMode = GetRedlineFlags();
+ SetRedlineFlags(nMode | RedlineFlags::On, /*bRecordAllViews=*/false);
+ }
+
+ SwPosition aCursorStart(*GetCursor()->Start());
+ SwPosition aCursorEnd(*GetCursor()->End());
+ SwRedlineTable& rTable = GetDoc()->getIDocumentRedlineAccess().GetRedlineTable();
+ for (size_t nIndex = 0; nIndex < rTable.size(); ++nIndex)
+ {
+ const SwRangeRedline& rRedline = *rTable[nIndex];
+ if (!rRedline.HasMark() || !rRedline.IsVisible())
+ {
+ continue;
+ }
+
+ if (*rRedline.End() < aCursorStart)
+ {
+ // Ends before the selection, skip to the next redline.
+ continue;
+ }
+
+ if (*rRedline.Start() > aCursorEnd)
+ {
+ // Starts after the selection, can stop.
+ break;
+ }
+
+ // Check if the redline is only partially selected.
+ const SwPosition* pStart = rRedline.Start();
+ if (*pStart < aCursorStart)
+ {
+ pStart = &aCursorStart;
+ }
+ const SwPosition* pEnd = rRedline.End();
+ if (*pEnd > aCursorEnd)
+ {
+ pEnd = &aCursorEnd;
+ }
+
+ // Process the (partially) selected redline.
+ SwPaM aPaM(*pEnd);
+ aPaM.SetMark();
+ *aPaM.GetMark() = *pStart;
+ ReinstatePaM(rRedline, aPaM);
+ }
+
+ EndAllAction();
+}
+
// Set the comment at the Redline
bool SwEditShell::SetRedlineComment( const OUString& rS )
{
diff --git a/sw/source/uibase/uiview/view2.cxx b/sw/source/uibase/uiview/view2.cxx
index 7dae30f73886..fe46ebea00be 100644
--- a/sw/source/uibase/uiview/view2.cxx
+++ b/sw/source/uibase/uiview/view2.cxx
@@ -910,6 +910,7 @@ void SwView::Execute(SfxRequest &rReq)
if( pCursor->HasMark() && nRedline == SwRedlineTable::npos)
{
bool bAccept = FN_REDLINE_ACCEPT_DIRECT == nSlot || FN_REDLINE_ACCEPT_TONEXT == nSlot;
+ bool bReinstate = nSlot == FN_REDLINE_REINSTATE_DIRECT;
SwUndoId eUndoId = bAccept ? SwUndoId::ACCEPT_REDLINE : SwUndoId::REJECT_REDLINE;
SwWrtShell& rSh = GetWrtShell();
SwRewriter aRewriter;
@@ -921,6 +922,10 @@ void SwView::Execute(SfxRequest &rReq)
}
if ( bAccept )
m_pWrtShell->AcceptRedlinesInSelection();
+ else if (bReinstate)
+ {
+ m_pWrtShell->ReinstateRedlinesInSelection();
+ }
else
m_pWrtShell->RejectRedlinesInSelection();
if ( bTableSelection )