sc/qa/unit/data/ods/two-col-shape.ods  |binary
 sc/qa/unit/helper/qahelper.cxx         |   18 +++++---
 sc/qa/unit/helper/qahelper.hxx         |    2 
 sc/qa/unit/subsequent_export-test2.cxx |   74 +++++++++++++++++++++++++++++++++
 sc/source/filter/xml/xmlexprt.cxx      |    7 ++-
 5 files changed, 94 insertions(+), 7 deletions(-)

New commits:
commit c8be3338287ba3bdb6af377d89939751cbb295b4
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Tue Aug 24 19:40:34 2021 +0300
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Aug 26 09:28:46 2021 +0200

    tdf#143929: chain XMLTextExportPropertySetMapper to sc's shape export
    
    This allows to export editengine columns to ODS. Alternatively, we could
    re-introduce chaining text attributes in XMLShapeExport ctor, which was
    commented out in commit d5b1e4827f8e6e0661563ec856cd80d926ba7b58 without
    explanation; but that would affect export from other modules as well
    (e.g., SdXMLExport::setSourceDocument sets up respective chaining in sd),
    so to be on the safe side, I do it only for ScXMLShapeExport.
    
    Change-Id: Iafee77b2b57e95031cfe1bbd2d43d7361a3e8469
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120958
    Tested-by: Mike Kaganski <mike.kagan...@collabora.com>
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    (cherry picked from commit cfa931784082d38bb6b98058c5acccbaf9870710)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120989
    Tested-by: Jenkins
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sc/qa/unit/data/ods/two-col-shape.ods 
b/sc/qa/unit/data/ods/two-col-shape.ods
new file mode 100644
index 000000000000..3829546b1c27
Binary files /dev/null and b/sc/qa/unit/data/ods/two-col-shape.ods differ
diff --git a/sc/qa/unit/helper/qahelper.cxx b/sc/qa/unit/helper/qahelper.cxx
index 590250847d95..64c23cef7c36 100644
--- a/sc/qa/unit/helper/qahelper.cxx
+++ b/sc/qa/unit/helper/qahelper.cxx
@@ -629,20 +629,26 @@ ScDocShellRef ScBootstrapFixture::load(
     return load( false, rURL, rFilter, rUserData, rTypeName, nFilterFlags, 
nClipboardID,  nFilterVersion, pPassword );
 }
 
-ScDocShellRef ScBootstrapFixture::loadDoc(
-    std::u16string_view rFileName, sal_Int32 nFormat, bool bReadWrite )
+ScDocShellRef ScBootstrapFixture::load(const OUString& rURL, sal_Int32 
nFormat, bool bReadWrite)
 {
-    OUString aFileExtension(aFileFormats[nFormat].pName, 
strlen(aFileFormats[nFormat].pName), RTL_TEXTENCODING_UTF8 );
     OUString aFilterName(aFileFormats[nFormat].pFilterName, 
strlen(aFileFormats[nFormat].pFilterName), RTL_TEXTENCODING_UTF8) ;
-    OUString aFileName;
-    createFileURL( rFileName, aFileExtension, aFileName );
     OUString aFilterType(aFileFormats[nFormat].pTypeName, 
strlen(aFileFormats[nFormat].pTypeName), RTL_TEXTENCODING_UTF8);
     SfxFilterFlags nFormatType = aFileFormats[nFormat].nFormatType;
     SotClipboardFormatId nClipboardId = SotClipboardFormatId::NONE;
     if (nFormatType != SfxFilterFlags::NONE)
         nClipboardId = SotClipboardFormatId::STARCALC_8;
 
-    return load(bReadWrite, aFileName, aFilterName, OUString(), aFilterType, 
nFormatType, nClipboardId, static_cast<sal_uIntPtr>(nFormatType));
+    return load(bReadWrite, rURL, aFilterName, OUString(), aFilterType, 
nFormatType, nClipboardId, static_cast<sal_uIntPtr>(nFormatType));
+}
+
+ScDocShellRef ScBootstrapFixture::loadDoc(
+    std::u16string_view rFileName, sal_Int32 nFormat, bool bReadWrite )
+{
+    OUString aFileExtension = OUString::fromUtf8(aFileFormats[nFormat].pName);
+    OUString aFileName;
+    createFileURL( rFileName, aFileExtension, aFileName );
+
+    return load(aFileName, nFormat, bReadWrite);
 }
 
 ScBootstrapFixture::ScBootstrapFixture( const OUString& rsBaseString ) : 
m_aBaseString( rsBaseString ) {}
diff --git a/sc/qa/unit/helper/qahelper.hxx b/sc/qa/unit/helper/qahelper.hxx
index ce981b5c9346..0435ef021651 100644
--- a/sc/qa/unit/helper/qahelper.hxx
+++ b/sc/qa/unit/helper/qahelper.hxx
@@ -199,6 +199,8 @@ protected:
         const OUString& rTypeName, SfxFilterFlags nFilterFlags, 
SotClipboardFormatId nClipboardID,
         sal_uIntPtr nFilterVersion = SOFFICE_FILEFORMAT_CURRENT, const 
OUString* pPassword = nullptr );
 
+    ScDocShellRef load(const OUString& rURL, sal_Int32 nFormat, bool 
bReadWrite = false);
+
     ScDocShellRef loadDoc(
         std::u16string_view rFileName, sal_Int32 nFormat, bool bReadWrite = 
false );
 
diff --git a/sc/qa/unit/subsequent_export-test2.cxx 
b/sc/qa/unit/subsequent_export-test2.cxx
index a67648215744..c467b19196aa 100644
--- a/sc/qa/unit/subsequent_export-test2.cxx
+++ b/sc/qa/unit/subsequent_export-test2.cxx
@@ -82,6 +82,7 @@
 #include <com/sun/star/frame/Desktop.hpp>
 #include <com/sun/star/graphic/GraphicType.hpp>
 #include <com/sun/star/sheet/GlobalSheetSettings.hpp>
+#include <com/sun/star/text/XTextColumns.hpp>
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::uno;
@@ -197,6 +198,7 @@ public:
     void testTdf142929_filterLessThanXLSX();
     void testTdf143220XLSX();
     void testTdf142264ManyChartsToXLSX();
+    void testTdf143929MultiColumnToODS();
 
     CPPUNIT_TEST_SUITE(ScExportTest2);
 
@@ -297,6 +299,7 @@ public:
     CPPUNIT_TEST(testTdf142929_filterLessThanXLSX);
     CPPUNIT_TEST(testTdf143220XLSX);
     CPPUNIT_TEST(testTdf142264ManyChartsToXLSX);
+    CPPUNIT_TEST(testTdf143929MultiColumnToODS);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2458,6 +2461,77 @@ void ScExportTest2::testTdf142264ManyChartsToXLSX()
     xDocSh->DoClose();
 }
 
+void ScExportTest2::testTdf143929MultiColumnToODS()
+{
+    ScDocShellRef xDocSh = loadDoc(u"two-col-shape.", FORMAT_ODS);
+    CPPUNIT_ASSERT(xDocSh);
+
+    {
+        css::uno::Reference<css::drawing::XDrawPagesSupplier> 
xSupplier(xDocSh->GetModel(),
+                                                                        
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::drawing::XDrawPage> 
xPage(xSupplier->getDrawPages()->getByIndex(0),
+                                                           
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::container::XIndexAccess> xIndexAccess(xPage,
+                                                                       
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::drawing::XShape> 
xShape(xIndexAccess->getByIndex(0),
+                                                         
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::beans::XPropertySet> xProps(xShape, 
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::text::XTextColumns> 
xCols(xProps->getPropertyValue("TextColumns"),
+                                                           
css::uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xCols->getColumnCount());
+        css::uno::Reference<css::beans::XPropertySet> xColProps(xCols, 
css::uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(css::uno::Any(sal_Int32(1000)),
+                             xColProps->getPropertyValue("AutomaticDistance"));
+    }
+
+    auto tempFile = exportTo(xDocSh.get(), FORMAT_ODS);
+    xDocSh = load(tempFile->GetURL(), FORMAT_ODS);
+    CPPUNIT_ASSERT(xDocSh);
+
+    {
+        css::uno::Reference<css::drawing::XDrawPagesSupplier> 
xSupplier(xDocSh->GetModel(),
+                                                                        
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::drawing::XDrawPage> 
xPage(xSupplier->getDrawPages()->getByIndex(0),
+                                                           
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::container::XIndexAccess> xIndexAccess(xPage,
+                                                                       
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::drawing::XShape> 
xShape(xIndexAccess->getByIndex(0),
+                                                         
css::uno::UNO_QUERY_THROW);
+        css::uno::Reference<css::beans::XPropertySet> xProps(xShape, 
css::uno::UNO_QUERY_THROW);
+
+        // Without the fix in place, this would have failed with:
+        //   An uncaught exception of type com.sun.star.uno.RuntimeException
+        //   - unsatisfied query for interface of type 
com.sun.star.text.XTextColumns!
+        css::uno::Reference<css::text::XTextColumns> 
xCols(xProps->getPropertyValue("TextColumns"),
+                                                           
css::uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(sal_Int16(2), xCols->getColumnCount());
+        css::uno::Reference<css::beans::XPropertySet> xColProps(xCols, 
css::uno::UNO_QUERY_THROW);
+        CPPUNIT_ASSERT_EQUAL(css::uno::Any(sal_Int32(1000)),
+                             xColProps->getPropertyValue("AutomaticDistance"));
+    }
+
+    xDocSh->DoClose();
+
+    xmlDocUniquePtr pXmlDoc = XPathHelper::parseExport(tempFile, m_xSFactory, 
"content.xml");
+    CPPUNIT_ASSERT(pXmlDoc);
+    // Without the fix in place, this would have failed with:
+    //   - Expected: 1
+    //   - Actual  : 0
+    //   - In <>, XPath 
'/office:document-content/office:automatic-styles/style:style[@style:family='graphic']/
+    //     style:graphic-properties/style:columns' number of nodes is incorrect
+    assertXPath(
+        pXmlDoc,
+        
"/office:document-content/office:automatic-styles/style:style[@style:family='graphic']/"
+        "style:graphic-properties/style:columns",
+        "column-count", "2");
+    // Only test that "column-gap" attribute exists, not its value that 
depends on locale (cm, in)
+    getXPath(
+        pXmlDoc,
+        
"/office:document-content/office:automatic-styles/style:style[@style:family='graphic']/"
+        "style:graphic-properties/style:columns",
+        "column-gap");
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/xml/xmlexprt.cxx 
b/sc/source/filter/xml/xmlexprt.cxx
index 28233c05fdd2..497daf4a49e3 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -312,7 +312,12 @@ namespace {
 class ScXMLShapeExport : public XMLShapeExport
 {
 public:
-    explicit ScXMLShapeExport(SvXMLExport& rExp) : XMLShapeExport(rExp) {}
+    explicit ScXMLShapeExport(SvXMLExport& rExp)
+        : XMLShapeExport(rExp,
+                         // chain text attributes
+                         XMLTextParagraphExport::CreateParaExtPropMapper(rExp))
+    {
+    }
 
     /** is called before a shape element for the given XShape is exported */
     virtual void onExport( const uno::Reference < drawing::XShape >& xShape ) 
override;

Reply via email to