sw/qa/core/text/data/number-portion-format.odt |binary sw/qa/core/text/data/number-portion-noformat.docx |binary sw/qa/core/text/text.cxx | 18 ++++++++++++++ sw/qa/extras/ooxmlexport/data/number-portion-format.odt |binary sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 6 ++++ sw/source/core/text/txtfld.cxx | 10 ++++---- sw/source/core/unocore/unoportenum.cxx | 20 ++++++++++++++++ sw/source/filter/ww8/docxattributeoutput.cxx | 2 - sw/source/filter/ww8/wrtw8nds.cxx | 15 +----------- 9 files changed, 52 insertions(+), 19 deletions(-)
New commits: commit 585d440df98ff3b967c191908ac2d4b2f7e29326 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Fri Dec 16 10:31:03 2022 +0100 Commit: Mike Kaganski <mike.kagan...@collabora.com> CommitDate: Wed Dec 21 14:24:39 2022 +0000 sw, numbering portion format: ignore char formats covering the entire paragraph The bugdoc has a single paragraph, where the numbering portion is bold in Writer but not in Word. The reason for this appears to be that Writer considers text node hints for the formatting of the numbering portion where the hint covers the entire paragraph, but Word doesn't do this. This behavior was added in commits cb0e1b52d68aa6d5b505f91cb4ce577f7f3b2a8f (sw, numbering portion format: consider full-para char formats as well, 2022-10-20) and DOCX export was also adjusted in commit f546f7573158e52359bbeae6194a83a1ff8ac52c (DOCX export, numbering portion format: consider full-para char formats as well, 2022-10-28). Fix the problem by partially reverting the above two commits and instead only consider hints that both start and end at the paragraph end. The revert of the first commit fixes the new bugdoc (its numbering portion is no longer bold) and the old bugdoc keeps working if the sw UNO API's text portion enumeration is extended to expose such empty autoformats at paragraph end. Related testcases: - CppunitTest_sw_ooxmlexport13's testTdf123460 explicitly tested that we don't expose the paragraph marker's formatting on the UNO API. - CppunitTest_sw_core_text's testNumberPortionFormat now uses the new ODT markup for these explicit paragraph marker char props (empty text span at para end). - CppunitTest_sw_uiwriter2's testTdfChangeNumberingListAutoFormat failed when only the above first commit (layout) was reverted, so revert the matching DOCX export commit as well, which is also good for consistency. - CppunitTest_sw_ooxmlexport18's testNumberPortionFormatFromODT also used the old ODT markup, updated. (cherry picked from commit 99ed51bcad4008a4006dcec24aa33fd7f757a433) Change-Id: Iee8acf72dabcd10b3f4d3d68b83ed248bf50c324 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144674 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> diff --git a/sw/qa/core/text/data/number-portion-format.odt b/sw/qa/core/text/data/number-portion-format.odt index 3047153b63af..19b23ae84420 100644 Binary files a/sw/qa/core/text/data/number-portion-format.odt and b/sw/qa/core/text/data/number-portion-format.odt differ diff --git a/sw/qa/core/text/data/number-portion-noformat.docx b/sw/qa/core/text/data/number-portion-noformat.docx new file mode 100644 index 000000000000..b289b9c69ef4 Binary files /dev/null and b/sw/qa/core/text/data/number-portion-noformat.docx differ diff --git a/sw/qa/core/text/text.cxx b/sw/qa/core/text/text.cxx index 5ba260bf9073..eaf5cce312ff 100644 --- a/sw/qa/core/text/text.cxx +++ b/sw/qa/core/text/text.cxx @@ -573,6 +573,24 @@ CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testNumberPortionFormat) assertXPath(pXmlDoc, "//Special[@nType='PortionType::Number']", "nHeight", "480"); } +CPPUNIT_TEST_FIXTURE(SwCoreTextTest, testNumberPortionNoformat) +{ + // Given a document with a numbering and a single paragraph, the entire run is red: + createSwDoc(DATA_DIRECTORY, "number-portion-noformat.docx"); + + // When laying out that document: + xmlDocUniquePtr pXmlDoc = parseLayoutDump(); + + // Then make sure that just because the entire run is red, the numbering portion is not red: + // Without the accompanying fix in place, this test would have failed with: + // - Expected: ffffffff (COL_AUTO) + // - Actual : 00ff0000 (COL_LIGHTRED) + // i.e. the run color affected the color of the number portion in Writer, but not in Word. + CPPUNIT_ASSERT_EQUAL( + OUString("ffffffff"), + getXPath(pXmlDoc, "//Special[@nType='PortionType::Number']/SwFont", "color")); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/qa/extras/ooxmlexport/data/number-portion-format.odt b/sw/qa/extras/ooxmlexport/data/number-portion-format.odt index 3047153b63af..66f3b175b50a 100644 Binary files a/sw/qa/extras/ooxmlexport/data/number-portion-format.odt and b/sw/qa/extras/ooxmlexport/data/number-portion-format.odt differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index 51634dcd8a00..2e2b4b754cd3 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -758,6 +758,12 @@ DECLARE_OOXMLEXPORT_TEST(testTdf123460, "tdf123460.docx") CPPUNIT_ASSERT(xRun->getString().endsWith("tellus.")); xRun.set(xRunEnum->nextElement(), uno::UNO_QUERY); CPPUNIT_ASSERT(hasProperty(xRun, "Bookmark")); + + // The paragraph marker's formatting. + xRun.set(xRunEnum->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Text"),getProperty<OUString>(xRun, "TextPortionType")); + CPPUNIT_ASSERT(xRun->getString().isEmpty()); + // deleted paragraph mark at the end of the second paragraph if (mbExported) { diff --git a/sw/source/core/text/txtfld.cxx b/sw/source/core/text/txtfld.cxx index b98b8481cadb..ede8e30f2308 100644 --- a/sw/source/core/text/txtfld.cxx +++ b/sw/source/core/text/txtfld.cxx @@ -781,13 +781,13 @@ SwNumberPortion *SwTextFormatter::NewNumberPortion( SwTextFormatInfo &rInf ) con const SwTextNode& rTextNode = *rInf.GetTextFrame()->GetTextNodeForParaProps(); if (const SwpHints* pHints = rTextNode.GetpSwpHints()) { - // Also look for a character hint that cover the entire current paragraph: + // Also look for an empty character hint that sits at the paragraph end: for (size_t i = 0; i < pHints->Count(); ++i) { - const SwTextAttr* pHint = pHints->Get(i); - if (pHint->Which() == RES_TXTATR_AUTOFMT && pHint->GetStart() == 0 - && pHint->GetEnd() - && *pHint->GetEnd() == rTextNode.GetText().getLength()) + const SwTextAttr* pHint = pHints->GetSortedByEnd(i); + if (pHint->Which() == RES_TXTATR_AUTOFMT && pHint->GetEnd() + && pHint->GetStart() == *pHint->GetEnd() + && pHint->GetStart() == rTextNode.GetText().getLength()) { std::shared_ptr<SfxItemSet> pSet = pHint->GetAutoFormat().GetStyleHandle(); diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx index be3ee4491e9e..f4ddd69bf862 100644 --- a/sw/source/core/unocore/unoportenum.cxx +++ b/sw/source/core/unocore/unoportenum.cxx @@ -1509,6 +1509,26 @@ static void lcl_CreatePortions( // text portion because there may be a hyperlink attribute xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT); } + else if (bAtEnd && !xRef.is() && pHints) + { + // See if there is an empty autofmt at the paragraph end. If so, export it, since that + // affects the formatting of number portions. + for (size_t i = 0; i < pHints->Count(); ++i) + { + const SwTextAttr* pHint = pHints->GetSortedByEnd(i); + if (pHint->GetStart() < pTextNode->Len()) + { + break; + } + if (pHint->Which() == RES_TXTATR_AUTOFMT && pHint->GetEnd() + && pHint->GetStart() == *pHint->GetEnd() + && pHint->GetStart() == pTextNode->Len()) + { + xRef = new SwXTextPortion(pUnoCursor, i_xParentText, PORTION_TEXT); + break; + } + } + } if (xRef.is()) { diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 206e0cde6478..70c21933ebdd 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -1378,7 +1378,7 @@ void lcl_writeParagraphMarkerProperties(DocxAttributeOutput& rAttributeOutput, c bool bFontSizeWritten = false; while (nWhichId) { - if (aIter.GetItemState(true, &pItem) == SfxItemState::SET && nWhichId != RES_CHRATR_GRABBAG) + if (aIter.GetItemState(true, &pItem) == SfxItemState::SET) { if (isCHRATR(nWhichId) || nWhichId == RES_TXTATR_CHARFMT) { diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx index 19be8482069e..f11f2e8c6a4a 100644 --- a/sw/source/filter/ww8/wrtw8nds.cxx +++ b/sw/source/filter/ww8/wrtw8nds.cxx @@ -3194,7 +3194,6 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) } else if (const SwpHints* pTextAttrs = rNode.GetpSwpHints()) { - bool bFoundAtEnd = false; for( size_t i = 0; i < pTextAttrs->Count(); ++i ) { const SwTextAttr* pHt = pTextAttrs->Get(i); @@ -3203,23 +3202,13 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode ) // Check if these attributes are for the last character in the paragraph // - which means the paragraph marker. If a paragraph has 7 characters, // then properties on character 8 are for the paragraph marker - if (!endPos) - { - continue; - } - bool bAtEnd = (startPos == *endPos ) && (*endPos == rNode.GetText().getLength()); - if (bAtEnd) - { - bFoundAtEnd = true; - } - bool bWholePara = startPos == 0 && *endPos == rNode.GetText().getLength(); - if (bAtEnd || (!bFoundAtEnd && bWholePara)) + if( endPos && (startPos == *endPos ) && (*endPos == rNode.GetText().getLength()) ) { SAL_INFO( "sw.ww8", startPos << "startPos == endPos" << *endPos); sal_uInt16 nWhich = pHt->GetAttr().Which(); SAL_INFO( "sw.ww8", "nWhich" << nWhich); if ((nWhich == RES_TXTATR_AUTOFMT && bCharFormatOnly) - || (nWhich == RES_TXTATR_CHARFMT && !bWholePara)) + || nWhich == RES_TXTATR_CHARFMT) { aParagraphMarkerProperties.Put(pHt->GetAttr()); }