From 40fba0f4418084d50cc5c388cb0b6e1abe395d61 Mon Sep 17 00:00:00 2001 From: Jakub Trzebiatowski Date: Tue, 21 Jun 2016 00:31:01 +0200 Subject: GSoC Writer Table Styles Import This patch is implementing import of table styles (table-template). Modified shared code: Added "background" to the cell styles export. To make cell export properties map accessible by both export and import code, moved from xmloff/source/table/XMLTableExport.cxx to xmloff/txtprmap.hxx. To avoid export of default valued properties implemented XPropertyState for SwXTextCellStyle Change-Id: I8b4f12e4b51f478f8ce8fde1203cd4611d7ae852 Reviewed-on: https://gerrit.libreoffice.org/26721 Tested-by: Jenkins Reviewed-by: Miklos Vajna --- xmloff/source/style/prstylei.cxx | 25 ++++--- xmloff/source/table/XMLTableExport.cxx | 30 +------- xmloff/source/table/XMLTableImport.cxx | 129 ++++++++++++++++++++++++++++++++- xmloff/source/table/table.hxx | 1 + xmloff/source/text/txtimp.cxx | 23 ++++++ xmloff/source/text/txtprmap.cxx | 26 +++++++ 6 files changed, 193 insertions(+), 41 deletions(-) (limited to 'xmloff') diff --git a/xmloff/source/style/prstylei.cxx b/xmloff/source/style/prstylei.cxx index 5c1b63b2e666..9aa121bdb53b 100644 --- a/xmloff/source/style/prstylei.cxx +++ b/xmloff/source/style/prstylei.cxx @@ -385,8 +385,6 @@ void XMLPropStyleContext::CreateAndInsert( bool bOverwrite ) if( bOverwrite || bNew ) { - Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY ); - rtl::Reference < XMLPropertySetMapper > xPrMap; if( xImpPrMap.is() ) xPrMap = xImpPrMap->getPropertySetMapper(); @@ -409,17 +407,20 @@ void XMLPropStyleContext::CreateAndInsert( bool bOverwrite ) if( xPropSetInfo->hasPropertyByName( rPrName ) ) aNameSet.insert( rPrName ); } - - nCount = aNameSet.size(); - Sequence aNames( comphelper::containerToSequence(aNameSet) ); - Sequence < PropertyState > aStates( xPropState->getPropertyStates(aNames) ); - const PropertyState *pStates = aStates.getConstArray(); - OUString* pNames = aNames.getArray(); - - for( i = 0; i < nCount; i++ ) + Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY ); + if (xPropState.is()) { - if( PropertyState_DIRECT_VALUE == *pStates++ ) - xPropState->setPropertyToDefault( pNames[i] ); + nCount = aNameSet.size(); + Sequence aNames( comphelper::containerToSequence(aNameSet) ); + Sequence < PropertyState > aStates( xPropState->getPropertyStates(aNames) ); + const PropertyState *pStates = aStates.getConstArray(); + OUString* pNames = aNames.getArray(); + + for( i = 0; i < nCount; i++ ) + { + if( PropertyState_DIRECT_VALUE == *pStates++ ) + xPropState->setPropertyToDefault( pNames[i] ); + } } } } diff --git a/xmloff/source/table/XMLTableExport.cxx b/xmloff/source/table/XMLTableExport.cxx index f0f51c7fdd09..ecf3fe023189 100644 --- a/xmloff/source/table/XMLTableExport.cxx +++ b/xmloff/source/table/XMLTableExport.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "table.hxx" @@ -61,7 +62,6 @@ using namespace ::com::sun::star::style; #define MAP_(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010, false } #define CMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_COLUMN,context) #define RMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_ROW,context) -#define CELLMAP(name,prefix,token,type,context) MAP_(name,prefix,token,type|XML_TYPE_PROP_TABLE_CELL,context) #define MAP_END { nullptr, 0, 0, XML_EMPTY, 0, 0, SvtSaveOptions::ODFVER_010, false } const XMLPropertyMapEntry* getColumnPropertiesMap() @@ -89,29 +89,6 @@ const XMLPropertyMapEntry* getRowPropertiesMap() return &aXMLRowProperties[0]; } -const XMLPropertyMapEntry* getSwCellStylePropertiesMap() -{ - static const XMLPropertyMapEntry aXMLSwCellStyleProperties[] = - { - CELLMAP( "BackColor", XML_NAMESPACE_FO, XML_BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, 0 ), - CELLMAP( "LeftBorder", XML_NAMESPACE_FO, XML_BORDER_LEFT, XML_TYPE_BORDER, 0 ), - CELLMAP( "RightBorder", XML_NAMESPACE_FO, XML_BORDER_RIGHT, XML_TYPE_BORDER, 0 ), - CELLMAP( "TopBorder", XML_NAMESPACE_FO, XML_BORDER_TOP, XML_TYPE_BORDER, 0 ), - CELLMAP( "BottomBorder", XML_NAMESPACE_FO, XML_BORDER_BOTTOM, XML_TYPE_BORDER, 0 ), - CELLMAP( "BorderDistance", XML_NAMESPACE_FO, XML_PADDING, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), - CELLMAP( "LeftBorderDistance", XML_NAMESPACE_FO, XML_PADDING_LEFT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), - CELLMAP( "RightBorderDistance", XML_NAMESPACE_FO, XML_PADDING_RIGHT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), - CELLMAP( "TopBorderDistance", XML_NAMESPACE_FO, XML_PADDING_TOP, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), - CELLMAP( "BottomBorderDistance", XML_NAMESPACE_FO, XML_PADDING_BOTTOM, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), - CELLMAP( "VertOrient", XML_NAMESPACE_STYLE, XML_VERTICAL_ALIGN, XML_TYPE_TEXT_VERTICAL_POS, 0 ), - CELLMAP( "WritingMode", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT, 0 ), - CELLMAP( "NumberFormat", XML_NAMESPACE_STYLE, XML_DATA_STYLE_NAME, XML_TYPE_NUMBER, 0 ), - MAP_END - }; - - return &aXMLSwCellStyleProperties[0]; -} - class StringStatisticHelper { private: @@ -184,7 +161,7 @@ XMLTableExport::XMLTableExport(SvXMLExport& rExp, const rtl::Reference< SvXMLExp if (mbWriter) { - mxCellExportPropertySetMapper = new SvXMLExportPropertyMapper( new XMLPropertySetMapper( getSwCellStylePropertiesMap(), xFactoryRef.get(), true ) ); + mxCellExportPropertySetMapper = new SvXMLExportPropertyMapper(new XMLTextPropertySetMapper(TextPropMap::CELL, true)); } else { @@ -534,6 +511,7 @@ const TableStyleElement* getTableStyleMap() { XML_ODD_ROWS, OUString("odd-rows") }, { XML_EVEN_COLUMNS, OUString("even-columns") }, { XML_ODD_COLUMNS, OUString("odd-columns") }, + { XML_BACKGROUND, OUString("background") }, { XML_TOKEN_END, OUString() } }; @@ -596,7 +574,7 @@ void XMLTableExport::exportTableTemplates() const TableStyleElement* pElements; if (mbWriter) { - mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, GetExport().EncodeStyleName(xTableStyle->getName())); + mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, xTableStyle->getName()); Reference xTableStylePropSet(xTableStyle.get(), UNO_QUERY_THROW); pElements = getWriterSpecificTableStyleAttributes(); while(pElements->meElement != XML_TOKEN_END) diff --git a/xmloff/source/table/XMLTableImport.cxx b/xmloff/source/table/XMLTableImport.cxx index d4b505d8bb9e..6ac15996f9d0 100644 --- a/xmloff/source/table/XMLTableImport.cxx +++ b/xmloff/source/table/XMLTableImport.cxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,7 @@ #include #include +#include #include "table.hxx" #include @@ -160,6 +162,7 @@ public: virtual void EndElement() override; + virtual void CreateAndInsert( bool bOverwrite ) override; private: XMLTableTemplate maTableTemplate; OUString msTemplateStyleName; @@ -186,8 +189,37 @@ SvXMLImportContext * XMLProxyContext::CreateChildContext( sal_uInt16 nPrefix, co XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef ) : mrImport( rImport ) { - mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper.get(), rImport ); - mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport)); + bool bWriter = false; + // check if called by Writer + Reference xFac(rImport.GetModel(), UNO_QUERY); + if (xFac.is()) try + { + Sequence sSNS = xFac->getAvailableServiceNames(); + const sal_Int32 nLength = sSNS.getLength(); + const OUString* pSNS = sSNS.getConstArray(); + for (sal_Int32 i=0; i < nLength; ++i, ++pSNS) + { + if (*pSNS == "com.sun.star.style.TableStyle") + { + bWriter = true; + break; + } + } + } + catch(const Exception&) + { + SAL_WARN("xmloff.table", "Error while checking avaiable service names"); + } + + if (bWriter) + { + mxCellImportPropertySetMapper = XMLTextImportHelper::CreateTableCellExtPropMapper(rImport); + } + else + { + mxCellImportPropertySetMapper = new SvXMLImportPropertyMapper( xCellPropertySetMapper.get(), rImport ); + mxCellImportPropertySetMapper->ChainImportMapper(XMLTextImportHelper::CreateParaExtPropMapper(rImport)); + } rtl::Reference < XMLPropertySetMapper > xRowMapper( new XMLPropertySetMapper( getRowPropertiesMap(), xFactoryRef.get(), false ) ); mxRowImportPropertySetMapper = new SvXMLImportPropertyMapper( xRowMapper, rImport ); @@ -218,6 +250,67 @@ void XMLTableImport::addTableTemplate( const OUString& rsStyleName, XMLTableTemp maTableTemplates[rsStyleName] = xPtr; } +void XMLTableImport::insertTabletemplate(const OUString& rsStyleName, bool bOverwrite) +{ + XMLTableTemplateMap::iterator it = maTableTemplates.find(rsStyleName); + if (it == maTableTemplates.end()) + return; + + try + { + Reference xFamiliesSupp(mrImport.GetModel(), UNO_QUERY_THROW); + Reference xFamilies(xFamiliesSupp->getStyleFamilies()); + const OUString sFamilyName("TableStyles"); + const OUString sCellFamilyName("CellStyles"); + + Reference xTableFamily(xFamilies->getByName(sFamilyName), UNO_QUERY_THROW); + Reference xCellFamily(xFamilies->getByName(sCellFamilyName), UNO_QUERY_THROW); + + const OUString sTemplateName(it->first); + Reference xFactory(mrImport.GetModel(), UNO_QUERY_THROW); + Reference xTemplate(xFactory->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW); + + std::shared_ptr xT(it->second); + + for (auto aStyleIter=xT->begin(); aStyleIter != xT->end(); ++aStyleIter) try + { + const OUString sPropName((*aStyleIter).first); + const OUString sStyleName((*aStyleIter).second); + // Internally unassigned cell styles are stored by display name. + // However table-template elements reference cell styles by its encoded name. + // This loop is looking for cell style by their encoded names. + sal_Int32 nCount = xCellFamily->getCount(); + for (sal_Int32 i=0; i < nCount; ++i) + { + Any xCellStyle = xCellFamily->getByIndex(i); + OUString sEncodedStyleName = mrImport.GetMM100UnitConverter().encodeStyleName( + xCellStyle.get>()->getName()); + if (sEncodedStyleName == sStyleName) + { + xTemplate->replaceByName(sPropName, xCellStyle); + break; + } + } + } + catch (Exception&) + { + SAL_WARN("xmloff.table", "XMLTableImport::insertTabletemplate(), exception caught!"); + } + + if (xTemplate.is()) + { + if (xTableFamily->hasByName(sTemplateName) && bOverwrite) + xTableFamily->replaceByName(sTemplateName, Any(xTemplate)); + else + xTableFamily->insertByName(sTemplateName, Any(xTemplate)); + } + } + catch (Exception&) + { + SAL_WARN("xmloff.table", "XMLTableImport::insertTabletemplate(), exception caught!"); + } +} + void XMLTableImport::finishStyles() { if( !maTableTemplates.empty() ) try @@ -692,7 +785,9 @@ void XMLTableTemplateContext::StartElement( const Reference< XAttributeList >& x { OUString sAttrName; sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( xAttrList->getNameByIndex( i ), &sAttrName ); - if( (nAttrPrefix == XML_NAMESPACE_TEXT ) && IsXMLToken( sAttrName, XML_STYLE_NAME ) ) + if( (nAttrPrefix == XML_NAMESPACE_TEXT && IsXMLToken( sAttrName, XML_STYLE_NAME )) + // Writer specific: according to oasis odf 1.2 prefix should be "table" and element name should be "name" + || (nAttrPrefix == XML_NAMESPACE_TABLE && IsXMLToken( sAttrName, XML_NAME ))) { msTemplateStyleName = xAttrList->getValueByIndex( i ); break; @@ -707,6 +802,13 @@ void XMLTableTemplateContext::EndElement() xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate ); } +void XMLTableTemplateContext::CreateAndInsert(bool bOverwrite) +{ + rtl::Reference xTableImport(GetImport().GetShapeImport()->GetShapeTableImport()); + if(xTableImport.is()) + xTableImport->insertTabletemplate(msTemplateStyleName, bOverwrite); +} + SvXMLImportContext * XMLTableTemplateContext::CreateChildContext( sal_uInt16 nPrefix, const OUString& rLocalName, const Reference< XAttributeList >& xAttrList ) { if( nPrefix == XML_NAMESPACE_TABLE ) @@ -730,6 +832,27 @@ SvXMLImportContext * XMLTableTemplateContext::CreateChildContext( sal_uInt16 nPr } } } + } else if (nPrefix == XML_NAMESPACE_LO_EXT) // Writer specific cell styles + { + const TableStyleElement* pElements = getWriterSpecificTableStyleMap(); + while ((pElements->meElement != XML_TOKEN_END) && !IsXMLToken(rLocalName, pElements->meElement )) + pElements++; + + if (pElements->meElement != XML_TOKEN_END) + { + sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0; + for (sal_Int16 i=0; i < nAttrCount; i++) + { + OUString sAttrName; + sal_uInt16 nAttrPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName(xAttrList->getNameByIndex( i ), &sAttrName); + if( (nAttrPrefix == XML_NAMESPACE_TEXT || nAttrPrefix == XML_NAMESPACE_TABLE) && + IsXMLToken( sAttrName, XML_STYLE_NAME ) ) + { + maTableTemplate[pElements->msStyleName] = xAttrList->getValueByIndex(i); + break; + } + } + } } return SvXMLImportContext::CreateChildContext( nPrefix, rLocalName, xAttrList ); diff --git a/xmloff/source/table/table.hxx b/xmloff/source/table/table.hxx index 4488c97e3b27..cb00e7cb13f4 100644 --- a/xmloff/source/table/table.hxx +++ b/xmloff/source/table/table.hxx @@ -31,6 +31,7 @@ struct TableStyleElement }; extern const TableStyleElement* getTableStyleMap(); +extern const TableStyleElement* getWriterSpecificTableStyleMap(); extern const XMLPropertyMapEntry* getColumnPropertiesMap(); extern const XMLPropertyMapEntry* getRowPropertiesMap(); diff --git a/xmloff/source/text/txtimp.cxx b/xmloff/source/text/txtimp.cxx index 9fb143c65887..468c31ea7f88 100644 --- a/xmloff/source/text/txtimp.cxx +++ b/xmloff/source/text/txtimp.cxx @@ -545,6 +545,7 @@ struct XMLTextImportHelper::Impl uno::Reference m_xNumStyles; uno::Reference m_xFrameStyles; uno::Reference m_xPageStyles; + uno::Reference m_xCellStyles; uno::Reference m_xChapterNumbering; uno::Reference m_xTextFrames; uno::Reference m_xGraphics; @@ -679,6 +680,12 @@ XMLTextImportHelper::GetPageStyles() const return m_xImpl->m_xPageStyles; } +uno::Reference const& +XMLTextImportHelper::GetCellStyles() const +{ + return m_xImpl->m_xCellStyles; +} + uno::Reference const& XMLTextImportHelper::GetChapterNumbering() const { @@ -969,6 +976,13 @@ XMLTextImportHelper::XMLTextImportHelper( m_xImpl->m_xPageStyles.set(xFamilies->getByName(aPageStyles), UNO_QUERY); } + + const OUString aCellStyles("CellStyles"); + if( xFamilies->hasByName( aCellStyles ) ) + { + m_xImpl->m_xCellStyles.set(xFamilies->getByName(aCellStyles), + UNO_QUERY); + } } Reference < XTextFramesSupplier > xTFS( rModel, UNO_QUERY ); @@ -1060,6 +1074,15 @@ SvXMLImportPropertyMapper* return new SvXMLImportPropertyMapper( pPropMapper, rImport ); } +SvXMLImportPropertyMapper* + XMLTextImportHelper::CreateTableCellExtPropMapper( + SvXMLImport& rImport ) +{ + XMLPropertySetMapper *pPropMapper = + new XMLTextPropertySetMapper( TextPropMap::CELL, false ); + return new SvXMLImportPropertyMapper( pPropMapper, rImport ); +} + void XMLTextImportHelper::SetCursor( const Reference < XTextCursor > & rCursor ) { m_xImpl->m_xCursor.set(rCursor); diff --git a/xmloff/source/text/txtprmap.cxx b/xmloff/source/text/txtprmap.cxx index dc60fae7fb8d..b6c8a02cac9d 100644 --- a/xmloff/source/text/txtprmap.cxx +++ b/xmloff/source/text/txtprmap.cxx @@ -70,6 +70,10 @@ using namespace ::xmloff::token; #define MR_E( a, p, l, t, c ) \ M_E_( a, p, l, (t|XML_TYPE_PROP_RUBY), c ) +// cell propertiess +#define MC_E( a, p, l, t, c ) \ + M_E_( a, p, l, (t|XML_TYPE_PROP_TABLE_CELL), c ) + // extensions import/export #define MAP_EXT(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_012_EXT_COMPAT, false } // extensions import only @@ -992,6 +996,25 @@ XMLPropertyMapEntry aXMLTableRowDefaultsMap[] = M_END() }; +XMLPropertyMapEntry aXMLCellPropMap[] = +{ + MC_E( "BackColor", FO, BACKGROUND_COLOR, XML_TYPE_COLORTRANSPARENT|MID_FLAG_MULTI_PROPERTY, 0 ), + MC_E( "LeftBorder", FO, BORDER_LEFT, XML_TYPE_BORDER, 0 ), + MC_E( "RightBorder", FO, BORDER_RIGHT, XML_TYPE_BORDER, 0 ), + MC_E( "TopBorder", FO, BORDER_TOP, XML_TYPE_BORDER, 0 ), + MC_E( "BottomBorder", FO, BORDER_BOTTOM, XML_TYPE_BORDER, 0 ), + MC_E( "BorderDistance", FO, PADDING, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), + MC_E( "LeftBorderDistance", FO, PADDING_LEFT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), + MC_E( "RightBorderDistance", FO, PADDING_RIGHT, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), + MC_E( "TopBorderDistance", FO, PADDING_TOP, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), + MC_E( "BottomBorderDistance", FO, PADDING_BOTTOM, XML_TYPE_MEASURE|MID_FLAG_MULTI_PROPERTY, 0 ), + MC_E( "VertOrient", STYLE, VERTICAL_ALIGN, XML_TYPE_TEXT_VERTICAL_POS, 0 ), + MC_E( "WritingMode", STYLE, WRITING_MODE, XML_TYPE_TEXT_WRITING_MODE_WITH_DEFAULT, 0 ), + MC_E( "NumberFormat", STYLE, DATA_STYLE_NAME, XML_TYPE_NUMBER, 0 ), + + M_END() +}; + static XMLPropertyMapEntry *lcl_txtprmap_getMap( TextPropMap nType ) { XMLPropertyMapEntry *pMap = nullptr; @@ -1036,6 +1059,9 @@ static XMLPropertyMapEntry *lcl_txtprmap_getMap( TextPropMap nType ) case TextPropMap::TABLE_ROW_DEFAULTS: pMap = aXMLTableRowDefaultsMap; break; + case TextPropMap::CELL: + pMap = aXMLCellPropMap; + break; } SAL_WARN_IF( !pMap, "xmloff", "illegal map type" ); return pMap; -- cgit