diff options
author | László Németh <nemeth@numbertext.org> | 2020-06-16 18:52:56 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-06-17 16:58:40 +0200 |
commit | 5568d92c5c705b4d728af859dc44afdd64e72195 (patch) | |
tree | 66050fcbb40b09dafaa0592c265f7fb531ae3708 | |
parent | 82a1650683df7d5c1769dfd68a26a4d071f1a546 (diff) |
tdf#76817 DOCX: fix round-tripped outline numbering
Fix automatic chapter numbering in DOCX documents
created by Writer.
Follow-up of commit de1b634a151c198584dc152676183f519c50a2da
(tdf#76817: DOCX import: fix custom chapter numbering).
Change-Id: I331b7dcf67efdf63b376122ec4da0a2e85bea761
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96529
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/extras/uiwriter/data2/tdf76817.fodt | 77 | ||||
-rw-r--r-- | sw/qa/extras/uiwriter/uiwriter2.cxx | 87 | ||||
-rw-r--r-- | writerfilter/source/dmapper/NumberingManager.cxx | 10 |
3 files changed, 172 insertions, 2 deletions
diff --git a/sw/qa/extras/uiwriter/data2/tdf76817.fodt b/sw/qa/extras/uiwriter/data2/tdf76817.fodt new file mode 100644 index 000000000000..4b6decb1a82a --- /dev/null +++ b/sw/qa/extras/uiwriter/data2/tdf76817.fodt @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:officeooo="http://openoffice.org/2009/office" xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text"> + <office:styles> + <style:style style:name="Standard" style:family="paragraph" style:class="text"/> + <style:default-style style:family="paragraph"> + <style:text-properties fo:language="en" fo:country="US"/> + </style:default-style> + <style:style style:name="Heading_20_1" style:display-name="Heading 1" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="1" style:class="text"> + <style:paragraph-properties fo:margin-top="0.423cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false"/> + <style:text-properties fo:font-size="130%" fo:font-weight="bold" style:font-size-asian="130%" style:font-weight-asian="bold" style:font-size-complex="130%" style:font-weight-complex="bold"/> + </style:style> + <style:style style:name="Heading_20_2" style:display-name="Heading 2" style:family="paragraph" style:parent-style-name="Heading" style:next-style-name="Text_20_body" style:default-outline-level="2" style:class="text"> + <style:paragraph-properties fo:margin-top="0.353cm" fo:margin-bottom="0.212cm" style:contextual-spacing="false"/> + <style:text-properties fo:font-size="115%" fo:font-weight="bold" style:font-size-asian="115%" style:font-weight-asian="bold" style:font-size-complex="115%" style:font-weight-complex="bold"/> + </style:style> + <text:outline-style style:name="Outline"> + <text:outline-level-style text:level="1" style:num-format="1"> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="2" style:num-format="1" text:display-levels="2"> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="3" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="4" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="5" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="6" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="7" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="8" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="9" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + <text:outline-level-style text:level="10" style:num-format=""> + <style:list-level-properties text:list-level-position-and-space-mode="label-alignment"> + <style:list-level-label-alignment text:label-followed-by="listtab"/> + </style:list-level-properties> + </text:outline-level-style> + </text:outline-style> + </office:styles> + <office:body> + <office:text> + <text:h text:style-name="Heading_20_1" text:outline-level="1">Should be 1</text:h> + <text:h text:style-name="Heading_20_2" text:outline-level="2">Should be 1.1</text:h> + <text:h text:style-name="Heading_20_1" text:outline-level="1">Should be 2</text:h> + <text:h text:style-name="Heading_20_2" text:outline-level="2">Should be 2.1</text:h> + </office:text> + </office:body> +</office:document> diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 68470cecdc72..01d05d963b3c 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -1225,6 +1225,93 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817) getProperty<OUString>(getParagraph(4), "ListLabelString")); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817_round_trip) +{ + load(DATA_DIRECTORY, "tdf76817.fodt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pTextDoc); + + // save it to DOCX + reload("Office Open XML Text", "tdf76817.docx"); + pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + + SwViewShell* pViewShell + = pTextDoc->GetDocShell()->GetDoc()->getIDocumentLayoutAccess().GetCurrentViewShell(); + pViewShell->Reformat(); + + CPPUNIT_ASSERT(pTextDoc); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty<OUString>(getParagraph(2), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), + getProperty<sal_Int32>(getParagraph(2), "OutlineLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("1.1"), + getProperty<OUString>(getParagraph(2), "ListLabelString")); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty<OUString>(getParagraph(4), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), + getProperty<sal_Int32>(getParagraph(4), "OutlineLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("2.1"), + getProperty<OUString>(getParagraph(4), "ListLabelString")); + + // set Heading 2 style of paragraph 2 to Heading 1 + + SwWrtShell* pWrtShell = pTextDoc->GetDocShell()->GetWrtShell(); + pWrtShell->Down(/*bSelect=*/false); + + uno::Sequence<beans::PropertyValue> aPropertyValues = comphelper::InitPropertySequence({ + { "Style", uno::makeAny(OUString("Heading 1")) }, + { "FamilyName", uno::makeAny(OUString("ParagraphStyles")) }, + }); + dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), + getProperty<OUString>(getParagraph(2), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), + getProperty<sal_Int32>(getParagraph(2), "OutlineLevel")); + // This was "1 Heading" instead of "2 Heading" + CPPUNIT_ASSERT_EQUAL(OUString("2"), getProperty<OUString>(getParagraph(2), "ListLabelString")); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty<OUString>(getParagraph(4), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), + getProperty<sal_Int32>(getParagraph(4), "OutlineLevel")); + // This was "2.1 Heading" + CPPUNIT_ASSERT_EQUAL(OUString("3.1"), + getProperty<OUString>(getParagraph(4), "ListLabelString")); + + // set Heading 1 style of paragraph 3 to Heading 2 + + pWrtShell->Down(/*bSelect=*/false); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 1"), + getProperty<OUString>(getParagraph(3), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1), + getProperty<sal_Int32>(getParagraph(3), "OutlineLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("3"), getProperty<OUString>(getParagraph(3), "ListLabelString")); + + uno::Sequence<beans::PropertyValue> aPropertyValues2 = comphelper::InitPropertySequence({ + { "Style", uno::makeAny(OUString("Heading 2")) }, + { "FamilyName", uno::makeAny(OUString("ParagraphStyles")) }, + }); + dispatchCommand(mxComponent, ".uno:StyleApply", aPropertyValues2); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty<OUString>(getParagraph(3), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), + getProperty<sal_Int32>(getParagraph(3), "OutlineLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("2.1"), + getProperty<OUString>(getParagraph(3), "ListLabelString")); + + CPPUNIT_ASSERT_EQUAL(OUString("Heading 2"), + getProperty<OUString>(getParagraph(4), "ParaStyleName")); + CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(2), + getProperty<sal_Int32>(getParagraph(4), "OutlineLevel")); + CPPUNIT_ASSERT_EQUAL(OUString("2.2"), + getProperty<OUString>(getParagraph(4), "ListLabelString")); +} + CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf76817_custom_outline) { load(DATA_DIRECTORY, "tdf76817.docx"); diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx index 5a33327597c8..2a51ca351135 100644 --- a/writerfilter/source/dmapper/NumberingManager.cxx +++ b/writerfilter/source/dmapper/NumberingManager.cxx @@ -577,9 +577,15 @@ void ListDef::CreateNumberingRules( DomainMapper& rDMapper, xOutlineRules->replaceByIndex(nLevel, uno::makeAny(comphelper::containerToSequence(aLvlProps))); } - // first level with custom pStyle - if ( WW_OUTLINE_MAX + 1 == m_nDefaultParentLevels && pAbsLevel->GetParaStyle( ) ) + // first level without default outline paragraph style + const tools::SvRef< StyleSheetEntry >& aParaStyle = pAbsLevel->GetParaStyle(); + if ( WW_OUTLINE_MAX + 1 == m_nDefaultParentLevels && ( !aParaStyle || + aParaStyle->sConvertedStyleName.getLength() != RTL_CONSTASCII_LENGTH( "Heading 1" ) || + !aParaStyle->sConvertedStyleName.startsWith("Heading ") || + aParaStyle->sConvertedStyleName[ RTL_CONSTASCII_LENGTH( "Heading " ) ] - u'1' != nLevel ) ) + { m_nDefaultParentLevels = nLevel; + } nLevel++; } |