diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index 675a012617ed..12e599211730 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -2579,7 +2579,7 @@ DECLARE_OOXMLEXPORT_TEST(testEmbeddedXlsx, "embedded-xlsx.docx") int nImageFiles = 0; for (int i=0; i xPropSet( m_rExport.pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW ); + OUString pName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG; + uno::Sequence< beans::PropertyValue > aGrabBag, aObjectsInteropList; + xPropSet->getPropertyValue( pName ) >>= aGrabBag; + for( sal_Int32 i=0; i < aGrabBag.getLength(); ++i ) + if ( aGrabBag[i].Name == "EmbeddedObjects" ) + { + aGrabBag[i].Value >>= aObjectsInteropList; + break; + } + for( std::list< PostponedOLE >::iterator it = m_postponedOLE->begin(); it != m_postponedOLE->end(); ++it ) { + SwOLEObj& aObject = it->object->GetOLEObj(); + uno::Reference < embed::XEmbeddedObject > xObj( aObject.GetOleRef() ); + comphelper::EmbeddedObjectContainer* aContainer = aObject.GetObject().GetContainer(); + OUString sObjectName = aContainer->GetEmbeddedObjectName( xObj ); + + // set some attributes according to the type of the embedded object + OUString sProgID, sMediaType, sRelationType; + for( sal_Int32 i=0; i < aObjectsInteropList.getLength(); ++i ) + if ( aObjectsInteropList[i].Name == sObjectName ) + { + aObjectsInteropList[i].Value >>= sProgID; + break; + } + if( sProgID.startsWith("Excel.Sheet") ) + { + sMediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; + sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"; + } + else if( sProgID.startsWith("PowerPoint.Show") ) + { + sMediaType = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; + sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package"; + } + else + { + sMediaType = "application/vnd.openxmlformats-officedocument.oleObject"; + sRelationType = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"; + } + // write embedded file - OString sId = m_rExport.WriteOLENode( *it->object ); + OString sId = m_rExport.WriteOLEObject( aObject, sMediaType, sRelationType ); if( sId.isEmpty() ) { @@ -3612,7 +3653,7 @@ void DocxAttributeOutput::WritePostponedOLE() // OLE object definition m_pSerializer->singleElementNS( XML_o, XML_OLEObject, XML_Type, "Embed", - XML_ProgID,"Excel.Sheet.12", //TODO: should be auto-detected somehow + XML_ProgID, OUStringToOString( sProgID, RTL_TEXTENCODING_UTF8 ).getStr(), XML_ShapeID, sShapeId.getStr(), XML_DrawAspect, "Content", XML_ObjectID, "_" + OString::number( rand() ), diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 41e70834de67..79077f5c554a 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -358,25 +358,23 @@ OString DocxExport::OutputChart( uno::Reference< frame::XModel >& xModel, sal_In return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 ); } -OString DocxExport::WriteOLENode( const SwOLENode& rNode ) +OString DocxExport::WriteOLEObject( SwOLEObj& rObject, OUString sMediaType, OUString sRelationType ) { - uno::Reference xObj( const_cast(rNode).GetOLEObj().GetOleRef() ); - OUString sId, sMediaType; - comphelper::EmbeddedObjectContainer* aContainer = const_cast(rNode).GetOLEObj().GetObject().GetContainer(); - uno::Reference< io::XInputStream > xInStream = aContainer->GetObjectStream( xObj, &sMediaType ); + uno::Reference xObj( rObject.GetOleRef() ); + comphelper::EmbeddedObjectContainer* aContainer = rObject.GetObject().GetContainer(); + uno::Reference< io::XInputStream > xInStream = aContainer->GetObjectStream( xObj, NULL ); - OUString sFileName = "embeddings/Microsoft_Excel_Worksheet" + OUString::number( ++m_nOLEObjects ) + ".xlsx"; + OUString sFileName = "embeddings/oleObject" + OUString::number( ++m_nOLEObjects ) + ".bin"; uno::Reference< io::XOutputStream > xOutStream = GetFilter().openFragmentStream( OUStringBuffer() .appendAscii( "word/" ) .append( sFileName ) .makeStringAndClear(), sMediaType ); - + OUString sId; if( lcl_CopyStream( xInStream, xOutStream ) ) sId = m_pFilter->addRelation( m_pDocumentFS->getOutputStream(), - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/package", - sFileName, false ); + sRelationType, sFileName, false ); return OUStringToOString( sId, RTL_TEXTENCODING_UTF8 ); } diff --git a/sw/source/filter/ww8/docxexport.hxx b/sw/source/filter/ww8/docxexport.hxx index 4ce76e31d7d1..01679d122a96 100644 --- a/sw/source/filter/ww8/docxexport.hxx +++ b/sw/source/filter/ww8/docxexport.hxx @@ -165,7 +165,7 @@ public: /// Returns the relationd id OString OutputChart( com::sun::star::uno::Reference< com::sun::star::frame::XModel >& xModel, sal_Int32 nCount, ::sax_fastparser::FSHelperPtr m_pSerializer ); - OString WriteOLENode( const SwOLENode& rNode ); + OString WriteOLEObject( SwOLEObj& rObject, OUString sMediaType, OUString sRelationType ); bool lcl_CopyStream( css::uno::Reference< css::io::XInputStream> xIn, css::uno::Reference< css::io::XOutputStream > xOut ); /// Writes the shape using drawingML syntax. diff --git a/writerfilter/source/dmapper/OLEHandler.cxx b/writerfilter/source/dmapper/OLEHandler.cxx index f9487e2aa3a4..fb49aa405df9 100644 --- a/writerfilter/source/dmapper/OLEHandler.cxx +++ b/writerfilter/source/dmapper/OLEHandler.cxx @@ -20,6 +20,7 @@ #include #include "GraphicHelpers.hxx" +#include #include #include #include @@ -170,6 +171,48 @@ void OLEHandler::lcl_sprm(Sprm & rSprm) } +void OLEHandler::saveInteropProperties( uno::Reference< text::XTextDocument > xTextDocument, OUString sObjectName ) +{ + const OUString sGrabBagPropName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG; + const OUString sEmbeddingsPropName = "EmbeddedObjects"; + + // get interop grab bag from document + uno::Reference< beans::XPropertySet > xDocProps( xTextDocument, uno::UNO_QUERY ); + uno::Sequence< beans::PropertyValue > aGrabBag; + xDocProps->getPropertyValue( sGrabBagPropName ) >>= aGrabBag; + + // get EmbeddedObjects property inside grab bag + sal_Int32 i = 0; + sal_Int32 nBagLength = aGrabBag.getLength(); + uno::Sequence< beans::PropertyValue > objectsList; + for( ; i < nBagLength; ++i ) + if ( aGrabBag[i].Name == sEmbeddingsPropName ) + { + aGrabBag[i].Value >>= objectsList; + break; + } + + // save ProgID of current object + sal_Int32 length = objectsList.getLength(); + objectsList.realloc( length + 1 ); + objectsList[length].Name = sObjectName; + objectsList[length].Value = uno::Any( m_sProgId ); + + // put objects list back into the grab bag + if( i == nBagLength ) + { + aGrabBag.realloc( nBagLength + 1 ); + aGrabBag[nBagLength].Name = sEmbeddingsPropName; + aGrabBag[nBagLength].Value = uno::Any( objectsList ); + } + else + aGrabBag[i].Value = uno::Any( objectsList ); + + // put grab bag back into the document + xDocProps->setPropertyValue( sGrabBagPropName, uno::Any( aGrabBag ) ); +} + + OUString OLEHandler::copyOLEOStream( uno::Reference< text::XTextDocument > xTextDocument ) { OUString sRet; @@ -202,6 +245,8 @@ OUString OLEHandler::copyOLEOStream( uno::Reference< text::XTextDocument > xText } } + saveInteropProperties( xTextDocument, aURL ); + static const OUString sProtocol("vnd.sun.star.EmbeddedObject:"); OUString aPersistName( xEmbeddedResolver->resolveEmbeddedObjectURL( aURL ) ); sRet = aPersistName.copy( sProtocol.getLength() ); diff --git a/writerfilter/source/dmapper/OLEHandler.hxx b/writerfilter/source/dmapper/OLEHandler.hxx index 1416a708f928..7a76dd076605 100644 --- a/writerfilter/source/dmapper/OLEHandler.hxx +++ b/writerfilter/source/dmapper/OLEHandler.hxx @@ -69,6 +69,10 @@ class OLEHandler : public LoggedProperties virtual void lcl_attribute(Id Name, Value & val); virtual void lcl_sprm(Sprm & sprm); + // Interoperability + virtual void saveInteropProperties( ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextDocument > xTextDocument, + OUString sObjectName ); + public: OLEHandler(); virtual ~OLEHandler();