diff --git a/sw/qa/core/text/data/redline-move.docx b/sw/qa/core/text/data/redline-move.docx new file mode 100644 index 000000000000..7377bed2f299 Binary files /dev/null and b/sw/qa/core/text/data/redline-move.docx differ diff --git a/sw/qa/core/text/itrpaint.cxx b/sw/qa/core/text/itrpaint.cxx index b5debdfa8f83..710f359ac0fc 100644 --- a/sw/qa/core/text/itrpaint.cxx +++ b/sw/qa/core/text/itrpaint.cxx @@ -150,6 +150,50 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlineRenderModeOmitInsertDelete) CPPUNIT_ASSERT_EQUAL(120, GetColorHue(aColor3)); } +CPPUNIT_TEST_FIXTURE(Test, testMoveRedlineRenderModeOmitDelete) +{ + // Given a move itbaselinemove it bugdoc: + createSwDoc("redline-move.docx"); + SwDocShell* pDocShell = getSwDocShell(); + SwWrtShell* pWrtShell = pDocShell->GetWrtShell(); + SwViewOption aOpt(*pWrtShell->GetViewOptions()); + aOpt.SetRedlineRenderMode(SwRedlineRenderMode::OmitDeletes); + pWrtShell->ApplyViewOptions(aOpt); + + // When rendering that while omitting deletes: + std::shared_ptr xMetaFile = pDocShell->GetPreviewMetaFile(); + + // Then make sure "from" has no strikethrough and "to" has no underline: + MetafileXmlDump dumper; + xmlDocUniquePtr pXmlDoc = dumpAndParse(dumper, *xMetaFile); + assertXPath(pXmlDoc, "//textarray", 3); + OUString aContent = getXPathContent(pXmlDoc, "(//textarray)[1]/text"); + sal_Int32 nIndex1 = getXPath(pXmlDoc, "(//textarray)[1]", "index").toInt32(); + sal_Int32 nLength1 = getXPath(pXmlDoc, "(//textarray)[1]", "length").toInt32(); + CPPUNIT_ASSERT_EQUAL(u"move it"_ustr, aContent.copy(nIndex1, nLength1)); + OUString aFontStrikeout + = getXPath(pXmlDoc, "(//textarray)[1]/preceding-sibling::font[1]", "strikeout"); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aFontStrikeout); + OUString aFontUnderline + = getXPath(pXmlDoc, "(//textarray)[1]/preceding-sibling::font[1]", "underline"); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 2 + // i.e. there was an unexpected underline, while only coloring is expected for moves when + // non-standard redline render mode is used. + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aFontUnderline); + sal_Int32 nIndex2 = getXPath(pXmlDoc, "(//textarray)[2]", "index").toInt32(); + sal_Int32 nLength2 = getXPath(pXmlDoc, "(//textarray)[2]", "length").toInt32(); + CPPUNIT_ASSERT_EQUAL(u"baseline"_ustr, aContent.copy(nIndex2, nLength2)); + sal_Int32 nIndex3 = getXPath(pXmlDoc, "(//textarray)[3]", "index").toInt32(); + sal_Int32 nLength3 = getXPath(pXmlDoc, "(//textarray)[3]", "length").toInt32(); + CPPUNIT_ASSERT_EQUAL(u"move it"_ustr, aContent.copy(nIndex3, nLength3)); + aFontStrikeout = getXPath(pXmlDoc, "(//textarray)[3]/preceding-sibling::font[1]", "strikeout"); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aFontStrikeout); + aFontUnderline = getXPath(pXmlDoc, "(//textarray)[3]/preceding-sibling::font[1]", "underline"); + CPPUNIT_ASSERT_EQUAL(u"0"_ustr, aFontUnderline); +} + struct ImageInfo { Bitmap m_aBitmap; diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx index ce7988b64d84..0cebaa0a83f9 100644 --- a/sw/source/core/text/redlnitr.cxx +++ b/sw/source/core/text/redlnitr.cxx @@ -891,6 +891,15 @@ short SwRedlineItr::Seek(SwFont& rFnt, const SwRedlineTable& rTable = m_rDoc.getIDocumentRedlineAccess().GetRedlineTable(); ::std::optional oFirstMatch; + const SwDocShell* pDocShell = m_rDoc.GetDocShell(); + const SwWrtShell* pWrtShell = pDocShell ? pDocShell->GetWrtShell() : nullptr; + SwRedlineRenderMode eRenderMode = SwRedlineRenderMode::Standard; + if (pWrtShell) + { + const SwViewOption* pOptions = pWrtShell->GetViewOptions(); + eRenderMode = pOptions->GetRedlineRenderMode(); + } + for ( ; m_nAct < rTable.size() ; ++m_nAct) { decltype(m_nStart) nStart; @@ -930,15 +939,18 @@ short SwRedlineItr::Seek(SwFont& rFnt, } if( 1 < pRed->GetStackCount() ) - FillHints( pRed->GetAuthor( 1 ), pRed->GetType( 1 ) ); - FillHints( pRed->GetAuthor(), pRed->GetType() ); + FillHints(pRed->GetAuthor(1), pRed->GetType(1), eRenderMode); + FillHints(pRed->GetAuthor(), pRed->GetType(), eRenderMode); SfxWhichIter aIter( *m_pSet ); // moved text: dark green with double underline or strikethrough bool bDisplayMovedTextInGreen = officecfg::Office::Writer::Comparison::DisplayMovedTextInGreen::get(); - if ( bDisplayMovedTextInGreen && pRed->IsMoved() ) + if (bDisplayMovedTextInGreen && pRed->IsMoved() + && eRenderMode == SwRedlineRenderMode::Standard) { + // Standard redline render mode, so move is more than just insert and + // delete. m_pSet->Put(SvxColorItem( COL_GREEN, RES_CHRATR_COLOR )); if (SfxItemState::SET == m_pSet->GetItemState(RES_CHRATR_CROSSEDOUT, true)) m_pSet->Put(SvxCrossedOutItem( STRIKEOUT_DOUBLE, RES_CHRATR_CROSSEDOUT )); @@ -1010,17 +1022,8 @@ short SwRedlineItr::Seek(SwFont& rFnt, return nRet + EnterExtend(rFnt, nNode, nNew); } -void SwRedlineItr::FillHints( std::size_t nAuthor, RedlineType eType ) +void SwRedlineItr::FillHints( std::size_t nAuthor, RedlineType eType, SwRedlineRenderMode eRenderMode ) { - const SwDocShell* pDocShell = m_rDoc.GetDocShell(); - const SwWrtShell* pWrtShell = pDocShell ? pDocShell->GetWrtShell() : nullptr; - SwRedlineRenderMode eRenderMode = SwRedlineRenderMode::Standard; - if (pWrtShell) - { - const SwViewOption* pOptions = pWrtShell->GetViewOptions(); - eRenderMode = pOptions->GetRedlineRenderMode(); - } - switch ( eType ) { case RedlineType::Insert: diff --git a/sw/source/core/text/redlnitr.hxx b/sw/source/core/text/redlnitr.hxx index 5c301312640e..3132af3053c8 100644 --- a/sw/source/core/text/redlnitr.hxx +++ b/sw/source/core/text/redlnitr.hxx @@ -67,6 +67,8 @@ public: void UpdateFont(SwFont &rFont) { ActualizeFont(rFont, m_rArr[m_nPos - m_nStart]); } }; +enum class SwRedlineRenderMode; + class SwRedlineItr { std::deque m_Hints; @@ -88,7 +90,7 @@ private: void Clear_( SwFont* pFnt ); bool ChkSpecialUnderline_() const; - void FillHints( std::size_t nAuthor, RedlineType eType ); + void FillHints(std::size_t nAuthor, RedlineType eType, SwRedlineRenderMode eRenderMode); short EnterExtend(SwFont& rFnt, SwNodeOffset const nNode, sal_Int32 const nNew) { if (m_pExt) return m_pExt->Enter(rFnt, nNode, nNew); diff --git a/vcl/source/gdi/mtfxmldump.cxx b/vcl/source/gdi/mtfxmldump.cxx index 26384025a84d..6dc825403e37 100644 --- a/vcl/source/gdi/mtfxmldump.cxx +++ b/vcl/source/gdi/mtfxmldump.cxx @@ -1353,6 +1353,7 @@ void MetafileXmlDump::writeXml(const GDIMetaFile& rMetaFile, tools::XmlWriter& r rWriter.attribute("wordunderline", aFont.IsWordLineMode() ? "true" : "false"); rWriter.attribute("outline", aFont.IsOutline() ? "true" : "false"); rWriter.attribute("strikeout", aFont.GetStrikeout()); + rWriter.attribute("underline", aFont.GetUnderline()); rWriter.endElement(); }