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.shi...@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; } _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits