sw/qa/extras/uiwriter/uiwriter6.cxx | 43 ++++++++++ sw/source/core/doc/DocumentContentOperationsManager.cxx | 68 ++++++++++++---- 2 files changed, 96 insertions(+), 15 deletions(-)
New commits: commit 4cf8de89bad9143a5b2dd3d6351080bf62b76029 Author: László Németh <nem...@numbertext.org> AuthorDate: Tue Oct 31 15:51:09 2023 +0100 Commit: László Németh <nem...@numbertext.org> CommitDate: Tue Oct 31 23:07:01 2023 +0100 tdf#157667 sw track changes: fix cycle case on multiple words Fix tracked cycle case on multiple selected words. Follow up to commit dc748d7dbd114fbf663752258dbaf003af2926c3 "tdf#141198 sw: fix cycle case with change tracking" and commit 79435eb55ef226fb0e3507aabdc2f8af062680f6 "tdf#157988 sw track changes: fix cycle case on a selected word". Change-Id: I81566f8be0cf6f4af6ed4af031116bd19e3884d7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158732 Tested-by: Jenkins Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/sw/qa/extras/uiwriter/uiwriter6.cxx b/sw/qa/extras/uiwriter/uiwriter6.cxx index 83bc43f6d866..8e6b91043b0b 100644 --- a/sw/qa/extras/uiwriter/uiwriter6.cxx +++ b/sw/qa/extras/uiwriter/uiwriter6.cxx @@ -759,6 +759,49 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf157988) CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer sodales tincidunt")); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf157667) +{ + createSwDoc("tdf130088.docx"); + SwDoc* pDoc = getSwDoc(); + SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell(); + + // select the first three words + pWrtShell->Right(SwCursorSkipMode::Chars, /*bSelect=*/true, 25, /*bBasicCall=*/false); + + // enable redlining + dispatchCommand(mxComponent, ".uno:TrackChanges", {}); + CPPUNIT_ASSERT_MESSAGE("redlining should be on", + pDoc->getIDocumentRedlineAccess().IsRedlineOn()); + + // show changes + CPPUNIT_ASSERT_MESSAGE( + "redlines should be visible", + IDocumentRedlineAccess::IsShowChanges(pDoc->getIDocumentRedlineAccess().GetRedlineFlags())); + + // cycle case with change tracking + + dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {}); + + CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith( + "Integer sodalesSodales tinciduntTincidunt tristique.")); + + dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {}); + + // This was false (missing revert of the tracked change) + CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer sodales tincidunt tristique.")); + + dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {}); + + CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith( + "Integer sodalesINTEGER SODALES tincidunt tristique.")); + + dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {}); + dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {}); + dispatchCommand(mxComponent, ".uno:ChangeCaseRotateCase", {}); + + CPPUNIT_ASSERT(getParagraph(1)->getString().startsWith("Integer sodales tincidunt tristique.")); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest6, testTdf108048) { createSwDoc(); diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 54b29b9b766c..d51565c5eaee 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -2984,7 +2984,8 @@ void DocumentContentOperationsManager::TransliterateText( sal_Int32 nEndCnt = pEnd->GetContentIndex(); SwTextNode* pTNd = pStt->GetNode().GetTextNode(); - if( (pStt == pEnd) && pTNd ) // no selection? + bool bNoSelection = (pStt == pEnd) && pTNd; // no selection? + if ( bNoSelection ) { /* Check if cursor is inside of a word */ assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is()); @@ -3061,27 +3062,52 @@ void DocumentContentOperationsManager::TransliterateText( rIDRA.GetRedlineTable().FindAtPosition( aPos, n ); if ( pFnd && RedlineType::Insert == pFnd->GetType() && n > 0 ) { - const SwRangeRedline* pFnd2 = rIDRA.GetRedlineTable()[n-1]; - if ( RedlineType::Delete == pFnd2->GetType() && - m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell() && - *pFnd2->End() == *pFnd->Start() && - pFnd->GetAuthor() == pFnd2->GetAuthor() ) + SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>( + m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell()); + + sal_Int32 nRejectedCharacters = 0; + SwRangeRedline* pFnd2 = rIDRA.GetRedlineTable()[--n]; + // loop on all redlines of a case changing, and reject them + while ( ( ( RedlineType::Insert == pFnd->GetType() && + RedlineType::Delete == pFnd2->GetType() ) || + ( RedlineType::Delete == pFnd->GetType() && + RedlineType::Insert == pFnd2->GetType() ) ) && + pWrtShell && + // use time stamp to recognize the multiple selections in the text, + // not only the changes from the same author within the (sometimes + // incomplete) selection + ( pFnd2->GetTimeStamp() == pFnd->GetTimeStamp() || + ( pStt->GetContentNode() < pFnd2->Start()->GetContentNode() || + ( pStt->GetContentNode() == pFnd2->Start()->GetContentNode() && + nSttCnt <= pFnd2->Start()->GetContentIndex() ) ) ) && + pFnd->GetAuthor() == pFnd2->GetAuthor() ) { bHasTrackedChange = true; - SwPosition aPos2(*pFnd2->Start()); + + if ( RedlineType::Insert == pFnd->GetType() ) + nRejectedCharacters += pFnd->GetText().getLength(); + rIDRA.RejectRedline(*pFnd, true); - rIDRA.RejectRedline(*pFnd2, true); - // positionate the text cursor before the changed word to select it - if ( SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>( - m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell()) ) - { - pWrtShell->GetCursor()->GetPoint()-> - Assign(*aPos2.GetContentNode(), aPos2.GetContentIndex()); - } + pFnd = pFnd2; + if ( n == 0 ) + break; + pFnd2 = rIDRA.GetRedlineTable()[--n]; + } + + // remove the last item and restore the original selection + if ( bHasTrackedChange ) + { + pWrtShell->GetCursor()->GetPoint()-> + Assign(*rPaM.Start()->GetContentNode(), nSttCnt); + pWrtShell->GetCursor()->GetMark()-> + Assign(*rPaM.End()->GetContentNode(), nEndCnt - nRejectedCharacters); + rIDRA.RejectRedline(*pFnd, true); } } } + + // TODO handle title case to lowercase if ( bHasTrackedChange ) return; } @@ -3163,6 +3189,18 @@ void DocumentContentOperationsManager::TransliterateText( { m_rDoc.GetIDocumentUndoRedo().AppendUndo(std::move(pUndo)); } + + // restore selection after tracked changes + if ( !bNoSelection && bUseRedlining ) + { + if ( SwWrtShell *pWrtShell = dynamic_cast<SwWrtShell*>( + m_rDoc.getIDocumentLayoutAccess().GetCurrentViewShell()) ) + { + *pWrtShell->GetCursor()->GetMark() = *pWrtShell->GetCursor()->End(); + pWrtShell->GetCursor()->GetPoint()->Assign(*pStt->GetContentNode(), nSttCnt); + } + } + m_rDoc.getIDocumentState().SetModified(); }