summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-08-27 13:13:45 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-08-27 14:00:12 +0200
commit9ea594ffcf4f807306440e4628eecca8c75be8ee (patch)
tree5d219b28e546eb9be3b8c063b11a678b186e8c51
parentc56178f0daf69abb362e6216f51b6e1f5aff1777 (diff)
tdf#137363 DOCX filter: don't loose <w:ilvl w:val="..."> of paragraph styles
This adds doc model, UNO API and DOCX import/export for this feature. The rest is not yet implemented (i.e. no layout, UI, etc.) An alternative would be to grab-bag the list level of paragraph styles, putting it to the doc model directly has the benefit that this is a step in the right direction. Change-Id: Idf7157e8a4177b4c2286d3cfb3d5acf2df845076 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121141 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
-rw-r--r--sw/qa/extras/ooxmlexport/data/para-style-num-level.docxbin0 -> 13101 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport17.cxx11
-rw-r--r--sw/qa/uitest/styleInspector/styleInspector.py20
-rw-r--r--sw/qa/uitest/styleInspector/tdf137513.py2
-rw-r--r--sw/source/core/bastyp/init.cxx1
-rw-r--r--sw/source/core/unocore/unomapproperties.hxx1
-rw-r--r--sw/source/filter/ww8/docxattributeoutput.cxx13
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx6
8 files changed, 41 insertions, 13 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/para-style-num-level.docx b/sw/qa/extras/ooxmlexport/data/para-style-num-level.docx
new file mode 100644
index 000000000000..2de0c50db621
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/para-style-num-level.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
index 4eb9d0d6aa1b..1b6f6cf713d1 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport17.cxx
@@ -42,6 +42,17 @@ DECLARE_OOXMLEXPORT_TEST(testTdf135164_cancelledNumbering, "tdf135164_cancelledN
CPPUNIT_ASSERT_EQUAL(OUString("i"), getProperty<OUString>(xPara, "ListLabelString"));
}
+CPPUNIT_TEST_FIXTURE(Test, testParaStyleNumLevel)
+{
+ loadAndSave("para-style-num-level.docx");
+ xmlDocUniquePtr pXmlDoc = parseExport("word/styles.xml");
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. a custom list level in a para style was lost on import+export.
+ assertXPath(pXmlDoc, "/w:styles/w:style[@w:styleId='Mystyle']/w:pPr/w:numPr/w:ilvl", "val", "1");
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/qa/uitest/styleInspector/styleInspector.py b/sw/qa/uitest/styleInspector/styleInspector.py
index 26e5c5be73a3..acaa85d693fe 100644
--- a/sw/qa/uitest/styleInspector/styleInspector.py
+++ b/sw/qa/uitest/styleInspector/styleInspector.py
@@ -24,7 +24,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without formatting and default style
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -34,7 +34,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with direct formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
@@ -52,7 +52,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with paragraph direct formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
xParDirFormatting = xListBox.getChild('1')
self.assertEqual(7, len(xParDirFormatting.getChildren()))
@@ -73,7 +73,7 @@ class styleNavigator(UITestCase):
xParStyle = xListBox.getChild('0')
self.assertEqual(3, len(xParStyle.getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xParStyle.getChild('0'))['Text'])
- self.assertEqual(136, len(xParStyle.getChild('0').getChildren()))
+ self.assertEqual(137, len(xParStyle.getChild('0').getChildren()))
self.assertEqual("Heading\t", get_state_as_dict(xParStyle.getChild('1'))['Text'])
self.assertEqual(28, len(xParStyle.getChild('1').getChildren()))
@@ -107,7 +107,7 @@ class styleNavigator(UITestCase):
xParStyle = xListBox.getChild('0')
self.assertEqual(3, len(xParStyle.getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xParStyle.getChild('0'))['Text'])
- self.assertEqual(136, len(xParStyle.getChild('0').getChildren()))
+ self.assertEqual(137, len(xParStyle.getChild('0').getChildren()))
self.assertEqual("Text Body\t", get_state_as_dict(xParStyle.getChild('1'))['Text'])
self.assertEqual(6, len(xParStyle.getChild('1').getChildren()))
@@ -142,7 +142,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without metadata
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -152,7 +152,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with paragraph metadata showed under direct paragraph formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
xParDirFormatting = xListBox.getChild('1')
self.assertEqual(1, len(xParDirFormatting.getChildren()))
@@ -201,7 +201,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without metadata
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
self.assertEqual(0, len(xListBox.getChild('3').getChildren()))
@@ -211,7 +211,7 @@ class styleNavigator(UITestCase):
# The cursor is on text with paragraph metadata showed under direct paragraph formatting
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
# Outer bookmark
xBookmarkFormatting = xListBox.getChild('4')
@@ -257,7 +257,7 @@ class styleNavigator(UITestCase):
# The cursor is on text without metadata
self.assertEqual(1, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
self.assertEqual(0, len(xListBox.getChild('1').getChildren()))
self.assertEqual(0, len(xListBox.getChild('2').getChildren()))
diff --git a/sw/qa/uitest/styleInspector/tdf137513.py b/sw/qa/uitest/styleInspector/tdf137513.py
index e5a02c8f5637..b030d6e70ba7 100644
--- a/sw/qa/uitest/styleInspector/tdf137513.py
+++ b/sw/qa/uitest/styleInspector/tdf137513.py
@@ -30,7 +30,7 @@ class tdf137513(UITestCase):
self.assertEqual(2, len(xListBox.getChild('0').getChildren()))
self.assertEqual("Default Paragraph Style\t", get_state_as_dict(xListBox.getChild('0').getChild('0'))['Text'])
self.assertEqual("Table Contents\t", get_state_as_dict(xListBox.getChild('0').getChild('1'))['Text'])
- self.assertEqual(136, len(xListBox.getChild('0').getChild('0').getChildren()))
+ self.assertEqual(137, len(xListBox.getChild('0').getChild('0').getChildren()))
xTableContent = xListBox.getChild('0').getChild('1')
self.assertEqual(5, len(xTableContent.getChildren()))
diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx
index b3cb99f84675..0ab9a5c8ae84 100644
--- a/sw/source/core/bastyp/init.cxx
+++ b/sw/source/core/bastyp/init.cxx
@@ -148,6 +148,7 @@ WhichRangesContainer const aBreakSetRange(svl::Items<
WhichRangesContainer const aTextFormatCollSetRange(svl::Items<
RES_CHRATR_BEGIN, RES_CHRATR_END-1,
RES_PARATR_BEGIN, RES_PARATR_END-1,
+ RES_PARATR_LIST_LEVEL, RES_PARATR_LIST_LEVEL,
RES_FRMATR_BEGIN, RES_FRMATR_END-1,
RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1,
diff --git a/sw/source/core/unocore/unomapproperties.hxx b/sw/source/core/unocore/unomapproperties.hxx
index 263a712010c0..1830ca2691de 100644
--- a/sw/source/core/unocore/unomapproperties.hxx
+++ b/sw/source/core/unocore/unomapproperties.hxx
@@ -438,6 +438,7 @@
{ u"" UNO_NAME_PARA_HYPHENATION_MAX_TRAILING_CHARS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MIN_TRAIL },\
{ u"" UNO_NAME_PARA_HYPHENATION_MAX_HYPHENS, RES_PARATR_HYPHENZONE, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, MID_HYPHEN_MAX_HYPHENS},\
{ u"" UNO_NAME_NUMBERING_STYLE_NAME, RES_PARATR_NUMRULE, cppu::UnoType<OUString>::get(), PropertyAttribute::MAYBEVOID, 0},\
+ { u"" UNO_NAME_NUMBERING_LEVEL, RES_PARATR_LIST_LEVEL, cppu::UnoType<sal_Int16>::get(), PropertyAttribute::MAYBEVOID, 0},\
{ u"" UNO_NAME_PARA_USER_DEFINED_ATTRIBUTES, RES_UNKNOWNATR_CONTAINER, cppu::UnoType<css::container::XNameContainer>::get(), PropertyAttribute::MAYBEVOID, 0 },\
{ u"" UNO_NAME_PARA_SHADOW_FORMAT, RES_SHADOW, cppu::UnoType<css::table::ShadowFormat>::get(), PROPERTY_NONE, CONVERT_TWIPS},\
{ u"" UNO_NAME_CHAR_COMBINE_IS_ON, RES_CHRATR_TWO_LINES, cppu::UnoType<bool>::get(), PROPERTY_NONE, MID_TWOLINES},\
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index c447bf7a60c8..b9cfa3c6bd37 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -8829,6 +8829,19 @@ void DocxAttributeOutput::ParaNumRule_Impl( const SwTextNode* pTextNd, sal_Int32
return;
}
+ if (!pTextNd && nLvl == 0)
+ {
+ // This is a paragraph style and the level would be zero. Then see if the importer set a
+ // custom numbering level.
+ const SfxItemSet* pSet = m_rExport.m_pISet;
+ if (pSet && pSet->HasItem(RES_PARATR_LIST_LEVEL))
+ {
+ // It did, so use that level.
+ const SfxPoolItem* pItem = pSet->GetItem(RES_PARATR_LIST_LEVEL);
+ nLvl = pItem->StaticWhichCast(RES_PARATR_LIST_LEVEL).GetValue();
+ }
+ }
+
m_pSerializer->startElementNS(XML_w, XML_numPr);
m_pSerializer->singleElementNS(XML_w, XML_ilvl, FSNS(XML_w, XML_val), OString::number(nLvl));
m_pSerializer->singleElementNS(XML_w, XML_numId, FSNS(XML_w, XML_val), OString::number(nNumId));
diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx
index f5731e735cbe..9503306b05ec 100644
--- a/writerfilter/source/dmapper/DomainMapper.cxx
+++ b/writerfilter/source/dmapper/DomainMapper.cxx
@@ -1329,8 +1329,7 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
if (pStyleSheetPropertyMap)
pStyleSheetPropertyMap->SetListLevel( static_cast<sal_Int16>(nIntValue) );
}
- else
- rContext->Insert( PROP_NUMBERING_LEVEL, uno::makeAny( static_cast<sal_Int16>(nIntValue) ));
+ rContext->Insert(PROP_NUMBERING_LEVEL, uno::makeAny(static_cast<sal_Int16>(nIntValue)));
break;
case NS_ooxml::LN_CT_NumPr_numId:
{
@@ -1564,6 +1563,9 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
StyleSheetPropertyMap* pStyleSheetPropertyMap = dynamic_cast< StyleSheetPropertyMap* >( rContext.get() );
if (pStyleSheetPropertyMap)
pStyleSheetPropertyMap->SetOutlineLevel(nIntValue);
+
+ // Prefer outline levels over numbering levels.
+ rContext->Erase(PROP_NUMBERING_LEVEL);
}
else
{