cool#13988 sw redline render mode: handle moves
Open the bugdoc, switch to a non-standard redline render mode (omit inserts or omit deletes), it's expected to see red-gray or gray-green pairs of text (for delete and insert), but instead double underline was shown for some inserts. This comes from the insert part of moves, which is wanted for the stanard redline render mode, where an author-specific color is used, then green (on top of that) means a move. Fix the problem by avoiding the move-specific rendering for the non-standard redline render mode case, similar to what the officecfg::Office::Writer::Comparison::DisplayMovedTextInGreen setting does. This required extending the metafile dumper a bit, since underlines were not exposed in the XML dump. Change-Id: I717eb0925c1959f787701ef9778ddb704b28031a Reviewed-on: https://gerrit.libreoffice.org/c/core/+/198583 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
This commit is contained in:
Binary file not shown.
@@ -150,6 +150,50 @@ CPPUNIT_TEST_FIXTURE(Test, testRedlineRenderModeOmitInsertDelete)
|
||||
CPPUNIT_ASSERT_EQUAL(120, GetColorHue(aColor3));
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testMoveRedlineRenderModeOmitDelete)
|
||||
{
|
||||
// Given a <from>move it</from>baseline<to>move it</to> 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<GDIMetaFile> 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;
|
||||
|
||||
@@ -891,6 +891,15 @@ short SwRedlineItr::Seek(SwFont& rFnt,
|
||||
const SwRedlineTable& rTable = m_rDoc.getIDocumentRedlineAccess().GetRedlineTable();
|
||||
::std::optional<decltype(m_nAct)> 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:
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
void UpdateFont(SwFont &rFont) { ActualizeFont(rFont, m_rArr[m_nPos - m_nStart]); }
|
||||
};
|
||||
|
||||
enum class SwRedlineRenderMode;
|
||||
|
||||
class SwRedlineItr
|
||||
{
|
||||
std::deque<SwTextAttr *> 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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user