summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLászló Németh <nemeth@numbertext.org>2020-02-04 19:31:41 +0100
committerMiklos Vajna <vmiklos@collabora.com>2021-03-05 11:04:35 +0100
commitb743f95b8d3b406da3d9b8c9ad017411f1351ad2 (patch)
tree0eb476aae9b987b7d2b703a8afb531992fd2c4c6
parenttdf#81100 DOCX import: repeat header according to table style (diff)
downloadcore-b743f95b8d3b406da3d9b8c9ad017411f1351ad2.tar.gz
core-b743f95b8d3b406da3d9b8c9ad017411f1351ad2.zip
tdf#129575 DOCX import: fix table style preference
handling by recognizing docDefault properties instead of default-value based heuristics. (cherry picked from commit f15d67442972c5f69c71925a6bfa5aa1a39d54eb) Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport13.cxx sw/qa/extras/ooxmlexport/ooxmlexport6.cxx writerfilter/source/dmapper/PropertyIds.cxx writerfilter/source/dmapper/PropertyMap.cxx writerfilter/source/dmapper/PropertyMap.hxx writerfilter/source/dmapper/StyleSheetTable.cxx writerfilter/source/dmapper/StyleSheetTable.hxx Change-Id: I3bab9d85d77d0e5f1c357121b1caf02cbe4899c4
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docxbin0 -> 18625 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docxbin0 -> 19246 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docxbin0 -> 38088 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docxbin0 -> 18620 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport6.cxx6
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport9.cxx65
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.cxx79
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableHandler.hxx2
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx19
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx2
-rw-r--r--writerfilter/source/dmapper/PropertyIds.cxx5
-rw-r--r--writerfilter/source/dmapper/PropertyIds.hxx2
-rw-r--r--writerfilter/source/dmapper/PropertyMap.cxx28
-rw-r--r--writerfilter/source/dmapper/PropertyMap.hxx19
-rw-r--r--writerfilter/source/dmapper/StyleSheetTable.cxx17
-rw-r--r--writerfilter/source/dmapper/StyleSheetTable.hxx1
16 files changed, 203 insertions, 42 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx b/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx
new file mode 100644
index 000000000000..c9856b02857b
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx b/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx
new file mode 100644
index 000000000000..5e75ef1be5d2
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx b/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx
new file mode 100644
index 000000000000..d7cdf2ec4308
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx b/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx
new file mode 100644
index 000000000000..97439011ff55
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
index cd1665489db5..4eae1b2a33df 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx
@@ -465,9 +465,9 @@ DECLARE_OOXMLEXPORT_TEST(testTdf119054, "tdf119054.docx")
xmlDocPtr pXmlDoc = parseExport();
if (!pXmlDoc)
return;
- // Don't overwrite before and after spacing of Heading2 by table style
- assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "before");
- assertXPathNoAttribute(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "after");
+ // Overwrite applied table style with before and after spacing of Heading2
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "before", "0");
+ assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "after", "360");
// Use table style based single line spacing instead of the docDefaults' 254
assertXPath(pXmlDoc, "/w:document/w:body/w:tbl/w:tr[1]/w:tc[1]/w:p[1]/w:pPr/w:spacing", "line", "240");
}
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
index e396ac0bea0b..9d6642a153ec 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx
@@ -31,6 +31,7 @@
#include <com/sun/star/view/XSelectionSupplier.hpp>
#include <com/sun/star/style/LineSpacing.hpp>
#include <com/sun/star/style/LineSpacingMode.hpp>
+//#include <com/sun/star/drawing/LineStyle.hpp>
#include <com/sun/star/style/ParagraphAdjust.hpp>
#include <com/sun/star/drawing/XControlShape.hpp>
#include <com/sun/star/text/TextContentAnchorType.hpp>
@@ -159,6 +160,70 @@ DECLARE_OOXMLEXPORT_TEST(testTdf106690Cell, "tdf106690-cell.docx")
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(494), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin"));
}
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_directBefore, "tdf129575-directBefore.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ // direct paragraph formatting
+ // This was 212 twips from the table style, but always direct paragraph formatting wins, in the case of the default 0 margin, too
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
+ // default margin
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_directAfter, "tdf129575-directAfter.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ // from table style
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
+ // direct paragraph formatting
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_styleAfter, "tdf129575-styleAfter.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ // direct paragraph formatting
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaTopMargin"));
+ // from table style
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(212), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
+}
+
+DECLARE_OOXMLEXPORT_TEST(testTdf129575_docDefault, "tdf129575-docDefault.docx")
+{
+ uno::Reference<text::XTextTablesSupplier> xTablesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XIndexAccess> xTables(xTablesSupplier->getTextTables(), uno::UNO_QUERY);
+ uno::Reference<text::XTextTable> xTable(xTables->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
+ // docDefault defines both bottom margin and line spacing, but
+ // applied bottom margin values are based on non-docDefault paragraph styles, line spacing is based on table style
+
+ // docDefault: <w:spacing w:after="160" w:line="320" w:lineRule="auto"/>
+ // table style: <w:spacing w:after="0" w:line="240" w:lineRule="auto"/> (single line space, overwriting bigger docDefault)
+
+ // Paragraph style Normal: <w:spacing w:after="160"/> (same as docDefault),
+ // table style based single line spacing
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(282), getProperty<sal_Int32>(getParagraphOfText(1, xCell->getText()), "ParaBottomMargin"));
+ style::LineSpacing aLineSpacing = getProperty<style::LineSpacing>(getParagraphOfText(1, xCell->getText()), "ParaLineSpacing");
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
+ // Heading 2: <w:spacing w:after="360"/> (different from docDefault),
+ // table style based single line spacing
+ CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(635), getProperty<sal_Int32>(getParagraphOfText(2, xCell->getText()), "ParaBottomMargin"));
+ aLineSpacing = getProperty<style::LineSpacing>(getParagraphOfText(1, xCell->getText()), "ParaLineSpacing");
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(style::LineSpacingMode::PROP), aLineSpacing.Mode);
+ CPPUNIT_ASSERT_EQUAL(sal_Int16(100), aLineSpacing.Height);
+
+}
+
DECLARE_OOXMLEXPORT_TEST(testTdf106970, "tdf106970.docx")
{
// The second paragraph (first numbered one) had 0 bottom margin:
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
index a0b077282885..1391e47127bd 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx
@@ -61,6 +61,7 @@ using namespace ::std;
#define CNF_FIRST_ROW_FIRST_COLUMN 0x004
#define CNF_LAST_ROW_LAST_COLUMN 0x002
#define CNF_LAST_ROW_FIRST_COLUMN 0x001
+#define CNF_ALL 0xFFF
DomainMapperTableHandler::DomainMapperTableHandler(
css::uno::Reference<css::text::XTextAppendAndConvert> const& xText,
@@ -226,6 +227,7 @@ struct TableInfo
PropertyMapPtr pTableBorders;
TableStyleSheetEntry* pTableStyle;
css::beans::PropertyValues aTableProperties;
+ std::vector< PropertyIds > aTablePropertyIds;
TableInfo()
: nLeftBorderDistance(DEF_BORDER_DIST)
@@ -636,6 +638,7 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo
}
rInfo.aTableProperties = m_aTableProperties->GetPropertyValues();
+ rInfo.aTablePropertyIds = m_aTableProperties->GetPropertyIds();
#ifdef DEBUG_WRITERFILTER
TagLogger::getInstance().startElement("debug.tableprops");
@@ -810,9 +813,6 @@ CellPropertyValuesSeq_t DomainMapperTableHandler::endTableGetCellProperties(Tabl
// Remove properties from style/row that aren't allowed in cells
pAllCellProps->Erase( PROP_HEADER_ROW_COUNT );
pAllCellProps->Erase( PROP_TBL_HEADER );
- // Remove paragraph properties from style/row that paragraph style can overwrite
- pAllCellProps->Erase( PROP_PARA_BOTTOM_MARGIN );
- pAllCellProps->Erase( PROP_PARA_LINE_SPACING );
// Then add the cell properties
pAllCellProps->InsertProps(*aCellIterator);
@@ -1018,29 +1018,59 @@ css::uno::Sequence<css::beans::PropertyValues> DomainMapperTableHandler::endTabl
// table style has got bigger precedence than docDefault style,
// but lower precedence than the paragraph styles and direct paragraph formatting
-void DomainMapperTableHandler::ApplyParaProperty(css::beans::PropertyValues aTableProperties, PropertyIds eId)
+void DomainMapperTableHandler::ApplyParagraphPropertiesFromTableStyle(TableInfo & rInfo)
{
- OUString sPropertyName = getPropertyName(eId);
- auto pTableProp = std::find_if(aTableProperties.begin(), aTableProperties.end(),
- [&](const beans::PropertyValue& rProp) { return rProp.Name == sPropertyName; });
- if (pTableProp != aTableProperties.end())
+ for( auto const& eId : rInfo.aTablePropertyIds )
{
- uno::Any aValue = pTableProp->Value;
- for (const auto& rParaProp : m_rDMapper_Impl.m_aParagraphsToEndTable)
+ // apply paragraph and character properties of the table style on table paragraphs
+ if ( isParagraphProperty(eId) || isCharacterProperty(eId) )
{
- // there is no direct paragraph formatting
- if (!rParaProp.m_pPropertyMap->isSet(eId))
+ // check all paragraphs of the table
+ for (const auto& rParaProp : m_rDMapper_Impl.m_aParagraphsToEndTable)
{
- OUString sParaStyleName;
- rParaProp.m_rPropertySet->getPropertyValue("ParaStyleName") >>= sParaStyleName;
- StyleSheetEntryPtr pEntry = m_rDMapper_Impl.GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(sParaStyleName);
- uno::Any aMargin = m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, pEntry, true, true);
- uno::Any aMarginDocDefault = m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, nullptr, true, true);
- // use table style only when 1) both values are empty (no docDefault and paragraph style definitions) or
- // 2) both non-empty values are equal (docDefault paragraph properties are copied to the base paragraph style during import)
- // TODO check the case, when two parent styles modify the docDefault and the last one set back the docDefault value
- if (aMargin == aMarginDocDefault)
- rParaProp.m_rPropertySet->setPropertyValue(sPropertyName, aValue);
+ // there is no direct paragraph formatting
+ if (!rParaProp.m_pPropertyMap->isSet(eId))
+ {
+ bool bDocDefault;
+ OUString sParaStyleName;
+ rParaProp.m_rPropertySet->getPropertyValue("ParaStyleName") >>= sParaStyleName;
+ StyleSheetEntryPtr pEntry = m_rDMapper_Impl.GetStyleSheetTable()->FindStyleSheetByConvertedStyleName(sParaStyleName);
+ uno::Any aParaStyle = m_rDMapper_Impl.GetPropertyFromStyleSheet(eId, pEntry, true, true, &bDocDefault);
+ // use table style when a docDefault value is applied instead of it,
+ // and there is no associated TableStyleSheetEntry
+ // TODO: replace CNF_ALL with the actual mask
+ if ( (aParaStyle == uno::Any() || bDocDefault) && !rInfo.pTableStyle->GetProperties(CNF_ALL)->getProperty(eId) )
+ {
+ OUString sPropertyName = getPropertyName(eId);
+ auto pTableProp = std::find_if(rInfo.aTableProperties.begin(), rInfo.aTableProperties.end(),
+ [&](const beans::PropertyValue& rProp) { return rProp.Name == sPropertyName; });
+ if (pTableProp != rInfo.aTableProperties.end())
+ {
+ try
+ {
+ rParaProp.m_rPropertySet->setPropertyValue( sPropertyName, pTableProp->Value );
+ }
+ catch ( const uno::Exception & )
+ {
+ SAL_WARN("writerfilter.dmapper", "Exception during table style correction");
+ }
+ }
+ }
+ // table style can overwrite paragraph style, when the paragraph style property has a default value, restore it
+ // TODO remove the associated TableStyleSheetEntry styles, if needed
+ else if ( aParaStyle != uno::Any() && !bDocDefault )
+ {
+ OUString sPropertyName = getPropertyName(eId);
+ try
+ {
+ rParaProp.m_rPropertySet->setPropertyValue( sPropertyName, aParaStyle );
+ }
+ catch ( const uno::Exception & )
+ {
+ SAL_WARN("writerfilter.dmapper", "Exception during table style correction");
+ }
+ }
+ }
}
}
}
@@ -1144,9 +1174,8 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab
}
}
- // OOXML table style may container paragraph properties, apply these now.
- ApplyParaProperty(aTableInfo.aTableProperties, PROP_PARA_BOTTOM_MARGIN);
- ApplyParaProperty(aTableInfo.aTableProperties, PROP_PARA_LINE_SPACING);
+ // OOXML table style may contain paragraph properties, apply these now.
+ ApplyParagraphPropertiesFromTableStyle(aTableInfo);
}
}
catch ( const lang::IllegalArgumentException &e )
diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
index 16d2a0cc37cc..b454be94f563 100644
--- a/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
+++ b/writerfilter/source/dmapper/DomainMapperTableHandler.hxx
@@ -91,7 +91,7 @@ public:
*/
void startTable(const TablePropertyMapPtr& pProps);
- void ApplyParaProperty(css::beans::PropertyValues aTableProperties, PropertyIds eId);
+ void ApplyParagraphPropertiesFromTableStyle(TableInfo & rInfo);
/// Handle end of table.
void endTable(unsigned int nestedTableLevel, bool bTableStartsAtCellStart);
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 2489f50ba94e..716c14e8a5bf 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -704,7 +704,7 @@ const OUString DomainMapper_Impl::GetDefaultParaStyleName()
return m_sDefaultParaStyleName;
}
-uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara)
+uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara, bool* pIsDocDefault)
{
while(pEntry.get( ) )
{
@@ -714,6 +714,9 @@ uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee
pEntry->pProperties->getProperty(eId);
if( aProperty )
{
+ if (pIsDocDefault)
+ *pIsDocDefault = pEntry->pProperties->isDocDefault(eId);
+
return aProperty->second;
}
}
@@ -737,7 +740,12 @@ uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee
{
boost::optional<PropertyMap::Property> aProperty = pDefaultParaProps->getProperty(eId);
if ( aProperty )
+ {
+ if (pIsDocDefault)
+ *pIsDocDefault = true;
+
return aProperty->second;
+ }
}
}
if ( bDocDefaults && isCharacterProperty(eId) )
@@ -747,9 +755,18 @@ uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee
{
boost::optional<PropertyMap::Property> aProperty = pDefaultCharProps->getProperty(eId);
if ( aProperty )
+ {
+ if (pIsDocDefault)
+ *pIsDocDefault = true;
+
return aProperty->second;
+ }
}
}
+
+ if (pIsDocDefault)
+ *pIsDocDefault = false;
+
return uno::Any();
}
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
index cf681ea34deb..955d806e5bab 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx
@@ -716,7 +716,7 @@ public:
const OUString GetDefaultParaStyleName();
// specified style - including inherited properties. Indicate whether paragraph defaults should be checked.
- css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId, StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara);
+ css::uno::Any GetPropertyFromStyleSheet(PropertyIds eId, StyleSheetEntryPtr pEntry, const bool bDocDefaults, const bool bPara, bool* bIsDocDefault = nullptr);
// current paragraph style - including inherited properties
css::uno::Any GetPropertyFromParaStyleSheet(PropertyIds eId);
// context's character style - including inherited properties
diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx
index 562f5f1795b1..35638f774c79 100644
--- a/writerfilter/source/dmapper/PropertyIds.cxx
+++ b/writerfilter/source/dmapper/PropertyIds.cxx
@@ -366,6 +366,11 @@ bool isCharacterProperty( const PropertyIds eId )
return eId > PROP_CHARACTER_STYLES && eId < PROP_CHARACTER_END;
}
+bool isParagraphProperty( const PropertyIds eId )
+{
+ return eId >= PROP_PARA_ADJUST && eId <= PROP_PARA_WIDOWS;
+}
+
} //namespace dmapper
} //namespace writerfilter
diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx
index 6b3136fe10a5..392c25e68b5a 100644
--- a/writerfilter/source/dmapper/PropertyIds.hxx
+++ b/writerfilter/source/dmapper/PropertyIds.hxx
@@ -363,6 +363,8 @@ OUString getPropertyName(PropertyIds eId);
bool isCharacterProperty(const PropertyIds eId);
+bool isParagraphProperty(const PropertyIds eId);
+
} //namespace dmapper
} // namespace writerfilter
#endif
diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx
index 5d51a89e976a..f1448dbd4423 100644
--- a/writerfilter/source/dmapper/PropertyMap.cxx
+++ b/writerfilter/source/dmapper/PropertyMap.cxx
@@ -189,6 +189,14 @@ uno::Sequence< beans::PropertyValue > PropertyMap::GetPropertyValues( bool bChar
return comphelper::containerToSequence( m_aValues );
}
+std::vector< PropertyIds > PropertyMap::GetPropertyIds()
+{
+ std::vector< PropertyIds > aRet;
+ for ( const auto& rPropPair : m_vMap )
+ aRet.push_back( rPropPair.first );
+ return aRet;
+}
+
#ifdef DEBUG_WRITERFILTER
static void lcl_AnyToTag( const uno::Any& rAny )
{
@@ -227,7 +235,7 @@ static void lcl_AnyToTag( const uno::Any& rAny )
}
#endif
-void PropertyMap::Insert( PropertyIds eId, const uno::Any& rAny, bool bOverwrite, GrabBagType i_GrabBagType )
+void PropertyMap::Insert( PropertyIds eId, const uno::Any& rAny, bool bOverwrite, GrabBagType i_GrabBagType, bool bDocDefault )
{
#ifdef DEBUG_WRITERFILTER
const OUString& rInsert = getPropertyName(eId);
@@ -239,7 +247,7 @@ void PropertyMap::Insert( PropertyIds eId, const uno::Any& rAny, bool bOverwrite
#endif
if ( !bOverwrite )
- m_vMap.insert(std::make_pair(eId, PropValue(rAny, i_GrabBagType)));
+ m_vMap.insert(std::make_pair(eId, PropValue(rAny, i_GrabBagType, bDocDefault)));
else
m_vMap[eId] = PropValue(rAny, i_GrabBagType);
@@ -268,6 +276,15 @@ bool PropertyMap::isSet( PropertyIds eId) const
return m_vMap.find( eId ) != m_vMap.end();
}
+bool PropertyMap::isDocDefault( PropertyIds eId ) const
+{
+ std::map< PropertyIds, PropValue >::const_iterator aIter = m_vMap.find( eId );
+ if ( aIter == m_vMap.end() )
+ return false;
+ else
+ return aIter->second.getIsDocDefault();
+}
+
#ifdef DEBUG_WRITERFILTER
void PropertyMap::dumpXml() const
{
@@ -324,7 +341,12 @@ void PropertyMap::InsertProps( const PropertyMapPtr& rMap, const bool bOverwrite
for ( const auto& rPropPair : rMap->m_vMap )
{
if ( bOverwrite || !m_vMap.count(rPropPair.first) )
- m_vMap[rPropPair.first] = rPropPair.second;
+ {
+ if ( !bOverwrite && !rPropPair.second.getIsDocDefault() )
+ m_vMap.insert(std::make_pair(rPropPair.first, PropValue(rPropPair.second.getValue(), rPropPair.second.getGrabBagType(), true)));
+ else
+ m_vMap[rPropPair.first] = rPropPair.second;
+ }
}
insertTableProperties( rMap.get(), bOverwrite );
diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx
index 6f16de26fe0a..9289534cc445 100644
--- a/writerfilter/source/dmapper/PropertyMap.hxx
+++ b/writerfilter/source/dmapper/PropertyMap.hxx
@@ -95,23 +95,35 @@ class PropValue
private:
css::uno::Any m_aValue;
GrabBagType m_GrabBagType;
+ bool m_bIsDocDefault;
public:
+ PropValue( const css::uno::Any& rValue, GrabBagType i_GrabBagType, bool bDocDefault )
+ : m_aValue( rValue )
+ , m_GrabBagType( i_GrabBagType )
+ , m_bIsDocDefault( bDocDefault )
+ {
+ }
+
PropValue( const css::uno::Any& rValue, GrabBagType i_GrabBagType )
: m_aValue( rValue )
, m_GrabBagType( i_GrabBagType )
+ , m_bIsDocDefault( false )
{
}
PropValue()
: m_aValue()
, m_GrabBagType( NO_GRAB_BAG )
+ , m_bIsDocDefault( false )
{
}
const css::uno::Any& getValue() const { return m_aValue; }
GrabBagType getGrabBagType() const { return m_GrabBagType; }
+
+ bool getIsDocDefault() const { return m_bIsDocDefault; }
};
class PropertyMap : public virtual SvRefBase
@@ -135,13 +147,15 @@ public:
// the contained properties are their Value.
css::uno::Sequence< css::beans::PropertyValue > GetPropertyValues( bool bCharGrabBag = true );
+ std::vector< PropertyIds > GetPropertyIds();
+
// Add property, optionally overwriting existing attributes
- void Insert( PropertyIds eId, const css::uno::Any& rAny, bool bOverwrite = true, GrabBagType i_GrabBagType = NO_GRAB_BAG );
+ void Insert( PropertyIds eId, const css::uno::Any& rAny, bool bOverwrite = true, GrabBagType i_GrabBagType = NO_GRAB_BAG, bool bDocDefault = false );
// Remove a named property from *this, does nothing if the property id has not been set
void Erase( PropertyIds eId);
- // Imports properties from pMap
+ // Imports properties from pMap (bOverwrite==false means m_bIsDocDefault=true setting)
void InsertProps( const tools::SvRef< PropertyMap >& rMap, const bool bOverwrite = true );
// Returns a copy of the property if it exists, .first is its PropertyIds and .second is its Value (type css::uno::Any)
@@ -149,6 +163,7 @@ public:
// Has the property named been set (via Insert)?
bool isSet( PropertyIds eId ) const;
+ bool isDocDefault( PropertyIds eId ) const;
const css::uno::Reference< css::text::XFootnote >& GetFootnote() const { return m_xFootnote; }
diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx
index 08145c98ad2f..31373d988611 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.cxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.cxx
@@ -397,6 +397,11 @@ StyleSheetTable::~StyleSheetTable()
{
}
+void StyleSheetTable::SetDefaultParaProps(PropertyIds eId, const css::uno::Any& rAny)
+{
+ m_pImpl->m_pDefaultParaProps->Insert(eId, rAny, /*bOverwrite=*/false, NO_GRAB_BAG, /*bDocDefault=*/true);
+}
+
PropertyMapPtr const & StyleSheetTable::GetDefaultParaProps()
{
return m_pImpl->m_pDefaultParaProps;
@@ -692,7 +697,7 @@ void StyleSheetTable::lcl_sprm(Sprm & rSprm)
if ( nSprmId == NS_ooxml::LN_CT_DocDefaults_pPrDefault && m_pImpl->m_pDefaultParaProps.get() &&
!m_pImpl->m_pDefaultParaProps->isSet( PROP_PARA_TOP_MARGIN ) )
{
- m_pImpl->m_pDefaultParaProps->Insert( PROP_PARA_TOP_MARGIN, uno::makeAny( sal_Int32(0) ) );
+ SetDefaultParaProps( PROP_PARA_TOP_MARGIN, uno::makeAny( sal_Int32(0) ) );
}
m_pImpl->m_rDMapper.PopStyleSheetProperties();
applyDefaults( true );
@@ -999,7 +1004,7 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable )
else if( bParaStyle )
{
// Paragraph styles that don't inherit from some parent need to apply the DocDefaults
- pEntry->pProperties->InsertProps( m_pImpl->m_pDefaultParaProps, /*bAllowOverwrite=*/false );
+ pEntry->pProperties->InsertProps( m_pImpl->m_pDefaultParaProps, /*bOverwrite=*/false );
//now it's time to set the default parameters - for paragraph styles
//Fonts: Western first entry in font table
@@ -1467,13 +1472,13 @@ void StyleSheetTable::applyDefaults(bool bParaProperties)
if( bParaProperties && m_pImpl->m_pDefaultParaProps.get())
{
// tdf#87533 LO will have different defaults here, depending on the locale. Import with documented defaults
- m_pImpl->m_pDefaultParaProps->Insert(PROP_WRITING_MODE, uno::makeAny(sal_Int16(text::WritingMode_LR_TB)), /*bOverwrite=*/false);
- m_pImpl->m_pDefaultParaProps->Insert(PROP_PARA_ADJUST, uno::makeAny(sal_Int16(style::ParagraphAdjust_LEFT)), false);
+ SetDefaultParaProps(PROP_WRITING_MODE, uno::makeAny(sal_Int16(text::WritingMode_LR_TB)));
+ SetDefaultParaProps(PROP_PARA_ADJUST, uno::makeAny(sal_Int16(style::ParagraphAdjust_LEFT)));
// Widow/Orphan -> set both to two if not already set
uno::Any aTwo = uno::makeAny(sal_Int8(2));
- m_pImpl->m_pDefaultParaProps->Insert(PROP_PARA_WIDOWS, aTwo, /*bOverwrite=*/false);
- m_pImpl->m_pDefaultParaProps->Insert(PROP_PARA_ORPHANS, aTwo, false);
+ SetDefaultParaProps(PROP_PARA_WIDOWS, aTwo);
+ SetDefaultParaProps(PROP_PARA_ORPHANS, aTwo);
uno::Reference<style::XStyleFamiliesSupplier> xStylesSupplier(m_pImpl->m_xTextDocument, uno::UNO_QUERY);
uno::Reference<container::XNameAccess> xStyleFamilies = xStylesSupplier->getStyleFamilies();
diff --git a/writerfilter/source/dmapper/StyleSheetTable.hxx b/writerfilter/source/dmapper/StyleSheetTable.hxx
index 686779acbd71..ee621093079e 100644
--- a/writerfilter/source/dmapper/StyleSheetTable.hxx
+++ b/writerfilter/source/dmapper/StyleSheetTable.hxx
@@ -102,6 +102,7 @@ public:
OUString getOrCreateCharStyle( PropertyValueVector_t& rCharProperties, bool bAlwaysCreate );
+ void SetDefaultParaProps(PropertyIds eId, const css::uno::Any& rAny);
PropertyMapPtr const & GetDefaultParaProps();
/// Returns the default character properties.
PropertyMapPtr const & GetDefaultCharProps();