diff options
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/activexbin.docx | bin | 0 -> 363044 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 28 | ||||
-rw-r--r-- | sw/source/filter/ww8/docxexport.cxx | 54 | ||||
-rw-r--r-- | writerfilter/inc/ooxml/OOXMLDocument.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/filter/ImportFilter.cxx | 6 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.cxx | 66 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLDocumentImpl.hxx | 3 | ||||
-rw-r--r-- | writerfilter/source/ooxml/OOXMLStreamImpl.cxx | 6 |
8 files changed, 140 insertions, 26 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/activexbin.docx b/sw/qa/extras/ooxmlexport/data/activexbin.docx Binary files differnew file mode 100644 index 000000000000..e7c15e81cfb7 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/activexbin.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 66a24c57dd53..18a00310e760 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -1617,6 +1617,34 @@ DECLARE_OOXML_TEST(testActiveXGrabBag, "activex.docx") CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements } +DECLARE_OOXML_TEST(testActiveXBinGrabBag, "activexbin.docx") +{ + // The problem was that activeX.bin files were missing from docx file after saving file. + // This test case tests whether activex bin files grabbagged properly in correct object. + + 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 bActiveX = sal_False; + for(int i = 0; i < aGrabBag.getLength(); ++i) + { + if (aGrabBag[i].Name == "OOXActiveXBin") + { + bActiveX = sal_True; + uno::Reference<io::XInputStream> aActiveXBin; + uno::Sequence<uno::Reference<io::XInputStream> > aActiveXBinList; + CPPUNIT_ASSERT(aGrabBag[i].Value >>= aActiveXBinList); // PropertyValue of proper type + sal_Int32 length = aActiveXBinList.getLength(); + CPPUNIT_ASSERT_EQUAL(sal_Int32(5), length); + aActiveXBin = aActiveXBinList[0]; + CPPUNIT_ASSERT(aActiveXBin.get()); // Reference not empty + } + } + CPPUNIT_ASSERT(bActiveX); // Grab Bag has all the expected elements +} + DECLARE_OOXML_TEST(testFdo69644, "fdo69644.docx") { // The problem was that the exporter exported the table definition diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 9053d6b5719c..e29cd64f0b8c 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -867,6 +867,7 @@ void DocxExport::WriteActiveX() return; uno::Sequence<uno::Reference<xml::dom::XDocument> > activeXDomlist; + uno::Sequence<uno::Reference<io::XInputStream> > activeXBinList; uno::Sequence< beans::PropertyValue > propList; xPropSet->getPropertyValue( pName ) >>= propList; for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp ) @@ -879,9 +880,20 @@ void DocxExport::WriteActiveX() } } + for ( sal_Int32 nProp=0; nProp < propList.getLength(); ++nProp ) + { + OUString propName = propList[nProp].Name; + if ( propName == "OOXActiveXBin" ) + { + propList[nProp].Value >>= activeXBinList; + break; + } + } + for (sal_Int32 j = 0; j < activeXDomlist.getLength(); j++) { uno::Reference<xml::dom::XDocument> activeXDom = activeXDomlist[j]; + uno::Reference<io::XInputStream> activeXBin = activeXBinList[j]; if ( activeXDom.is() ) { @@ -895,7 +907,47 @@ void DocxExport::WriteActiveX() "application/vnd.ms-office.activeX+xml" ) ); serializer->serialize( uno::Reference< xml::sax::XDocumentHandler >( writer, uno::UNO_QUERY_THROW ), uno::Sequence< beans::StringPair >() ); - } + } + + if ( activeXBin.is() ) + { + uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream("word/activeX/activeX"+OUString::number((j+1))+".bin", + "application/vnd.ms-office.activeX"); + + try + { + sal_Int32 nBufferSize = 512; + uno::Sequence< sal_Int8 > aDataBuffer(nBufferSize); + sal_Int32 nRead; + do + { + nRead = activeXBin->readBytes( aDataBuffer, nBufferSize ); + if( nRead ) + { + if( nRead < nBufferSize ) + { + nBufferSize = nRead; + aDataBuffer.realloc(nRead); + } + xOutStream->writeBytes( aDataBuffer ); + } + } + while( nRead ); + xOutStream->flush(); + } + catch(const uno::Exception&) + { + SAL_WARN("sw.ww8", "WriteActiveX() ::Failed to copy Inputstream to outputstream exception catched!"); + } + + xOutStream->closeOutput(); + // Adding itemprops's relationship entry to item.xml.rels file + m_pFilter->addRelation( GetFilter().openFragmentStream( "/word/activeX/activeX"+OUString::number((j+1))+".xml", + "application/vnd.ms-office.activeX+xml" ) , + "http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary", + "activeX"+OUString::number((j+1))+".bin" ); + + } } } diff --git a/writerfilter/inc/ooxml/OOXMLDocument.hxx b/writerfilter/inc/ooxml/OOXMLDocument.hxx index e75cf629510a..97bb8764494c 100644 --- a/writerfilter/inc/ooxml/OOXMLDocument.hxx +++ b/writerfilter/inc/ooxml/OOXMLDocument.hxx @@ -76,7 +76,7 @@ class WRITERFILTER_OOXML_DLLPUBLIC OOXMLStream { public: enum StreamType_t { UNKNOWN, DOCUMENT, STYLES, FONTTABLE, NUMBERING, - FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, SETTINGS, VBAPROJECT }; + FOOTNOTES, ENDNOTES, COMMENTS, THEME, CUSTOMXML, CUSTOMXMLPROPS, ACTIVEX, ACTIVEXBIN, SETTINGS, VBAPROJECT }; typedef boost::shared_ptr<OOXMLStream> Pointer_t; virtual ~OOXMLStream() {} @@ -245,6 +245,7 @@ public: virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList( ) = 0; virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList( ) = 0; + virtual uno::Sequence<uno::Reference<io::XInputStream> > getActiveXBinList() = 0; }; diff --git a/writerfilter/source/filter/ImportFilter.cxx b/writerfilter/source/filter/ImportFilter.cxx index f29e7ecac39a..ff47df9fbb83 100644 --- a/writerfilter/source/filter/ImportFilter.cxx +++ b/writerfilter/source/filter/ImportFilter.cxx @@ -203,11 +203,15 @@ sal_Bool WriterFilter::filter( const uno::Sequence< beans::PropertyValue >& aDes // We want to keep the previous items xDocProps->getPropertyValue( aGrabBagPropName ) >>= aGrabBag; sal_Int32 length = aGrabBag.getLength(); - aGrabBag.realloc(length+1); + aGrabBag.realloc(length+2); beans::PropertyValue* pValue = aGrabBag.getArray(); pValue[length].Name = "OOXActiveX"; pValue[length].Value = uno::makeAny( pDocument->getActiveXDomList() ); + + pValue[length+1].Name = "OOXActiveXBin"; + pValue[length+1].Value = uno::makeAny( pDocument->getActiveXBinList() ); + xDocProps->setPropertyValue( aGrabBagPropName, uno::Any( aGrabBag ) ); } } diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx index d71c339bf274..f272375b682a 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.cxx @@ -153,6 +153,10 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre { importSubStreamRelations(pStream, OOXMLStream::CUSTOMXMLPROPS); } + if(OOXMLStream::ACTIVEX == nType) + { + importSubStreamRelations(pStream, OOXMLStream::ACTIVEXBIN); + } return xRet; } @@ -160,46 +164,52 @@ uno::Reference<xml::dom::XDocument> OOXMLDocumentImpl::importSubStream(OOXMLStre void OOXMLDocumentImpl::importSubStreamRelations(OOXMLStream::Pointer_t pStream, OOXMLStream::StreamType_t nType) { - // imporing itemprops files for item.xml from customXml. - if(OOXMLStream::CUSTOMXMLPROPS == nType) + uno::Reference<xml::dom::XDocument> xRelation; + OOXMLStream::Pointer_t cStream; + try { - uno::Reference<xml::dom::XDocument> xCustomProps; - OOXMLStream::Pointer_t cStream; - try - { - cStream = OOXMLDocumentFactory::createStream(pStream, OOXMLStream::CUSTOMXMLPROPS); - } - catch (uno::Exception const& e) - { - SAL_WARN("writerfilter", "importSubStreamRelations: exception while " - "importing stream " << nType << " : " << e.Message); - mxCustomXmlProsDom = xCustomProps; - } + cStream = OOXMLDocumentFactory::createStream(pStream, nType); + } + catch (uno::Exception const& e) + { + SAL_WARN("writerfilter", "importSubStreamRelations: exception while " + "importing stream " << nType << " : " << e.Message); + } - uno::Reference<io::XInputStream> xcpInputStream = - cStream->getDocumentStream(); + uno::Reference<io::XInputStream> xcpInputStream = + cStream->getDocumentStream(); - if (xcpInputStream.is()) + if (xcpInputStream.is()) + { + // imporing itemprops files for item.xml from customXml. + if(OOXMLStream::CUSTOMXMLPROPS == nType) { try { uno::Reference<uno::XComponentContext> xcpContext(pStream->getContext()); uno::Reference<xml::dom::XDocumentBuilder> xDomBuilder(xml::dom::DocumentBuilder::create(xcpContext)); - xCustomProps = xDomBuilder->parse(xcpInputStream); + xRelation = xDomBuilder->parse(xcpInputStream); } catch (uno::Exception const& e) { SAL_WARN("writerfilter", "importSubStream: exception while " "parsing stream " << nType << " : " << e.Message); - mxCustomXmlProsDom = xCustomProps; + mxCustomXmlProsDom = xRelation; } - } - if(xCustomProps.is()) + if(xRelation.is()) + { + mxCustomXmlProsDom = xRelation; + } + } + else if(OOXMLStream::ACTIVEXBIN == nType) { - mxCustomXmlProsDom = xCustomProps; + // imporing activex.bin files for activex.xml from activeX folder. + mxActiveXBin = xcpInputStream; } } + + } void OOXMLDocumentImpl::setXNoteId(const sal_Int32 nId) @@ -527,6 +537,7 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) uno::Sequence< uno::Sequence< beans::StringPair > >aSeqs = mxRelationshipAccess->getAllRelationships(); uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomListTemp(aSeqs.getLength()); + uno::Sequence<uno::Reference<io::XInputStream> > mxActiveXBinListTemp(aSeqs.getLength()); for (sal_Int32 j = 0; j < aSeqs.getLength(); j++) { uno::Sequence< beans::StringPair > aSeq = aSeqs[j]; @@ -551,6 +562,10 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) if(activeXTemp.is()) { mxActiveXDomListTemp[counter] = activeXTemp; + if(mxActiveXBin.is()) + { + mxActiveXBinListTemp[counter] = mxActiveXBin; + } counter++; resolveFastSubStream(rStream, OOXMLStream::ACTIVEX); } @@ -558,7 +573,9 @@ void OOXMLDocumentImpl::resolveActiveXStream(Stream & rStream) } } mxActiveXDomListTemp.realloc(counter); + mxActiveXBinListTemp.realloc(counter); mxActiveXDomList = mxActiveXDomListTemp; + mxActiveXBinList = mxActiveXBinListTemp; } } @@ -639,6 +656,11 @@ uno::Sequence<uno::Reference<xml::dom::XDocument> > OOXMLDocumentImpl::getActive return mxActiveXDomList; } +uno::Sequence<uno::Reference<io::XInputStream> > OOXMLDocumentImpl::getActiveXBinList( ) +{ + return mxActiveXBinList; +} + OOXMLDocument * OOXMLDocumentFactory::createDocument (OOXMLStream::Pointer_t pStream) diff --git a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx index 74c1006425eb..d7506cef7135 100644 --- a/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx +++ b/writerfilter/source/ooxml/OOXMLDocumentImpl.hxx @@ -46,6 +46,8 @@ class OOXMLDocumentImpl : public OOXMLDocument uno::Sequence<uno::Reference<xml::dom::XDocument> > mxCustomXmlDomPropsList; uno::Reference<xml::dom::XDocument> mxCustomXmlProsDom; uno::Sequence<uno::Reference<xml::dom::XDocument> > mxActiveXDomList; + uno::Sequence<uno::Reference<io::XInputStream> > mxActiveXBinList; + uno::Reference<io::XInputStream> mxActiveXBin; bool mbIsSubstream; protected: @@ -120,6 +122,7 @@ public: virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomList(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getCustomXmlDomPropsList(); virtual uno::Sequence<uno::Reference<xml::dom::XDocument> > getActiveXDomList(); + virtual uno::Sequence<uno::Reference<io::XInputStream> > getActiveXBinList(); }; }} #endif // OOXML_DOCUMENT_IMPL_HXX diff --git a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx index 8b658c51faeb..dd6875426b33 100644 --- a/writerfilter/source/ooxml/OOXMLStreamImpl.cxx +++ b/writerfilter/source/ooxml/OOXMLStreamImpl.cxx @@ -113,6 +113,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> static OUString sCustomType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml"); static OUString sCustomPropsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps"); static OUString sActiveXType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/control"); + static OUString sActiveXBinType("http://schemas.microsoft.com/office/2006/relationships/activeXControlBinary"); static OUString sSettingsType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings"); static OUString sTarget("Target"); static OUString sTargetMode("TargetMode"); @@ -159,6 +160,9 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> case ACTIVEX: sStreamType = sActiveXType; break; + case ACTIVEXBIN: + sStreamType = sActiveXBinType; + break; case SETTINGS: sStreamType = sSettingsType; break; @@ -189,7 +193,7 @@ bool OOXMLStreamImpl::lcl_getTarget(uno::Reference<embed::XRelationshipAccess> bFound = true; else if (aPair.First.compareTo(sTarget) == 0) { - // checking item[n].xml is not visited already. + // checking item[n].xml or activex[n].xml is not visited already. if(customTarget != aPair.Second && (sStreamType == sCustomType || sStreamType == sActiveXType)) { bFound = false; |