sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx |binary sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx |binary sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx |binary sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 3 sw/qa/extras/ooxmlexport/ooxmlexport6.cxx | 6 - sw/qa/extras/ooxmlexport/ooxmlexport9.cxx | 65 +++++++++++ writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 79 +++++++++----- writerfilter/source/dmapper/DomainMapperTableHandler.hxx | 2 writerfilter/source/dmapper/DomainMapper_Impl.cxx | 19 +++ writerfilter/source/dmapper/DomainMapper_Impl.hxx | 2 writerfilter/source/dmapper/PropertyIds.cxx | 5 writerfilter/source/dmapper/PropertyIds.hxx | 2 writerfilter/source/dmapper/PropertyMap.cxx | 28 ++++ writerfilter/source/dmapper/PropertyMap.hxx | 19 +++ writerfilter/source/dmapper/StyleSheetTable.cxx | 17 +-- writerfilter/source/dmapper/StyleSheetTable.hxx | 1 17 files changed, 203 insertions(+), 45 deletions(-)
New commits: commit f15d67442972c5f69c71925a6bfa5aa1a39d54eb Author: László Németh <nem...@numbertext.org> AuthorDate: Tue Feb 4 19:31:41 2020 +0100 Commit: László Németh <nem...@numbertext.org> CommitDate: Wed Feb 12 14:16:30 2020 +0100 tdf#129575 DOCX import: fix table style preference handling by recognizing docDefault properties instead of default-value based heuristics. Change-Id: I3bab9d85d77d0e5f1c357121b1caf02cbe4899c4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88457 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> 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 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf129575-directAfter.docx 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 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf129575-directBefore.docx 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 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf129575-docDefault.docx 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 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf129575-styleAfter.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index 550255d54e8a..27c66c141357 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -325,8 +325,6 @@ DECLARE_OOXMLEXPORT_TEST(testTdf123636_newlinePageBreak4, "tdf123636_newlinePage assertXPath(pDump, "/root/page[2]/body/txt[1]/Text", 0); } -// disabled temporarily, next commit enables it again -#if 0 DECLARE_OOXMLEXPORT_TEST(testTdf118947_tableStyle, "tdf118947_tableStyle.docx") { uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY); @@ -354,7 +352,6 @@ DECLARE_OOXMLEXPORT_TEST(testTdf118947_tableStyle, "tdf118947_tableStyle.docx") CPPUNIT_ASSERT_EQUAL_MESSAGE("Table style sets 0 right margin", sal_Int32(0), getProperty<sal_Int32>(xPara, "ParaRightMargin")); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Table sets 2.5 line-spacing", sal_Int16(250), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height, 1); } -#endif DECLARE_OOXMLEXPORT_TEST(tdf123912_protectedForm, "tdf123912_protectedForm.odt") { diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx index 3b5726dceb28..45bcc9ac5f27 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport6.cxx @@ -459,9 +459,9 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128752, "tdf128752.docx") DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf119054, "tdf119054.docx") { xmlDocPtr pXmlDoc = parseExport(); - // 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 149b5dc3e3cd..df96f077389a 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport9.cxx @@ -30,6 +30,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> @@ -184,6 +185,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 e753852985a7..ab51d4fdd48d 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -59,6 +59,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, @@ -225,6 +226,7 @@ struct TableInfo PropertyMapPtr pTableBorders; TableStyleSheetEntry* pTableStyle; css::beans::PropertyValues aTableProperties; + std::vector< PropertyIds > aTablePropertyIds; TableInfo() : nLeftBorderDistance(DEF_BORDER_DIST) @@ -664,6 +666,7 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo } rInfo.aTableProperties = m_aTableProperties->GetPropertyValues(); + rInfo.aTablePropertyIds = m_aTableProperties->GetPropertyIds(); #ifdef DBG_UTIL TagLogger::getInstance().startElement("debug.tableprops"); @@ -863,9 +866,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); @@ -1066,29 +1066,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 & ) + { + TOOLS_INFO_EXCEPTION("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 & ) + { + TOOLS_INFO_EXCEPTION("writerfilter.dmapper", "Exception during table style correction"); + } + } + } } } } @@ -1192,9 +1222,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 & ) 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 2f3e79ec852e..259e1ebbf678 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -807,7 +807,7 @@ 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( ) ) { @@ -817,6 +817,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; } } @@ -840,7 +843,12 @@ uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee { o3tl::optional<PropertyMap::Property> aProperty = pDefaultParaProps->getProperty(eId); if ( aProperty ) + { + if (pIsDocDefault) + *pIsDocDefault = true; + return aProperty->second; + } } } if ( bDocDefaults && isCharacterProperty(eId) ) @@ -850,9 +858,18 @@ uno::Any DomainMapper_Impl::GetPropertyFromStyleSheet(PropertyIds eId, StyleShee { o3tl::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 bc688a463cd7..0fd51ab2298e 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -761,7 +761,7 @@ public: 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 8b925fe37f9f..bb133dff2f7a 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -364,6 +364,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 writerfilter /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index b2e10a13ee46..ce238f340a59 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -362,6 +362,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 69cc86a73153..b15e17696a78 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -185,6 +185,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 DBG_UTIL static void lcl_AnyToTag( const uno::Any& rAny ) { @@ -223,7 +231,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 DBG_UTIL const OUString& rInsert = getPropertyName(eId); @@ -235,7 +243,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); @@ -264,6 +272,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 DBG_UTIL void PropertyMap::dumpXml() const { @@ -320,7 +337,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 b7603301ccc8..11df0d8fad9c 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; @@ -139,13 +151,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 PropertyMapPtr& 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) @@ -153,6 +167,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; } const OUString& GetFootnoteStyle() const { return m_sFootnoteCharStyleName; } diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx index bf3fb63664ed..33c22e357110 100644 --- a/writerfilter/source/dmapper/StyleSheetTable.cxx +++ b/writerfilter/source/dmapper/StyleSheetTable.cxx @@ -396,6 +396,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() const { return m_pImpl->m_pDefaultParaProps; @@ -691,7 +696,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 ); @@ -990,7 +995,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 @@ -1454,13 +1459,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 0866852c36e6..0d367de59f52 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() const; /// Returns the default character properties. PropertyMapPtr const & GetDefaultCharProps() const; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits