[Libreoffice-commits] core.git: chart2/qa oox/source sw/source writerfilter/inc writerfilter/source

sushil_shinde sushil.shinde at synerzip.com
Sun Mar 23 03:02:58 PDT 2014


 chart2/qa/extras/chart2export.cxx                            |   39 ++++++
 chart2/qa/extras/data/docx/testchartoleobjectembeddings.docx |binary
 oox/source/export/chartexport.cxx                            |    6 
 sw/source/filter/ww8/docxexport.cxx                          |    2 
 writerfilter/inc/ooxml/OOXMLDocument.hxx                     |    2 
 writerfilter/source/ooxml/OOXMLDocumentImpl.cxx              |   68 ++++++++---
 writerfilter/source/ooxml/OOXMLDocumentImpl.hxx              |    3 
 writerfilter/source/ooxml/OOXMLStreamImpl.cxx                |   23 +++
 8 files changed, 125 insertions(+), 18 deletions(-)

New commits:
commit 23b65a84fd827555dfb84c7e2f78879c479c2f78
Author: sushil_shinde <sushil.shinde at synerzip.com>
Date:   Wed Mar 19 18:34:45 2014 +0530

    fdo#76356 : Docx file contianing chart in footer/header gets corrupted.
    
        -  Docx file with chart in footer/header or .bin file referred in chart
           was getting corrupted.
        -  Embedded file for footer.xml was not grabbaged.
        -  .bin embedded files were not grab baged.
        -  Added grab bag support for both case.
        -  Added UT to check .bin files are grab baged properly.
    
    Reviewed on:
    	https://gerrit.libreoffice.org/8674
    
    Change-Id: I221e3867798fc2a3a42f6385d687e80b80a3678f

diff --git a/chart2/qa/extras/chart2export.cxx b/chart2/qa/extras/chart2export.cxx
index 5a57ea4..c0d20f1 100644
--- a/chart2/qa/extras/chart2export.cxx
+++ b/chart2/qa/extras/chart2export.cxx
@@ -52,6 +52,7 @@ public:
     void testErrorBarDataRangeODS();
     void testChartCrash();
     void testPieChartRotation();
+    void testEmbeddingsOleObjectGrabBag();
 
     CPPUNIT_TEST_SUITE(Chart2ExportTest);
     CPPUNIT_TEST(test);
@@ -76,6 +77,7 @@ public:
     CPPUNIT_TEST(testErrorBarDataRangeODS);
     CPPUNIT_TEST(testChartCrash);
     CPPUNIT_TEST(testPieChartRotation);
+    CPPUNIT_TEST(testEmbeddingsOleObjectGrabBag);
     CPPUNIT_TEST_SUITE_END();
 
 protected:
@@ -673,6 +675,43 @@ void Chart2ExportTest::testPieChartRotation()
     assertXPath(pXmlDoc, "/c:chartSpace/c:chart/c:view3D/c:rotY", "val", "30");
 }
 
+void Chart2ExportTest::testEmbeddingsOleObjectGrabBag()
+{
+   // The problem was that .bin files were missing from docx file from embeddings folder
+   // after saving file.
+   // This test case tests whether embeddings files grabbagged properly in correct object.
+
+   load("/chart2/qa/extras/data/docx/", "testchartoleobjectembeddings.docx" );
+   uno::Reference<text::XTextDocument> xTextDocument(mxComponent, uno::UNO_QUERY);
+   uno::Reference<beans::XPropertySet> xTextDocumentPropertySet(xTextDocument, uno::UNO_QUERY);
+   uno::Sequence<beans::PropertyValue> aGrabBag(0);
+   xTextDocumentPropertySet->getPropertyValue(OUString("InteropGrabBag")) >>= aGrabBag;
+   CPPUNIT_ASSERT(aGrabBag.hasElements()); // Grab Bag not empty
+   bool bEmbeddings = false;
+   const char* testEmbeddedFileNames[1] = {"word/embeddings/oleObject1.bin"};
+   for(int i = 0; i < aGrabBag.getLength(); ++i)
+   {
+       if (aGrabBag[i].Name == "OOXEmbeddings")
+       {
+           bEmbeddings = true;
+           uno::Sequence<beans::PropertyValue> aEmbeddingsList(0);
+           uno::Reference<io::XInputStream> aEmbeddingXlsxStream;
+           OUString aEmbeddedfileName;
+           CPPUNIT_ASSERT(aGrabBag[i].Value >>= aEmbeddingsList); // PropertyValue of proper type
+           sal_Int32 length = aEmbeddingsList.getLength();
+           CPPUNIT_ASSERT_EQUAL(sal_Int32(1), length);
+           for(int j = 0; j < length; ++j)
+           {
+               aEmbeddingsList[j].Value >>= aEmbeddingXlsxStream;
+               aEmbeddedfileName = aEmbeddingsList[j].Name;
+               CPPUNIT_ASSERT(aEmbeddingXlsxStream.get()); // Reference not empty
+               CPPUNIT_ASSERT_EQUAL(OUString::createFromAscii(testEmbeddedFileNames[j]),aEmbeddedfileName);
+           }
+       }
+   }
+   CPPUNIT_ASSERT(bEmbeddings); // Grab Bag has all the expected elements
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/chart2/qa/extras/data/docx/testchartoleobjectembeddings.docx b/chart2/qa/extras/data/docx/testchartoleobjectembeddings.docx
new file mode 100644
index 0000000..8167de7
Binary files /dev/null and b/chart2/qa/extras/data/docx/testchartoleobjectembeddings.docx differ
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index 91d761f..0d30e29 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -801,8 +801,12 @@ void ChartExport::exportExternalData( Reference< ::com::sun::star::chart::XChart
             }
         }
         FSHelperPtr pFS = GetFS();
+        OUString type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
+        if (relationPath.endsWith(OUString(".bin")))
+            type = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject";
+
         OUString sRelId = GetFB()->addRelation(pFS->getOutputStream(),
-                        "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package",
+                        type,
                         relationPath);
         pFS->singleElementNS( XML_c, XML_externalData,
                 FSNS(XML_r, XML_id), OUStringToOString(sRelId, RTL_TEXTENCODING_UTF8),
diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx
index 5e20cc3..ff74f3a 100644
--- a/sw/source/filter/ww8/docxexport.cxx
+++ b/sw/source/filter/ww8/docxexport.cxx
@@ -1217,6 +1217,8 @@ void DocxExport::WriteEmbeddings()
         OUString contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
         if (embeddingPath.endsWith(OUString(".xlsm")))
             contentType = "application/vnd.ms-excel.sheet.macroEnabled.12";
+        else if (embeddingPath.endsWith(OUString(".bin")))
+            contentType = "application/vnd.openxmlformats-officedocument.oleObject";
 
         if ( embeddingsStream.is() )
         {
diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx
index 7f104ab..c7b4ec1 100644
--- a/writerfilter/inc/ooxml/OOXMLDocument.hxx
+++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx
@@ -77,7 +77,7 @@ class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream
 {
 public:
     enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, WEBSETTINGS, FONTTABLE, NUMBERING,
-        FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT };
+        FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, GLOSSARY, CHARTS, EMBEDDINGS, SETTINGS, VBAPROJECT, FOOTER, HEADER };
     typedef boost::shared_ptr<OOXMLStream> Pointer_t;
 
     virtual ~OOXMLStream() {}
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
index 83cdb58..9a1c50c 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx
@@ -233,6 +233,10 @@ void OOXMLDocumentImpl::importSubStreamRelations(OOXMLStream::Pointer_t pStream,
             // imporing activex.bin files for activex.xml from activeX folder.
             mxEmbeddings = xcpInputStream;
         }
+        else if(OOXMLStream::CHARTS == nType)
+        {
+            importSubStreamRelations(cStream, OOXMLStream::EMBEDDINGS);
+        }
     }
 
 
@@ -494,7 +498,7 @@ void OOXMLDocumentImpl::resolve(Stream & rStream)
         if (mxGlossaryDocDom.is())
             resolveGlossaryStream(rStream);
 
-        resolveEmbeddingsStream(rStream);
+        resolveEmbeddingsStream(mpStream);
 
         // Custom xml's are handled as part of grab bag.
         resolveCustomXmlStream(rStream);
@@ -705,20 +709,25 @@ void OOXMLDocumentImpl::resolveGlossaryStream(Stream & /*rStream*/)
       }
 }
 
-void OOXMLDocumentImpl::resolveEmbeddingsStream(Stream & /*rStream*/)
+void OOXMLDocumentImpl::resolveEmbeddingsStream(OOXMLStream::Pointer_t pStream)
 {
     uno::Reference<embed::XRelationshipAccess> mxRelationshipAccess;
-    mxRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*mpStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
+    mxRelationshipAccess.set((dynamic_cast<OOXMLStreamImpl&>(*pStream.get())).accessDocumentStream(), uno::UNO_QUERY_THROW);
     if (mxRelationshipAccess.is())
     {
         OUString sChartType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart");
         OUString sChartTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/chart");
+        OUString sFootersType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
+        OUString sFootersTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/footer");
+        OUString sHeaderType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
+        OUString sHeaderTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/header");
+
         OUString sTarget("Target");
         bool bFound = false;
-        sal_Int32 counter = 0;
+        bool bHeaderFooterFound = false;
+        OOXMLStream::StreamType_t streamType;
         uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs =
                 mxRelationshipAccess->getAllRelationships();
-        uno::Sequence<beans::PropertyValue > mxEmbeddingsListTemp(aSeqs.getLength());
         for (sal_Int32 j = 0; j < aSeqs.getLength(); j++)
         {
             uno::Sequence< beans::StringPair > aSeq = aSeqs[j];
@@ -727,34 +736,65 @@ void OOXMLDocumentImpl::resolveEmbeddingsStream(Stream & /*rStream*/)
                 beans::StringPair aPair = aSeq[i];
                 if (aPair.Second.compareTo(sChartType) == 0 ||
                         aPair.Second.compareTo(sChartTypeStrict) == 0)
+                {
                     bFound = true;
-                else if(aPair.First.compareTo(sTarget) == 0 && bFound)
+                }
+                else if(aPair.Second.compareTo(sFootersType) == 0 ||
+                        aPair.Second.compareTo(sFootersTypeStrict) == 0)
+                {
+                    bHeaderFooterFound = true;
+                    streamType = OOXMLStream::FOOTER;
+                }
+                else if(aPair.Second.compareTo(sHeaderType) == 0 ||
+                        aPair.Second.compareTo(sHeaderTypeStrict) == 0)
+                {
+                    bHeaderFooterFound = true;
+                    streamType = OOXMLStream::HEADER;
+                }
+                else if(aPair.First.compareTo(sTarget) == 0 && ( bFound || bHeaderFooterFound ))
                 {
                     // Adding value to extern variable customTarget. It will be used in ooxmlstreamimpl
                     // to ensure chart.xml target is visited in lcl_getTarget.
                     customTarget = aPair.Second;
                 }
             }
-            if(bFound)
+            if(( bFound || bHeaderFooterFound))
             {
-                uno::Reference<xml::dom::XDocument> chartTemp = importSubStream(OOXMLStream::CHARTS);
+                if(bFound)
+                {
+                    importSubStreamRelations(pStream, OOXMLStream::CHARTS);
+                }
+                if(bHeaderFooterFound)
+                {
+                    OOXMLStream::Pointer_t Stream = OOXMLDocumentFactory::createStream(pStream, streamType);
+                    if(Stream)
+                        resolveEmbeddingsStream(Stream);
+                }
+
                 beans::PropertyValue embeddingsTemp;
-                // This will add all ActiveX[n].xml to grabbag list.
-                if(chartTemp.is())
+                // This will add all .xlsx and .bin to grabbag list.
+                if(bFound)
                 {
                     if(mxEmbeddings.is())
                     {
                         embeddingsTemp.Name = embeddingsTarget;
                         embeddingsTemp.Value = uno::makeAny(mxEmbeddings);
-                        mxEmbeddingsListTemp[counter] = embeddingsTemp;
+                        mxEmbeddingsListTemp.push_back(embeddingsTemp);
+                        mxEmbeddings.clear();
                     }
-                    counter++;
                 }
                 bFound = false;
+                bHeaderFooterFound = false;
             }
         }
-        mxEmbeddingsListTemp.realloc(counter);
-        mxEmbeddingsList = mxEmbeddingsListTemp;
+    }
+    if(0 != mxEmbeddingsListTemp.size())
+    {
+        mxEmbeddingsList.realloc(mxEmbeddingsListTemp.size());
+        for (size_t i = 0; i < mxEmbeddingsListTemp.size(); i++)
+        {
+            mxEmbeddingsList[i] = mxEmbeddingsListTemp[i];
+        }
     }
 }
 
diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
index 4af7570..c36945a 100644
--- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
+++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx
@@ -53,6 +53,7 @@ class OOXMLDocumentImpl : public OOXMLDocument
     uno::Reference<io::XInputStream> mxActiveXBin;
     uno::Reference<io::XInputStream> mxEmbeddings;
     uno::Sequence < beans::PropertyValue > mxEmbeddingsList;
+    std::vector<beans::PropertyValue> mxEmbeddingsListTemp;
     bool mbIsSubstream;
     /// How many paragraphs equal to 1 percent?
     sal_Int32 mnPercentSize;
@@ -87,7 +88,7 @@ protected:
     void resolveCustomXmlStream(Stream & rStream);
     void resolveActiveXStream(Stream & rStream);
     void resolveGlossaryStream(Stream & rStream);
-    void resolveEmbeddingsStream(Stream & rStream);
+    void resolveEmbeddingsStream(OOXMLStream::Pointer_t pStream);
 public:
     OOXMLDocumentImpl(OOXMLStream::Pointer_t pStream, const uno::Reference<task::XStatusIndicator>& xStatusIndicator);
     virtual ~OOXMLDocumentImpl();
diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
index 8f81842..6c6b2ee 100644
--- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
+++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx
@@ -119,6 +119,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
     static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings");
     static OUString sChartType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart");
     static OUString sEmbeddingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/package");
+    static OUString sFooterType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer");
+    static OUString sHeaderType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/header");
+    static OUString sOleObjectType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject");
     // OOXML strict
     static OUString sDocumentTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument");
     static OUString sStylesTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/styles");
@@ -136,6 +139,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
     static OUString sSettingsTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/settings");
     static OUString sChartTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/chart");
     static OUString sEmbeddingsTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/package");
+    static OUString sFootersTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/footer");
+    static OUString sHeaderTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/header");
+    static OUString sOleObjectTypeStrict("http://purl.oclc.org/ooxml/officeDocument/relationships/oleObject");
     static OUString sTarget("Target");
     static OUString sTargetMode("TargetMode");
     static OUString sExternal("External");
@@ -218,6 +224,14 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
             sStreamType = sEmbeddingsType;
             sStreamTypeStrict = sEmbeddingsTypeStrict;
           break;
+        case FOOTER:
+            sStreamType = sFooterType;
+            sStreamTypeStrict = sFootersTypeStrict;
+          break;
+        case HEADER:
+            sStreamType = sHeaderType;
+            sStreamTypeStrict = sHeaderTypeStrict;
+          break;
         default:
             break;
     }
@@ -241,13 +255,20 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess>
                     ( aPair.Second.compareTo(sStreamType) == 0 ||
                       aPair.Second.compareTo(sStreamTypeStrict) == 0))
                     bFound = true;
+                else if(aPair.First.compareTo(sType) == 0 &&
+                        ((aPair.Second.compareTo(sOleObjectType) == 0 ||
+                          aPair.Second.compareTo(sOleObjectTypeStrict) == 0) &&
+                          nStreamType == EMBEDDINGS))
+                {
+                    bFound = true;
+                }
                 else if (aPair.First.compareTo(sId) == 0 &&
                          aPair.Second.compareTo(rId) == 0)
                     bFound = true;
                 else if (aPair.First.compareTo(sTarget) == 0)
                 {
                     // checking item[n].xml or activex[n].xml is not visited already.
-                    if(customTarget != aPair.Second && (sStreamType == sCustomType || sStreamType == sActiveXType || sStreamType == sChartType))
+                    if(customTarget != aPair.Second && (sStreamType == sCustomType || sStreamType == sActiveXType || sStreamType == sChartType || sStreamType == sFooterType || sStreamType == sHeaderType))
                     {
                         bFound = false;
                     }


More information about the Libreoffice-commits mailing list