Deduplicate table styles insertion
(Not adding a test here, as this should already be covered
by several tests in sw/qa/extras/odfexport/odfexport.cxx.)
Change-Id: Ic3cae9f38efc55d3d9055a45bc642d7b15fa382a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143840
Tested-by: Jenkins
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
diff --git a/include/xmloff/table/XMLTableImport.hxx b/include/xmloff/table/XMLTableImport.hxx
index 0889637..3577ed8 100644
--- a/include/xmloff/table/XMLTableImport.hxx
+++ b/include/xmloff/table/XMLTableImport.hxx
@@ -58,13 +58,12 @@ public:
const rtl::Reference< SvXMLImportPropertyMapper >& GetColumnImportPropertySetMapper() const { return mxColumnImportPropertySetMapper; }
void addTableTemplate( const OUString& rsStyleName, XMLTableTemplate& xTableTemplate );
/// Inserts to the doc template with given name.
void insertTabletemplate( const OUString& rsStyleName, bool bOverwrite);
/// Inserts all table templates.
void finishStyles();
private:
SvXMLImport& mrImport;
bool mbWriter;
rtl::Reference< SvXMLImportPropertyMapper > mxCellImportPropertySetMapper;
rtl::Reference< SvXMLImportPropertyMapper > mxRowImportPropertySetMapper;
rtl::Reference< SvXMLImportPropertyMapper > mxColumnImportPropertySetMapper;
diff --git a/sw/source/filter/xml/xmlfmt.cxx b/sw/source/filter/xml/xmlfmt.cxx
index 8d21591..9bd4d2a 100644
--- a/sw/source/filter/xml/xmlfmt.cxx
+++ b/sw/source/filter/xml/xmlfmt.cxx
@@ -919,6 +919,8 @@ OUString SwXMLStylesContext_Impl::GetServiceName( XmlStyleFamily nFamily ) const
void SwXMLStylesContext_Impl::endFastElement(sal_Int32 )
{
GetSwImport().InsertStyles( IsAutomaticStyle() );
if (!IsAutomaticStyle())
GetImport().GetShapeImport()->GetShapeTableImport()->finishStyles();
}
namespace {
diff --git a/xmloff/source/table/XMLTableImport.cxx b/xmloff/source/table/XMLTableImport.cxx
index 65b6be0..40899a4 100644
--- a/xmloff/source/table/XMLTableImport.cxx
+++ b/xmloff/source/table/XMLTableImport.cxx
@@ -206,7 +206,6 @@ public:
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
virtual void CreateAndInsert( bool bOverwrite ) override;
protected:
virtual void SetAttribute( sal_Int32 nElement,
const OUString& rValue ) override;
@@ -234,21 +233,21 @@ css::uno::Reference< css::xml::sax::XFastContextHandler > XMLProxyContext::creat
XMLTableImport::XMLTableImport( SvXMLImport& rImport, const rtl::Reference< XMLPropertySetMapper >& xCellPropertySetMapper, const rtl::Reference< XMLPropertyHandlerFactory >& xFactoryRef )
: mrImport( rImport )
, mbWriter( false )
{
bool bWriter = false;
// check if called by Writer
Reference<XMultiServiceFactory> xFac(rImport.GetModel(), UNO_QUERY);
if (xFac.is()) try
{
Sequence<OUString> sSNS = xFac->getAvailableServiceNames();
bWriter = comphelper::findValue(sSNS, "com.sun.star.style.TableStyle") != -1;
mbWriter = comphelper::findValue(sSNS, "com.sun.star.style.TableStyle") != -1;
}
catch(const Exception&)
{
SAL_WARN("xmloff.table", "Error while checking available service names");
}
if (bWriter)
if (mbWriter)
{
mxCellImportPropertySetMapper = XMLTextImportHelper::CreateTableCellExtPropMapper(rImport);
}
@@ -288,69 +287,6 @@ void XMLTableImport::addTableTemplate( const OUString& rsStyleName, XMLTableTemp
maTableTemplates.emplace_back(rsStyleName, xPtr);
}
void XMLTableImport::insertTabletemplate(const OUString& rsStyleName, bool bOverwrite)
{
// FIXME: All templates will be inserted eventually, but
// instead of simply iterating them, like in finishStyles(),
// we search here by name again and again.
auto it = std::find_if(maTableTemplates.begin(), maTableTemplates.end(),
[&rsStyleName](const auto& item) { return rsStyleName == item.first; });
if (it == maTableTemplates.end())
return;
try
{
Reference<XStyleFamiliesSupplier> xFamiliesSupp(mrImport.GetModel(), UNO_QUERY_THROW);
Reference<XNameAccess> xFamilies(xFamiliesSupp->getStyleFamilies());
Reference<XNameContainer> xTableFamily(xFamilies->getByName("TableStyles"), UNO_QUERY_THROW);
Reference<XIndexAccess> xCellFamily(xFamilies->getByName("CellStyles"), UNO_QUERY_THROW);
const OUString sTemplateName(it->first);
Reference<XMultiServiceFactory> xFactory(mrImport.GetModel(), UNO_QUERY_THROW);
Reference<XNameReplace> xTemplate(xFactory->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW);
std::shared_ptr<XMLTableTemplate> xT(it->second);
for (const auto& rStyle : *xT) try
{
const OUString sPropName(rStyle.first);
const OUString sStyleName(rStyle.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<Reference<XStyle>>()->getName());
if (sEncodedStyleName == sStyleName)
{
xTemplate->replaceByName(sPropName, xCellStyle);
break;
}
}
}
catch (Exception const &)
{
TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
}
if (xTemplate.is())
{
if (xTableFamily->hasByName(sTemplateName) && bOverwrite)
xTableFamily->replaceByName(sTemplateName, Any(xTemplate));
else
xTableFamily->insertByName(sTemplateName, Any(xTemplate));
}
}
catch (Exception&)
{
TOOLS_WARN_EXCEPTION("xmloff.table", "XMLTableImport::insertTabletemplate()");
}
}
void XMLTableImport::finishStyles()
{
if( maTableTemplates.empty() )
@@ -361,15 +297,20 @@ void XMLTableImport::finishStyles()
Reference< XStyleFamiliesSupplier > xFamiliesSupp( mrImport.GetModel(), UNO_QUERY_THROW );
Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
Reference< XNameContainer > xTableFamily( xFamilies->getByName( "table" ), UNO_QUERY_THROW );
Reference< XNameAccess > xCellFamily( xFamilies->getByName( "cell" ), UNO_QUERY_THROW );
const OUString aTableFamily(mbWriter ? u"TableStyles" : u"table");
const OUString aCellFamily(mbWriter ? u"CellStyles" : u"cell");
Reference< XNameContainer > xTableFamily( xFamilies->getByName( aTableFamily ), UNO_QUERY_THROW );
Reference< XNameAccess > xCellFamily( xFamilies->getByName( aCellFamily ), UNO_QUERY_THROW );
Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY_THROW );
Reference< XSingleServiceFactory > xFactory( xTableFamily, UNO_QUERY );
assert(xFactory.is() != mbWriter);
Reference< XMultiServiceFactory > xMultiFactory( mrImport.GetModel(), UNO_QUERY_THROW );
for( const auto& rTemplate : maTableTemplates ) try
{
const OUString sTemplateName( rTemplate.first );
Reference< XNameReplace > xTemplate( xFactory->createInstance(), UNO_QUERY_THROW );
Reference< XNameReplace > xTemplate(xFactory ? xFactory->createInstance() :
xMultiFactory->createInstance("com.sun.star.style.TableStyle"), UNO_QUERY_THROW);
std::shared_ptr< XMLTableTemplate > xT( rTemplate.second );
@@ -790,13 +731,6 @@ void XMLTableTemplateContext::endFastElement(sal_Int32 )
xTableImport->addTableTemplate( msTemplateStyleName, maTableTemplate );
}
void XMLTableTemplateContext::CreateAndInsert(bool bOverwrite)
{
rtl::Reference<XMLTableImport> xTableImport(GetImport().GetShapeImport()->GetShapeTableImport());
if(xTableImport.is())
xTableImport->insertTabletemplate(msTemplateStyleName, bOverwrite);
}
css::uno::Reference< css::xml::sax::XFastContextHandler > XMLTableTemplateContext::createFastChildContext(
sal_Int32 nElement,
const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )