include/xmloff/table/XMLTableImport.hxx |    3 -
 sd/qa/unit/misc-tests.cxx               |   52 ++++++++++++++++++
 sw/source/filter/xml/xmlfmt.cxx         |    2 
 xmloff/source/table/XMLTableExport.cxx  |    4 -
 xmloff/source/table/XMLTableImport.cxx  |   92 ++++----------------------------
 5 files changed, 70 insertions(+), 83 deletions(-)

New commits:
commit 95a3d7733c5b48c99b2b74b06c7eeee718fdcd03
Author:     Maxim Monastirsky <momonas...@gmail.com>
AuthorDate: Thu Dec 8 14:07:36 2022 +0200
Commit:     Maxim Monastirsky <momonas...@gmail.com>
CommitDate: Fri Dec 9 00:13:42 2022 +0000

    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 <momonas...@gmail.com>

diff --git a/include/xmloff/table/XMLTableImport.hxx 
b/include/xmloff/table/XMLTableImport.hxx
index 0889637f2e23..3577ed8adedf 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 8d21591e12b9..9bd4d2a5f41b 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 65b6be09d2ff..40899a4fda84 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 )
commit 8bd31225d79f10993d0e0727ee7d27c729874b51
Author:     Maxim Monastirsky <momonas...@gmail.com>
AuthorDate: Wed Dec 7 15:51:01 2022 +0200
Commit:     Maxim Monastirsky <momonas...@gmail.com>
CommitDate: Fri Dec 9 00:13:30 2022 +0000

    Fix sd encoded table style name handling
    
    Found this while looking into improving insertion of pages
    with tables, as SdDrawDocument::InsertBookmarkAsPage uses "_"
    as the rename suffix for styles with identical names but a
    different content.
    
    This commit fixes two issues:
    
    - For import, cell styles with encoded names couldn't be found
    by table styles. The reason is that styles are referenced in
    ODF by encoded names, but at runtime by display names. Yet we
    were searching the cell style family by encoded names. This was
    already handled for sw in insertTabletemplate(), and now do the
    same for sd.
    
    - For export, table template names were encoded, but then
    referenced by tables using their non-encoded names. This is
    unlike the sw code that doesn't encode them, and therefore
    doesn't have this problem. Looking at the schema, both
    table:name attribute of a table template, and table:template-name
    attribute of a table are of type "string", which suggests that
    there is indeed no need to encode those names. This aligns with
    the fact that table templates don't have a display-name attribute.
    
    Change-Id: Ie61b6a1c95b033404ee98f3fc40d8e82434a6a6c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143839
    Tested-by: Jenkins
    Reviewed-by: Maxim Monastirsky <momonas...@gmail.com>

diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
index bc741c6ac2fe..ee03008dfb47 100644
--- a/sd/qa/unit/misc-tests.cxx
+++ b/sd/qa/unit/misc-tests.cxx
@@ -24,6 +24,7 @@
 #include <com/sun/star/container/XIndexAccess.hpp>
 #include <com/sun/star/table/XTable.hpp>
 #include <com/sun/star/table/XMergeableCellRange.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
 
 #include <DrawDocShell.hxx>
 #include <drawdoc.hxx>
@@ -80,6 +81,7 @@ public:
     void testTdf131033();
     void testTdf129898LayerDrawnInSlideshow();
     void testTdf136956();
+    void testEncodedTableStyles();
 
     CPPUNIT_TEST_SUITE(SdMiscTest);
     CPPUNIT_TEST(testTdf99396);
@@ -101,6 +103,7 @@ public:
     CPPUNIT_TEST(testTdf131033);
     CPPUNIT_TEST(testTdf129898LayerDrawnInSlideshow);
     CPPUNIT_TEST(testTdf136956);
+    CPPUNIT_TEST(testEncodedTableStyles);
     CPPUNIT_TEST_SUITE_END();
 
     virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override
@@ -891,6 +894,55 @@ void SdMiscTest::testTdf136956()
     CPPUNIT_ASSERT_EQUAL(sal_Int32(3), xTable->getRowCount());
 }
 
+void SdMiscTest::testEncodedTableStyles()
+{
+    // Silence unrelated failure:
+    // Error: element "table:table-template" is missing 
"first-row-start-column" attribute
+    skipValidation();
+
+    createSdDrawDoc();
+
+    {
+        uno::Reference<style::XStyleFamiliesSupplier> 
xStyleFamiliesSupplier(mxComponent,
+                                                                             
uno::UNO_QUERY_THROW);
+        uno::Reference<css::lang::XSingleServiceFactory> xTableStyleFamily(
+            xStyleFamiliesSupplier->getStyleFamilies()->getByName("table"), 
uno::UNO_QUERY_THROW);
+        uno::Reference<css::lang::XSingleServiceFactory> xCellStyleFamily(
+            xStyleFamiliesSupplier->getStyleFamilies()->getByName("cell"), 
uno::UNO_QUERY_THROW);
+
+        uno::Reference<style::XStyle> 
xTableStyle(xTableStyleFamily->createInstance(),
+                                                  uno::UNO_QUERY_THROW);
+        uno::Reference<style::XStyle> 
xCellStyle(xCellStyleFamily->createInstance(),
+                                                 uno::UNO_QUERY_THROW);
+
+        uno::Reference<container::XNameContainer>(xTableStyleFamily, 
uno::UNO_QUERY_THROW)
+            ->insertByName("table_1", uno::Any(xTableStyle));
+        uno::Reference<container::XNameContainer>(xCellStyleFamily, 
uno::UNO_QUERY_THROW)
+            ->insertByName("table-body_1", uno::Any(xCellStyle));
+        uno::Reference<container::XNameReplace>(xTableStyle, 
uno::UNO_QUERY_THROW)
+            ->replaceByName("body", uno::Any(xCellStyle));
+    }
+
+    saveAndReload("draw8");
+
+    {
+        uno::Reference<style::XStyleFamiliesSupplier> 
xStyleFamiliesSupplier(mxComponent,
+                                                                             
uno::UNO_QUERY_THROW);
+        uno::Reference<container::XNameAccess> xTableStyleFamily(
+            xStyleFamiliesSupplier->getStyleFamilies()->getByName("table"), 
uno::UNO_QUERY_THROW);
+        // Such style used to be exported as "table_5f_1" instead.
+        CPPUNIT_ASSERT(xTableStyleFamily->hasByName("table_1"));
+
+        uno::Reference<container::XNameAccess> 
xTableStyle(xTableStyleFamily->getByName("table_1"),
+                                                           
uno::UNO_QUERY_THROW);
+        uno::Reference<style::XStyle> 
xCellStyle(xTableStyle->getByName("body"), uno::UNO_QUERY);
+        // Such style used to not be found by the table style, as it was
+        // searching for "table-body_5f_1" instead of "table-body_1".
+        CPPUNIT_ASSERT(xCellStyle.is());
+        CPPUNIT_ASSERT_EQUAL(OUString("table-body_1"), xCellStyle->getName());
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/xmloff/source/table/XMLTableExport.cxx 
b/xmloff/source/table/XMLTableExport.cxx
index f415bb171af9..0b8fd95aadda 100644
--- a/xmloff/source/table/XMLTableExport.cxx
+++ b/xmloff/source/table/XMLTableExport.cxx
@@ -640,9 +640,9 @@ void XMLTableExport::exportTableTemplates()
                     // tdf#106780 historically this wrong attribute was used
                     // for the name; write it if extended because LO < 5.3 can
                     // read only text:style-name, not the correct table:name
-                    mrExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, 
GetExport().EncodeStyleName( xTableStyle->getName() ) );
+                    mrExport.AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME, 
xTableStyle->getName());
                 }
-                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, 
GetExport().EncodeStyleName(xTableStyle->getName()));
+                mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, 
xTableStyle->getName());
             }
 
             SvXMLElementExport tableTemplate( mrExport, XML_NAMESPACE_TABLE, 
XML_TABLE_TEMPLATE, true, true );
diff --git a/xmloff/source/table/XMLTableImport.cxx 
b/xmloff/source/table/XMLTableImport.cxx
index afc86cf4000c..65b6be09d2ff 100644
--- a/xmloff/source/table/XMLTableImport.cxx
+++ b/xmloff/source/table/XMLTableImport.cxx
@@ -376,7 +376,7 @@ void XMLTableImport::finishStyles()
             for( const auto& rStyle : *xT ) try
             {
                 const OUString sPropName( rStyle.first );
-                const OUString sStyleName( rStyle.second );
+                const OUString sStyleName( 
mrImport.GetStyleDisplayName(XmlStyleFamily::TABLE_CELL, rStyle.second) );
                 xTemplate->replaceByName( sPropName, xCellFamily->getByName( 
sStyleName ) );
             }
             catch( Exception& )

Reply via email to