offapi/com/sun/star/table/CellProperties.idl | 10 ++ offapi/com/sun/star/text/TextTable.idl | 10 ++ sw/inc/unoprnms.hxx | 2 sw/qa/extras/ooxmlexport/data/table-theme-preservation.docx |binary sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 22 ++++ sw/source/core/bastyp/init.cxx | 2 sw/source/core/unocore/unomap.cxx | 2 sw/source/filter/ww8/docxattributeoutput.cxx | 60 +++++++++++- writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 11 ++ writerfilter/source/dmapper/PropertyIds.cxx | 2 writerfilter/source/dmapper/PropertyIds.hxx | 2 writerfilter/source/dmapper/TablePropertiesHandler.cxx | 10 +- 12 files changed, 125 insertions(+), 8 deletions(-)
New commits: commit 3e9d9b073f1b8fd934e00c8cff69fb0f9ef40781 Author: Jacobo Aragunde Pérez <jaragu...@igalia.com> Date: Wed Apr 2 16:39:06 2014 +0200 oox: Preserve table style. Table style is a property that defines a set of background and line attributes for cells. These attributes depend on theme settings (e.g. theme colors). We added a grabbag to the table object to save the table style name. We detect that name on export and write it back to the document. Finally, modified an existing unit test to check this attribute too. TODO: To get the table style working properly after a roundtrip, we must preserve it and also check that its values are not being overwritten by different cell or table properties. Change-Id: Id0e022a389561960c21ab874db33649499735024 diff --git a/offapi/com/sun/star/text/TextTable.idl b/offapi/com/sun/star/text/TextTable.idl index c637fe0..9771210 100644 --- a/offapi/com/sun/star/text/TextTable.idl +++ b/offapi/com/sun/star/text/TextTable.idl @@ -211,6 +211,16 @@ published service TextTable */ [optional, property] boolean CollapsingBorders; + /** Grab bag of table properties, used as a string-any map for interim interop purposes. + + @since LibreOffice 4.3 + + <p>This property is intentionally not handled by the ODF filter. Any + member that should be handled there should be first moved out from this grab + bag to a separate property.</p> + */ + [optional, property] sequence<com::sun::star::beans::PropertyValue> TableInteropGrabBag; + }; diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index 280c7e4..be90c9d 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -840,6 +840,7 @@ #define UNO_NAME_CHAR_INTEROP_GRAB_BAG "CharInteropGrabBag" #define UNO_NAME_TEXT_VERT_ADJUST "TextVerticalAdjust" #define UNO_NAME_CELL_INTEROP_GRAB_BAG "CellInteropGrabBag" +#define UNO_NAME_TABLE_INTEROP_GRAB_BAG "TableInteropGrabBag" #endif diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 04f474c..15a5ddf 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -1953,6 +1953,10 @@ DECLARE_OOXMLEXPORT_TEST(testTableThemePreservation, "table-theme-preservation.d assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFill", "accent6"); assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFillShade", "80"); assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFillTint", ""); + + // check table style has been preserved + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tblPr/w:tblStyle", "val", "Sombreadoclaro-nfasis1"); + } DECLARE_OOXMLEXPORT_TEST(testcantSplit, "2_table_doc.docx") diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index af76602..fce0a3b 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -195,6 +195,7 @@ sal_uInt16 aTableSetRange[] = { RES_COLLAPSING_BORDERS, RES_COLLAPSING_BORDERS, // <-- collapsing RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + RES_FRMATR_GRABBAG, RES_FRMATR_GRABBAG, 0 }; diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx index 7e0a059..efe34b1 100644 --- a/sw/source/core/unocore/unomap.cxx +++ b/sw/source/core/unocore/unomap.cxx @@ -1100,6 +1100,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s // #i29550# { OUString(UNO_NAME_COLLAPSING_BORDERS), RES_COLLAPSING_BORDERS, cppu::UnoType<bool>::get(), PROPERTY_NONE, 0}, _REDLINE_NODE_PROPERTIES + { OUString(UNO_NAME_TABLE_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, { OUString(), 0, css::uno::Type(), 0, 0 } }; diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index d7cc220..dd8ee93 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2672,6 +2672,22 @@ void DocxAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t FSNS( XML_w, XML_type ), widthType, FSEND ); + // Look for the table style property in the table grab bag + const SfxPoolItem *pI = NULL; + std::map<OUString, com::sun::star::uno::Any> aGrabBag; + if ( SFX_ITEM_ON == pTblFmt->GetAttrSet().GetItemState( RES_FRMATR_GRABBAG, false, &pI ) ) + aGrabBag = dynamic_cast<const SfxGrabBagItem *>(pI)->GetGrabBag(); + + // Write table style property if it exists + std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement = aGrabBag.find("TableStyleName"); + if( aGrabBagElement != aGrabBag.end() ) + { + OString sStyleName = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 ); + m_pSerializer->singleElementNS( XML_w, XML_tblStyle, + FSNS( XML_w, XML_val ), sStyleName.getStr(), + FSEND ); + } + // Output the table alignement const char* pJcVal; sal_Int32 nIndent = 0; diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index a9a4221..7ed56aa 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -340,6 +340,8 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo PropertyMap::iterator aTableStyleIter = m_aTableProperties->find(META_PROP_TABLE_STYLE_NAME); + uno::Sequence< beans::PropertyValue > aGrabBag( 1 ); + sal_Int32 nGrabBagSize = 0; if(aTableStyleIter != m_aTableProperties->end()) { // Apply table style properties recursively @@ -350,6 +352,10 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo pTableStyle = dynamic_cast<TableStyleSheetEntry*>( pStyleSheet.get( ) ); m_aTableProperties->erase( aTableStyleIter ); + aGrabBag[0].Name = "TableStyleName"; + aGrabBag[0].Value = uno::makeAny( sTableStyleName ); + nGrabBagSize++; + if( pStyleSheet ) { // First get the style properties, then the table ones @@ -394,6 +400,11 @@ TableStyleSheetEntry * DomainMapperTableHandler::endTableGetTableStyle(TableInfo dmapper_logger->endElement(); #endif + if( nGrabBagSize > 0 ) + { + m_aTableProperties->Insert( PROP_TABLE_INTEROP_GRAB_BAG, uno::makeAny( aGrabBag ) ); + } + m_aTableProperties->getValue( TablePropertyMap::GAP_HALF, nGapHalf ); m_aTableProperties->getValue( TablePropertyMap::LEFT_MARGIN, nLeftMargin ); diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index 24e523b..1aa4252 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -389,6 +389,7 @@ OUString PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_CHAR_CNTXTALTS_TEXT_EFFECT : sName = "CharCntxtAltsTextEffect"; break; case PROP_SDTPR : sName = "SdtPr"; break; case PROP_CELL_INTEROP_GRAB_BAG : sName = "CellInteropGrabBag"; break; + case PROP_TABLE_INTEROP_GRAB_BAG : sName = "TableInteropGrabBag"; break; } ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt = m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName )); diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index ab6f92f..88d1c89 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -361,6 +361,7 @@ enum PropertyIds ,PROP_CHAR_CNTXTALTS_TEXT_EFFECT ,PROP_SDTPR ,PROP_CELL_INTEROP_GRAB_BAG + ,PROP_TABLE_INTEROP_GRAB_BAG }; struct PropertyNameSupplier_Impl; class PropertyNameSupplier commit a3efbb5d33f5c6928141fd3e7aa7c6d3bdc6a087 Author: Jacobo Aragunde Pérez <jaragu...@igalia.com> Date: Tue Apr 1 17:18:39 2014 +0200 oox: Preserve cell theme color. When some background color is set to a table cell, it is stored in the cell properties tag <tcPr> like this: <w:shd w:fill="ECD2B6" w:color="auto" w:themeFill="accent6" w:themeFillTint="66" w:val="clear"/> The theme-related attributes in w:shd were not being preserved. To fix this I added an InteropGrabBag to the cell properties object, which is filled with the attributes of w:shd to be checked on export. The exporter checks if the cell color is still the original color that was imported from the file, if it is not it means the user has manually changed it during the edition and the new color is written instead. Finally, added a unit test for theme attributes on tables. Change-Id: Ica8091b5eb4075e51912a255650a1d9d64f5767a diff --git a/offapi/com/sun/star/table/CellProperties.idl b/offapi/com/sun/star/table/CellProperties.idl index 94b71db..3e01b31 100644 --- a/offapi/com/sun/star/table/CellProperties.idl +++ b/offapi/com/sun/star/table/CellProperties.idl @@ -263,6 +263,16 @@ published service CellProperties */ [optional, property] com::sun::star::table::BorderLine2 DiagonalBLTR2; + /** Grab bag of cell properties, used as a string-any map for interim interop purposes. + + @since LibreOffice 4.3 + + <p>This property is intentionally not handled by the ODF filter. Any + member that should be handled there should be first moved out from this grab + bag to a separate property.</p> + */ + [optional, property] sequence<com::sun::star::beans::PropertyValue> CellInteropGrabBag; + }; diff --git a/sw/inc/unoprnms.hxx b/sw/inc/unoprnms.hxx index ab08fc2..280c7e4 100644 --- a/sw/inc/unoprnms.hxx +++ b/sw/inc/unoprnms.hxx @@ -839,6 +839,7 @@ #define UNO_NAME_STYLE_INTEROP_GRAB_BAG "StyleInteropGrabBag" #define UNO_NAME_CHAR_INTEROP_GRAB_BAG "CharInteropGrabBag" #define UNO_NAME_TEXT_VERT_ADJUST "TextVerticalAdjust" +#define UNO_NAME_CELL_INTEROP_GRAB_BAG "CellInteropGrabBag" #endif diff --git a/sw/qa/extras/ooxmlexport/data/table-theme-preservation.docx b/sw/qa/extras/ooxmlexport/data/table-theme-preservation.docx new file mode 100644 index 0000000..fe6b953 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/table-theme-preservation.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index fd080d0..04f474c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -1937,6 +1937,24 @@ DECLARE_OOXMLEXPORT_TEST(testThemePreservation, "theme-preservation.docx") assertXPath(pXmlDocument, "/w:document/w:body/w:p[6]/w:pPr/w:shd", "themeFill", "text2"); } +DECLARE_OOXMLEXPORT_TEST(testTableThemePreservation, "table-theme-preservation.docx") +{ + xmlDocPtr pXmlDocument = parseExport("word/document.xml"); + if (!pXmlDocument) + return; + + // check cell theme colors have been preserved + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd", "themeFill", "accent6"); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd", "themeFillShade", ""); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[1]/w:tcPr/w:shd", "themeFillTint", "33"); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:shd", "themeFill", "accent6"); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:shd", "themeFillShade", ""); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[2]/w:tcPr/w:shd", "themeFillTint", ""); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFill", "accent6"); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFillShade", "80"); + assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[2]/w:tc[3]/w:tcPr/w:shd", "themeFillTint", ""); +} + DECLARE_OOXMLEXPORT_TEST(testcantSplit, "2_table_doc.docx") { // if Split table value is true for a table then during export do not write <w:cantSplit w:val="false"/> diff --git a/sw/source/core/bastyp/init.cxx b/sw/source/core/bastyp/init.cxx index e3b5743..af76602 100644 --- a/sw/source/core/bastyp/init.cxx +++ b/sw/source/core/bastyp/init.cxx @@ -218,6 +218,7 @@ sal_uInt16 aTableBoxSetRange[] = { RES_FRAMEDIR, RES_FRAMEDIR, RES_BOXATR_BEGIN, RES_BOXATR_END-1, RES_UNKNOWNATR_BEGIN, RES_UNKNOWNATR_END-1, + RES_FRMATR_GRABBAG, RES_FRMATR_GRABBAG, 0 }; diff --git a/sw/source/core/unocore/unomap.cxx b/sw/source/core/unocore/unomap.cxx index 1e7125a..7e0a059 100644 --- a/sw/source/core/unocore/unomap.cxx +++ b/sw/source/core/unocore/unomap.cxx @@ -1132,6 +1132,7 @@ const SfxItemPropertyMapEntry* SwUnoPropertyMapProvider::GetPropertyMapEntries(s { OUString(UNO_NAME_VERT_ORIENT), RES_VERT_ORIENT, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE ,MID_VERTORIENT_ORIENT }, { OUString(UNO_NAME_WRITING_MODE), RES_FRAMEDIR, cppu::UnoType<sal_Int16>::get(), PROPERTY_NONE, 0 }, { OUString(UNO_NAME_ROW_SPAN), FN_UNO_CELL_ROW_SPAN, cppu::UnoType<sal_Int32>::get(), 0, 0 }, + { OUString(UNO_NAME_CELL_INTEROP_GRAB_BAG), RES_FRMATR_GRABBAG, cppu::UnoType< cppu::UnoSequenceType<css::beans::PropertyValue> >::get(), PROPERTY_NONE, 0 }, _REDLINE_NODE_PROPERTIES { OUString(), 0, css::uno::Type(), 0, 0 } }; diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index 6e71a6d..d7cc220 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -2781,10 +2781,46 @@ void DocxAttributeOutput::TableBackgrounds( ww8::WW8TableNodeInfoInner::Pointer_ aColor = COL_AUTO; OString sColor = msfilter::util::ConvertColor( aColor ); - m_pSerializer->singleElementNS( XML_w, XML_shd, - FSNS( XML_w, XML_fill ), sColor.getStr( ), - FSNS( XML_w, XML_val ), "clear", - FSEND ); + + std::map<OUString, com::sun::star::uno::Any> aGrabBag; + if ( SFX_ITEM_ON == pFmt->GetAttrSet().GetItemState( RES_FRMATR_GRABBAG, false, &pI ) ) + aGrabBag = dynamic_cast<const SfxGrabBagItem *>(pI)->GetGrabBag(); + + OString sOriginalColor; + std::map<OUString, com::sun::star::uno::Any>::iterator aGrabBagElement = aGrabBag.find("fill"); + if( aGrabBagElement != aGrabBag.end() ) + sOriginalColor = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 ); + + if ( sOriginalColor != sColor ) + { + // color changed by the user, or no grab bag: write sColor + m_pSerializer->singleElementNS( XML_w, XML_shd, + FSNS( XML_w, XML_fill ), sColor.getStr( ), + FSNS( XML_w, XML_val ), "clear", + FSEND ); + } + else + { + ::sax_fastparser::FastAttributeList* aAttrList = NULL; + AddToAttrList( aAttrList, FSNS( XML_w, XML_fill ), sColor.getStr() ); + + for( aGrabBagElement = aGrabBag.begin(); aGrabBagElement != aGrabBag.end(); ++aGrabBagElement ) + { + OString sValue = OUStringToOString( aGrabBagElement->second.get<OUString>(), RTL_TEXTENCODING_UTF8 ); + if( aGrabBagElement->first == "themeFill") + AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFill ), sValue.getStr() ); + else if( aGrabBagElement->first == "themeFillTint") + AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillTint ), sValue.getStr() ); + else if( aGrabBagElement->first == "themeFillShade") + AddToAttrList( aAttrList, FSNS( XML_w, XML_themeFillShade ), sValue.getStr() ); + else if( aGrabBagElement->first == "color") + AddToAttrList( aAttrList, FSNS( XML_w, XML_color ), sValue.getStr() ); + else if( aGrabBagElement->first == "val") + AddToAttrList( aAttrList, FSNS( XML_w, XML_val ), sValue.getStr() ); + } + m_pSerializer->singleElementNS( XML_w, XML_shd, + XFastAttributeListRef( aAttrList ) ); + } } void DocxAttributeOutput::TableRowRedline( ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner ) diff --git a/writerfilter/source/dmapper/PropertyIds.cxx b/writerfilter/source/dmapper/PropertyIds.cxx index 8bdba4e..24e523b 100644 --- a/writerfilter/source/dmapper/PropertyIds.cxx +++ b/writerfilter/source/dmapper/PropertyIds.cxx @@ -388,6 +388,7 @@ OUString PropertyNameSupplier::GetName( PropertyIds eId ) const case PROP_CHAR_STYLISTICSETS_TEXT_EFFECT : sName = "CharStylisticSetsTextEffect"; break; case PROP_CHAR_CNTXTALTS_TEXT_EFFECT : sName = "CharCntxtAltsTextEffect"; break; case PROP_SDTPR : sName = "SdtPr"; break; + case PROP_CELL_INTEROP_GRAB_BAG : sName = "CellInteropGrabBag"; break; } ::std::pair<PropertyNameMap_t::iterator,bool> aInsertIt = m_pImpl->aNameMap.insert( PropertyNameMap_t::value_type( eId, sName )); diff --git a/writerfilter/source/dmapper/PropertyIds.hxx b/writerfilter/source/dmapper/PropertyIds.hxx index 1d29c0b..ab6f92f 100644 --- a/writerfilter/source/dmapper/PropertyIds.hxx +++ b/writerfilter/source/dmapper/PropertyIds.hxx @@ -360,6 +360,7 @@ enum PropertyIds ,PROP_CHAR_STYLISTICSETS_TEXT_EFFECT ,PROP_CHAR_CNTXTALTS_TEXT_EFFECT ,PROP_SDTPR + ,PROP_CELL_INTEROP_GRAB_BAG }; struct PropertyNameSupplier_Impl; class PropertyNameSupplier diff --git a/writerfilter/source/dmapper/TablePropertiesHandler.cxx b/writerfilter/source/dmapper/TablePropertiesHandler.cxx index e5e4172..877c602 100644 --- a/writerfilter/source/dmapper/TablePropertiesHandler.cxx +++ b/writerfilter/source/dmapper/TablePropertiesHandler.cxx @@ -322,12 +322,14 @@ namespace dmapper { if( pProperties.get()) { CellColorHandlerPtr pCellColorHandler( new CellColorHandler ); - if (m_pCurrentInteropGrabBag) - pCellColorHandler->enableInteropGrabBag("shd"); + pCellColorHandler->enableInteropGrabBag("shd"); //enable to store shd unsupported props in grab bag pProperties->resolve( *pCellColorHandler ); + beans::PropertyValue aGrabBag = pCellColorHandler->getInteropGrabBag(); if (m_pCurrentInteropGrabBag) - m_pCurrentInteropGrabBag->push_back(pCellColorHandler->getInteropGrabBag()); - cellProps( pCellColorHandler->getProperties()); + m_pCurrentInteropGrabBag->push_back(aGrabBag); + TablePropertyMapPtr pPropertyMap = pCellColorHandler->getProperties(); + pPropertyMap->Insert( PROP_CELL_INTEROP_GRAB_BAG, aGrabBag.Value ); + cellProps( pPropertyMap ); } } break;
_______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits