[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - sc/inc sc/qa sc/source

Mike Kaganski (via logerrit) logerrit at kemper.freedesktop.org
Sat Apr 20 14:33:36 UTC 2019


 sc/inc/dpobject.hxx                         |   18 +++++++++
 sc/qa/unit/data/xlsx/pivot_dark1.xlsx       |binary
 sc/qa/unit/pivottable_filters_test.cxx      |   53 ++++++++++++++++++++++++++++
 sc/source/core/data/dpobject.cxx            |    3 +
 sc/source/filter/excel/xepivotxml.cxx       |   42 ++++++++++++++++++++++
 sc/source/filter/inc/pivottablebuffer.hxx   |    3 +
 sc/source/filter/oox/pivottablebuffer.cxx   |   16 ++++++++
 sc/source/filter/oox/pivottablefragment.cxx |    3 +
 8 files changed, 138 insertions(+)

New commits:
commit 33eb6ba09ba5561f71878d998886c54f3e1c5185
Author:     Mike Kaganski <mike.kaganski at collabora.com>
AuthorDate: Thu Apr 18 15:41:03 2019 +0300
Commit:     Mike Kaganski <mike.kaganski at collabora.com>
CommitDate: Sat Apr 20 16:32:51 2019 +0200

    tdf#124810: Roundtrip pivot table style info from XLSX.
    
    Also provide a default pivot table style for those tables that don't
    have a style info. Let's use the style settings that Excel uses.
    
    Change-Id: I8006a33a0aa0e92629f7db0a9c24a6ff52d17945
    Reviewed-on: https://gerrit.libreoffice.org/70933
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kaganski at collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/71006
    Tested-by: Mike Kaganski <mike.kaganski at collabora.com>

diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 39299c79ab26..cba87b674d7c 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -94,6 +94,11 @@ private:
                                             // cached data
     css::uno::Reference<css::sheet::XDimensionsSupplier> xSource;
     ScDPOutput*             pOutput;
+
+    // name -> sequence of sequences of css::xml::FastAttribute or css::xml::Attribute
+    // see PivotTable::putToInteropGrabBag in sc/source/filter/oox/pivottablebuffer.cxx for details
+    std::map<OUString, css::uno::Any> maInteropGrabBag;
+
     long                    nHeaderRows;    // page fields plus filter button
     bool                    mbHeaderLayout:1;  // true : grid, false : standard
     bool                    bAllowMove:1;
@@ -252,6 +257,19 @@ public:
 
     static bool         IsOrientationAllowed( css::sheet::DataPilotFieldOrientation nOrient, sal_Int32 nDimFlags );
 
+    void PutInteropGrabBag(std::map<OUString, css::uno::Any>&& val)
+    {
+        maInteropGrabBag = std::move(val);
+    }
+    std::pair<bool, css::uno::Any> GetInteropGrabBagValue(const OUString& sName) const
+    {
+        const auto it = maInteropGrabBag.find(sName);
+        if (it != maInteropGrabBag.end())
+            return { true, it->second };
+
+        return { false, css::uno::Any() };
+    }
+
 #if DUMP_PIVOT_TABLE
     void Dump() const;
     void DumpCache() const;
diff --git a/sc/qa/unit/data/xlsx/pivot_dark1.xlsx b/sc/qa/unit/data/xlsx/pivot_dark1.xlsx
new file mode 100644
index 000000000000..8341e5b09d6d
Binary files /dev/null and b/sc/qa/unit/data/xlsx/pivot_dark1.xlsx differ
diff --git a/sc/qa/unit/pivottable_filters_test.cxx b/sc/qa/unit/pivottable_filters_test.cxx
index 423e5ff63ead..bd44a8fc4282 100644
--- a/sc/qa/unit/pivottable_filters_test.cxx
+++ b/sc/qa/unit/pivottable_filters_test.cxx
@@ -92,6 +92,7 @@ public:
     void testTdf124651();
     void testTdf124736();
     void tesTtdf124772NumFmt();
+    void testTdf124810();
 
     CPPUNIT_TEST_SUITE(ScPivotTableFiltersTest);
 
@@ -138,6 +139,7 @@ public:
     CPPUNIT_TEST(testTdf124651);
     CPPUNIT_TEST(testTdf124736);
     CPPUNIT_TEST(tesTtdf124772NumFmt);
+    CPPUNIT_TEST(testTdf124810);
 
     CPPUNIT_TEST_SUITE_END();
 
@@ -2560,6 +2562,57 @@ void ScPivotTableFiltersTest::tesTtdf124772NumFmt()
                 "formatCode", "\\$#,##0");
 }
 
+void ScPivotTableFiltersTest::testTdf124810()
+{
+    {
+        // First, test that we roundtrip existing pivot table style information from XLSX.
+        ScDocShellRef xDocSh = loadDoc("pivot_dark1.", FORMAT_XLSX);
+        CPPUNIT_ASSERT(xDocSh.is());
+
+        std::shared_ptr<utl::TempFile> pXPathFile
+            = ScBootstrapFixture::exportTo(xDocSh.get(), FORMAT_XLSX);
+        xDocSh->DoClose();
+
+        xmlDocPtr pTable
+            = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml");
+        CPPUNIT_ASSERT(pTable);
+
+        // All attributes must have been roundtripped correctly (testdoc uses some non-default values)
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "name",
+                    "PivotStyleDark1");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showRowHeaders", "1");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showColHeaders", "1");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showRowStripes", "1");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showColStripes", "0");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showLastColumn", "0");
+    }
+
+    {
+        // Now check that we export default style information when there's no such information in
+        // original document. Just use some ODS as source. This might be changed when we start
+        // exporting better pivot table style information.
+        ScDocShellRef xDocSh = loadDoc("tdf124651_simplePivotTable.", FORMAT_ODS);
+        CPPUNIT_ASSERT(xDocSh.is());
+
+        std::shared_ptr<utl::TempFile> pXPathFile
+            = ScBootstrapFixture::exportTo(xDocSh.get(), FORMAT_XLSX);
+        xDocSh->DoClose();
+
+        xmlDocPtr pTable
+            = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/pivotTables/pivotTable1.xml");
+        CPPUNIT_ASSERT(pTable);
+
+        // The default style for pivot tables in Excel 2007 through 2016 is PivotStyleLight16
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "name",
+                    "PivotStyleLight16");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showRowHeaders", "1");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showColHeaders", "1");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showRowStripes", "0");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showColStripes", "0");
+        assertXPath(pTable, "/x:pivotTableDefinition/x:pivotTableStyleInfo", "showLastColumn", "1");
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScPivotTableFiltersTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 6570542145dd..449e7b35c8f2 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -333,6 +333,7 @@ ScDPObject::ScDPObject(const ScDPObject& r) :
     pServDesc( nullptr ),
     mpTableData(static_cast<ScDPTableData*>(nullptr)),
     pOutput( nullptr ),
+    maInteropGrabBag(r.maInteropGrabBag),
     nHeaderRows( r.nHeaderRows ),
     mbHeaderLayout( r.mbHeaderLayout ),
     bAllowMove(false),
@@ -364,6 +365,7 @@ ScDPObject& ScDPObject::operator= (const ScDPObject& r)
     aTableTag = r.aTableTag;
     aOutRange = r.aOutRange;
     nHeaderRows = r.nHeaderRows;
+    maInteropGrabBag = r.maInteropGrabBag;
     mbHeaderLayout = r.mbHeaderLayout;
     bAllowMove = false;
     bSettingsChanged = false;
@@ -812,6 +814,7 @@ void ScDPObject::Clear()
     pImpDesc = nullptr;
     pServDesc = nullptr;
     ClearTableData();
+    maInteropGrabBag.clear();
 }
 
 void ScDPObject::ClearTableData()
diff --git a/sc/source/filter/excel/xepivotxml.cxx b/sc/source/filter/excel/xepivotxml.cxx
index d333bedd379a..5c3ff71da8a2 100644
--- a/sc/source/filter/excel/xepivotxml.cxx
+++ b/sc/source/filter/excel/xepivotxml.cxx
@@ -711,6 +711,38 @@ sal_Int32 GetSubtotalAttrToken(ScGeneralFunction eFunc)
     return XML_defaultSubtotal;
 }
 
+// An item is expected to contain sequences of css::xml::FastAttribute and css::xml::Attribute
+void WriteGrabBagItemToStream(XclExpXmlStream& rStrm, sal_Int32 tokenId, const css::uno::Any& rItem)
+{
+    css::uno::Sequence<css::uno::Any> aSeqs;
+    if (rItem >>= aSeqs)
+    {
+        auto& pStrm = rStrm.GetCurrentStream();
+        pStrm->write("<")->writeId(tokenId);
+
+        css::uno::Sequence<css::xml::FastAttribute> aFastSeq;
+        css::uno::Sequence<css::xml::Attribute> aUnkSeq;
+        for (const auto& a : aSeqs)
+        {
+            if (a >>= aFastSeq)
+            {
+                for (const auto& rAttr : aFastSeq)
+                    rStrm.WriteAttributes(rAttr.Token, rAttr.Value.toUtf8(), FSEND);
+            }
+            else if (a >>= aUnkSeq)
+            {
+                for (const auto& rAttr : aUnkSeq)
+                    pStrm->write(" ")
+                        ->write(rAttr.Name)
+                        ->write("=\"")
+                        ->writeEscaped(rAttr.Value)
+                        ->write("\"");
+            }
+        }
+
+        pStrm->write("/>");
+    }
+}
 }
 
 void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDPObject& rDPObj, sal_Int32 nCacheId )
@@ -1137,6 +1169,16 @@ void XclExpXmlPivotTables::SavePivotTableXml( XclExpXmlStream& rStrm, const ScDP
         pPivotStrm->endElement(XML_dataFields);
     }
 
+    // Now add style info (use grab bag, or just a set which is default on Excel 2007 through 2016)
+    const auto aValPair = rDPObj.GetInteropGrabBagValue("pivotTableStyleInfo");
+    if (aValPair.first)
+        WriteGrabBagItemToStream(rStrm, XML_pivotTableStyleInfo, aValPair.second);
+    else
+        pPivotStrm->singleElement(XML_pivotTableStyleInfo, XML_name, "PivotStyleLight16",
+                                  XML_showRowHeaders, "1", XML_showColHeaders, "1",
+                                  XML_showRowStripes, "0", XML_showColStripes, "0",
+                                  XML_showLastColumn, "1", FSEND);
+
     OUStringBuffer aBuf("../pivotCache/pivotCacheDefinition");
     aBuf.append(nCacheId);
     aBuf.append(".xml");
diff --git a/sc/source/filter/inc/pivottablebuffer.hxx b/sc/source/filter/inc/pivottablebuffer.hxx
index 083d434bfd58..3c0579a7496a 100644
--- a/sc/source/filter/inc/pivottablebuffer.hxx
+++ b/sc/source/filter/inc/pivottablebuffer.hxx
@@ -297,6 +297,8 @@ public:
     void                importPageField( const AttributeList& rAttribs );
     /** Reads the settings of a field located in the data dimension from the dataField element. */
     void                importDataField( const AttributeList& rAttribs );
+    /** Puts the attributes to the named grab bag value. */
+    void putToInteropGrabBag(const OUString& sName, const AttributeList& rAttribs);
 
     /** Reads global pivot table settings from the PTDEFINITION record. */
     void                importPTDefinition( SequenceInputStream& rStrm );
@@ -379,6 +381,7 @@ private:
     PivotCache*           mpPivotCache;       /// The pivot cache this table is based on.
     css::uno::Reference< css::sheet::XDataPilotDescriptor >
                           mxDPDescriptor;     /// Descriptor of the DataPilot object.
+    std::map<OUString, css::uno::Any> maInteropGrabBag;
 
 };
 
diff --git a/sc/source/filter/oox/pivottablebuffer.cxx b/sc/source/filter/oox/pivottablebuffer.cxx
index 91a0f63915b6..fa54a0e59330 100644
--- a/sc/source/filter/oox/pivottablebuffer.cxx
+++ b/sc/source/filter/oox/pivottablebuffer.cxx
@@ -38,6 +38,7 @@
 #include <com/sun/star/sheet/XDataPilotField.hpp>
 #include <com/sun/star/sheet/XDataPilotTablesSupplier.hpp>
 #include <com/sun/star/sheet/XSheetOperation.hpp>
+#include <com/sun/star/xml/sax/XFastAttributeList.hpp>
 #include <oox/helper/binaryinputstream.hxx>
 #include <oox/helper/attributelist.hxx>
 #include <oox/helper/containerhelper.hxx>
@@ -1033,6 +1034,18 @@ void PivotTable::importDataField( const AttributeList& rAttribs )
     maDataFields.push_back( aModel );
 }
 
+void PivotTable::putToInteropGrabBag(const OUString& sName, const AttributeList& rAttribs)
+{
+    if (auto xFastAttributeList = rAttribs.getFastAttributeList())
+    {
+        // Store both known and unknown attribute sequences to the grab bag as is
+        css::uno::Sequence<css::xml::FastAttribute> aFast = xFastAttributeList->getFastAttributes();
+        css::uno::Sequence<css::xml::Attribute> aUnk = xFastAttributeList->getUnknownAttributes();
+        css::uno::Sequence<css::uno::Any> aVal{ css::uno::Any(aFast), css::uno::Any(aUnk) };
+        maInteropGrabBag[sName] <<= aVal;
+    }
+}
+
 void PivotTable::importPTDefinition( SequenceInputStream& rStrm )
 {
     sal_uInt32 nFlags1, nFlags2, nFlags3;
@@ -1274,6 +1287,9 @@ void PivotTable::finalizeImport()
                 if( !maPageFields.empty() )
                     aPos.Row = ::std::max< sal_Int32 >( static_cast< sal_Int32 >( aPos.Row - maPageFields.size() - 1 ), 0 );
 
+                // save interop grab bag
+                mpDPObject->PutInteropGrabBag(std::move(maInteropGrabBag));
+
                 // insert the DataPilot table into the sheet
                 xDPTables->insertNewByName( maDefModel.maName, aPos, mxDPDescriptor );
             }
diff --git a/sc/source/filter/oox/pivottablefragment.cxx b/sc/source/filter/oox/pivottablefragment.cxx
index 03441459a337..56c0a30c47a2 100644
--- a/sc/source/filter/oox/pivottablefragment.cxx
+++ b/sc/source/filter/oox/pivottablefragment.cxx
@@ -181,6 +181,9 @@ ContextHandlerRef PivotTableFragment::onCreateContext( sal_Int32 nElement, const
                 case XLS_TOKEN( pageFields ):   return this;
                 case XLS_TOKEN( dataFields ):   return this;
                 case XLS_TOKEN( filters ):      return this;
+                case XLS_TOKEN(pivotTableStyleInfo):
+                    mrPivotTable.putToInteropGrabBag("pivotTableStyleInfo", rAttribs);
+                    break;
             }
         break;
 


More information about the Libreoffice-commits mailing list